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
keduvoctranslation.cpp
keduvoccontainer.cpp
keduvoclesson.cpp
+ keduvocleitnerbox.cpp
keduvoctext.cpp
keduvocarticle.cpp
keduvocconjugation.cpp
keduvocarticle.h
keduvocconjugation.h
keduvoclesson.h
+ keduvocleitnerbox.h
keduvoccontainer.h
keduvocwordtype.h
keduvocmultiplechoice.h
#include "keduvocexpression.h"
#include "keduvoclesson.h"
+#include "keduvocleitnerbox.h"
#include "keduvocwordtype.h"
#include "keduvockvtmlwriter.h"
#include "keduvockvtml2writer.h"
KEduVocLesson * m_lessonContainer;
KEduVocWordType * m_wordTypeContainer;
- KEduVocLesson * m_leitnerContainer;
-
+ KEduVocLeitnerBox * m_leitnerContainer;
};
KEduVocDocument::KEduVocDocumentPrivate::~KEduVocDocumentPrivate()
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));
return d->m_wordTypeContainer;
}
-KEduVocLesson * KEduVocDocument::leitnerContainer()
+KEduVocLeitnerBox * KEduVocDocument::leitnerContainer()
{
return d->m_leitnerContainer;
}
class KEduVocExpression;
class KEduVocLesson;
class KEduVocWordType;
+class KEduVocLeitnerBox;
/**
* This class contains the expressions of your vocabulary
KEduVocWordType * wordTypeContainer();
- KEduVocLesson * leitnerContainer();
+ KEduVocLeitnerBox * leitnerContainer();
// *** file format specific methods ***
#include "keduvocdocument.h"
#include "keduvoclesson.h"
+#include "keduvocleitnerbox.h"
#include "keduvocwordtype.h"
#include "kvtml2defs.h"
#include "keduvockvtmlreader.h"
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);
return true;
}
-
bool KEduVocKvtml2Reader::readLesson( KEduVocLesson* parentLesson, QDomElement &lessonElement )
{
//<name>Lesson name</name>
return true;
}
-
bool KEduVocKvtml2Reader::readSynonymsAntonymsFalseFriends( QDomElement &rootElement )
{
QDomElement pairElement;
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 <entry id="123"></entryid>
+ int entryId = entryElement.attribute( KVTML_ID ).toInt();
+ QDomElement translationElement = entryElement.firstChildElement( KVTML_TRANSLATION );
+ while( !translationElement.isNull() ) {
+ // <translation id="234"/>
+ 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
return true;
}
-
bool KEduVocKvtml2Reader::readTenses( QDomElement &tensesElement )
{
QStringList tenses;
*/
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 <container> tags within a word type definition.
* @param parentContainer
--- /dev/null
+/***************************************************************************
+ Copyright 2008 Frederik Gladhorn <frederik.gladhorn@kdemail.net>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 <KDebug>
+
+#include <QtCore/QSet>
+
+class KEduVocLeitnerBox::Private
+{
+public:
+ // cache the entries
+ QList<KEduVocExpression*> m_expressions;
+ // list of translations
+ QList<KEduVocTranslation*> 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<KEduVocExpression*> 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);
+}
+
--- /dev/null
+/***************************************************************************
+ Copyright 2008 Frederik Gladhorn <frederik.gladhorn@kdemail.net>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 <QtCore/QList>
+#include <QtCore/QString>
+
+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
#include "keduvocdeclension.h"
#include "keduvocwordtype.h"
+#include "keduvocleitnerbox.h"
#include "kvtml2defs.h"
#include "keduvockvtml2writer.h"
#include <KDebug>
/// 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.
QList< KEduVocTranslation* > m_falseFriends;
};
-
KEduVocTranslation::KEduVocTranslationPrivate::KEduVocTranslationPrivate(KEduVocExpression* parent)
{
m_entry = parent;
m_wordType = 0;
+ m_leitnerBox = 0;
m_declension = 0;
}
// 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;
{
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 &&
{
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;
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;
d->m_entry = entry;
}
+
+
class KEduVocExpression;
class KEduVocString;
class KEduVocWordType;
-class KEduVocLesson;
+class KEduVocLeitnerBox;
class KEduVocDeclension;
/**
/** 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
#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"