moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kvoctrain / kvoctrain / query-dialogs / RandomQueryDlg.cpp
blob09fe15355655fe88c1f162cb85cde592d718b341
1 /***************************************************************************
3 dialog when in query mode
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 "RandomQueryDlg.h"
27 #include "common-dialogs/ProgressDlg.h"
29 #include <kv_resource.h>
31 #include <kstandarddirs.h>
32 #include <klocale.h>
33 #include <kapplication.h>
34 #include <kprogress.h>
36 #include <qcheckbox.h>
37 #include <qgroupbox.h>
38 #include <qlabel.h>
39 #include <qlayout.h>
40 #include <qlineedit.h>
41 #include <qpushbutton.h>
42 #include <qregexp.h>
43 #include <qtimer.h>
45 QStringList RandomQueryDlg::extractTranslations (QString trans)
47 QRegExp full_stop ("^(.*[^\\. ])\\.* *$");
48 //full_stop.setMinimal (true);
49 if ( full_stop.search (trans) >= 0 )
50 trans = full_stop.cap (1);
51 int i;
52 QStringList translations;
53 if ( periods )
54 for ( i = fields - 1; i > 0; i -- )
56 QString regexp ("^ *");
57 for ( int j = 0; j < i; j ++ )
58 regexp += "([^ ][^.]*)\\.[. ]*";
59 regexp += "([^. ].*)$";
60 QRegExp regex (regexp);
61 if ( regex.search (trans) >= 0 )
63 translations = regex.capturedTexts();
64 translations.remove (translations.at (0));
65 break;
68 if ( colons && translations.count() <= 1 )
70 translations.clear();
71 for ( i = fields - 1; i > 0; i -- )
73 QString regexp ("^ *");
74 for ( int j = 0; j < i; j ++ )
75 regexp += "([^ ][^:]*):[: ]*";
76 regexp += "([^: ].*)$";
77 QRegExp regex (regexp);
78 if ( regex.search (trans) >= 0 )
80 translations = regex.capturedTexts();
81 translations.remove (translations.at (0));
82 break;
86 if ( semicolons && translations.count() <= 1 )
88 translations.clear();
89 for ( i = fields - 1; i > 0; i -- )
91 QString regexp ("^ *");
92 for ( int j = 0; j < i; j ++ )
93 regexp += "([^ ][^;]*);[; ]*";
94 regexp += "([^; ].*)$";
95 QRegExp regex (regexp);
96 if ( regex.search (trans) >= 0 )
98 translations = regex.capturedTexts();
99 translations.remove (translations.at (0));
100 break;
104 if ( commas && translations.count() <= 1 )
106 translations.clear();
107 for ( i = fields - 1; i > 0; i -- )
109 QString regexp ("^ *");
110 for ( int j = 0; j < i; j ++ )
111 regexp += "([^ ][^,]*),[, ]*";
112 regexp += "([^, ].*)$";
113 QRegExp regex (regexp);
114 if ( regex.search (trans) >= 0 )
116 translations = regex.capturedTexts();
117 translations.remove (translations.at (0));
118 break;
122 if ( translations.count() <= 1 )
123 translations = QStringList (trans);
124 return translations;
127 RandomQueryDlg::RandomQueryDlg(
128 QString org,
129 QString trans,
130 int entry,
131 int orgcol,
132 int transcol,
133 int q_cycle,
134 int q_num,
135 int q_start,
136 kvoctrainExpr *exp,
137 kvoctrainDoc *doc,
138 int mqtime,
139 bool show,
140 bool _suggestions,
141 bool _split,
142 bool _periods,
143 bool _colons,
144 bool _semicolons,
145 bool _commas,
146 int _fields,
147 bool _show_more,
148 bool _i_know,
149 bool _swap)
150 : QueryDlgBase(i18n("Random Query"))
152 mw = new QueryDlgForm(this);
153 setMainWidget(mw);
155 connect( mw->c_type, SIGNAL(clicked()), SLOT(slotTypeClicked()) );
156 connect( mw->c_remark, SIGNAL(clicked()), SLOT(slotRemClicked()) );
157 connect( mw->c_falsefriend, SIGNAL(clicked()), SLOT(slotFFClicked()) );
158 connect( mw->dont_know, SIGNAL(clicked()), SLOT(dontKnowClicked()) );
159 connect( mw->know_it, SIGNAL(clicked()), SLOT(knowItClicked()) );
160 connect( mw->verify, SIGNAL(clicked()), SLOT(verifyClicked()) );
161 connect( mw->show_all, SIGNAL(clicked()), SLOT(showAllClicked()) );
162 connect( mw->show_more, SIGNAL(clicked()), SLOT(showMoreClicked()) );
164 mw->show_more -> setEnabled (_show_more);
165 mw->know_it -> setEnabled (_i_know);
167 if ( ! _split || _fields < 1 )
168 _fields = 1;
169 else if ( _fields > 10 )
170 _fields = 10;
171 suggestions = _suggestions;
172 split = _split;
173 periods = _periods;
174 colons = _colons;
175 semicolons = _semicolons;
176 commas = _commas;
177 fields = _fields;
179 QVBoxLayout * vb = new QVBoxLayout(mw->TranslationFrame, 0, KDialog::spacingHint());
181 int i;
182 if ( suggestions )
184 for ( i = 0; i < fields; i ++ )
186 transCombos.append (new QComboBox (false, mw->TranslationFrame, QCString ("transCombo") + QCString().setNum (i)));
187 transCombos.at(i) -> setSizePolicy (QSizePolicy ((QSizePolicy::SizeType)7, (QSizePolicy::SizeType)1, 0, 0, transCombos.at(i) -> sizePolicy().hasHeightForWidth()));
188 transCombos.at(i) -> setEditable (true);
189 transCombos.at(i) -> setInsertionPolicy (QComboBox::NoInsertion);
190 transCombos.at(i) -> setDuplicatesEnabled (false);
191 vb->addWidget(transCombos.at(i));
192 connect (transCombos.at(i), SIGNAL (textChanged (const QString&)), SLOT (slotTransChanged (const QString&)));
193 connect (transCombos.at(i) -> lineEdit(), SIGNAL (lostFocus()), SLOT (slotTransLostFocus()));
196 else
198 for ( i = 0; i < fields; i ++ )
200 transFields.append (new QLineEdit (mw->TranslationFrame, QCString ("transField") + QCString().setNum (i)));
201 transFields.at(i) -> setSizePolicy (QSizePolicy ((QSizePolicy::SizeType)7, (QSizePolicy::SizeType)1, 0, 0, transFields.at(i) -> sizePolicy().hasHeightForWidth()));
202 vb->addWidget(transFields.at(i));
203 connect (transFields.at(i), SIGNAL (textChanged (const QString&)), SLOT (slotTransChanged (const QString&)));
204 connect (transFields.at(i), SIGNAL (lostFocus()), SLOT (slotTransLostFocus()));
208 kv_doc = 0;
209 qtimer = 0;
210 //setCaption (kapp->makeStdCaption(i18n("Random Query")));
211 setQuery (org, trans, entry, orgcol, transcol, q_cycle, q_num, q_start, exp, doc, mqtime, show);
212 mw->countbar->setFormat("%v/%m");
213 mw->timebar->setFormat("%v");
215 if ( suggestions )
217 ProgressDlg* pdlg = 0;
218 if ( split && kv_doc -> numEntries() >= 500 )
220 pdlg = new ProgressDlg (QString(), QString(), kapp -> makeStdCaption (i18n("Loading Random Query")));
221 pdlg -> resize (pdlg -> width(), pdlg -> minimumSize().height());
222 pdlg -> show();
223 kapp -> processEvents();
225 for ( i = 0; i < kv_doc -> numEntries(); i ++ )
227 kvoctrainExpr* expr = kv_doc -> getEntry (i);
228 if ( split )
229 vocabulary += extractTranslations (q_tcol ? expr -> getTranslation (q_tcol) : expr -> getOriginal());
230 else
231 vocabulary += q_tcol ? expr -> getTranslation (q_tcol) : expr -> getOriginal();
232 if ( _swap )
234 if ( split )
235 vocabulary += extractTranslations (q_ocol ? expr -> getTranslation (q_ocol) : expr -> getOriginal());
236 else
237 vocabulary += q_ocol ? expr -> getTranslation (q_ocol) : expr -> getOriginal();
239 if ( pdlg )
241 pdlg -> setValue (doc, i * 100 / kv_doc -> numEntries());
242 kapp -> processEvents();
245 vocabulary.sort();
246 for ( uint k = 1; k < vocabulary.count(); k ++ )
247 if ( vocabulary [k - 1] == vocabulary [k] )
248 vocabulary.remove (vocabulary.at (k --));
249 if ( pdlg )
250 delete pdlg;
252 resize(configDialogSize("RandomQueryDialog"));
256 RandomQueryDlg::~RandomQueryDlg()
258 saveDialogSize("RandomQueryDialog");
262 void RandomQueryDlg::setQuery(QString org,
263 QString trans,
264 int entry,
265 int orgcol,
266 int transcol,
267 int q_cycle,
268 int q_num,
269 int q_start,
270 kvoctrainExpr *,
271 kvoctrainDoc *doc,
272 int mqtime,
273 bool _show)
275 //type_timeout = type_to;
276 kv_doc = doc;
277 q_row = entry;
278 q_ocol = orgcol;
279 q_tcol = transcol;
280 translation = trans;
281 showCounter = _show;
282 if ( split )
283 translations = extractTranslations (trans);
284 else
285 translations = trans;
286 mw->timebar->setEnabled(showCounter);
287 mw->timelabel->setEnabled(showCounter);
288 int i;
289 uint k;
290 if ( suggestions )
292 for ( i = 0; i < fields; i ++ )
294 transCombos.at(i) -> clearEdit();
295 resetField (transCombos.at(i) -> lineEdit());
297 for ( k = 0; k < translations.count(); k ++ )
298 transCombos.at(k) -> show();
299 for ( i = k; i < fields; i ++ )
300 transCombos.at(i) -> hide();
302 else
304 for ( i = 0; i < fields; i ++ )
306 transFields.at(i) -> clear();
307 transFields.at(i) -> setFont (Prefs::tableFont());
308 resetField (transFields.at(i));
310 for ( k = 0; k < translations.count(); k ++ )
311 transFields.at(k) -> show();
312 for ( i = k; i < fields; i ++ )
313 transFields.at(i) -> hide();
315 mw->verify -> setEnabled (true);
316 mw->orgField->setFont(Prefs::tableFont());
317 mw->orgField->setText (org);
318 mw->show_all->setDefault(true);
319 QString s;
320 s.setNum (q_cycle);
321 mw->progCount->setText (s);
323 mw->remark->hide();
324 mw->falseFriend->hide();
325 mw->type->hide();
327 mw->c_remark->setChecked(false);
328 mw->c_falsefriend->setChecked(false);
329 mw->c_type->setChecked(false);
330 setHintFields();
332 mw->countbar->setTotalSteps(q_start);
333 mw->countbar->setProgress(q_start - q_num + 1);
335 if (mqtime >= 1000) { // more than 1000 milli-seconds
336 if (qtimer == 0) {
337 qtimer = new QTimer( this );
338 connect( qtimer, SIGNAL(timeout()), this, SLOT(timeoutReached()) );
341 if (Prefs::queryTimeout() != Prefs::EnumQueryTimeout::NoTimeout) {
342 timercount = mqtime/1000;
343 mw->timebar->setTotalSteps(timercount);
344 mw->timebar->setProgress(timercount);
345 qtimer->start(1000, TRUE);
347 else
348 mw->timebar->setEnabled(false);
350 else
351 mw->timebar->setEnabled(false);
353 mw->status -> clear();
354 suggestion_hint = false;
358 void RandomQueryDlg::initFocus() const
360 RandomQueryDlg* that = (RandomQueryDlg*) this;
361 if ( suggestions )
362 that -> transCombos.at(0) -> setFocus();
363 else
364 that -> transFields.at(0) -> setFocus();
368 void RandomQueryDlg::verifyClicked()
370 QStringList trans (translations);
371 uint i, j;
372 if ( suggestions )
374 QPtrList<QComboBox> combos (transCombos);
375 for ( i = combos.count() - 1; i >= translations.count(); i -- )
376 combos.remove (i);
377 for ( i = 0; i < combos.count(); i ++ )
378 for ( j = 0; j < trans.count(); j ++ )
379 if ( smartCompare (trans[j], combos.at(i) -> currentText(), 0) )
381 verifyField (combos.at(i) -> lineEdit(), trans[j]);
382 trans.remove (trans.at(j));
383 combos.remove (i --);
384 break;
386 if ( trans.count() == 0 )
388 int percent = (mw->countbar->progress()/mw->countbar->totalSteps()) * 100;
389 //status->setText(getOKComment(countbar->getPercentage()));
390 mw->status->setText(getOKComment(percent));
391 knowItClicked();
393 else
395 for ( i = 0; i < combos.count(); i ++ )
396 verifyField (combos.at(i) -> lineEdit(), "a\na"); // always fail
397 mw->status->setText(getNOKComment((mw->countbar->progress()/mw->countbar->totalSteps()) * 100));
398 mw->dont_know->setDefault(true);
401 else
403 QPtrList<QLineEdit> fields (transFields);
404 for ( i = fields.count() - 1; i >= translations.count(); i -- )
405 fields.remove (i);
406 for ( i = 0; i < fields.count(); i ++ )
407 for ( j = 0; j < trans.count(); j ++ )
408 if ( smartCompare (trans[j], fields.at(i) -> text(), 0) )
410 verifyField (fields.at(i), "a\na"); // always fail
411 trans.remove (trans.at(j));
412 fields.remove (i --);
413 break;
415 if ( trans.count() == 0 )
417 mw->status->setText(getOKComment((mw->countbar->progress()/mw->countbar->totalSteps()) * 100));
418 knowItClicked();
420 else
422 for ( i = 0; i < fields.count(); i ++ )
423 verifyField (fields.at(i), trans[i]);
424 mw->status->setText(getNOKComment((mw->countbar->progress()/mw->countbar->totalSteps()) * 100));
425 mw->dont_know->setDefault(true);
428 suggestion_hint = false;
432 void RandomQueryDlg::showMoreClicked()
434 if ( suggestions )
435 for ( uint i = 0; i < translations.count(); i ++ )
437 QComboBox* combo = transCombos.at(i);
438 if ( ! smartCompare (combo -> currentText(), translations[i], 0) )
440 uint length = combo -> currentText().length() + 1;
441 if ( length >= translations[i].length() )
443 combo -> setEditText (translations[i]);
444 verifyField (combo -> lineEdit(), translations[i]);
445 mw->verify -> setEnabled (false);
447 else
449 combo -> setEditText (translations[i].left (length));
450 resetField (combo -> lineEdit());
452 mw->dont_know -> setDefault (true);
453 break;
456 else
457 for ( uint i = 0; i < translations.count(); i ++ )
459 QLineEdit* field = transFields.at(i);
460 if ( ! smartCompare (field -> text(), translations[i], 0) )
462 uint length = field -> text().length() + 1;
463 if ( length >= translations[i].length() )
465 field -> setText (translations[i]);
466 verifyField (field, translations[i]);
467 mw->verify -> setEnabled (false);
469 else
471 field -> setText (translations[i].left (length));
472 resetField (field);
474 mw->dont_know -> setDefault (true);
475 break;
478 mw->status -> clear();
479 suggestion_hint = false;
483 void RandomQueryDlg::showAllClicked()
485 if ( suggestions )
486 for ( uint i = 0; i < translations.count(); i ++ )
488 transCombos.at(i) -> setEditText (translations[i]);
489 verifyField (transCombos.at(i) -> lineEdit(), translations[i]);
491 else
492 for ( uint i = 0; i < translations.count(); i ++ )
494 transFields.at(i) -> setText (translations[i]);
495 verifyField (transFields.at(i), translations[i]);
497 mw->verify -> setEnabled (false);
498 mw->dont_know->setDefault(true);
499 mw->status -> clear();
500 suggestion_hint = false;
504 void RandomQueryDlg::slotTransChanged(const QString&)
506 mw->verify->setDefault(true);
507 if ( suggestions && sender() && sender() -> isA ("QComboBox") )
509 QLineEdit* edit = ((QComboBox*) sender()) -> lineEdit();
510 resetField (edit);
511 suggestion_hint = ! edit -> text().isEmpty() && edit -> text().length() <= 10;
512 if ( suggestion_hint )
513 mw->status -> setText (QString (i18n("Press F5 for a list of translations starting with '%1'\n"
514 "Press F6 for a list of translations containing '%2'")).arg (edit -> text()).arg (edit -> text()));
515 else
516 mw->status -> clear();
518 else if ( ! suggestions && sender() && sender() -> isA ("QLineEdit") )
519 resetField ((QLineEdit*) sender());
522 void RandomQueryDlg::slotTransLostFocus()
524 if ( suggestion_hint )
525 mw->status -> clear();
526 suggestion_hint = false;
530 void RandomQueryDlg::knowItClicked()
532 mw->status -> clear();
533 suggestion_hint = false;
534 emit sigQueryChoice (Known);
538 void RandomQueryDlg::timeoutReached()
540 if (timercount > 0) {
541 timercount--;
542 mw->timebar->setProgress(timercount);
543 qtimer->start(1000, TRUE);
546 if (timercount <= 0) {
547 mw->timebar->setProgress(0);
548 if (Prefs::queryTimeout() == Prefs::EnumQueryTimeout::Show) {
549 showAllClicked();
550 mw->dont_know->setDefault(true);
552 else if (Prefs::queryTimeout() == Prefs::EnumQueryTimeout::Continue) {
553 emit sigQueryChoice (Timeout);
555 mw->status->setText(getTimeoutComment((mw->countbar->progress()/mw->countbar->totalSteps()) * 100));
558 suggestion_hint = false;
562 void RandomQueryDlg::dontKnowClicked()
564 mw->status -> clear();
565 suggestion_hint = false;
566 emit sigQueryChoice (Unknown);
570 void RandomQueryDlg::setHintFields()
572 QString s;
573 kvoctrainExpr *exp = kv_doc->getEntry(q_row);
575 s = exp->getRemark(q_ocol);
576 mw->remark->setText (s);
577 mw->c_remark->setEnabled(!s.isEmpty() );
579 s = exp->getFauxAmi(q_ocol, q_ocol != 0);
580 mw->falseFriend->setText (s);
581 mw->c_falsefriend->setEnabled(!s.isEmpty() );
583 s = "";
584 vector<TypeRelation> all_types = QueryManager::getRelation(false);
585 for (int i = 0; i < (int) all_types.size(); i++) {
586 if ( exp->getType(q_ocol) == all_types[i].shortStr()) {
587 s = all_types[i].longStr();
588 break;
591 mw->type->setText (s);
592 mw->c_type->setEnabled(!s.isEmpty() );
596 void RandomQueryDlg::slotUser2()
598 if (qtimer != 0)
599 qtimer->stop();
601 emit sigEditEntry (q_row, KV_COL_ORG+q_ocol);
603 kvoctrainExpr *exp = kv_doc->getEntry(q_row);
604 mw->orgField->setText (q_ocol == 0
605 ? exp->getOriginal()
606 : exp->getTranslation(q_ocol));
608 if ( suggestions )
609 for ( int i = 0; i < fields; i ++ )
610 transCombos.at(i) -> clearEdit();
611 else
612 for ( int i = 0; i < fields; i ++ )
613 transFields.at(i) -> clear();
614 mw->status -> clear();
615 suggestion_hint = false;
617 setHintFields();
621 void RandomQueryDlg::slotFFClicked()
623 if (mw->c_falsefriend->isChecked() )
624 mw->falseFriend->show();
625 else
626 mw->falseFriend->hide();
630 void RandomQueryDlg::slotRemClicked()
632 if (mw->c_remark->isChecked())
633 mw->remark->show();
634 else
635 mw->remark->hide();
639 void RandomQueryDlg::slotTypeClicked()
641 if (mw->c_type->isChecked() )
642 mw->type->show();
643 else
644 mw->type->hide();
648 void RandomQueryDlg::keyPressEvent( QKeyEvent *e )
650 if ( suggestions )
652 QComboBox* combo = 0;
653 if ( e -> key() == Key_F4 || e -> key() == Key_F5 || e -> key() == Key_F6 )
654 for ( uint i = 0; i < translations.count(); i ++ )
655 if ( transCombos.at(i) -> hasFocus() )
657 combo = transCombos.at(i);
658 break;
660 switch( e->key() )
662 case Key_F5:
663 case Key_F6:
664 if ( combo && ! combo -> currentText().isEmpty() )
666 QString curText (combo -> currentText());
667 combo -> clear();
668 for ( uint i = 0; i < vocabulary.count(); i ++ )
670 QString trans (vocabulary[i]);
671 if ( (e -> key() == Key_F5 && trans.startsWith (curText, false)
672 || e -> key() == Key_F6 && trans.contains (curText, false)) )
673 combo -> insertItem (trans);
675 combo -> setEditText (curText);
677 case Key_F4:
678 if ( combo )
679 combo -> popup();
680 break;
684 switch( e->key() )
686 case Key_Escape:
687 dontKnowClicked();
688 break;
690 case Key_Return:
691 case Key_Enter:
692 if (mw->dont_know->isDefault() )
693 dontKnowClicked();
694 else if (mw->know_it->isDefault() )
695 knowItClicked();
696 else if (mw->show_all->isDefault() )
697 showAllClicked();
698 else if (mw->verify->isDefault() )
699 verifyClicked();
700 break;
702 default:
703 e->ignore();
704 break;
708 #include "RandomQueryDlg.moc"