• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

parley

  • sources
  • kde-4.14
  • kdeedu
  • parley
  • src
  • collection
entryfilter.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  Copyright 2008 Frederik Gladhorn <frederik.gladhorn@kdemail.net>
3  ***************************************************************************/
4 
5 /***************************************************************************
6  * *
7  * This program is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  ***************************************************************************/
13 
14 #include "entryfilter.h"
15 
16 
17 #include <krandom.h>
18 
19 #include <KDebug>
20 #include <KDialog>
21 #include <KMessageBox>
22 
23 #include <keduvocdocument.h>
24 #include <keduvocwordtype.h>
25 #include <keduvocexpression.h>
26 
27 #include "documentsettings.h"
28 #include "testentry.h"
29 
30 
31 // Blocking times for pregrade levels.
32 //
33 // It could be argued that these should be configurable but I am not
34 // sure what that would bring us or the user. Definitely not improved
35 // learning...
36 //
37 // FIXME: Find out what the optimal values are.
38 int preGradeTimes[] = {
39  0,
40  3 * 60 + 30, // 1: 3.5 minutes
41  7 * 60, // 2: 7 minutes
42  15 * 60, // 3: 15 minutes
43  1 * 3600, // 4: 1 hour
44  2 * 3600, // 5: 2 hours
45  4 * 3600, // 6: 4 hours
46  8 * 3600, // 7: 8 hours
47 };
48 
49 
50 EntryFilter::EntryFilter(KEduVocDocument* doc, QObject * parent)
51  : QObject(parent)
52  , m_doc(doc)
53  , m_dialog(0)
54 {
55  if (Prefs::practiceMode() == Prefs::EnumPracticeMode::ConjugationPractice) {
56  DocumentSettings documentSettings(m_doc->url().url() + QString::number(m_toTranslation));
57  documentSettings.readConfig();
58  m_tenses = documentSettings.conjugationTenses();
59  kDebug() << "Tenses" << m_tenses;
60  }
61 }
62 
63 static void debugEntry(const QString &comment, KEduVocExpression *vocexp,
64  KEduVocTranslation *from, KEduVocTranslation *to)
65 {
66  Q_UNUSED(vocexp);
67 
68  kDebug() << comment << "from" << from->text() << "to" << to->text();
69 }
70 
71 QList<TestEntry*> EntryFilter::entries(bool showDialog)
72 {
73  switch (Prefs::practiceDirection()) {
74  case Prefs::EnumPracticeDirection::KnownToLearning:
75  m_numSets = 1;
76  m_fromTranslation = Prefs::knownLanguage();
77  m_toTranslation = Prefs::learningLanguage();
78  break;
79  case Prefs::EnumPracticeDirection::LearningToKnown:
80  m_numSets = 1;
81  m_fromTranslation = Prefs::learningLanguage();
82  m_toTranslation = Prefs::knownLanguage();
83  break;
84  case Prefs::EnumPracticeDirection::MixedDirectionsWordsOnly:
85  m_numSets = 2;
86  m_fromTranslation = Prefs::knownLanguage();
87  m_toTranslation = Prefs::learningLanguage();
88  break;
89  case Prefs::EnumPracticeDirection::MixedDirectionsWithSound:
90  // FIXME: Not yet supported. Use same settings as MixedModeWordsOnly
91  m_numSets = 2;
92  m_fromTranslation = Prefs::knownLanguage();
93  m_toTranslation = Prefs::learningLanguage();
94  break;
95  default:
96  // Use KnownToLearning as default.
97  m_numSets = 1;
98  m_fromTranslation = Prefs::knownLanguage();
99  m_toTranslation = Prefs::learningLanguage();
100  break;
101  }
102 
103  for (int pass = 0; pass < m_numSets; ++pass) {
104  // If we only do one pass, then from/to translation are already set.
105  // But in mixed mode we need to set up pass 1 and later.
106  if (pass == 1) {
107  m_fromTranslation = Prefs::learningLanguage();
108  m_toTranslation = Prefs::knownLanguage();
109  }
110 
111  //kDebug() << "Filter for " << m_fromTranslation << " to " << m_toTranslation;
112  expireEntries(pass);
113 
114  collectEntries(pass);
115  }
116 
117  static QString noEntriesError =
118  i18n("The vocabulary document contains no entries that can be used for the chosen type"
119  " of practice.");
120 
121  //kDebug() << "Document contains " << m_entries[0].count() + m_entries[1].count() << " valid entries.";
122  if (m_entries[0].count() + m_entries[1].count() == 0) {
123  if (showDialog) {
124  KMessageBox::error(0, noEntriesError);
125  }
126  return QList<TestEntry*>();
127  }
128 
129  updateTotal();
130 
131  bool ignoreBlocked = false;
132  int numSelected = m_currentSelection[0].count() + m_currentSelection[1].count();
133  if (numSelected == 0 && showDialog) {
134  //kDebug() << "Creating practice filter dialog.";
135  m_dialog = new KDialog;
136  m_dialog->setCaption(i18n("Start Practice"));
137  QWidget *widget = new QWidget(m_dialog);
138  ui.setupUi(widget);
139  m_dialog->setMainWidget(widget);
140  m_dialog->setButtons(KDialog::Ok | KDialog::Cancel);
141 
142  int numEntries = m_entries[0].count() + m_entries[1].count();
143  ui.lessonLabel ->setText(QString::number(numEntries
144  - m_entriesLesson[0].count()
145  - m_entriesLesson[1].count()));
146  ui.wordTypeLabel ->setText(QString::number(numEntries
147  - m_entriesWordType[0].count()
148  - m_entriesWordType[1].count()));
149  ui.blockedLabel ->setText(QString::number(numEntries
150  - m_entriesNotBlocked[0].count()
151  - m_entriesNotBlocked[1].count()));
152  ui.timesWrongLabel ->setText(QString::number(numEntries
153  - m_entriesTimesWrong[0].count()
154  - m_entriesTimesWrong[1].count()));
155  ui.timesPracticedLabel->setText(QString::number(numEntries
156  - m_entriesTimesPracticed[0].count()
157  - m_entriesTimesPracticed[1].count()));
158  ui.minMaxGradeLabel ->setText(QString::number(numEntries
159  - m_entriesMinMaxGrade[0].count()
160  - m_entriesMinMaxGrade[1].count()));
161 
162  ui.documentTotalLabel->setText(QString::number(numEntries));
163  updateTotal();
164 
165  ui.lessonCheckBox->setChecked(m_entriesLesson[0].count() + m_entriesLesson[1].count() == 0);
166  ui.wordTypeCheckBox->setChecked(m_entriesWordType[0].count() + m_entriesWordType[1].count() == 0);
167  ui.blockedCheckBox->setChecked(m_entriesNotBlocked[0].count() + m_entriesNotBlocked[1].count() == 0);
168  ui.timesWrongCheckBox->setChecked(m_entriesTimesWrong[0].count() + m_entriesTimesWrong[1].count() == 0);
169  ui.timesPracticedCheckBox->setChecked(m_entriesTimesPracticed[0].count() + m_entriesTimesPracticed[1].count() == 0);
170  ui.minMaxGradeCheckBox->setChecked(m_entriesMinMaxGrade[0].count() + m_entriesMinMaxGrade[1].count() == 0);
171 
172  connect(ui.lessonCheckBox, SIGNAL(toggled(bool)), this, SLOT(checkBoxChanged(bool)));
173  connect(ui.wordTypeCheckBox, SIGNAL(toggled(bool)), this, SLOT(checkBoxChanged(bool)));
174  connect(ui.blockedCheckBox, SIGNAL(toggled(bool)), this, SLOT(checkBoxChanged(bool)));
175  connect(ui.timesWrongCheckBox, SIGNAL(toggled(bool)), this, SLOT(checkBoxChanged(bool)));
176  connect(ui.timesPracticedCheckBox, SIGNAL(toggled(bool)), this, SLOT(checkBoxChanged(bool)));
177  connect(ui.minMaxGradeCheckBox, SIGNAL(toggled(bool)), this, SLOT(checkBoxChanged(bool)));
178 
179  updateTotal();
180 
181  if (!Prefs::wordTypesInPracticeEnabled()) {
182  ui.wordTypeLabel->setVisible(false);
183  ui.wordTypeCheckBox->setVisible(false);
184  }
185 
186  if (m_dialog->exec() == QDialog::Rejected) {
187  delete m_dialog;
188  return QList<TestEntry*>();
189  }
190  ignoreBlocked = ui.blockedCheckBox->isChecked();
191  delete m_dialog;
192  }
193 
194  // Finally, create the list of test entries from the selected
195  // lists of EduVocTranslations.
196  if (Prefs::practiceMode() == Prefs::EnumPracticeMode::ConjugationPractice) {
197  QList< TestEntry* > ret = conjugationTestEntries(ignoreBlocked);
198  if (ret.count() == 0) {
199  KMessageBox::error(0, noEntriesError);
200  }
201  return ret;
202  } else {
203  // FIXME: Create entries already from the beginning so we
204  // don't have to work with kvtml translations first and
205  // then entries later.
206  QList<TestEntry*> testEntries;
207  for (int setNo = 0; setNo < m_numSets; ++setNo) {
208  int from;
209  int to;
210 
211  if (setNo == 0) {
212  switch (Prefs::practiceDirection()) {
213  case Prefs::EnumPracticeDirection::KnownToLearning:
214  from = Prefs::knownLanguage();
215  to = Prefs::learningLanguage();
216  break;
217  case Prefs::EnumPracticeDirection::LearningToKnown:
218  from = Prefs::learningLanguage();
219  to = Prefs::knownLanguage();
220  break;
221  case Prefs::EnumPracticeDirection::MixedDirectionsWordsOnly:
222  case Prefs::EnumPracticeDirection::MixedDirectionsWithSound:
223  default:
224  from = Prefs::knownLanguage();
225  to = Prefs::learningLanguage();
226  break;
227  }
228  }
229  else {
230  from = Prefs::learningLanguage();
231  to = Prefs::knownLanguage();
232  }
233 
234  foreach(KEduVocExpression * entry, m_currentSelection[setNo]) {
235  // Set the from and to translation for the entry itself.
236  TestEntry *testEntry = new TestEntry(entry);
237 
238  testEntry->setLanguageFrom(from);
239  testEntry->setLanguageTo(to);
240 
241  randomizedInsert(testEntries, testEntry);
242  }
243  }
244  return testEntries;
245  }
246 }
247 
248 
249 void EntryFilter::expireEntries(int setNo)
250 {
251  if (Prefs::expire()) {
252  int counter = 0;
253  foreach(KEduVocExpression * entry, m_entries[setNo]) {
254  int grade = entry->translation(m_toTranslation)->grade();
255 
256  const QDateTime &date = entry->translation(m_toTranslation)->practiceDate();
257 
258  const QDateTime &expireDate = QDateTime::currentDateTime().addSecs(-Prefs::expireItem(grade));
259 
260  if (date < expireDate && grade > 0) {
261  // decrease the grade
262  entry->translation(m_toTranslation)->decGrade();
263 
264  // prevent from endless dropping
265  entry->translation(m_toTranslation)->setPracticeDate(QDateTime::currentDateTime().addSecs(-Prefs::expireItem(grade - 2)));
266  counter++;
267  }
268  }
269  kDebug() << "Expired words dropped their confidence: " << counter;
270  }
271 }
272 
273 
274 void EntryFilter::collectEntries(int setNo)
275 {
276  // Set up the lists/sets of filtered vocabulary
277  m_entries[setNo] = m_doc->lesson()->entries(KEduVocLesson::Recursive).toSet();
278  cleanupInvalid(setNo);
279 
280  // FIXME the filtering needs to be done for each word or the grammar modes get included with written or somesuch
281 
282  /* FIXME
283  if (Prefs::genderPractice())
284  {
285  if (m_doc->identifier(m_toTranslation).article().isEmpty())
286  {
287  KMessageBox::error(0, i18n("The vocabulary document contains no articles for the current language. Please add some in the Edit->Grammar menu."));
288  return QList<KEduVocExpression*>();
289  }
290  }
291  */
292 
293  lessonEntries(setNo);
294  wordTypeEntries(setNo);
295  blockedEntries(setNo);
296  timesWrongEntries(setNo);
297  timesPracticedEntries(setNo);
298  minMaxGradeEntries(setNo);
299 }
300 
301 
302 void EntryFilter::lessonEntries(int setNo)
303 {
304  foreach(KEduVocExpression * entry, m_entries[setNo]) {
305  if (entry->lesson()->inPractice()) {
306  m_entriesLesson[setNo].insert(entry);
307  }
308  }
309 }
310 
311 void EntryFilter::wordTypeEntries(int setNo)
312 {
313  if (Prefs::wordTypesInPracticeEnabled()) {
314  foreach(KEduVocExpression * entry, m_entries[setNo]) {
315  if (entry->translation(m_toTranslation)->wordType()) {
316  if (entry->translation(m_toTranslation)->wordType()->inPractice()) {
317  m_entriesWordType[setNo].insert(entry);
318  }
319  }
320  }
321  } else {
322  m_entriesWordType[setNo] = m_entries[setNo];
323  }
324 }
325 
326 void EntryFilter::blockedEntries(int setNo)
327 {
328  if (!Prefs::block()) {
329  m_entriesNotBlocked[setNo] = m_entries[setNo];
330  return;
331  }
332 
333  switch (Prefs::practiceMode()) {
334  case Prefs::EnumPracticeMode::ConjugationPractice:
335  foreach(KEduVocExpression * entry, m_entries[setNo]) {
336  if (!isConjugationBlocked(entry->translation(m_toTranslation))) {
337  m_entriesNotBlocked[setNo].insert(entry);
338  }
339  }
340  break;
341  case Prefs::EnumPracticeMode::GenderPractice:
342  foreach(KEduVocExpression * entry, m_entries[setNo]) {
343  KEduVocText article = entry->translation(m_toTranslation)->article();
344  if (!isBlocked(&article)) {
345  m_entriesNotBlocked[setNo].insert(entry);
346  }
347  }
348  break;
349  case Prefs::EnumPracticeMode::ComparisonPractice:
350  foreach(KEduVocExpression * entry, m_entries[setNo]) {
351  KEduVocTranslation* translation = entry->translation(m_toTranslation);
352  KEduVocText comparative = translation->comparativeForm();
353  KEduVocText superlative = translation->superlativeForm();
354  if (!isBlocked(&(comparative))
355  || !isBlocked(&(superlative))) {
356  m_entriesNotBlocked[setNo].insert(entry);
357  }
358  }
359  break;
360  default:
361  foreach(KEduVocExpression * entry, m_entries[setNo]) {
362  if (!isBlocked(entry->translation(m_toTranslation))) {
363  m_entriesNotBlocked[setNo].insert(entry);
364  //debugEntry("Not blocked:", entry,
365  // entry->translation(m_fromTranslation),
366  // entry->translation(m_toTranslation));
367  }
368  else {
369  //debugEntry("Blocked:", entry,
370  // entry->translation(m_fromTranslation),
371  // entry->translation(m_toTranslation));
372  }
373  }
374  break;
375  }
376 }
377 
378 bool EntryFilter::isConjugationBlocked(KEduVocTranslation* translation) const
379 {
380  foreach(const QString & tense, translation->conjugationTenses()) {
381  if (m_tenses.contains(tense)) {
382  QList<KEduVocWordFlags> pronouns = translation->conjugation(tense).keys();
383  foreach(const KEduVocWordFlags & pronoun, pronouns) {
384  KEduVocText grade = translation->conjugation(tense).conjugation(pronoun);
385  if (!isBlocked(&(grade))) {
386  // just need to find any form that is not blocked for generating test entries
387  // exact filtering is done later in conjugationTestEntries
388  return false;
389  }
390  }
391  }
392  }
393  return true;
394 }
395 
396 bool EntryFilter::isBlocked(const KEduVocText* const text) const
397 {
398  grade_t grade = text->grade();
399  grade_t preGrade = text->preGrade();
400 
401  // Sanity checks.
402  // Note that grade_t is unsigned so no need to check < 0.
403  //
404  // FIXME: This should be done when the prefs are first read.
405  if (preGrade > KV_MAX_GRADE) {
406  preGrade = KV_MAX_GRADE;
407  }
408  if (grade > KV_MAX_GRADE) {
409  grade = KV_MAX_GRADE;
410  }
411 
412  QDateTime now = QDateTime::currentDateTime();
413 
414  if ((grade == KV_NORM_GRADE && preGrade == KV_NORM_GRADE)
415  || (grade > 0 && Prefs::blockItem(grade) == 0))
416  {
417  // Always include untrained words and all words when blocking is off.
418 
419  //kDebug() << "Not blocked, test 1; word =" << text->text() << "grade =" << grade
420  // << "blockItem(grade) =" << Prefs::blockItem(grade);
421 
422  return false;
423  }
424  else if (grade == KV_NORM_GRADE) {
425  // Test for pregrade blocking.
426  QDateTime date = text->practiceDate();
427  if (date.addSecs(preGradeTimes[preGrade]) < now) {
428  //kDebug() << "Not blocked, test 2";
429  return false;
430  }
431  }
432  else {
433  // Test for grade blocking.
434 
435  QDateTime date = text->practiceDate();
436  if (date.addSecs(Prefs::blockItem(grade)) < now) {
437  //kDebug() << "Not blocked, test 3";
438  return false;
439  }
440  }
441 
442  return true;
443 }
444 
445 void EntryFilter::timesWrongEntries(int setNo)
446 {
447  foreach(KEduVocExpression * entry, m_entries[setNo]) {
448  if (entry->translation(m_toTranslation)->badCount() >= Prefs::practiceMinimumWrongCount() && entry->translation(m_toTranslation)->badCount() <= Prefs::practiceMaximumWrongCount()) {
449  m_entriesTimesWrong[setNo].insert(entry);
450  }
451  }
452 }
453 
454 void EntryFilter::timesPracticedEntries(int setNo)
455 {
456  foreach(KEduVocExpression * entry, m_entries[setNo]) {
457  if (entry->translation(m_toTranslation)->practiceCount() >= Prefs::practiceMinimumTimesAsked() && entry->translation(m_toTranslation)->practiceCount() <= Prefs::practiceMaximumTimesAsked()) {
458  m_entriesTimesPracticed[setNo].insert(entry);
459  }
460  }
461 }
462 
463 void EntryFilter::minMaxGradeEntries(int setNo)
464 {
465  foreach(KEduVocExpression * entry, m_entries[setNo]) {
466  int grade = entry->translation(m_toTranslation)->grade();
467  if (grade >= Prefs::practiceMinimumGrade() && grade <= Prefs::practiceMaximumGrade()) {
468  m_entriesMinMaxGrade[setNo].insert(entry);
469  }
470  }
471 }
472 /*
473  if (m_testType == Prefs::EnumTestType::ArticleTest) {
474  KMessageBox::information(0,
475  i18n("You selected to practice the genders of nouns, but no appropriate nouns could be found. Use \"Edit Entry\" and select Noun as word type and the gender."),
476  i18n("No valid word type found"));
477  return;
478 }
479  if (m_testType == Prefs::EnumTestType::ComparisonTest) {
480  KMessageBox::information(0,
481  i18n("You selected to practice comparison forms, but no adjectives or adverbs containing comparison forms could be found. Use \"Edit Entry\" and select Adverb or Adjective as word type and enter the comparison forms."),
482  i18n("No valid word type found"));
483  return;
484 }
485  if (m_testType == Prefs::EnumTestType::ConjugationTest) {
486  KMessageBox::information(0, i18n("You selected to practice conjugations, but no vocabulary containing conjugations in the tenses you selected could be found. Use \"Edit Entry\" and select Verb as word type and enter the conjugation forms."), i18n("No valid word type found"));
487  return;
488 }
489 }
490 
491  if ( removeTestEntryList.count() == m_entries.count() ) {
492  if ( KMessageBox::questionYesNo(0, i18n("<p>The units you selected for the practice contain no entries when the threshold settings are respected.</p><p>Hint: To configure the thresholds use the \"Threshold Page\" in the \"Configure Practice\" dialog.</p><p>Would you like to ignore the threshold setting?</p>"), i18n("No Entries with Current Threshold Settings") ) == KMessageBox::No ) {
493  return;
494 }
495 
496 */
497 
498 void EntryFilter::cleanupInvalid(int setNo)
499 {
500  Prefs::EnumPracticeMode::type mode = Prefs::practiceMode();
501  bool wordTypeNeeded = (mode == Prefs::EnumPracticeMode::GenderPractice) ||
502  (mode == Prefs::EnumPracticeMode::ComparisonPractice) ||
503  (mode == Prefs::EnumPracticeMode::ConjugationPractice);
504 
505  QSet<KEduVocExpression*>::iterator i = m_entries[setNo].begin();
506  while (i != m_entries[setNo].end()) {
507  KEduVocTranslation *fromTranslation = (*i)->translation(m_fromTranslation);
508  KEduVocTranslation *toTranslation = (*i)->translation(m_toTranslation);
509 
510  // Remove empty entries.
511  bool keep = ((!fromTranslation->text().isEmpty()
512  || (Prefs::allowImageInsteadOfWord()
513  && !fromTranslation->imageUrl().isEmpty()))
514  && !toTranslation->text().isEmpty());
515  if (!keep) {
516  i = m_entries[setNo].erase(i);
517  //debugEntry("Removing empty:", *i, fromTranslation, toTranslation);
518  continue;
519  }
520 
521  // For grammar stuff we need the word to have its word type set, else continue
522  if (wordTypeNeeded && !(*i)->translation(m_toTranslation)->wordType()) {
523  i = m_entries[setNo].erase(i);
524  continue;
525  }
526 
527  // Grammar modes need different things:
528  switch (Prefs::practiceMode()) {
529 
530  // example sentences: need the example sentence to exist
531  case Prefs::EnumPracticeMode::ExampleSentencesPractice:
532  if ((*i)->translation(m_toTranslation)->example().simplified().isEmpty()) {
533  i = m_entries[setNo].erase(i);
534  continue;
535  }
536  break;
537 
538  case Prefs::EnumPracticeMode::GenderPractice:
539  if (!((*i)->translation(m_toTranslation)->wordType()->wordType() & KEduVocWordFlag::Noun)) {
540  i = m_entries[setNo].erase(i);
541  continue;
542  }
543  break;
544 
545  case Prefs::EnumPracticeMode::ComparisonPractice:
546  if (
547  // only adjective/adverb
548  (((*i)->translation(m_toTranslation)->wordType()->wordType() != KEduVocWordFlag::Adjective)
549  && ((*i)->translation(m_toTranslation)->wordType()->wordType() != KEduVocWordFlag::Adverb))
550  // at least one comparison forms is there
551  || ((*i)->translation(m_toTranslation)->comparative().isEmpty() || (*i)->translation(m_toTranslation)->superlative().isEmpty())) {
552  i = m_entries[setNo].erase(i);
553  continue;
554  }
555  break;
556 
557  case Prefs::EnumPracticeMode::ConjugationPractice: {
558  KEduVocTranslation* translation = (*i)->translation(m_toTranslation);
559  bool erase = false;
560 
561  // Remove entries which are not verbs
562  if (translation->wordType()->wordType() != KEduVocWordFlag::Verb) {
563  erase = true;
564  }
565 
566  // Remove entries which don't have any of the tenses which are configured for practice
567  QSet<QString> practice_tenses = QSet<QString>::fromList(m_tenses);
568  QSet<QString> existing_tenses;
569  foreach(const QString & tense, translation->conjugationTenses()) {
570  if (!translation->conjugation(tense).isEmpty()) {
571  existing_tenses << tense;
572  }
573  }
574  if (existing_tenses.intersect(practice_tenses).isEmpty()) erase = true;
575 
576  if (erase) {
577  i = m_entries[setNo].erase(i);
578  continue;
579  }
580  break;
581  }
582  default:
583  break;
584  } // switch
585  ++i;
586  } // while
587  //kDebug() << "Invalid items removed. Remaining: " << m_entries[setNo].count();
588 }
589 
590 QList< TestEntry* > EntryFilter::conjugationTestEntries(bool ignoreBlocked) const
591 {
592  kDebug() << "Filtering conjugation entries for tenses... " << m_tenses;
593 
594  // TODO CM make this configurable
595  enum MODE {
596  M_SEPARATE,
597  M_COMPLETE
598  };
599  MODE mode = M_SEPARATE;
600 
601  QList<TestEntry*> testEntries;
602  for (int i = 0; i < m_numSets; ++i) {
603  foreach(KEduVocExpression * entry, m_currentSelection[i]) {
604  foreach(const QString & tense, entry->translation(m_toTranslation)->conjugationTenses()) {
605 
606  // Only include tenses which are both non-empty and which should be practiced
607  if (!m_tenses.contains(tense)) {
608  continue;
609  }
610  KEduVocConjugation& conjugation = entry->translation(m_toTranslation)->conjugation(tense);
611  if (conjugation.isEmpty()) {
612  continue;
613  }
614 
615  bool blocked = true;
616  QList<KEduVocWordFlags> pronouns = conjugation.keys();
617  foreach(const KEduVocWordFlags & pronoun, pronouns) {
618  KEduVocText* grade = &conjugation.conjugation(pronoun);
619  if (ignoreBlocked || !isBlocked(grade)) {
620  blocked = false;
621 
622  if (mode == M_SEPARATE) {
623  TestEntry* testEntry = new TestEntry(entry);
624  testEntry->setConjugationTense(tense);
625  QList<KEduVocWordFlags> list;
626  list << pronoun;
627  testEntry->setConjugationPronouns(list);
628  randomizedInsert(testEntries, testEntry);
629  }
630  }
631  }
632 
633  if (!blocked && mode == M_COMPLETE) {
634  TestEntry* testEntry = new TestEntry(entry);
635  testEntry->setConjugationTense(tense);
636  testEntry->setConjugationPronouns(pronouns);
637  randomizedInsert(testEntries, testEntry);
638  }
639  }
640  }
641  }
642  return testEntries;
643 }
644 
645 
646 // ----------------------------------------------------------------
647 // Support functions for the dialog
648 
649 
650 void EntryFilter::checkBoxChanged(bool filter)
651 {
652  Q_UNUSED(filter)
653  updateTotal();
654 }
655 
656 void EntryFilter::updateTotal()
657 {
658  QSet< KEduVocExpression * > selected[2];
659 
660  for (int i = 0; i < m_numSets; ++i) {
661  selected[i] = m_entries[i];
662  if (!m_dialog || !ui.lessonCheckBox->isChecked()) {
663  selected[i] = selected[i].intersect(m_entriesLesson[i]);
664  }
665  if (!m_dialog || !ui.wordTypeCheckBox->isChecked()) {
666  selected[i] = selected[i].intersect(m_entriesWordType[i]);
667  }
668  if (!m_dialog || !ui.blockedCheckBox->isChecked()) {
669  selected[i] = selected[i].intersect(m_entriesNotBlocked[i]);
670  }
671  if (!m_dialog || !ui.timesWrongCheckBox->isChecked()) {
672  selected[i] = selected[i].intersect(m_entriesTimesWrong[i]);
673  }
674  if (!m_dialog || !ui.timesPracticedCheckBox->isChecked()) {
675  selected[i] = selected[i].intersect(m_entriesTimesPracticed[i]);
676  }
677  if (!m_dialog || !ui.minMaxGradeCheckBox->isChecked()) {
678  selected[i] = selected[i].intersect(m_entriesMinMaxGrade[i]);
679  }
680 
681  m_currentSelection[i] = selected[i];
682  }
683 
684  if (m_dialog) {
685  int numSelected = selected[0].count() + selected[1].count();
686  ui.totalLabel->setText(QString::number(numSelected));
687  m_dialog->enableButtonOk(numSelected > 0);
688  }
689 }
690 
691 
692 // ----------------------------------------------------------------
693 // Utilities
694 
695 
696 void EntryFilter::randomizedInsert(QList<TestEntry*>& list, TestEntry* entry)
697 {
698  list.insert(KRandom::random() % (list.size() + 1), entry);
699 }
700 
701 #include "entryfilter.moc"
Prefs::wordTypesInPracticeEnabled
static bool wordTypesInPracticeEnabled()
Get Only selected word types will be included in practice.
Definition: prefs.h:1191
QWidget
TestEntry::setLanguageFrom
void setLanguageFrom(int from)
Definition: testentry.cpp:34
Prefs::EnumPracticeMode::ComparisonPractice
Definition: prefs.h:26
Prefs::EnumPracticeMode::ConjugationPractice
Definition: prefs.h:26
debugEntry
static void debugEntry(const QString &comment, KEduVocExpression *vocexp, KEduVocTranslation *from, KEduVocTranslation *to)
Definition: entryfilter.cpp:63
EntryFilter
Definition: entryfilter.h:31
Prefs::practiceMode
static EnumPracticeMode::type practiceMode()
Get The practice method that is currently selected.
Definition: prefs.h:1324
Prefs::practiceMinimumGrade
static int practiceMinimumGrade()
Get The entry must have at least this confidence level to be included in the practice (0...
Definition: prefs.h:1153
TestEntry::setLanguageTo
void setLanguageTo(int to)
Definition: testentry.cpp:39
Prefs::practiceMaximumTimesAsked
static int practiceMaximumTimesAsked()
Get The entry must have been asked at most this often to be included in the practice.
Definition: prefs.h:1096
documentsettings.h
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
DocumentSettings
Definition: documentsettings.h:9
Prefs::EnumPracticeMode::type
type
Definition: prefs.h:26
EntryFilter::EntryFilter
EntryFilter(KEduVocDocument *doc, QObject *parent)
Definition: entryfilter.cpp:50
Prefs::expireItem
static int expireItem(int i)
Get Amount of time after which different confidence levels should expire.
Definition: prefs.h:1381
KDialog
QSet::insert
const_iterator insert(const T &value)
preGradeTimes
int preGradeTimes[]
Definition: entryfilter.cpp:38
entryfilter.h
Prefs::EnumPracticeDirection::MixedDirectionsWithSound
Definition: prefs.h:31
QList::size
int size() const
Prefs::blockItem
static int blockItem(int i)
Get Amount of time different confidence levels should be blocked.
Definition: prefs.h:1362
testentry.h
TestEntry::setConjugationTense
void setConjugationTense(const QString &tense)
Definition: testentry.cpp:159
Prefs::practiceMinimumTimesAsked
static int practiceMinimumTimesAsked()
Get The entry must have been asked at least this often to be included in the practice.
Definition: prefs.h:1077
QString::number
QString number(int n, int base)
QList::count
int count(const T &value) const
Prefs::EnumPracticeMode::GenderPractice
Definition: prefs.h:26
QObject
Prefs::expire
static bool expire()
Get In Blocking Query Tab Dialog, if checked then the Query accepts an expiring time.
Definition: prefs.h:317
Prefs::practiceMinimumWrongCount
static int practiceMinimumWrongCount()
Get The entry must have been answered incorrectly at least this often to be included in the practice...
Definition: prefs.h:1115
Prefs::practiceMaximumWrongCount
static int practiceMaximumWrongCount()
Get The entry must have been answered incorrectly at most this often to be included in the practice...
Definition: prefs.h:1134
Scripting::Parley::doc
QObject doc
Abreviation of document property (same as Parley.document)
Definition: parley.h:158
Prefs::practiceDirection
static EnumPracticeDirection::type practiceDirection()
Get The practice mode that is currently selected.
Definition: prefs.h:1343
QSet
Prefs::block
static bool block()
Get In Blocking Query Tab Dialog, if checked then the Query is blocked.
Definition: prefs.h:298
QString
QList< TestEntry * >
Prefs::practiceMaximumGrade
static int practiceMaximumGrade()
Get The entry must have at most this confidence level to be included in the practice (0...
Definition: prefs.h:1172
QSet::count
int count() const
QSet::begin
iterator begin()
QSet::erase
iterator erase(iterator pos)
TestEntry::setConjugationPronouns
void setConjugationPronouns(const QList< KEduVocWordFlags > &flags)
Definition: testentry.cpp:169
QDateTime::currentDateTime
QDateTime currentDateTime()
Prefs::knownLanguage
static int knownLanguage()
Get The language that you know already.
Definition: prefs.h:1267
Prefs::EnumPracticeDirection::LearningToKnown
Definition: prefs.h:31
QSet::intersect
QSet< T > & intersect(const QSet< T > &other)
QList::insert
void insert(int i, const T &value)
Prefs::EnumPracticeMode::ExampleSentencesPractice
Definition: prefs.h:26
QSet::fromList
QSet< T > fromList(const QList< T > &list)
Prefs::allowImageInsteadOfWord
static bool allowImageInsteadOfWord()
Get Allow using images instead of words in flashcards.
Definition: prefs.h:735
Prefs::learningLanguage
static int learningLanguage()
Get The language that you are learning.
Definition: prefs.h:1248
QDateTime::addSecs
QDateTime addSecs(int s) const
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::parent
QObject * parent() const
Prefs::EnumPracticeDirection::KnownToLearning
Definition: prefs.h:31
EntryFilter::entries
QList< TestEntry * > entries(bool showDialog=true)
Returns the list of test entries after filtering out invalid entries according to the settings...
Definition: entryfilter.cpp:71
QDateTime
Prefs::EnumPracticeDirection::MixedDirectionsWordsOnly
Definition: prefs.h:31
TestEntry
Definition: testentry.h:22
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:15:56 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

parley

Skip menu "parley"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal