From: Frederik Gladhorn Date: Sat, 28 Jun 2008 23:33:54 +0000 (+0000) Subject: Move a lot of stuff around to get Leitner Boxes functionallity in there. X-Git-Tag: v4.1.80~41^2~4 X-Git-Url: https://git.rmz.fi/?a=commitdiff_plain;h=f7eb2e49c4b0a5a98181a1500a05f98378aa37cf;p=libqmvoc.git Move a lot of stuff around to get Leitner Boxes functionallity in there. Leitner Boxes are read now and their contents is displayed in the main view. Crashes on exit. (need to investigate) Not written yet. svn path=/branches/work/soc-parley/libkdeedu/; revision=825666 --- diff --git a/keduvocdocument/CMakeLists.txt b/keduvocdocument/CMakeLists.txt index 59e4f3a..f3295c5 100644 --- a/keduvocdocument/CMakeLists.txt +++ b/keduvocdocument/CMakeLists.txt @@ -9,6 +9,7 @@ keduvocdocument.cpp keduvoctranslation.cpp keduvoccontainer.cpp keduvoclesson.cpp + keduvocleitnerbox.cpp keduvoctext.cpp keduvocarticle.cpp keduvocconjugation.cpp @@ -47,6 +48,7 @@ install(FILES keduvocarticle.h keduvocconjugation.h keduvoclesson.h + keduvocleitnerbox.h keduvoccontainer.h keduvocwordtype.h keduvocmultiplechoice.h diff --git a/keduvocdocument/keduvocdocument.cpp b/keduvocdocument/keduvocdocument.cpp index 4f188f4..7599dc3 100644 --- a/keduvocdocument/keduvocdocument.cpp +++ b/keduvocdocument/keduvocdocument.cpp @@ -31,6 +31,7 @@ #include "keduvocexpression.h" #include "keduvoclesson.h" +#include "keduvocleitnerbox.h" #include "keduvocwordtype.h" #include "keduvockvtmlwriter.h" #include "keduvockvtml2writer.h" @@ -98,8 +99,7 @@ public: KEduVocLesson * m_lessonContainer; KEduVocWordType * m_wordTypeContainer; - KEduVocLesson * m_leitnerContainer; - + KEduVocLeitnerBox * m_leitnerContainer; }; KEduVocDocument::KEduVocDocumentPrivate::~KEduVocDocumentPrivate() @@ -124,7 +124,7 @@ void KEduVocDocument::KEduVocDocumentPrivate::init() if ( m_leitnerContainer ) { delete m_leitnerContainer; } - m_leitnerContainer = new KEduVocLesson(i18n( "Leitner Box" )); + m_leitnerContainer = new KEduVocLeitnerBox(i18n( "Leitner Box" )); ///test m_leitnerContainer->appendChildContainer(new KEduVocLesson(i18n("Box 7 (best)"), m_leitnerContainer)); @@ -751,7 +751,7 @@ KEduVocWordType * KEduVocDocument::wordTypeContainer() return d->m_wordTypeContainer; } -KEduVocLesson * KEduVocDocument::leitnerContainer() +KEduVocLeitnerBox * KEduVocDocument::leitnerContainer() { return d->m_leitnerContainer; } diff --git a/keduvocdocument/keduvocdocument.h b/keduvocdocument/keduvocdocument.h index 782dce3..063c0f1 100644 --- a/keduvocdocument/keduvocdocument.h +++ b/keduvocdocument/keduvocdocument.h @@ -35,6 +35,7 @@ class QStringList; class KEduVocExpression; class KEduVocLesson; class KEduVocWordType; +class KEduVocLeitnerBox; /** * This class contains the expressions of your vocabulary @@ -307,7 +308,7 @@ public: KEduVocWordType * wordTypeContainer(); - KEduVocLesson * leitnerContainer(); + KEduVocLeitnerBox * leitnerContainer(); // *** file format specific methods *** diff --git a/keduvocdocument/keduvockvtml2reader.cpp b/keduvocdocument/keduvockvtml2reader.cpp index fd7162c..195c73a 100644 --- a/keduvocdocument/keduvockvtml2reader.cpp +++ b/keduvocdocument/keduvockvtml2reader.cpp @@ -27,6 +27,7 @@ #include "keduvocdocument.h" #include "keduvoclesson.h" +#include "keduvocleitnerbox.h" #include "keduvocwordtype.h" #include "kvtml2defs.h" #include "keduvockvtmlreader.h" @@ -189,6 +190,11 @@ bool KEduVocKvtml2Reader::readGroups( QDomElement &domElementParent ) readChildWordTypes( m_doc->wordTypeContainer(), groupElement ); } + groupElement = domElementParent.firstChildElement( KVTML_LEITNERBOXES ); + if ( !groupElement.isNull() ) { + readLeitner( m_doc->leitnerContainer(), groupElement ); + } + groupElement = domElementParent.firstChildElement( KVTML_LESSONS ); if ( !groupElement.isNull() ) { readChildLessons(m_doc->lesson(), groupElement); @@ -363,7 +369,6 @@ bool KEduVocKvtml2Reader::readChildLessons( KEduVocLesson* parentLesson, QDomEle return true; } - bool KEduVocKvtml2Reader::readLesson( KEduVocLesson* parentLesson, QDomElement &lessonElement ) { //Lesson name @@ -390,7 +395,6 @@ bool KEduVocKvtml2Reader::readLesson( KEduVocLesson* parentLesson, QDomElement & return true; } - bool KEduVocKvtml2Reader::readSynonymsAntonymsFalseFriends( QDomElement &rootElement ) { QDomElement pairElement; @@ -500,6 +504,35 @@ bool KEduVocKvtml2Reader::readChildWordTypes(KEduVocWordType* parentContainer, Q return true; } +bool KEduVocKvtml2Reader::readLeitner( KEduVocLeitnerBox* parentContainer, QDomElement &leitnerParentElement ) +{ + QDomElement leitnerElement = leitnerParentElement.firstChildElement( KVTML_CONTAINER ); + while ( !leitnerElement.isNull() ) { + QString name = leitnerElement.firstChildElement( KVTML_NAME ).text(); + + KEduVocLeitnerBox * leitner = new KEduVocLeitnerBox(name, parentContainer); + parentContainer->appendChildContainer(leitner); + // for leitner we only allow a flat list, no sub boxes. + + // read entries + QDomElement entryElement = leitnerElement.firstChildElement( KVTML_ENTRY ); + while ( !entryElement.isNull() ) { + // read + int entryId = entryElement.attribute( KVTML_ID ).toInt(); + QDomElement translationElement = entryElement.firstChildElement( KVTML_TRANSLATION ); + while( !translationElement.isNull() ) { + // + int translationId = translationElement.attribute( KVTML_ID ).toInt(); + m_allEntries.value(entryId)->translation(translationId)->setLeitnerBox(leitner); + translationElement = translationElement.nextSiblingElement( KVTML_TRANSLATION ); + } + entryElement = entryElement.nextSiblingElement( KVTML_ENTRY ); + } + leitnerElement = leitnerElement.nextSiblingElement( KVTML_CONTAINER ); + } + return true; +} + bool KEduVocKvtml2Reader::readWordType( KEduVocWordType* parentContainer, QDomElement &typeElement ) { // set type and specialtype @@ -556,7 +589,6 @@ bool KEduVocKvtml2Reader::readWordType( KEduVocWordType* parentContainer, QDomEl return true; } - bool KEduVocKvtml2Reader::readTenses( QDomElement &tensesElement ) { QStringList tenses; diff --git a/keduvocdocument/keduvockvtml2reader.h b/keduvocdocument/keduvockvtml2reader.h index f7bdcbf..8f2ac84 100644 --- a/keduvocdocument/keduvockvtml2reader.h +++ b/keduvocdocument/keduvockvtml2reader.h @@ -84,6 +84,17 @@ private: */ bool readWordType( KEduVocWordType* parentContainer, QDomElement &typesElement ); + /** + * Read a leitner box container. + * This is a grading system where the vocabulary are kept in boxes and promoted/demoted during the learning. + * Be aware that leitner boxes are a list only and no sub boxes will ever be read or written. + * While reusing the lesson class is quite easy for this a proper subclass of KEduVocContainer would be the better solution. + * @param parentContainer the parent to append the new leitner container to + * @param leitnerElement the element in the dom + * @return success + */ + bool readLeitner( KEduVocLeitnerBox* parentContainer, QDomElement &leitnerElement ); + /** * Read all tags within a word type definition. * @param parentContainer diff --git a/keduvocdocument/keduvocleitnerbox.cpp b/keduvocdocument/keduvocleitnerbox.cpp new file mode 100644 index 0000000..8c78f6e --- /dev/null +++ b/keduvocdocument/keduvocleitnerbox.cpp @@ -0,0 +1,117 @@ +/*************************************************************************** + Copyright 2008 Frederik Gladhorn + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "keduvocleitnerbox.h" + +#include "keduvocexpression.h" + +#include + +#include + +class KEduVocLeitnerBox::Private +{ +public: + // cache the entries + QList m_expressions; + // list of translations + QList m_translations; +}; + +KEduVocLeitnerBox::KEduVocLeitnerBox(const QString& name, KEduVocLeitnerBox *parent) + : KEduVocContainer(name, Leitner, parent), d( new Private ) +{ +} + +KEduVocLeitnerBox::~KEduVocLeitnerBox() +{ + foreach(KEduVocTranslation* translation, d->m_translations) { + translation->setLeitnerBox(0); + } + delete d; +} + +QList KEduVocLeitnerBox::entries(EnumEntriesRecursive recursive) +{ + if (recursive == Recursive) { + return entriesRecursive(); + } + + return d->m_expressions; +} + +int KEduVocLeitnerBox::entryCount(EnumEntriesRecursive recursive) +{ + if (recursive == Recursive) { + return entriesRecursive().count(); + } + return d->m_expressions.count(); +} + +void KEduVocLeitnerBox::addTranslation(KEduVocTranslation* translation) +{ + // add to expression - if not already there because another translation of the same word is there. + bool found = false; + foreach(int i, translation->entry()->translationIndices()) { + if (translation->entry()->translation(i)->leitnerBox() == this) { + found = true; + break; + } + } + if (!found) { + d->m_expressions.append(translation->entry()); + } + d->m_translations.append( translation ); + invalidateChildLessonEntries(); +} + +void KEduVocLeitnerBox::removeTranslation(KEduVocTranslation* translation) +{ + d->m_translations.removeAt( d->m_translations.indexOf(translation) ); + + // no lesson found - this entry is being deleted. remove all its siblings. + if (!translation->entry()->lesson()) { + int index = d->m_expressions.indexOf(translation->entry()); + if (index != -1) { + d->m_expressions.removeAt(index); + } + } + + // remove from cache + bool found = false; + foreach(int i, translation->entry()->translationIndices()) { + if (translation->entry()->translation(i)->leitnerBox() == this) { + found = true; + break; + } + } + if (!found) { + d->m_expressions.removeAt(d->m_expressions.indexOf(translation->entry())); + } + + invalidateChildLessonEntries(); +} + +KEduVocTranslation * KEduVocLeitnerBox::translation(int row) +{ + return d->m_translations.value(row); +} + +KEduVocExpression * KEduVocLeitnerBox::entry(int row, EnumEntriesRecursive recursive) +{ + if (recursive == Recursive) { + return entriesRecursive().value(row); + } + return entries().value(row); +} + diff --git a/keduvocdocument/keduvocleitnerbox.h b/keduvocdocument/keduvocleitnerbox.h new file mode 100644 index 0000000..37bd780 --- /dev/null +++ b/keduvocdocument/keduvocleitnerbox.h @@ -0,0 +1,75 @@ +/*************************************************************************** + Copyright 2008 Frederik Gladhorn + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KEDUVOCLEITNERBOX_H +#define KEDUVOCLEITNERBOX_H + +#include "libkeduvocdocument_export.h" + +#include "keduvoccontainer.h" + +#include +#include + +class KEduVocExpression; +class KEduVocTranslation; + +/** + * Leitner Boxes are an alternative grading system. + * Classically flash cards are kept in boxes and moved corresponding to the users knowledge level. + */ +class KEDUVOCDOCUMENT_EXPORT KEduVocLeitnerBox :public KEduVocContainer +{ +public: + /** default constructor */ + explicit KEduVocLeitnerBox(const QString& name, KEduVocLeitnerBox *parent = 0); + + /** destructor */ + ~KEduVocLeitnerBox(); + + /** + * The leitner box class keeps track of individual translations, because for one entry, the translations can have different grades. + * @param row + * @return + */ + KEduVocTranslation * translation(int row); + + /** + * get a list of all entries in the box + * @return + */ + QList < KEduVocExpression* > entries(EnumEntriesRecursive recursive = NotRecursive); + + KEduVocExpression* entry(int row, EnumEntriesRecursive recursive = NotRecursive); + + /** get the number of entries in the lesson */ + int entryCount(EnumEntriesRecursive recursive = NotRecursive); + +private: + class Private; + Private * const d; + + /** add an entry to the lesson + * @param entryid id of the entry to add + */ + void addTranslation(KEduVocTranslation* translation); + + /** remove an entry from the lesson + * @param entryid id of the entry to remove + */ + void removeTranslation(KEduVocTranslation* translation); + + friend class KEduVocTranslation; +}; + +#endif diff --git a/keduvocdocument/keduvoctranslation.cpp b/keduvocdocument/keduvoctranslation.cpp index a662237..8054918 100644 --- a/keduvocdocument/keduvoctranslation.cpp +++ b/keduvocdocument/keduvoctranslation.cpp @@ -19,6 +19,7 @@ #include "keduvocdeclension.h" #include "keduvocwordtype.h" +#include "keduvocleitnerbox.h" #include "kvtml2defs.h" #include "keduvockvtml2writer.h" #include @@ -36,6 +37,9 @@ public: /// Type of a word noun, verb, adjective etc KEduVocWordType* m_wordType; + /// Leitner box of the translation. + KEduVocLeitnerBox* m_leitnerBox; + /// A comment giving additional information. QString m_comment; /// A hint, to make guessing the word easier. @@ -72,11 +76,11 @@ public: QList< KEduVocTranslation* > m_falseFriends; }; - KEduVocTranslation::KEduVocTranslationPrivate::KEduVocTranslationPrivate(KEduVocExpression* parent) { m_entry = parent; m_wordType = 0; + m_leitnerBox = 0; m_declension = 0; } @@ -103,6 +107,7 @@ KEduVocTranslation::KEduVocTranslation( const KEduVocTranslation &other ) // beter no word type copy as this is pointer copying // will not work as this is not added to the word type container! // d->m_wordType = other.d->m_wordType; +// d->m_leitnerBox = translation.d->m_leitnerBox; d->m_comment = other.d->m_comment; d->m_paraphrase = other.d->m_paraphrase; d->m_example = other.d->m_example; @@ -141,6 +146,7 @@ bool KEduVocTranslation::operator == ( const KEduVocTranslation & translation ) { return KEduVocText::operator==(translation) && d->m_wordType == translation.d->m_wordType && + d->m_leitnerBox == translation.d->m_leitnerBox && d->m_comment == translation.d->m_comment && d->m_paraphrase == translation.d->m_paraphrase && d->m_example == translation.d->m_example && @@ -161,7 +167,8 @@ KEduVocTranslation & KEduVocTranslation::operator = ( const KEduVocTranslation & { KEduVocText::operator=(translation); d->m_entry = translation.d->m_entry; - d->m_wordType = translation.d->m_wordType; +// d->m_wordType = translation.d->m_wordType; +// d->m_leitnerBox = translation.d->m_leitnerBox; d->m_comment = translation.d->m_comment; d->m_paraphrase = translation.d->m_paraphrase; d->m_example = translation.d->m_example; @@ -351,6 +358,22 @@ void KEduVocTranslation::setWordType(KEduVocWordType * wordType) d->m_wordType = wordType; } +KEduVocLeitnerBox * KEduVocTranslation::leitnerBox() const +{ + return d->m_leitnerBox; +} + +void KEduVocTranslation::setLeitnerBox(KEduVocLeitnerBox * leitnerBox) +{ + if ( d->m_leitnerBox ) { + d->m_leitnerBox->removeTranslation(this); + } + if ( leitnerBox ) { + leitnerBox->addTranslation(this); + } + d->m_leitnerBox = leitnerBox; +} + KEduVocExpression * KEduVocTranslation::entry() { return d->m_entry; @@ -457,3 +480,5 @@ void KEduVocTranslation::setEntry(KEduVocExpression * entry) d->m_entry = entry; } + + diff --git a/keduvocdocument/keduvoctranslation.h b/keduvocdocument/keduvoctranslation.h index dc102d5..7a55998 100644 --- a/keduvocdocument/keduvoctranslation.h +++ b/keduvocdocument/keduvoctranslation.h @@ -27,7 +27,7 @@ class KEduVocExpression; class KEduVocString; class KEduVocWordType; -class KEduVocLesson; +class KEduVocLeitnerBox; class KEduVocDeclension; /** @@ -140,12 +140,12 @@ public: /** returns the leitner box of this translation * @return the box */ - KEduVocLesson* leitnerBox() const; + KEduVocLeitnerBox* leitnerBox() const; /** sets the leitner box of this translation * @param leitnerBox the box */ - void setLeitnerBox( KEduVocLesson* leitnerBox ); + void setLeitnerBox( KEduVocLeitnerBox* leitnerBox ); /** * returns a conjugation if available diff --git a/keduvocdocument/kvtml2defs.h b/keduvocdocument/kvtml2defs.h index c4dd617..8bf2733 100644 --- a/keduvocdocument/kvtml2defs.h +++ b/keduvocdocument/kvtml2defs.h @@ -102,7 +102,6 @@ static const QString KVTML_GRAMMATICAL_DEFINITENESS[] = { #define KVTML_CONTAINER "container" #define KVTML_INPRACTICE "inpractice" - // these are necessary to enable practices based on word types. users can give types arbitrary names, but these few are hardcoded. special container types #define KVTML_SPECIALWORDTYPE "specialwordtype" #define KVTML_SPECIALWORDTYPE_NOUN "noun"