moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kvoctrain / kvoctrain / kvoctrain.cpp
blobe7f3a6d0b737c7feb3b9207cb562e603dca8f754
1 /***************************************************************************
3 main part of kvoctrain
5 -----------------------------------------------------------------------
7 begin : Thu Mar 11 20:50:53 MET 1999
9 copyright : (C) 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de>
10 (C) 2001 The KDE-EDU team
11 (C) 2004-2005 Peter Hedlund <peter@peterandlinda.com>
13 -----------------------------------------------------------------------
15 ***************************************************************************/
17 /***************************************************************************
18 * *
19 * This program is free software; you can redistribute it and/or modify *
20 * it under the terms of the GNU General Public License as published by *
21 * the Free Software Foundation; either version 2 of the License, or *
22 * (at your option) any later version. *
23 * *
24 ***************************************************************************/
26 #include <kstatusbar.h>
27 #include <klineedit.h>
28 #include <kcombobox.h>
29 #include <kprogress.h>
30 #include <kconfig.h>
31 #include <kstandarddirs.h>
32 #include <klocale.h>
33 #include <kdebug.h>
34 #include <kiconloader.h>
36 #include <kinputdialog.h>
37 #include <qtimer.h>
39 #include <time.h>
40 #include <ctype.h>
42 #include <kvoctraincore.h>
43 #include "kvoctrain.h"
44 #include "entry-dialogs/EntryDlg.h"
45 #include "option-dialogs/GeneralOptionsDlg.h"
46 #include "docprop-dialogs/DocPropDlg.h"
47 #include "docprop-dialogs/DocPropLangDlg.h"
48 #include "statistik-dialogs/StatistikDlg.h"
49 #include "common-dialogs/kvoctrainprefs.h"
50 #include "prefs.h"
52 /*void kvoctrainApp::slotSaveOptions()
54 saveOptions(true);
58 kvoctrainApp::~kvoctrainApp()
60 removeEntryDlg();
61 delete header_m;
62 delete btimer;
63 delete view;
64 delete doc;
68 void kvoctrainApp::slotCancelSelection ()
70 view->getTable()->clearSelection();
74 void kvoctrainApp::slotSelectAll ()
76 QTableSelection ts;
77 KVocTrainTable *table = view->getTable();
78 table->clearSelection();
79 ts.init(0,0);
80 ts.expandTo(table->numRows()-1, table->numCols()-1);
81 table->addSelection(ts);
85 void kvoctrainApp::slotCurrentCellChanged(int row, int col)
87 col -= KV_EXTRA_COLS;
89 statusBar()->clear();
90 if ( doc->numEntries() <= row
91 ||doc->numLangs() <= col
92 || row < 0
93 || col < 0) {
94 if (rem_label != 0)
95 rem_label->setText (i18n (PREFIX_Remark));
96 if (pron_label != 0)
97 pron_label->setText (i18n (PREFIX_Pronunce));
98 if (type_label != 0)
99 type_label->setText (i18n (PREFIX_Type));
101 if (entryDlg != 0) {
102 slotEditEntry(row, col+KV_EXTRA_COLS);
103 entryDlg->setEnabled(EntryDlg::EnableOnlyCommon);
106 return;
109 kvoctrainExpr *expr = doc->getEntry(row);
111 if (rem_label != 0)
112 rem_label->setText( i18n(PREFIX_Remark) + expr->getRemark (col) );
113 if (pron_label != 0)
114 pron_label->setText( i18n(PREFIX_Pronunce) + expr->getPronunce (col) );
115 if (type_label != 0)
116 type_label->setText( i18n(PREFIX_Type)
117 + QueryManager::typeStr(expr->getType(col)) );
119 if (entryDlg != 0) {
120 if (col == 0)
121 entryDlg->setEnabled(EntryDlg::EnableOnlyOriginal);
122 else
123 entryDlg->setEnabled(EntryDlg::EnableAll);
124 slotEditEntry(row, col+KV_EXTRA_COLS);
129 void kvoctrainApp::slotEditRow()
131 slotEditEntry (view->getTable()->currentRow(), view->getTable()->currentColumn());
135 void kvoctrainApp::slotEditCallBack(int res)
137 // cout << "secb\n";
138 switch (res) {
139 case EntryDlg::EditCancel:
140 removeEntryDlg();
141 break;
143 case EntryDlg::EditApply:
144 commitEntryDlg(true);
145 if (Prefs::smartAppend())
147 int row = view->getTable()->currentRow();
148 if (row == view->getTable()->numRows()-1)
150 int col = view->getTable()->currentColumn();
151 if (col < view->getTable()->numCols()-1 && col >= KV_COL_ORG )
153 int lesson = doc->getEntry(row)->getLesson();
154 if (lesson >= lessons->count())
155 lesson = QMAX (0, lessons->count()-1);
156 slotChooseLesson(lesson);
158 QString exp;
159 exp = doc->getEntry(row)->getTranslation(col+1-KV_COL_ORG);
160 if (exp.isEmpty())
161 view->getTable()->setCurrentRow(row, col+1);
163 else
164 slotAppendRow();
167 break;
169 case EntryDlg::EditUndo:
170 int row, col;
171 vector<QTableSelection> tabsel;
172 entryDlg->getCell(row, col, tabsel);
173 setDataEntryDlg(row, col);
174 break;
179 void kvoctrainApp::commitEntryDlg(bool force)
181 // cout << "ced\n";
182 if (entryDlg == 0) {
183 kdError() << "kvoctrainApp::commitEntryDlg: entryDlg == 0\n";
184 return;
187 if (!force && entryDlg->isModified() && !Prefs::autoEntryApply()) {
188 if( KMessageBox::No == KMessageBox::warningYesNo(this,
189 i18n("The entry dialog contains unsaved changes.\n"
190 "Do you want to apply or discard your changes?"),
191 kapp->makeStdCaption(i18n("Unsaved Changes")),
192 KStdGuiItem::apply(), KStdGuiItem::discard())) {
193 return;
197 int row, col;
198 vector<QTableSelection> tabsel;
199 entryDlg->getCell(row, col, tabsel);
200 int hasSel = tabsel.size() > 1;
201 if (tabsel.size() == 1)
202 hasSel = (tabsel[0].bottomRow() - tabsel[0].topRow()) > 0;
204 fillLessonBox(doc);
205 if (!hasSel) {
206 kvoctrainExpr *expr = doc->getEntry(row);
207 if (col >= KV_COL_ORG) {
208 col -= KV_EXTRA_COLS;
209 if (col == 0)
210 expr->setOriginal(entryDlg->getExpr());
211 else
212 expr->setTranslation(col, entryDlg->getExpr());
214 expr->setRemark (col, entryDlg->getRemark());
215 expr->setPronunce (col, entryDlg->getPronunce());
217 expr->setSynonym (col, entryDlg->getSynonym());
218 expr->setAntonym (col, entryDlg->getAntonym());
219 expr->setExample (col, entryDlg->getExample());
220 expr->setUsageLabel (col, entryDlg->getUsageLabel());
221 expr->setParaphrase (col, entryDlg->getParaphrase());
222 expr->setConjugation (col, entryDlg->getConjugation());
223 expr->setComparison(col, entryDlg->getComparison() );
224 expr->setMultipleChoice(col, entryDlg->getMultipleChoice() );
226 expr->setFauxAmi (col, entryDlg->getFromFauxAmi(), false);
227 expr->setFauxAmi (col, entryDlg->getToFauxAmi(), true);
228 expr->setGrade(col, entryDlg->getFromGrade(), false);
229 expr->setGrade(col, entryDlg->getToGrade(), true);
230 expr->setQueryCount(col, entryDlg->getFromQCount(), false);
231 expr->setQueryCount(col, entryDlg->getToQCount(), true);
232 expr->setBadCount(col, entryDlg->getFromBCount(), false);
233 expr->setBadCount(col, entryDlg->getToBCount(), true);
234 expr->setQueryDate(col, entryDlg->getFromDate(), false);
235 expr->setQueryDate(col, entryDlg->getToDate(), true);
236 expr->setType (col, entryDlg->getType());
238 for (int j = 0; j <= expr->numTranslations(); j++)
239 if (expr->getType(j).isEmpty() )
240 expr->setType(j, entryDlg->getType());
242 for (int j = 0; j <= expr->numTranslations(); j++)
243 if (QueryManager::getMainType(expr->getType(j))
245 QueryManager::getMainType(entryDlg->getType()) )
246 expr->setType(j, entryDlg->getType());
248 expr->setLesson (entryDlg->getLesson());
249 expr->setActive(entryDlg->getActive());
251 entryDlg->setModified(false);
252 doc->setModified(true);
253 view->getTable()->updateCell(row, col+KV_EXTRA_COLS);
255 else {
256 col -= KV_EXTRA_COLS;
257 for (uint ts = 0; ts < tabsel.size(); ++ts) {
258 for (int er = tabsel[ts].topRow(); er <= tabsel[ts].bottomRow(); ++er) {
259 kvoctrainExpr *expr = doc->getEntry(er);
261 if (col >= 0) {
262 // only updated "common" props in multimode
263 if (entryDlg->fromGradeDirty() )
264 expr->setGrade(col, entryDlg->getFromGrade(), false);
265 if (entryDlg->toGradeDirty() )
266 expr->setGrade(col, entryDlg->getToGrade(), true);
268 if (entryDlg->fromQCountDirty() )
269 expr->setQueryCount(col, entryDlg->getFromQCount(), false);
270 if (entryDlg->toQCountDirty() )
271 expr->setQueryCount(col, entryDlg->getToQCount(), true);
273 if (entryDlg->fromBCountDirty() )
274 expr->setBadCount(col, entryDlg->getFromBCount(), false);
275 if (entryDlg->toBCountDirty() )
276 expr->setBadCount(col, entryDlg->getToBCount(), true);
278 if (entryDlg->fromDateDirty() )
279 expr->setQueryDate(col, entryDlg->getFromDate(), false);
280 if (entryDlg->toDateDirty() )
281 expr->setQueryDate(col, entryDlg->getToDate(), true);
283 if (entryDlg->usageDirty() ) {
284 for (int j = 0; j <= expr->numTranslations(); j++)
285 expr->setUsageLabel (j, entryDlg->getUsageLabel());
288 if (entryDlg->typeDirty() )
289 for (int j = 0; j <= expr->numTranslations(); j++)
290 expr->setType(j, entryDlg->getType());
293 if (entryDlg->activeDirty() )
294 expr->setActive(entryDlg->getActive());
296 if (entryDlg->lessonDirty() )
297 expr->setLesson (entryDlg->getLesson());
300 entryDlg->setModified(false);
301 doc->setModified(true);
302 for (uint ts = 0; ts < tabsel.size(); ++ts)
303 for (int r = tabsel[ts].topRow(); r <= tabsel[ts].bottomRow(); ++r)
304 for (int c = 0; c < view->getTable()->numCols(); ++c)
305 view->getTable()->updateCell(r, c);
311 void kvoctrainApp::createEntryDlg(int row, int col)
313 if (entryDlg != 0) {
314 kdError() << "kvoctrainApp::createEntryDlg: entryDlg != 0\n";
315 return;
318 if ((row < 0) || (col < 0) || (view->getTable()->numRows() <= 0))
319 return;
321 QString title, text, lang;
323 int lesson = doc->getEntry(row)->getLesson();
324 if (lesson >= lessons->count())
325 lesson = QMAX (0, lessons->count()-1);
327 if (col < KV_EXTRA_COLS) {
328 title = i18n("Edit General Properties");
329 col -= KV_EXTRA_COLS;
330 entryDlg = new EntryDlg (
331 this,
332 doc,
333 hasSelection(),
334 true,
343 QString::null,
344 QString::null,
345 QString::null,
346 lesson,
347 lessons,
348 doc->getOriginalIdent(),
349 langset,
350 QString::null,
351 doc->getEntry(row)->getType(col),
352 QString::null,
353 QString::null,
354 QString::null,
355 QString::null,
356 QString::null,
357 QString::null,
358 doc->getConjugation(0),
359 Conjugation(),
360 doc->getArticle(0),
361 Comparison(),
362 MultipleChoice(),
363 querymanager,
364 title,
365 doc->getEntry(row)->isActive(),
366 Prefs::iPAFont());
368 else {
369 col -= KV_EXTRA_COLS;
371 if (col == 0) {
372 lang = doc->getOriginalIdent();
373 text = doc->getEntry(row)->getOriginal();
374 title = i18n("Edit Properties for Original");
376 else {
377 lang = doc->getIdent(col);
378 text = doc->getEntry(row)->getTranslation(col);
379 title = i18n("Edit Properties of a Translation");
382 entryDlg = new EntryDlg (
383 this,
384 doc,
385 hasSelection(),
386 col==0,
387 doc->getEntry(row)->getGrade(col, false),
388 doc->getEntry(row)->getGrade(col, true),
389 doc->getEntry(row)->getQueryCount(col, false),
390 doc->getEntry(row)->getQueryCount(col, true),
391 doc->getEntry(row)->getBadCount(col, false),
392 doc->getEntry(row)->getBadCount(col, true),
393 doc->getEntry(row)->getQueryDate(col, false),
394 doc->getEntry(row)->getQueryDate(col, true),
395 doc->getEntry(row)->getFauxAmi(col, false),
396 doc->getEntry(row)->getFauxAmi(col, true),
397 text,
398 lesson,
399 lessons,
400 lang,
401 langset,
402 doc->getEntry(row)->getRemark(col),
403 doc->getEntry(row)->getType(col),
404 doc->getEntry(row)->getPronunce(col),
405 doc->getEntry(row)->getSynonym(col),
406 doc->getEntry(row)->getAntonym(col),
407 doc->getEntry(row)->getExample(col),
408 doc->getEntry(row)->getUsageLabel(col),
409 doc->getEntry(row)->getParaphrase(col),
410 doc->getConjugation(col),
411 doc->getEntry(row)->getConjugation(col),
412 doc->getArticle(col),
413 doc->getEntry(row)->getComparison(col),
414 doc->getEntry(row)->getMultipleChoice(col),
415 querymanager,
416 title,
417 doc->getEntry(row)->isActive(),
418 Prefs::iPAFont());
420 connect( entryDlg, SIGNAL(sigEditChoice(int)),
421 this, SLOT(slotEditCallBack(int)));
423 view->getTable()->setReadOnly(true);
425 if (col == 0)
426 entryDlg->setEnabled(EntryDlg::EnableOnlyOriginal);
427 else
428 entryDlg->setEnabled(EntryDlg::EnableAll);
430 vector<QTableSelection> tabsel;
431 entryDlg->setCell(row, col+KV_EXTRA_COLS, tabsel);
432 entryDlg->show();
436 void kvoctrainApp::removeEntryDlg()
438 // cout << "red\n";
439 if (entryDlg != 0) {
440 commitEntryDlg(false);
441 delete entryDlg;
442 entryDlg = 0;
445 view->getTable()->setReadOnly(false);
449 void kvoctrainApp::slotEditEntry (int row, int col)
451 if (entryDlg == 0) {
452 createEntryDlg(row, col);
453 return;
456 if (entryDlg->isModified()) {
457 commitEntryDlg(false);
460 setDataEntryDlg(row, col);
464 void kvoctrainApp::setDataEntryDlg (int row, int col)
466 // cout << "sded\n";
467 if (entryDlg == 0) {
468 kdError() << "kvoctrainApp::setDataEntryDlg: entryDlg == 0\n";
469 return;
472 if ((row < 0) || (col < 0) || (view->getTable()->numRows() <= 0))
473 return;
475 QString text, lang, title;
477 kvoctrainExpr *expr = doc->getEntry(row);
479 if (expr == 0)
480 return; // entry delete in the meantime
482 int lesson = expr->getLesson();
483 if (lesson >= lessons->count())
484 lesson = QMAX (0, lessons->count()-1);
486 bool hasSel = hasSelection();
488 if (col < KV_EXTRA_COLS) {
489 title = i18n("Edit General Properties");
490 col -= KV_EXTRA_COLS;
491 entryDlg->setData(doc,
492 hasSel,
493 true,
502 QString::null,
503 QString::null,
504 QString::null,
505 lesson,
506 lessons,
507 doc->getOriginalIdent(),
508 langset,
509 QString::null,
510 doc->getEntry(row)->getType(0),
511 QString::null,
512 QString::null,
513 QString::null,
514 QString::null,
515 QString::null,
516 QString::null,
517 doc->getConjugation(0),
518 Conjugation(),
519 doc->getArticle(0),
520 Comparison(),
521 MultipleChoice(),
522 querymanager,
523 title,
524 doc->getEntry(row)->isActive());
526 else {
527 col -= KV_EXTRA_COLS;
529 if (col == 0) {
530 title = i18n("Edit Properties for Original");
531 lang = doc->getOriginalIdent();
532 text = doc->getEntry(row)->getOriginal();
534 else {
535 lang = doc->getIdent(col);
536 text = doc->getEntry(row)->getTranslation(col);
537 title = i18n("Edit Properties of a Translation");
540 entryDlg->setData(doc,
541 hasSel,
542 col==0,
543 doc->getEntry(row)->getGrade(col, false),
544 doc->getEntry(row)->getGrade(col, true),
545 doc->getEntry(row)->getQueryCount(col, false),
546 doc->getEntry(row)->getQueryCount(col, true),
547 doc->getEntry(row)->getBadCount(col, false),
548 doc->getEntry(row)->getBadCount(col, true),
549 doc->getEntry(row)->getQueryDate(col, false),
550 doc->getEntry(row)->getQueryDate(col, true),
551 doc->getEntry(row)->getFauxAmi(col, false),
552 doc->getEntry(row)->getFauxAmi(col, true),
553 text,
554 lesson,
555 lessons,
556 lang,
557 langset,
558 doc->getEntry(row)->getRemark(col),
559 doc->getEntry(row)->getType(col),
560 doc->getEntry(row)->getPronunce(col),
561 doc->getEntry(row)->getSynonym(col),
562 doc->getEntry(row)->getAntonym(col),
563 doc->getEntry(row)->getExample(col),
564 doc->getEntry(row)->getUsageLabel(col),
565 doc->getEntry(row)->getParaphrase(col),
566 doc->getConjugation(col),
567 doc->getEntry(row)->getConjugation(col),
568 doc->getArticle(col),
569 doc->getEntry(row)->getComparison(col),
570 doc->getEntry(row)->getMultipleChoice(col),
571 querymanager,
572 title,
573 doc->getEntry(row)->isActive());
575 view->getTable()->updateCell(row, col);
576 vector<QTableSelection> tabsel;
577 if (hasSel) {
578 for (int i = 0; i < view->getTable()->numSelections(); ++i)
579 tabsel.push_back(view->getTable()->selection(i));
581 entryDlg->setCell(row, col+KV_EXTRA_COLS, tabsel);
585 void kvoctrainApp::slotDocProps ()
587 int old_lessons = (int) lessons->count();
588 int old_types = (int) doc->getTypeDescr().size();
589 int old_tenses = (int) doc->getTenseDescr().size();
590 int old_usages = (int) doc->getUsageDescr().size();
591 vector<int> old_lessoninquery = doc->getLessonsInQuery();
593 DocPropsDlg ddlg (doc,
595 lessons,
596 doc->getTitle(),
597 doc->getAuthor(),
598 doc->getLicense(),
599 doc->getDocRemark(),
600 doc->getTypeDescr(),
601 doc->getTenseDescr(),
602 doc->getUsageDescr());
604 int res = ddlg.exec();
606 if (res == QDialog::Accepted) {
607 vector<int> typeIndex;
608 vector<int> tenseIndex;
609 vector<int> usageIndex;
610 vector<int> lessonIndex;
611 vector<QString> new_typeStr;
612 vector<QString> new_tenseStr;
613 vector<QString> new_usageStr;
614 vector<QString> new_lessonStr;
615 vector<int> new_lessoninquery;
617 doc->allowSorting(ddlg.getSorting() );
619 doc->setTitle(ddlg.getTitle() );
620 doc->setAuthor(ddlg.getAuthor() );
621 doc->setLicense(ddlg.getLicense() );
622 doc->setDocRemark(ddlg.getDocRemark() );
624 slotStatusMsg(i18n("Updating lesson indices..."));
625 QApplication::setOverrideCursor( waitCursor );
627 ddlg.getLesson(lessons, lessonIndex);
628 ddlg.getTypeNames(new_typeStr, typeIndex);
629 ddlg.getTenseNames(new_tenseStr, tenseIndex);
630 ddlg.getUsageLabels(new_usageStr, usageIndex);
632 new_lessoninquery = old_lessoninquery;
633 LessOptPage::cleanUnused(doc, lessons, lessonIndex, old_lessons, new_lessoninquery);
634 for (int i = 1; i < lessons->count(); i++)
635 new_lessonStr.push_back(lessons->text(i));
637 slotStatusMsg(i18n("Updating type indices..."));
638 TypeOptPage::cleanUnused(doc, typeIndex, old_types);
639 QueryManager::setTypeNames (new_typeStr);
641 slotStatusMsg(i18n("Updating tense indices..."));
642 TenseOptPage::cleanUnused(doc, tenseIndex, old_tenses);
643 Conjugation::setTenseNames (new_tenseStr);
645 slotStatusMsg(i18n("usage (area) of an expression",
646 "Updating usage label indices..."));
647 UsageOptPage::cleanUnused(doc, usageIndex, old_usages);
648 UsageManager::setUsageNames (new_usageStr);
650 doc->setTypeDescr (new_typeStr);
651 doc->setTenseDescr (new_tenseStr);
652 doc->setUsageDescr (new_usageStr);
653 doc->setLessonDescr (new_lessonStr);
654 doc->setLessonsInQuery(new_lessoninquery);
655 querymanager.setLessonItems(new_lessoninquery);
657 doc->setModified();
658 view->getTable()->updateContents();
660 setCaption(kapp->makeStdCaption(doc->getTitle(), false, doc->isModified()));
662 QApplication::restoreOverrideCursor();
663 slotStatusMsg(IDS_DEFAULT);
668 void kvoctrainApp::slotDocPropsLang ()
670 DocPropsLangDlg ldlg (doc, &langset);
671 int res = ldlg.exec();
673 if (res == QDialog::Accepted) {
674 for (int i = 0; i < doc->numLangs(); i++) {
675 doc->setArticle(i, ldlg.getArticle(i) );
676 doc->setConjugation(i, ldlg.getConjugation(i) );
679 doc->setModified();
680 view->getTable()->updateContents();
681 setCaption(kapp->makeStdCaption(doc->getTitle(), false, doc->isModified()));
683 slotStatusMsg(IDS_DEFAULT);
688 void kvoctrainApp::slotModifiedDoc(bool mod)
690 setCaption(kapp->makeStdCaption(doc->getTitle(), false, doc->isModified()));
691 toolBar()->setItemEnabled(ID_FILE_SAVE, mod);
692 slotStatusMsg(IDS_DEFAULT);
696 bool kvoctrainApp::hasSelection()
698 int num = view->getTable()->numSelections();
699 if (num < 1) return false;
700 if (num > 1) return true;
701 QTableSelection ts = view->getTable()->selection(0);
702 return (ts.bottomRow() - ts.topRow()) > 0;
706 void kvoctrainApp::slotRemoveRow()
708 if (!hasSelection()) {
709 if( KMessageBox::Yes == KMessageBox::questionYesNo(this,
710 i18n("Do you really want to delete the selected entry?\n"),
711 kapp->makeStdCaption("")))
713 KVocTrainTable *table = view->getTable();
714 doc->removeEntry(table->currentRow());
715 doc->setModified();
716 table->updateContents();
719 else {
720 if(KMessageBox::Yes == KMessageBox::questionYesNo(this,
721 i18n("Do you really want to delete the selected range?\n"),
722 kapp->makeStdCaption("")))
724 KVocTrainTable *table = view->getTable();
726 int numRows = table->numRows();
727 // Must count backwards otherwise entry-numbering goes wrong when
728 // deleting.
729 for (int i = numRows-1; i >= 0; i--)
730 if (table->isRowSelected(i) )
731 doc->removeEntry(i);
732 doc->setModified();
733 table->updateContents();
736 editRemoveSelectedArea->setEnabled(view->getTable()->numRows() > 0);
740 void kvoctrainApp::slotAppendRow ()
742 kvoctrainExpr expr;
743 expr.setLesson(act_lesson);
744 doc->appendEntry(&expr);
745 doc->setModified();
746 int row = doc->numEntries()-1;
747 view->getTable()->setRowHeight(row, view->getTable()->fontMetrics().lineSpacing() );
748 view->getTable()->setCurrentRow(row, KV_COL_ORG);
749 view->getTable()->updateContents(row, KV_COL_ORG);
750 view->getTable()->clearSelection();
751 view->getTable()->selectRow(row);
752 editRemoveSelectedArea->setEnabled(view->getTable()->numRows() > 0);
756 void kvoctrainApp::keyReleaseEvent( QKeyEvent *e )
758 switch( e->key() ) {
759 case Key_Shift: shiftActive = false;
760 break;
762 case Key_Alt: altActive = false;
763 break;
765 case Key_Control: controlActive = false;
766 break;
771 void kvoctrainApp::keyPressEvent( QKeyEvent *e )
773 controlActive = (e->state() & ControlButton) != 0;
774 shiftActive = (e->state() & ShiftButton) != 0;
775 altActive = (e->state() & AltButton) != 0;
777 switch( e->key() ) {
778 case Key_Plus:
779 if (controlActive) {
780 int less = lessons->currentItem();
781 if (less == lessons->count()-1)
782 lessons->setCurrentItem(0);
783 else
784 lessons->setCurrentItem(less+1);
785 slotChooseLesson(lessons->currentItem());
787 break;
789 case Key_Minus:
790 if (controlActive) {
791 int less = lessons->currentItem();
792 if (less == 0)
793 lessons->setCurrentItem(lessons->count()-1);
794 else
795 lessons->setCurrentItem(less-1);
796 slotChooseLesson(lessons->currentItem());
798 break;
800 case Key_Shift: shiftActive = true;
801 break;
803 case Key_Alt: altActive = true;
804 break;
806 case Key_Control: controlActive = true;
807 break;
809 case Key_Tab:
810 if (view->getTable()->hasFocus() ) {
811 searchLine->setFocus();
812 searchLine->selectAll();
814 else
815 view->getTable()->setFocus();
816 break;
818 case Key_Backtab:
819 if (searchLine->hasFocus() )
820 view->getTable()->setFocus();
821 else {
822 searchLine->setFocus();
823 searchLine->selectAll();
825 break;
827 case Key_Delete:
828 slotRemoveRow();
829 break;
831 case Key_Insert: {
832 slotAppendRow();
834 break;
836 default:
837 bool found = false;
838 if (!found)
839 e->ignore();
841 slotStatusMsg(IDS_DEFAULT);
845 void kvoctrainApp::slotChooseLesson(int idx)
847 act_lesson = idx;
848 doc->setCurrentLesson(idx);
849 doc->setModified(true);
853 void kvoctrainApp::slotCreateLesson(int header)
855 vector <int> sel;
856 doc->setModified();
857 for (int i = 0; i < view->getTable()->count(); i++) {
858 kvoctrainExpr *kv = view->getTable()->getRow(i);
859 kv->setLesson(0);
860 if (kv->getGrade(header) > THRESH_LESSON
861 && !kv->getTranslation(header).isEmpty() )
862 sel.push_back(i);
865 int cnt = 0;
866 while (cnt < MAX_LESSON && sel.size() != 0) {
867 int nr = random.getLong(sel.size());
868 kvoctrainExpr *kv = view->getTable()->getRow(sel[nr]);
869 // include non-lesson and non-empty string
870 if (kv->getLesson() == 0) {
871 kv->setLesson(1);
872 sel.erase (sel.begin() + nr);
873 cnt++;
876 view->getTable()->updateContents();
880 void kvoctrainApp::slotShowStatist()
882 StatistikDlg sdlg (langset, doc);
883 sdlg.exec();
887 void kvoctrainApp::slotCleanVocabulary ()
889 prepareProgressBar();
890 QApplication::setOverrideCursor( waitCursor );
891 int num = doc->cleanUp();
892 QApplication::restoreOverrideCursor();
893 removeProgressBar();
895 slotStatusMsg(IDS_DEFAULT);
897 if (num != 0) {
898 view->setView(doc, langset);
899 QString s =
900 i18n("1 entry with the same content has been found and removed.",
901 "%n entries with the same content have been found and removed.", num);
903 KMessageBox::information(this,
905 kapp->makeStdCaption(i18n("Clean Up")));
910 void kvoctrainApp::slotCreateRandom()
912 bool ok = FALSE;
913 int res = KInputDialog::getInteger(i18n( "Entries in Lesson" ),
914 i18n( "Enter number of entries in lesson:" ), Prefs::entriesPerLesson(), 1, 1000, 1, &ok, this );
915 if (!ok)
916 return;
918 Prefs::setEntriesPerLesson(res);
920 slotStatusMsg(i18n("Creating random lessons..."));
921 QApplication::setOverrideCursor( waitCursor );
923 vector<kvoctrainExpr*> randomList;
924 for (int i = 0; i < doc->numEntries(); i++) {
925 kvoctrainExpr *expr = doc->getEntry(i);
926 if (expr->getLesson() == 0)
927 randomList.push_back(expr);
930 if (randomList.size () != 0) {
931 int less_no = lessons->count() /* +1 anyway */ ;
932 QString s;
933 s.setNum (less_no);
934 s.insert (0, "- ");
935 lessons->insertItem (s);
936 int less_cnt = Prefs::entriesPerLesson();
937 while (randomList.size () != 0) {
938 if (--less_cnt <= 0) {
939 less_cnt = Prefs::entriesPerLesson();
940 less_no++;
941 s.setNum (less_no);
942 s.insert (0, "- ");
943 lessons->insertItem (s);
945 int nr = random.getLong(randomList.size());
946 randomList[nr]->setLesson(less_no);
947 randomList.erase(randomList.begin() + nr);
950 vector<QString> new_lessonStr;
951 for (int i = 1; i < lessons->count(); i++)
952 new_lessonStr.push_back(lessons->text(i));
953 doc->setLessonDescr (new_lessonStr);
954 view->getTable()->updateContents();
955 doc->setModified ();
957 QApplication::restoreOverrideCursor();
958 slotStatusMsg(IDS_DEFAULT);
962 void kvoctrainApp::slotGeneralOptions()
964 slotGeneralOptionsPage(-1);
968 void kvoctrainApp::slotGeneralOptionsPage(int index)
970 //if (KVocTrainPrefs::showDialog( "settings" ))
971 // return;
973 //KConfigDialog didn't find an instance of this dialog, so lets create it :
974 KVocTrainPrefs* dialog = new KVocTrainPrefs(langset, doc, lessons, &querymanager, this, "settings", Prefs::self() );
975 connect(dialog, SIGNAL(settingsChanged()), this, SLOT(slotApplyPreferences()));
976 if (index >= 0)
977 dialog->selectPage(index);
978 dialog->show();
980 QString defTrans;
981 GeneralOptionsDlg godlg (defTrans,
982 Prefs::separator(),
983 Prefs::backupTime() /(60*1000),
984 langset,
985 lastPixName,
986 lessons,
987 Prefs::pasteOrder(),
988 Prefs::useCurrent(),
989 doc,
990 Prefs::tableFont(),
991 Prefs::iPAFont(),
992 &querymanager,
993 Prefs::smartAppend(),
994 Prefs::autoEntryApply());
996 if (index >= 0)
997 godlg.selectPage(index);
999 int res = godlg.exec();
1000 if (res == QDialog::Accepted) {
1002 defTrans = godlg.getDefaultLang();
1003 Prefs::setBackupTime(godlg.getBackupTime()*60*1000);
1004 Prefs::setSmartAppend(godlg.getSmartAppend());
1005 Prefs::setAutoEntryApply(godlg.getAutoApply());
1006 Prefs::setSeparator(godlg.getSeparator());
1007 langset = godlg.getLangSet();
1008 Prefs::setPasteOrder(godlg.getPasteOrder());
1009 Prefs::setUseCurrent(godlg.getUseCurrent()),
1010 Prefs::setTableFont(godlg.getFont());
1011 Prefs::setIPAFont(godlg.getIPAFont());
1013 if (pron_label)
1014 pron_label->setFont(Prefs::iPAFont());
1015 view->getTable()->setFont(Prefs::tableFont());
1016 view->getTable()->updateContents();
1018 // update header buttons
1019 for (int i = 0; i < (int) doc->numLangs(); i++) {
1020 QString sid = i>0 ? doc->getIdent(i)
1021 : doc->getOriginalIdent();
1023 int idx = langset.indexShortId(sid);
1024 QString pm = "";
1025 QString lid = sid;
1026 if (idx >= 0) {
1027 lid = langset.longId(idx);
1028 pm = langset.PixMapFile(idx);
1030 view->setHeaderProp (i+KV_EXTRA_COLS, lid, pm);
1032 slotStatusMsg(IDS_DEFAULT);
1037 void kvoctrainApp::slotApplyPreferences()
1039 kdDebug() << "Prefs Update" << endl;
1040 if (pron_label)
1041 pron_label->setFont(Prefs::iPAFont());
1042 view->getTable()->setFont(Prefs::tableFont());
1043 view->getTable()->updateContents();
1045 readLanguages();
1046 // update header buttons
1047 for (int i = 0; i < (int) doc->numLangs(); i++)
1049 QString sid = i>0 ? doc->getIdent(i): doc->getOriginalIdent();
1050 int idx = langset.indexShortId(sid);
1051 QString pm = "";
1052 QString lid = sid;
1053 if (idx >= 0)
1055 lid = langset.longId(idx);
1056 pm = langset.PixMapFile(idx);
1058 view->setHeaderProp(i+KV_EXTRA_COLS, lid, pm);
1061 //emit settingsChanged();
1065 void kvoctrainApp::slotAppendLang(int header_and_cmd)
1067 int lang_id = (header_and_cmd >> 16) & 0xFF;
1069 if (lang_id == 0xFF) {
1070 QString msg = i18n("To append a new language which is not listed in "
1071 "the submenu, you must first add its data in the "
1072 "general options dialog.\n"
1073 "Should this dialog be invoked now?");
1074 if( KMessageBox::Yes == KMessageBox::questionYesNo(this,
1075 msg,
1076 kapp->makeStdCaption("")));
1078 slotGeneralOptionsPage(1);
1080 return;
1083 if (lang_id >= (int) langset.size())
1084 return;
1085 kdDebug() << "I'm here" << endl;
1086 doc->appendLang("");
1087 int num = doc->numEntries()-1;
1088 for (int i = 0; i < (int) num; i++) {
1089 kvoctrainExpr *expr = doc->getEntry(i);
1090 expr->setType (num, expr->getType(0));
1093 doc->setIdent(doc->numLangs()-1, langset.shortId(lang_id));
1094 view->setView(doc, langset);
1095 doc->setModified();
1099 void kvoctrainApp::slotInitSearch()
1101 searchpos = 0;
1102 searchstr = "";
1106 void kvoctrainApp::slotSearchNext()
1108 kdDebug() << "Searching..." << endl;
1109 slotResumeSearch(searchstr);
1113 void kvoctrainApp::slotResumeSearch(const QString& s)
1115 if (s.length() == 0) {
1116 slotInitSearch();
1117 return;
1120 slotStatusMsg(i18n("Searching expression..."));
1121 QApplication::setOverrideCursor( waitCursor );
1123 // new word or shortend word
1124 if (s.length() < searchstr.length() )
1125 searchpos = 0;
1127 // search in current col from current row till end
1128 // SHIFT means start search from beginning of word
1129 bool word_beg = controlActive;
1130 int idx = doc->search(s, view->getTable()->currentColumn()-KV_EXTRA_COLS, searchpos, -1, word_beg, false);
1131 if (idx >= 0) {
1132 view->getTable()->clearSelection();
1133 view->getTable()->setCurrentRow(idx, view->getTable()->currentColumn());
1134 searchpos = idx+1;
1136 else { // try again from beginning up to current pos
1137 int idx = doc->search(s, view->getTable()->currentColumn()-KV_EXTRA_COLS, 0, searchpos, word_beg, false);
1138 if (idx >= 0) {
1139 view->getTable()->clearSelection();
1140 view->getTable()->setCurrentRow(idx, view->getTable()->currentColumn());
1141 searchpos = idx+1;
1143 else
1144 searchpos = 0;
1147 searchstr = s;
1148 QApplication::restoreOverrideCursor();
1149 slotStatusMsg(IDS_DEFAULT);
1153 void kvoctrainApp::slotStatusMsg(const QString &/*text*/)
1156 ///////////////////////////////////////////////////////////////////
1157 // change status message permanently
1158 statusBar()->clear();
1159 statusBar()->changeItem(text, ID_STATUS_MSG );
1164 void kvoctrainApp::aboutToShowLearn()
1166 learn_menu->clear();
1168 vector<QString> set_names;
1169 for (int i = 0; i < (int) langset.size(); i++) {
1170 if(langset.longId(i).isEmpty() )
1171 set_names.push_back(langset.shortId(i));
1172 else
1173 set_names.push_back(langset.longId(i));
1176 vector<QString> main_names;
1177 for (int j = 0; j < (int) doc->numLangs(); j++) {
1178 int i;
1179 QString did = j == 0 ? doc->getOriginalIdent()
1180 : doc->getIdent(j);
1181 if ((i = langset.indexShortId(did)) >= 0)
1182 main_names.push_back(langset.longId(i));
1183 else
1184 main_names.push_back(did);
1187 for (int header = 0; header < (int) doc->numLangs(); header++) {
1188 // show pixmap and long name if available
1189 int j;
1190 header_m = new QPopupMenu();
1191 if (header != 0 ) {
1192 header_m->insertItem(SmallIconSet("run_query"), i18n("Create Random &Query"), (header << 16) | IDH_START_QUERY);
1193 header_m->insertItem(SmallIconSet("run_multi"), i18n("Create &Multiple Choice"), (header << 16) | IDH_START_MULTIPLE);
1195 header_m->setItemEnabled((header << 16) | IDH_START_MULTIPLE, doc->numLangs() > 1);
1196 header_m->setItemEnabled((header << 16) | IDH_START_QUERY, doc->numLangs() > 1);
1197 header_m->insertSeparator();
1199 header_m->insertItem(i18n("&Verbs"), (header << 16) | IDH_START_VERB);
1200 header_m->insertItem(i18n("&Articles"), (header << 16) | IDH_START_ARTICLE);
1201 header_m->insertItem(i18n("&Comparison Forms"), (header << 16) | IDH_START_ADJECTIVE);
1202 header_m->insertSeparator();
1203 header_m->insertItem(i18n("S&ynonyms"), (header << 16) | IDH_START_SYNONYM);
1204 header_m->insertItem(i18n("A&ntonyms"), (header << 16) | IDH_START_ANTONYM);
1205 header_m->insertItem(i18n("E&xamples"), (header << 16) | IDH_START_EXAMPLE);
1206 header_m->insertItem(i18n("&Paraphrase"), (header << 16) | IDH_START_PARAPHRASE);
1208 else {
1209 QPopupMenu *query_m = new QPopupMenu();
1210 QPopupMenu *multiple_m = new QPopupMenu();
1212 for (int i = 1; i < (int) doc->numLangs(); i++) {
1213 // show pixmap and long name if available
1214 int j;
1215 if((j = langset.indexShortId(doc->getIdent(i))) >= 0
1216 && !langset.PixMapFile(j).isEmpty()
1217 && !langset.longId(j).isEmpty() ) {
1218 query_m->insertItem(QPixmap(langset.PixMapFile(j)), i18n("from %1").arg(main_names[i]),
1219 (i << (16+8)) | IDH_START_QUERY); // hack: IDs => header-ids + cmd
1221 else {
1222 query_m->insertItem(i18n("from %1").arg(doc->getIdent(i)), (i << (16+8)) | IDH_START_QUERY);
1226 header_m->insertItem(SmallIconSet("run_query"), i18n("Create Random &Query"), query_m, (3 << 16) | IDH_NULL);
1227 connect (query_m, SIGNAL(activated(int)), this, SLOT(slotHeaderCallBack(int)));
1228 connect (query_m, SIGNAL(highlighted(int)), this, SLOT(slotHeaderStatus(int)));
1230 for (int i = 1; i < (int) doc->numLangs(); i++) {
1231 // show pixmap and long name if available
1232 int j;
1233 if((j = langset.indexShortId(doc->getIdent(i))) >= 0
1234 && !langset.PixMapFile(j).isEmpty()
1235 && !langset.longId(j).isEmpty() ) {
1236 multiple_m->insertItem(QPixmap(langset.PixMapFile(j)), i18n("from %1").arg(main_names[i]),
1237 (i << (16+8)) | IDH_START_MULTIPLE); // hack: IDs => header-ids + cmd
1239 else {
1240 multiple_m->insertItem(i18n("from %1").arg(doc->getIdent(i)), (i << (16+8)) | IDH_START_MULTIPLE);
1243 header_m->insertItem(SmallIconSet("run_multi"), i18n("Create &Multiple Choice"), multiple_m, (4 << 16) | IDH_NULL);
1244 header_m->insertSeparator();
1246 header_m->insertItem(i18n("Train &Verbs"), (header << 16) | IDH_START_VERB);
1247 header_m->insertItem(i18n("&Article Training"), (header << 16) | IDH_START_ARTICLE);
1248 header_m->insertItem(i18n("&Comparison Training"), (header << 16) | IDH_START_ADJECTIVE);
1249 header_m->insertSeparator();
1250 header_m->insertItem(i18n("&Synonyms"), (header << 16) | IDH_START_SYNONYM);
1251 header_m->insertItem(i18n("&Antonyms"), (header << 16) | IDH_START_ANTONYM);
1252 header_m->insertItem(i18n("E&xamples"), (header << 16) | IDH_START_EXAMPLE);
1253 header_m->insertItem(i18n("&Paraphrase"), (header << 16) | IDH_START_PARAPHRASE);
1255 connect (multiple_m, SIGNAL(activated(int)), this, SLOT(slotHeaderCallBack(int)));
1256 connect (multiple_m, SIGNAL(highlighted(int)), this, SLOT(slotHeaderStatus(int)));
1259 connect (header_m, SIGNAL(activated(int)), this, SLOT(slotHeaderCallBack(int)));
1260 connect (header_m, SIGNAL(highlighted(int)), this, SLOT(slotHeaderStatus(int)));
1262 QString id = header == 0 ? doc->getOriginalIdent()
1263 : doc->getIdent(header);
1264 if((j = langset.indexShortId(id)) >= 0
1265 && !langset.PixMapFile(j).isEmpty()
1266 && !langset.longId(j).isEmpty() ) {
1267 learn_menu->insertItem(QPixmap(langset.PixMapFile(j)), main_names[header], header_m, IDH_NULL);
1269 else {
1270 learn_menu->insertItem(id, header_m, IDH_NULL);
1274 learn_menu->insertSeparator();
1275 learn_menu->insertItem(SmallIconSet("run_query"), i18n("Resume &Query"), ID_RESUME_QUERY );
1276 learn_menu->insertItem(SmallIconSet("run_multi"), i18n("Resume &Multiple Choice"), ID_RESUME_MULTIPLE );
1278 learn_menu->setItemEnabled(ID_RESUME_QUERY, query_num != 0);
1279 learn_menu->setItemEnabled(ID_RESUME_MULTIPLE, query_num != 0);
1283 void kvoctrainApp::aboutToShowVocabAppendLanguage()
1285 if (doc != 0)
1287 vocabAppendLanguage->clear();
1288 QPopupMenu * add_m = vocabAppendLanguage->popupMenu();
1290 QStringList names;
1291 for (int i = 0; i < (int) langset.size(); i++)
1293 if(langset.longId(i).isEmpty() )
1294 names.append(langset.shortId(i));
1295 else
1296 names.append(langset.longId(i));
1299 for (int i = 0; i < (int) langset.size(); i++)
1301 if(!langset.PixMapFile(i).isEmpty() && !langset.longId(i).isEmpty())
1302 add_m->insertItem(QPixmap(langset.PixMapFile(i)), names[i], (i << 16) | IDH_APPEND);
1303 else
1304 add_m->insertItem(names[i], (i << 16) | IDH_APPEND);
1307 add_m->insertItem(i18n("Another Language..."), (0xFF << 16) | IDH_APPEND);
1312 void kvoctrainApp::aboutToShowVocabSetLanguage()
1314 if (doc != 0)
1316 vocabSetLanguage->clear();
1317 QPopupMenu * set_m = vocabSetLanguage->popupMenu();
1319 QStringList names;
1320 for (int i = 0; i < (int) langset.size(); i++)
1322 if(langset.longId(i).isEmpty() )
1323 names.append(langset.shortId(i));
1324 else
1325 names.append(langset.longId(i));
1328 for (int header = 0; header < doc->numLangs(); ++header )
1330 // select one of the available languages for the column
1331 QPopupMenu *langs_m = new QPopupMenu();
1332 // hack: ID => header-id + language
1334 for (int i = 0; i < (int) langset.size(); i++) {
1335 if(!langset.PixMapFile(i).isEmpty() && !langset.longId(i).isEmpty())
1336 langs_m->insertItem(QPixmap(langset.PixMapFile(i)), names[i], (header << 16) | (i << (16+8)) | IDH_SET_LANG);
1337 else
1338 langs_m->insertItem(names[i], (header << 16) | (i << (16+8)) | IDH_SET_LANG);
1341 connect (langs_m, SIGNAL(activated(int)), this, SLOT(slotSetHeaderProp(int)));
1342 connect (langs_m, SIGNAL(highlighted(int)), this, SLOT(slotHeaderStatus(int)));
1344 if (header == 0)
1345 set_m->insertItem(i18n("&Original"), langs_m, (2 << 16) | IDH_NULL);
1346 else {
1347 if (doc->numLangs() <= 2)
1348 set_m->insertItem(i18n("&Translation"), langs_m, (2 << 16) | IDH_NULL);
1349 else
1350 set_m->insertItem(i18n("&%1. Translation").arg(header), langs_m, (2 << 16) | IDH_NULL);
1357 void kvoctrainApp::aboutToShowVocabRemoveLanguage()
1359 if (doc != 0)
1361 vocabRemoveLanguage->clear();
1362 QPopupMenu * remove_m = vocabRemoveLanguage->popupMenu();
1364 QStringList names;
1365 for (int j = 1; j < (int) doc->numLangs(); j++)
1367 int i;
1368 if ((i = langset.indexShortId(doc->getIdent(j))) >= 0)
1369 names.append(langset.longId(i));
1370 else
1371 names.append(doc->getIdent(j));
1374 for (int i = 1; i < (int) doc->numLangs(); i++)
1376 // show pixmap and long name if available
1377 int j;
1378 if((j = langset.indexShortId(doc->getIdent(i))) >= 0
1379 && !langset.PixMapFile(j).isEmpty()
1380 && !langset.longId(j).isEmpty() )
1381 remove_m->insertItem(QPixmap(langset.PixMapFile(j)), names[i-1], (i << 16) | IDH_REMOVE); // hack: IDs => header-ids + cmd
1382 else
1383 remove_m->insertItem(doc->getIdent(i), (i << 16) | IDH_REMOVE);
1389 void kvoctrainApp::slotStatusHelpMsg(const QString &text)
1391 ///////////////////////////////////////////////////////////////////
1392 // change status message of whole statusbar temporary (text, msec)
1393 if (pbar == 0 || !pbar->isVisible() )
1394 statusBar()->message(text, 3000);
1397 #include "kvoctrain.moc"