This is a rather big change, which affects the apps using libkdeedu.
I guess there are quite a few bugs left. So far I know the destructor of
either expression or translation sometimes seems to double delete. Need
to look into that.
Start an experimental new practice app that is independend of the main
app. Still hardly anything implemented there.
FEATURE: Parley: New main window gui using dock windows. The edit entry
dialog does no longer exist. It is much nicer to edit vocabulary now.
Ported KHangMan, KAnagram, KWordQuiz and Parley
Notes:
-Containers: There are two subclasses for KEduVocContainer.
KEduVocLesson and KEduVocWordType. This is very benificial as from now
on, I can use the same models/views for both in parley. Leitner boxes
are also easy to realize subclassing the containers.
-The KEduVocDocument class was huge and contained some functions
specific to expression handling. This redundand api has been removed.
instead the document now contains one root lesson
(KEduVocDocument::lesson()) to manage all entries. This lesson can
contain entries directly as well as child lessons. This makes it easy to
access all vocabulary entries by using doc->lesson()->entriesRecursive()
which collects all entries including those from sublessons.
-Lessons and word types are now able to contain child lessons/word types
to an arbitrary depth.
-Entries can be in multiple lessons.
-Expression->translation() now returns a pointer. This is more
consistent and avoids some reference trouble. In general now everything
is a pointer (containers also).
-KWordQuiz now saves the size hints per document in the kconfig. This
could also be used for cell heights.
-KWordQuiz only edits entries in the top level lesson. I'll change it to
use all entries in the document.
-Statistics in Parley are disabled for now, needs to be rewritten.
-Usages have been removed completely.
-Comparison forms do no longer have a proper class but only two strings.
Eventually it should be considered making them a class to support
male/female again. The base form should always be the adjective/adverb
itself.
I hope everything works, but I must have missed something. Bug me.
CCMAIL: peter@peterandlinda.com
svn path=/trunk/KDE/kdeedu/libkdeedu/; revision=757794
if ( !s.simplified().isEmpty() ) {
KEduVocExpression expression( s.split(separator) );
- languageCount = qMax( languageCount, expression.translationIndices().count() );
- m_doc->appendEntry( &expression );
+ languageCount = qMax( languageCount,
+ expression.translationIndices().count() );
- lesson->addEntry( &expression );
++ lesson->appendEntry( &expression );
}
}
#include <QtCore/QMap>
#include <KDebug>
-/*
-class KEduVocComparison::Private
-{
-public:
- QString ls1;
- QString ls2;
- QString ls3;
-};
-
-KEduVocComparison::KEduVocComparison()
- : d( new Private )
-{}
-
-KEduVocComparison::KEduVocComparison( const KEduVocComparison &other )
- : d( new Private )
-{
- setL1( other.l1() );
- setL2( other.l2() );
- setL3( other.l3() );
-}
-
-KEduVocComparison::KEduVocComparison( const QString &l1, const QString &l2, const QString &l3 )
- : d( new Private )
-{
- setL1( l1 );
- setL2( l2 );
- setL3( l3 );
-}
-
-KEduVocComparison::~KEduVocComparison()
-{
- delete d;
-}
-
-KEduVocComparison &KEduVocComparison::operator= ( const KEduVocComparison& other )
-{
- setL1( other.l1() );
- setL2( other.l2() );
- setL3( other.l3() );
-
- return *this;
-}
-
-bool KEduVocComparison::isEmpty() const
-{
- return d->ls1.simplified().isEmpty() && d->ls2.simplified().isEmpty() && d->ls3.simplified().isEmpty();
-}
-
-
-void KEduVocComparison::clear()
-{
- d->ls1 = "";
- d->ls2 = "";
- d->ls3 = "";
-}
-
-bool KEduVocComparison::operator == ( const KEduVocComparison& a ) const
-{
- return ( d->ls1 == a.l1() && d->ls2 == a.l2() && d->ls3 == a.l3() );
-}
-
-void KEduVocComparison::setL1( const QString &s )
-{
- d->ls1 = s;
-}
-
-void KEduVocComparison::setL2( const QString &s )
-{
- d->ls2 = s;
-}
-
-void KEduVocComparison::setL3( const QString &s )
-{
- d->ls3 = s;
-}
-
-QString KEduVocComparison::l1() const
-{
- return d->ls1;
-}
-QString KEduVocComparison::l2() const
-{
- return d->ls2;
-}
-
-QString KEduVocComparison::l3() const
-{
- return d->ls3;
-}
-*/
-
-
-
-//=================================================================
- class KEduVocComparison::Private
- {
- public:
- QString ls1;
- QString ls2;
- QString ls3;
- };
-
- KEduVocComparison::KEduVocComparison()
- : d( new Private )
- {}
-
- KEduVocComparison::KEduVocComparison( const KEduVocComparison &other )
- : d( new Private )
- {
- setL1( other.l1() );
- setL2( other.l2() );
- setL3( other.l3() );
- }
-
- KEduVocComparison::KEduVocComparison( const QString &l1, const QString &l2, const QString &l3 )
- : d( new Private )
- {
- setL1( l1 );
- setL2( l2 );
- setL3( l3 );
- }
-
- KEduVocComparison::~KEduVocComparison()
- {
- delete d;
- }
-
- KEduVocComparison &KEduVocComparison::operator= ( const KEduVocComparison& other )
- {
- setL1( other.l1() );
- setL2( other.l2() );
- setL3( other.l3() );
-
- return *this;
- }
-
- bool KEduVocComparison::isEmpty() const
- {
- return d->ls1.simplified().isEmpty() && d->ls2.simplified().isEmpty() && d->ls3.simplified().isEmpty();
- }
-
-
- void KEduVocComparison::clear()
- {
- d->ls1 = "";
- d->ls2 = "";
- d->ls3 = "";
- }
-
- bool KEduVocComparison::operator == ( const KEduVocComparison& a ) const
- {
- return ( d->ls1 == a.l1() && d->ls2 == a.l2() && d->ls3 == a.l3() );
- }
-
- void KEduVocComparison::setL1( const QString &s )
- {
- d->ls1 = s;
- }
-
- void KEduVocComparison::setL2( const QString &s )
- {
- d->ls2 = s;
- }
-
- void KEduVocComparison::setL3( const QString &s )
- {
- d->ls3 = s;
- }
-
- QString KEduVocComparison::l1() const
- {
- return d->ls1;
- }
- QString KEduVocComparison::l2() const
- {
- return d->ls2;
- }
-
- QString KEduVocComparison::l3() const
- {
- return d->ls3;
- }
-
-
-
-
- //=================================================================
-
class KEduVocArticle::Private
{
public:
};
- class KEDUVOCDOCUMENT_EXPORT KEduVocComparison
- {
- public:
-
- /**
- * The constructor without arguments
- */
- explicit KEduVocComparison();
-
- /** copy constructor
- * @param other comparison object to copy
- */
- KEduVocComparison( const KEduVocComparison &other );
-
- /**
- * The constructor with arguments
- * @param l1
- * @param l2
- * @param l3
- */
- KEduVocComparison( const QString &l1, const QString &l2, const QString &l3 );
-
- /** default destructor, deletes the d-pointer */
- ~KEduVocComparison();
-
- /** set the first comparison
- @param s value to set
- */
- void setL1( const QString &s );
-
- /** set the second comparison
- @param s value to set
- */
- void setL2( const QString &s );
-
- /** set the third comparison
- @param s value to set
- */
- void setL3( const QString &s );
-
- /** get the first comparison
- * @returns the first comparison
- */
- QString l1() const;
-
- /** get the second comparison
- * @returns the second comparison
- */
- QString l2() const;
-
- /** get the third comparison
- * @returns the third comparison
- */
- QString l3() const;
-
- /** is the comparison empty
- * @returns true if empty, false otherwise
- */
- bool isEmpty() const;
-
- /** clear the comparison */
- void clear();
-
- /** equality operator
- * @param a object to compare to
- * @returns true if comparisons are the same, false otherwise
- */
- bool operator == ( const KEduVocComparison& a ) const;
-
- /** assignment operator for d-pointer copying
- * @param other object to copy from
- * @returns reference to this object
- */
- KEduVocComparison &operator= ( const KEduVocComparison& other );
-
- private:
- class Private;
- Private * const d;
- };
-// class KEDUVOCDOCUMENT_EXPORT KEduVocComparison
-// {
-// public:
-//
-// /**
-// * The constructor without arguments
-// */
-// explicit KEduVocComparison();
-//
-// /** copy constructor
-// * @param other comparison object to copy
-// */
-// KEduVocComparison( const KEduVocComparison &other );
-//
-// /**
-// * The constructor with arguments
-// * @param l1
-// * @param l2
-// * @param l3
-// */
-// KEduVocComparison( const QString &l1, const QString &l2, const QString &l3 );
-//
-// /** default destructor, deletes the d-pointer */
-// ~KEduVocComparison();
-//
-// /** set the first comparison
-// @param s value to set
-// */
-// void setL1( const QString &s );
-//
-// /** set the second comparison
-// @param s value to set
-// */
-// void setL2( const QString &s );
-//
-// /** set the third comparison
-// @param s value to set
-// */
-// void setL3( const QString &s );
-//
-// /** get the first comparison
-// * @returns the first comparison
-// */
-// QString l1() const;
-//
-// /** get the second comparison
-// * @returns the second comparison
-// */
-// QString l2() const;
-//
-// /** get the third comparison
-// * @returns the third comparison
-// */
-// QString l3() const;
-//
-// /** is the comparison empty
-// * @returns true if empty, false otherwise
-// */
-// bool isEmpty() const;
-//
-// /** clear the comparison */
-// void clear();
-//
-// /** equality operator
-// * @param a object to compare to
-// * @returns true if comparisons are the same, false otherwise
-// */
-// bool operator == ( const KEduVocComparison& a ) const;
-//
-// /** assignment operator for d-pointer copying
-// * @param other object to copy from
-// * @returns reference to this object
-// */
-// KEduVocComparison &operator= ( const KEduVocComparison& other );
-//
-// private:
-// class Private;
-// Private * const d;
-// };
--
--
#endif // KEDUVOCGRAMMAR_H
groupElement = domElementParent.firstChildElement( KVTML_LESSONS );
if ( !groupElement.isNull() ) {
- QDomNodeList entryList = groupElement.elementsByTagName( KVTML_CONTAINER );
- for ( int i = 0; i < entryList.count(); ++i ) {
- currentElement = entryList.item( i ).toElement();
- if ( currentElement.parentNode() == groupElement ) {
- result = readLesson( currentElement );
- if ( !result )
- return false;
- }
- }
+ readChildLessons(m_doc->lesson(), groupElement);
+ }
- ///@todo past 4.0: remove reading "lesson" it was only for compability with documents created during the beta for KDE 4.0
- entryList = groupElement.elementsByTagName( "lesson" );
- for ( int i = 0; i < entryList.count(); ++i ) {
- currentElement = entryList.item( i ).toElement();
- if ( currentElement.parentNode() == groupElement ) {
- result = readLesson( currentElement );
- if ( !result )
- return false;
- }
+ // Additional cleanup: Put orphaned entries without a lesson into a default lesson.
+ KEduVocLesson *defaultLesson = new KEduVocLesson(i18n("Default Lesson"), m_doc->lesson());
+
+ // now make sure we don't have any orphan entries
+ foreach (KEduVocExpression * entry, m_allEntries.values()) {
+ if (entry->lessons().count() == 0)
+ {
- defaultLesson->addEntry(entry);
++ defaultLesson->appendEntry(entry);
}
- // end @todo
+ }
+
+ if (defaultLesson->entryCount() > 0)
+ {
+ m_doc->lesson()->appendChildContainer(defaultLesson);
+ } else {
+ delete defaultLesson;
}
return true;
currentElement = lessonElement.firstChildElement( KVTML_ENTRY );
while ( !currentElement.isNull() ) {
bool result = false;
- int id = currentElement.attribute( KVTML_ID ).toInt( &result );
+ int entryId = currentElement.attribute( KVTML_ID ).toInt( &result );
if(result) {
- m_doc->entry(id)->setLesson(lessonId);
- m_doc->lesson(lessonId).addEntry(id);
- lesson->addEntry( m_allEntries[entryId] );
++ lesson->appendEntry( m_allEntries[entryId] );
}
currentElement = currentElement.nextSiblingElement( KVTML_ENTRY );
}
bool readConjugation( QDomElement &conjugElement, KEduVocConjugation &conjugation );
bool readConjugationPerson( QDomElement &personElement, KEduVocConjugation &conjugation, KEduVocConjugation::ConjugationNumber number );
- /**
- * Read an individual word type
- * @param parentContainer
- * @param typesElement
- * @return
+ /** read the types
+ * @param typesElement QDomElement for the types group
*/
- bool readWordTypes( QDomElement &typesElement );
+ bool readWordType( KEduVocWordType* parentContainer, QDomElement &typesElement );
+
+ /**
+ * Read all <container> tags within a word type definition.
+ * @param parentContainer
+ * @param lessonElement
+ * @return
+ */
+ bool readChildWordTypes( KEduVocWordType* parentContainer, QDomElement &lessonElement );
/** read the tenses
* @param tensesElement QDomElement for the tenses group
textstr = currentElement.lastChild().toText().data();
if ( i == 0 ) {
- expr = KEduVocExpression( textstr, lesson );
- expr.setActive( active );
+ entry = new KEduVocExpression( textstr );
+ entry->setActive( active );
+ if ( lessonNumber != -1 ) {
- static_cast<KEduVocLesson*>(m_doc->lesson()->childContainer(lessonNumber))->addEntry(entry);
++ static_cast<KEduVocLesson*>(m_doc->lesson()->childContainer(lessonNumber))->appendEntry(entry);
+ } else {
- m_doc->lesson()->addEntry(entry);
++ m_doc->lesson()->appendEntry(entry);
+ }
} else {
- expr.setTranslation( i, textstr );
+ entry->setTranslation( i, textstr );
}
// better make sure, translation(i) already exists...
#include "keduvoclesson.h"
- #include <QSet>
+ #include "keduvocexpression.h"
+
++#include <KRandomSequence>
+ #include <QList>
/** private class to store information about a lesson */
class KEduVocLesson::Private
return d->m_entries.count();
}
- void KEduVocLesson::addEntry( int entryid )
-void KEduVocLesson::addEntry(KEduVocExpression* entry)
++void KEduVocLesson::appendEntry(KEduVocExpression* entry)
{
- d->m_entries.insert( entryid );
+ d->m_entries.append( entry );
+ entry->addLesson(this);
}
- void KEduVocLesson::removeEntry( int entryid )
++void KEduVocLesson::insertEntry(int index, KEduVocExpression * entry)
+{
- d->m_entries.remove( entryid );
++ d->m_entries.insert( index, entry );
++ entry->addLesson(this);
+}
+
- void KEduVocLesson::incrementEntriesAbove( int entryid )
+ void KEduVocLesson::removeEntry(KEduVocExpression* entry)
{
- QList<int> entries = d->m_entries.toList();
-
- // increment all entry id's above entryid
- for (int i = 0; i < entries.size(); ++i) {
- if (entries[i] >= entryid) {
- entries[i] = entries[i] + 1;
- }
- }
-
- // then put the new list into the set
- d->m_entries = entries.toSet();
- }
-
- void KEduVocLesson::decrementEntriesAbove( int entryid )
- {
- QList<int> entries = d->m_entries.toList();
-
- // increment all entry id's above entryid
- int i = 0;
- while (i < entries.size()) {
- if (entries[i] == entryid) {
- entries.removeAt(i);
- }
- else if (entries[i] > entryid) {
- entries[i] = entries[i] - 1;
- ++i;
- }
- else {
- ++i;
- }
- }
-
- // then put the new list into the set
- d->m_entries = entries.toSet();
+ d->m_entries.removeAt( d->m_entries.indexOf(entry) );
+ entry->removeLesson(this);
}
- bool KEduVocLesson::inPractice()
+ KEduVocExpression * KEduVocLesson::entry(int row)
{
- return d->m_inPractice;
+ return d->m_entries.value(row);
}
- void KEduVocLesson::setInPractice(bool inPractice)
++void KEduVocLesson::randomizeEntries()
+{
- d->m_inPractice = inPractice;
++ KRandomSequence randomSequence(QDateTime::currentDateTime().toTime_t());
++ randomSequence.randomize( d->m_entries );
+}
++
/** get the number of entries in the lesson */
int entryCount();
-- /** add an entry to the lesson
++ /** append an entry to the lesson
* @param entryid id of the entry to add
*/
- void addEntry( int entryid );
- void addEntry(KEduVocExpression* entry);
++ void appendEntry(KEduVocExpression* entry);
+
- /** remove an entry from the lesson
- * @param entryid id of the entry to remove
- */
- void removeEntry( int entryid );
-
- /** increments all entryids > entryid, because their entryid has been incremented
- * @param entryid id of the entry that was inserted
- */
- void incrementEntriesAbove( int entryid );
-
- /** decrements all etryids > entryid, because their entryid has been decremented
- * @param entryid id of the entry that was removed
++ /**
++ * insert an entry at a specific position
++ * @param index
++ * @param entry
+ */
- void decrementEntriesAbove( int entryid );
++ void insertEntry(int index, KEduVocExpression* entry);
+
- bool inPractice();
- void setInPractice( bool inPractice );
++ /**
++ * shuffle the order of the entries in the lesson
++ */
++ void randomizeEntries();
- /** equality operator */
- bool operator==(const KEduVocLesson &other);
+ /** remove an entry from the lesson
+ * @param entryid id of the entry to remove
+ */
+ void removeEntry(KEduVocExpression* entry);
private:
class Private;
}
}
- KEduVocExpression expr = KEduVocExpression( front );
- expr.setTranslation( 1, back );
- m_doc->appendEntry( &expr );
+ KEduVocLesson* lesson = new KEduVocLesson(i18n("Vocabulary"), m_doc->lesson());
+ m_doc->lesson()->appendChildContainer(lesson);
+
+ KEduVocExpression* expr = new KEduVocExpression( QStringList() << front << back);
- lesson->addEntry( expr );
++ lesson->appendEntry( expr );
}
words = expression.split( "\"," );
original = words[0].mid( 1 );
translation = words[1].mid( 1 );
- lesson = words[2].toInt() - 1;
+ lessonNumber = words[2].toInt() - 1;
+
+ while(m_doc->lesson()->childContainerCount() < lessonNumber) {
+ KEduVocLesson* lesson = new KEduVocLesson(i18n("Lesson %1", lessonNumber), m_doc->lesson());
+ m_doc->lesson()->appendChildContainer(lesson);
+ }
- KEduVocExpression kve;
- kve.setTranslation( 0, original );
- kve.setTranslation( 1, translation );
- kve.translation( 1 ).gradeFrom( 0 ).setGrade( 0 );
- kve.translation( 0 ).gradeFrom( 1 ).setGrade( 0 );
- kve.setLesson( lesson );
+ KEduVocExpression* kve = new KEduVocExpression;
+ kve->setTranslation( 0, original );
+ kve->setTranslation( 1, translation );
- m_doc->appendEntry( &kve );
- static_cast<KEduVocLesson*>(m_doc->lesson()->childContainer(lessonNumber))->addEntry(kve);
++ static_cast<KEduVocLesson*>(m_doc->lesson()->childContainer(lessonNumber))->appendEntry(kve);
inputStream.readLine();
inputStream.readLine();
KEduVocExpression expr = KEduVocExpression( s );
expr.setTranslation( 1, b );
- m_doc->appendEntry( &expr );
- m_doc->lesson()->addEntry( &expr );
++ m_doc->lesson()->appendEntry( &expr );
}
return true;
}
KEduVocExpression expr = KEduVocExpression( front );
expr.setTranslation( 1, back );
- m_doc->appendEntry( &expr );
- m_doc->lesson()->addEntry( &expr );
++ m_doc->lesson()->appendEntry( &expr );
}