]> Git trees. - libqmvoc.git/commitdiff
This is really a work branch now.
authorFrederik Gladhorn <gladhorn@kde.org>
Sun, 18 Nov 2007 23:30:20 +0000 (23:30 +0000)
committerFrederik Gladhorn <gladhorn@kde.org>
Sun, 18 Nov 2007 23:30:20 +0000 (23:30 +0000)
Start the rewrite of the table model and lesson model.
The table now contains all single line things, the other editing will use dock widgets.
Nothing works.
Both models are not editable yet.
Rewrite of the lesson part of the lib - now there is one root lesson containing the world.
Another time crash and burn...

svn path=/branches/work/kdeedu_parley/libkdeedu/; revision=738466

12 files changed:
keduvocdocument/CMakeLists.txt
keduvocdocument/keduvocdocument.cpp
keduvocdocument/keduvocdocument.h
keduvocdocument/keduvocexpression.cpp
keduvocdocument/keduvocexpression.h
keduvocdocument/keduvockvtml2reader.cpp
keduvocdocument/keduvockvtml2reader.h
keduvocdocument/keduvockvtml2writer.cpp
keduvocdocument/keduvockvtml2writer.h
keduvocdocument/keduvoclesson.cpp
keduvocdocument/keduvoclesson.h
keduvocdocument/tests/keduvocdocumentvalidatortest.cpp

index bcbe6ce806cfa44d6a41a12886bd219df4c64b8f..66e3d3dba14ee0a4431d0863c7dc222fa3330a24 100644 (file)
@@ -3,9 +3,7 @@ add_subdirectory(tests)
 ########### next target ###############
 
 set(keduvocdocument_LIB_SRCS
-   keduvoccsvreader.cpp
-   keduvoccsvwriter.cpp
-   keduvocdocument.cpp
+keduvocdocument.cpp
    keduvocidentifier.cpp
    keduvocexpression.cpp
    keduvoctranslation.cpp
@@ -15,17 +13,19 @@ set(keduvocdocument_LIB_SRCS
    keduvocconjugation.cpp
    keduvocpersonalpronoun.cpp
    keduvocdeclination.cpp
+   keduvocmultiplechoice.cpp
    keduvocwordtype.cpp
-   keduvockvtmlreader.cpp
+   keduvockvtmlcompability.cpp
+   #keduvockvtmlreader.cpp
    keduvockvtml2reader.cpp
-   keduvockvtmlwriter.cpp
+   #keduvockvtmlwriter.cpp
    keduvockvtml2writer.cpp
-   keduvockvtmlcompability.cpp
-   keduvocmultiplechoice.cpp
-   keduvocpaukerreader.cpp
-   keduvocvokabelnreader.cpp
-   keduvocwqlreader.cpp
-   keduvocxdxfreader.cpp
+   #keduvoccsvreader.cpp
+   #keduvoccsvwriter.cpp
+   #keduvocpaukerreader.cpp
+   #keduvocvokabelnreader.cpp
+   #keduvocwqlreader.cpp
+   #keduvocxdxfreader.cpp
    sharedkvtmlfiles.cpp )
 
 kde4_add_library(keduvocdocument SHARED ${keduvocdocument_LIB_SRCS})
index 2b476a741a20d081f47b82076e8c3a0441f6bd44..90ecd589810ce92a0863c4c1c29584fac5817503 100644 (file)
@@ -55,7 +55,10 @@ public:
     KEduVocDocumentPrivate( KEduVocDocument* qq )
             : q( qq )
     {
+kDebug() << "Creating new Document - init:";
+        m_rootLesson = 0;
         init();
+kDebug() << "Creating new Document - init done";
     }
 
     ~KEduVocDocumentPrivate();
@@ -77,11 +80,11 @@ public:
     QString                   m_generator;
     QString                   m_queryorg;
     QString                   m_querytrans;
-    QList<KEduVocExpression>  m_vocabulary;
 
     QStringList               m_tenseDescriptions;
     QSet<QString>             m_usages;
-    QString                   m_title;
+// use the name of the root lesson as title
+//     QString                   m_title;
     QString                   m_author;
     QString                   m_license;
     QString                   m_comment;
@@ -93,8 +96,7 @@ public:
       */
     QString                   m_category;
 
-    // A map is too error prone. Lesson order is very important.
-    QList<KEduVocLesson>      m_lessons;
+    KEduVocLesson * m_rootLesson;
 
     KEduVocWordType           m_wordTypes;
 };
@@ -105,29 +107,35 @@ KEduVocDocument::KEduVocDocumentPrivate::~KEduVocDocumentPrivate()
 
 void KEduVocDocument::KEduVocDocumentPrivate::init()
 {
-    m_lessons.clear();
+    if ( m_rootLesson ) {
+        delete m_rootLesson;
+    }
+kDebug() << "create root lesson";
+    m_rootLesson = new KEduVocLesson(i18n("Document"));
+kDebug() << "create root lesson done";
     m_tenseDescriptions.clear();
     m_identifiers.clear();
     m_extraSizeHints.clear();
     m_sizeHints.clear();
-    m_vocabulary.clear();
     m_dirty = false;
     m_currentLesson = 0;
     m_queryorg = "";
     m_querytrans = "";
     m_url.setFileName( i18n( "Untitled" ) );
-    m_title = "";
     m_author = "";
     m_comment = "";
     m_version = "";
     m_generator = "";
     m_csvDelimiter = QString( '\t' );
+kDebug() << "init done";
 }
 
 
 KEduVocDocument::KEduVocDocument( QObject *parent )
         : QObject( parent ), d( new KEduVocDocumentPrivate( this ) )
-{}
+{
+    kDebug() << "constructor done";
+}
 
 
 KEduVocDocument::~KEduVocDocument()
@@ -143,29 +151,6 @@ void KEduVocDocument::setModified( bool dirty )
 }
 
 
-void KEduVocDocument::appendEntry( KEduVocExpression *expression )
-{
-    insertEntry(expression, d->m_vocabulary.count());
-}
-
-
-void KEduVocDocument::insertEntry( KEduVocExpression *expression, int index )
-{
-    d->m_vocabulary.insert( index, *expression );
-
-    // now we need to go fix the entryids that are greater than index in the lessons
-    for (int i = 0; i < d->m_lessons.size(); ++i)
-    {
-        d->m_lessons[i].incrementEntriesAbove(index);
-    }
-    // if the expression is added and the lesson already exists (not at doc loading time, but added later) make sure it ends up in the lesson as well.
-    if ( expression->lesson() >= 0 && expression->lesson() < d->m_lessons.count() ) {
-        d->m_lessons[expression->lesson()].addEntry(index);
-    }
-    setModified();
-}
-
-
 KEduVocDocument::FileType KEduVocDocument::detectFileType( const QString &fileName )
 {
     QIODevice * f = KFilterDev::deviceForFile( fileName );
@@ -244,6 +229,7 @@ KEduVocDocument::FileType KEduVocDocument::detectFileType( const QString &fileNa
 
 int KEduVocDocument::open( const KUrl& url )
 {
+kDebug() << "open";
     d->init();
     if ( !url.isEmpty() ) {
         d->m_url = url;
@@ -272,7 +258,8 @@ int KEduVocDocument::open( const KUrl& url )
                 }
             }
             break;
-
+///@todo port me
+/*
             case Wql: {
                 kDebug() << "Reading WordQuiz (WQL) document...";
                 KEduVocWqlReader wqlReader( f );
@@ -325,7 +312,7 @@ int KEduVocDocument::open( const KUrl& url )
                     errorMessage = i18n( "Parse error at line %1, column %2:\n%3", xdxfReader.lineNumber(), xdxfReader.columnNumber(), xdxfReader.errorString() );
                 }
             }
-            break;
+            break;*/
 
             default: {
                 kDebug() << "Reading KVTML document (fallback)...";
@@ -349,22 +336,6 @@ int KEduVocDocument::open( const KUrl& url )
         KIO::NetAccess::removeTempFile( temporaryFile );
     }
 
-    // Additional cleanup: Put entries without a lesson into a default lesson.
-    int defaultLessonNumber = appendLesson(i18n("Default Lesson"));
-    // now make sure we don't have any orphan entries (lesson -1)
-    for (int i = 0; i < entryCount(); ++i)
-    {
-        if (entry(i)->lesson() == -1)
-        {
-            entry(i)->setLesson(defaultLessonNumber);
-            lesson(defaultLessonNumber).addEntry(i);
-        }
-    }
-    if (lesson(defaultLessonNumber).entries().size() == 0)
-    {
-        removeLesson(defaultLessonNumber, DeleteEmptyLesson);
-    }
-
     if ( !read ) {
         return FileReaderFailed;
     }
@@ -403,17 +374,18 @@ int KEduVocDocument::saveAs( const KUrl & url, FileType ft, const QString & gene
             saved = kvtmlWriter.writeDoc( this, generator );
         }
         break;
-        case Kvtml1: {
-            // write old version 1 file
-            KEduVocKvtmlWriter kvtmlWriter( &f );
-            saved = kvtmlWriter.writeDoc( this, generator );
-        }
-        break;
-        case Csv: {
-            KEduVocCsvWriter csvWriter( &f );
-            saved = csvWriter.writeDoc( this, generator );
-        }
-        break;
+        ///@todo port me
+//         case Kvtml1: {
+//             // write old version 1 file
+//             KEduVocKvtmlWriter kvtmlWriter( &f );
+//             saved = kvtmlWriter.writeDoc( this, generator );
+//         }
+//         break;
+//         case Csv: {
+//             KEduVocCsvWriter csvWriter( &f );
+//             saved = csvWriter.writeDoc( this, generator );
+//         }
+//         break;
         default: {
             kError() << "kvcotrainDoc::saveAs(): unknown filetype" << endl;
         }
@@ -647,38 +619,6 @@ void KEduVocDocument::merge( KEduVocDocument *docToMerge, bool matchIdentifiers
 }
 
 
-KEduVocExpression *KEduVocDocument::entry( int index )
-{
-    if ( index < 0 || index >= d->m_vocabulary.size() )
-        return 0;
-    else
-        return &d->m_vocabulary[index];
-}
-
-
-void KEduVocDocument::removeEntry( int index )
-{
-    if ( index >= 0 && index < d->m_vocabulary.size() ) {
-        d->m_vocabulary.removeAt( index );
-    }
-
-    // now we need to go fix the entryids that are greater than index in the lessons
-    for (int i = 0; i < d->m_lessons.size(); ++i)
-    {
-        d->m_lessons[i].decrementEntriesAbove(index);
-    }
-}
-
-
-int KEduVocDocument::indexOfIdentifier( const QString& name ) const
-{
-    for ( int i=0; i < d->m_identifiers.count(); i++ ) {
-        if ( d->m_identifiers.value(i).name() == name ) {
-            return i;
-        }
-    }
-    return -1;
-}
 
 
 KEduVocIdentifier& KEduVocDocument::identifier( int index )
@@ -729,58 +669,11 @@ void KEduVocDocument::setTenseDescriptions( const QStringList &names )
 }
 
 
-int KEduVocDocument::sizeHint( int idx ) const
-{
-    if ( idx < 0 ) {
-        idx = -idx;
-        if ( idx >= d->m_extraSizeHints.size() )
-            return 80; // make a good guess about column size
-        else {
-//      cout << "gsh " << idx << "  " << extraSizehints[idx] << endl;
-            return d->m_extraSizeHints[idx];
-        }
-    } else {
-        if ( idx >= d->m_sizeHints.size() )
-            return 150; // make a good guess about column size
-        else {
-//      cout << "gsh " << idx << "  " << sizehints[idx] << endl;
-            return d->m_sizeHints[idx];
-        }
-    }
-}
-
-
-void KEduVocDocument::setSizeHint( int idx, const int width )
-{
-//  cout << "ssh " << idx << "  " << width << endl;
-    if ( idx < 0 ) {
-        idx = -idx;
-        if ( idx >= d->m_extraSizeHints.size() ) {
-            for ( int i = d->m_extraSizeHints.size(); i <= idx; i++ )
-                d->m_extraSizeHints.append( 80 );
-        }
-        d->m_extraSizeHints[idx] = width;
-
-    } else {
-        if ( idx >= d->m_sizeHints.size() ) {
-            for ( int i = d->m_sizeHints.size(); i <= idx; i++ )
-                d->m_sizeHints.append( 150 );
-        }
-        d->m_sizeHints[idx] = width;
-    }
-}
-
-
 void KEduVocDocument::removeIdentifier( int index )
 {
     if ( index < d->m_identifiers.size() && index >= 0 ) {
         d->m_identifiers.removeAt( index );
-        for ( int i = 0; i < d->m_vocabulary.count(); i++ ) {
-            d->m_vocabulary[i].removeTranslation( index );
-            for ( int j = index; j < d->m_identifiers.size(); j++ ) {
-                d->m_vocabulary[i].translation(j) = d->m_vocabulary[i].translation(j+1);
-            }
-        }
+        d->m_rootLesson->removeTranslation( index );
     }
 }
 
@@ -791,21 +684,8 @@ bool KEduVocDocument::isModified() const
 }
 
 
-int KEduVocDocument::entryCount() const
-{
-    return d->m_vocabulary.count();
-}
 
 
-void KEduVocDocument::resetEntry( int index, int lesson )
-{
-    for ( int i = 0; i < d->m_vocabulary.count(); i++ )
-        if ( /*lesson == 0 ||*/ lesson == d->m_vocabulary[i].lesson() ) {
-            // index is the translation number whose grades are reset
-            d->m_vocabulary[i].resetGrades( index );
-        }
-}
-
 
 int KEduVocDocument::identifierCount() const
 {
@@ -825,33 +705,15 @@ kDebug() << "appendIdentifier: " << i << id.name() << id.locale();
         }
     }
 
-    if ( i > 0 ) {
-        for (int j = 0; j < entryCount(); j++) {
-            entry(j)->translation(i).setType(entry(j)->translation(0).type());
-        }
-    }
 
     return i;
 }
 
 
-int KEduVocDocument::appendLesson( const QString &lessonName, bool inPractice )
-{
-    KEduVocLesson lesson;
-    lesson.setName( lessonName );
-    lesson.setInPractice( inPractice );
-    d->m_lessons.append( lesson );
-    return d->m_lessons.count() - 1;
-}
 
-QList<KEduVocLesson> & KEduVocDocument::lessons() const
+KEduVocLesson * KEduVocDocument::lesson()
 {
-    return d->m_lessons;
-}
-
-KEduVocLesson & KEduVocDocument::lesson( int index )
-{
-    return d->m_lessons[index];
+    return d->m_rootLesson;
 }
 
 
@@ -869,10 +731,10 @@ void KEduVocDocument::setUrl( const KUrl& url )
 
 QString KEduVocDocument::title() const
 {
-    if ( d->m_title.isEmpty() )
+    if ( d->m_rootLesson->name().isEmpty() )
         return d->m_url.fileName();
     else
-        return d->m_title;
+        return d->m_rootLesson->name();
 }
 
 
@@ -920,7 +782,7 @@ void KEduVocDocument::setQueryIdentifier( const QString &org, const QString &tra
 
 void KEduVocDocument::setTitle( const QString & title )
 {
-    d->m_title = title.simplified();
+    d->m_rootLesson->setName(title.simplified());
 }
 
 
@@ -966,103 +828,6 @@ void KEduVocDocument::setVersion( const QString & vers )
 }
 
 
-int KEduVocDocument::currentLesson() const
-{
-    return d->m_currentLesson;
-}
-
-
-void KEduVocDocument::setCurrentLesson( int lesson )
-{
-    d->m_currentLesson = lesson;
-}
-
-
-QStringList KEduVocDocument::lessonNames() const
-{
-    QStringList descriptions;
-    foreach ( KEduVocLesson lesson, d->m_lessons ) {
-        descriptions.append(lesson.name());
-    }
-    return descriptions;
-}
-
-int KEduVocDocument::lessonCount() const
-{
-    return d->m_lessons.count();
-}
-
-bool KEduVocDocument::removeLesson( int lessonIndex, int deleteMode )
-{
-    if (deleteMode == DeleteEmptyLesson) {
-        if (d->m_lessons[lessonIndex].entryCount() > 0) {
-            return false; // stop if there are vocabs left in the lesson
-        }
-    }
-    else if (deleteMode == DeleteEntriesAndLesson) {
-        while (d->m_lessons[lessonIndex].entryCount() > 0) {
-            // get the next entryid
-            int entry = d->m_lessons[lessonIndex].entries()[0];
-            // take it out of this lesson
-            d->m_lessons[lessonIndex].removeEntry(entry);
-            // delete the entry from the document
-            removeEntry(entry);
-        }
-    }
-
-    // for all above this lesson number - reduce lesson by one.
-    for ( int ent = 0; ent < entryCount(); ent++ ) {
-        if ( entry( ent )->lesson() > lessonIndex ) {
-            entry( ent )->setLesson( entry( ent )->lesson()-1 );
-        }
-    } // reduce lesson
-
-    // finally just remove the lesson
-    d->m_lessons.removeAt(lessonIndex);
-
-    return true;
-}
-
-
-//void KEduVocDocument::setLessonDescriptions(const QStringList &names)
-//{
-//  d->m_lessonDescriptions = names;
-//}
-
-//void KEduVocDocument::moveLesson(int from, int to)
-//{
-/////@todo move in query as well!
-//  // still counting from 1
-//  d->m_lessonDescriptions.move(from -1, to -1);
-
-//  /*
-//  to > from?
-//    lesson >= from && lesson < to: lesson++
-//  to < from?
-//    lesson >= to && lesson < from: lesson++
-//  */
-//  for (int ent = 0; ent < entryCount(); ent++) {
-//    // put from directly to to
-//    if (entry(ent)->lesson() == from) {
-//      entry(ent)->setLesson(to);
-//    }
-//    else
-//    {
-//      if(to > from)
-//      {
-//        if(entry(ent)->lesson() >= from && entry(ent)->lesson() < to)
-//          entry(ent)->setLesson(entry(ent)->lesson()-1);
-//      }
-//      else
-//      {
-//        if(entry(ent)->lesson() >= to && entry(ent)->lesson() < from)
-//          entry(ent)->setLesson(entry(ent)->lesson()+1);
-//      }
-//    }
-//  }
-//}
-
-
 QString KEduVocDocument::csvDelimiter() const
 {
     return d->m_csvDelimiter;
@@ -1107,74 +872,6 @@ public:
     KEduVocExpression *exp;
 };
 
-typedef QList<ExpRef> ExpRefList;
-
-int KEduVocDocument::cleanUp()
-{
-    int count = 0;
-    KEduVocExpression *kve1, *kve2;
-    ExpRefList shadow;
-    QList<int> to_delete;
-
-    for ( int i = 0; i < d->m_vocabulary.count(); i++ ) {
-        shadow.append( ExpRef( entry( i ), i ) );
-    }
-    qStableSort( shadow.begin(), shadow.end() );
-
-    int ent_no = 0;
-    int ent_percent = d->m_vocabulary.size() / 100;
-    float f_ent_percent = d->m_vocabulary.size() / 100.0;
-    emit progressChanged( this, 0 );
-
-    for ( int i = shadow.size() - 1; i > 0; i-- ) {
-        kve1 = shadow[i].exp;
-        kve2 = shadow[i - 1].exp;
-
-        ent_no++;
-        if ( ent_percent != 0 && ( ent_no % ent_percent ) == 0 ) {
-            emit progressChanged( this, ( int )(( ent_no / f_ent_percent ) / 2.0 ) );
-        }
-
-        bool equal = true;
-        for ( int l = 0; equal && l < identifierCount(); l++ ) {
-            if ( kve1->translation( l ).text() != kve2->translation( l ).text() ) {
-                equal = false;
-            }
-        }
-
-        if ( equal ) {
-            to_delete.append( shadow[i - 1].idx );
-            count++;
-        }
-    }
-
-    // removing might take very long
-    ent_no = 0;
-    ent_percent = to_delete.size() / 100;
-    f_ent_percent = to_delete.size() / 100.0;
-    emit progressChanged( this, 0 );
-
-    qStableSort( to_delete.begin(), to_delete.end() );
-
-    for ( int i = ( int ) to_delete.count() - 1; i >= 0; i-- ) {
-        ent_no++;
-        if ( ent_percent != 0 && ( ent_no % ent_percent ) == 0 )
-            emit progressChanged( this, ( int )( 50 + ent_no / f_ent_percent / 2.0 ) );
-        removeEntry( to_delete[i] );
-        setModified();
-    }
-
-    return count;
-}
-
-
-void KEduVocDocument::shuffle()
-{
-    KRandomSequence rs;
-    rs.randomize( d->m_vocabulary );
-    setModified();
-}
-
 
 QString KEduVocDocument::pattern( FileDialogMode mode )
 {
@@ -1241,48 +938,4 @@ KEduVocWordType& KEduVocDocument::wordTypes()
 }
 
 
-QStringList KEduVocDocument::usages() const
-{
-    return d->m_usages.values();
-}
-
-
-void KEduVocDocument::addUsage( const QString &usage )
-{
-    d->m_usages.insert( usage );
-}
-
-
-void KEduVocDocument::renameUsage( const QString &oldName, const QString &newName )
-{
-    if ( d->m_usages.contains( oldName ) ) {
-        d->m_usages.remove( oldName );
-        d->m_usages.insert( newName );
-    } else {
-        return;
-    }
-
-    for ( int i = 0; i < d->m_vocabulary.count(); i++ ) {
-        foreach( int translationIndex, d->m_vocabulary[i].translationIndices() ) {
-            if ( d->m_vocabulary[i].translation( translationIndex ).usages().contains( oldName ) ) {
-                d->m_vocabulary[i].translation( translationIndex ).usages().remove( oldName );
-                d->m_vocabulary[i].translation( translationIndex ).usages().insert( newName );
-            }
-        }
-    }
-}
-
-
-void KEduVocDocument::removeUsage( const QString &name )
-{
-    d->m_usages.remove( name );
-
-    for ( int i = 0; i < d->m_vocabulary.count(); i++ ) {
-        foreach( int translationIndex, d->m_vocabulary[i].translationIndices() ) {
-            d->m_vocabulary[i].translation( translationIndex ).usages().remove( name );
-        }
-    }
-}
-
-
 #include "keduvocdocument.moc"
index 05be0ef90007e1def99c9fbe1c500939fd6cfbfa..7fa0b4f0d730268249a4539e5e6736ecae2c0161 100644 (file)
@@ -195,64 +195,6 @@ public:
     /** @returns the version of the loaded file */
     QString version() const;
 
-
-    // *** entry methods ***
-
-    /**
-     * Appends a new expression to the end of the vocabulary
-     *
-     * @param expression      expression to append
-     */
-    void appendEntry( KEduVocExpression *expression );
-
-    /**
-     * Inserts a new expression at position @p index
-     *
-     * @param expression      expression to insert
-     * @param index           index of entry
-     */
-    void insertEntry( KEduVocExpression *expression, int index );
-
-    /**
-     * Removes an expression from the document
-     *
-     * @param index           index of expression
-     */
-    void removeEntry( int index );
-
-    /**
-     * Shuffles vocabulary in a random order
-     */
-    void shuffle();
-
-    /**
-     * Removes duplicate entries (original plus all translations)
-     *
-     * @returns                 number of removed entries
-     */
-    int cleanUp();
-
-    /**
-     * @returns the number of entries
-     */
-    int entryCount() const;
-
-    /**
-     * Returns the recommended size
-     *
-     * @param index            number of expr, -1 = lesson
-     * @returns                width of column
-     */
-    int sizeHint( int index ) const;
-
-    /**
-     * Sets the recommended size
-     *
-     * @param index            number of expr, -1 = lesson
-     * @param width            width of column
-     */
-    void setSizeHint( int index, const int width );
-
     // *** identifier methods ***
 
     /**
@@ -372,23 +314,6 @@ public:
 
     // *** grade methods ***
 
-    /**
-     * Sets grades to KV_NORM_GRADE, counts to 0 ...
-     *
-     * @param index    index of language 0..x, -1 = all
-     * @param lesson   lesson id, if this is 0 all lesson are affected,
-     *                 otherwise only matching numbers
-     */
-    void resetEntry( int index = -1, int lesson = 0 );
-
-    /**
-     * Returns pointer to expression object @p index
-     *
-     * @param index     index of desired entry
-     * @returns         pointer to object or NULL if index out of range
-     */
-    KEduVocExpression *entry( int index );
-
 
     /**
      * Retrieves the identifiers for the current query
@@ -410,60 +335,10 @@ public:
 
     // *** lesson methods ***
 
-    /**
-     * @returns the current lesson index
-     */
-    int currentLesson() const;
-
-    /**
-     * Sets current lesson index
-     * @param lesson    index of lesson
-     */
-    void setCurrentLesson( int lesson );
-
-    /** get a lesson object
-     * @returns a pointer to the lesson object at the specified index
-     * NOTE: this will create one if it doesn't exist
-     */
-    KEduVocLesson & lesson( int index );
-
-    /** get all lesson objects
-     * @returns a map of pointers to lesson objects
-     */
-    QList<KEduVocLesson> & lessons() const;
-
-    /**
-     * @returns                the number of lessons defined
-     */
-    int lessonCount() const;
-
-    /**
-     * Append a new lesson to the list of lessons.
-     * @param lessonName name for the new lesson
-     * @returns the index of the new lesson
-     */
-    int appendLesson( const QString &lessonName, bool inQuery=true );
-
-    /**
-     * Delete a lesson.
-     * @param lessonIndex which lesson
-     * @param deleteMode either KEduVocDocument::DeleteEmptyLesson (delete only if empty) or KEduVocDocument::DeleteEntriesAndLesson (delete including vocabulary in that lesson)
-     * @returns if the deletion was successful. If there are vocabularies in the lesson, but DeleteEmptyLesson, this will return false and not delete the lesson.
-     */
-    bool removeLesson( int lessonIndex, int deleteMode );
-
-    /** DEPRECATED
-     * All lesson descriptions as stringlist.
-     * @returns a list of defined lessons
-     */
-    KDE_DEPRECATED QStringList lessonNames() const;
-
-    /** @todo implement this?
-     * Moves the lesson at index position from to index position to.
-     * @param from the lesson to be moved
-     * @param to the new position
+    /** get the lesson root object
+     * @returns a pointer to the lesson object
      */
-    void moveLesson(int from, int to);
+    KEduVocLesson * lesson();
 
     // *** file format specific methods ***
 
index edf3bc1e1d18f6dd7cb2b4859b98a1590cf1be63..1a28a19fa3545d4ff87bffa66e40a1bf6e04d4c2 100644 (file)
@@ -36,10 +36,8 @@ public:
 
     KEduVocExpression* q;
 
-    int m_sortIndex;
-    int m_lesson;
+    QList<KEduVocLesson*> m_lessons;
     bool m_active;
-    int m_sizeHint;
 
     QMap <int, KEduVocTranslation> m_translations;
 };
@@ -49,9 +47,6 @@ void KEduVocExpression::KEduVocExpressionPrivate::init()
 {
     m_translations.clear();
     m_active = true;
-    m_lesson = -1;
-    m_sortIndex = 0;
-    m_sizeHint = 0;
 }
 
 
@@ -59,8 +54,7 @@ bool KEduVocExpression::KEduVocExpressionPrivate::operator== ( const KEduVocExpr
 {
     return
         m_translations == p.m_translations &&
-        m_lesson == p.m_lesson &&
-        m_sortIndex == p.m_sortIndex &&
+        m_lessons == p.m_lessons &&
         m_active == p.m_active;
 }
 
@@ -69,28 +63,29 @@ KEduVocExpression::KEduVocExpression()
         : d( new KEduVocExpressionPrivate( this ) )
 {}
 
-KEduVocExpression::KEduVocExpression( const QString & expression, int lesson )
+KEduVocExpression::KEduVocExpression( KEduVocLesson* lesson,  const QString & expression )
         : d( new KEduVocExpressionPrivate( this ) )
 {
-    d->m_lesson = lesson;
+    d->m_lessons.append(lesson);
     setTranslation( 0, expression.simplified() );
 }
 
-KEduVocExpression::KEduVocExpression( const QStringList & translations, int lesson )
+KEduVocExpression::KEduVocExpression( KEduVocLesson* lesson, const QStringList & translations)
         : d( new KEduVocExpressionPrivate( this ) )
 {
-    d->m_lesson = lesson;
+    d->m_lessons.append(lesson);
     foreach ( QString translation, translations ) {
         setTranslation(d->m_translations.count(), translation);
     }
 }
 
-KEduVocExpression::KEduVocExpression( const KEduVocExpression &expression )
-        : d( new KEduVocExpressionPrivate( *expression.d ) )
-{}
 
 KEduVocExpression::~KEduVocExpression()
 {
+///@todo probably infinite loop when a parent lesson decides to delete it :)
+//     foreach(KEduVocLesson * lesson, d->m_lessons) {
+//         lesson->removeEntry(this);
+//     }
     delete d;
 }
 
@@ -98,6 +93,13 @@ KEduVocExpression::~KEduVocExpression()
 void KEduVocExpression::removeTranslation( int index )
 {
     d->m_translations.remove( index );
+
+    for ( int j = index; j < d->m_translations.count(); j++ ) {
+        translation(j) = translation(j+1);
+    }
+    kDebug() << "Checkme - removing last tranlation ?!!?";
+    ///@todo - no idea if this works
+    d->m_translations.remove(d->m_translations.count() - 1);
 }
 
 
@@ -111,15 +113,9 @@ void KEduVocExpression::setTranslation( int index, const QString & expr )
 }
 
 
-int KEduVocExpression::lesson() const
+QList<KEduVocLesson*> KEduVocExpression::lessons() const
 {
-    return d->m_lesson;
-}
-
-
-void KEduVocExpression::setLesson( int l )
-{
-    d->m_lesson = l;
+    return d->m_lessons;
 }
 
 
@@ -134,15 +130,6 @@ void KEduVocExpression::setActive( bool flag )
     d->m_active = flag;
 }
 
-int KEduVocExpression::sizeHint() const
-{
-    return d->m_sizeHint;
-}
-
-void KEduVocExpression::setSizeHint( int sizeHint )
-{
-    d->m_sizeHint = sizeHint;
-}
 
 void KEduVocExpression::resetGrades( int index )
 {
@@ -182,3 +169,13 @@ QList< int > KEduVocExpression::translationIndices() const
     return d->m_translations.keys();
 }
 
+void KEduVocExpression::addLesson(KEduVocLesson * l)
+{
+    d->m_lessons.append(l);
+}
+
+void KEduVocExpression::removeLesson(KEduVocLesson * l)
+{
+    d->m_lessons.removeAt(d->m_lessons.indexOf(l));
+}
+
index 1f242c64109faca1d283263bf20c78d4977cd6f9..b072c5fbde8ec49c23b0c5880bc475af6c3261e2 100644 (file)
@@ -26,6 +26,8 @@
 #include "keduvocmultiplechoice.h"
 #include "keduvoctranslation.h"
 
+class KEduVocLesson;
+
 /**
   This class contains one vocabulary expression as an original with one or more
   translations
@@ -43,7 +45,7 @@ public:
      * @param expression       translation
      * @param lesson           lesson number
      */
-    explicit KEduVocExpression( const QString & expression, int lesson = -1 );
+    explicit KEduVocExpression( KEduVocLesson* lesson, const QString & expression );
 
     /** Constructor for a vocabulary expression with an original and one or more translations
      *
@@ -51,19 +53,14 @@ public:
      * @param separator        expression will be split into an original and one or more translations using separator
      * @param lesson           lesson number, 0 for none
      */
-    explicit KEduVocExpression( const QStringList & translations, int lesson = -1 );
-
-    KEduVocExpression( const KEduVocExpression &expression );
+    explicit KEduVocExpression( KEduVocLesson* lesson, const QStringList & translations );
 
     ~KEduVocExpression();
 
     /** returns index of lesson (-1 = none)
      */
-    int lesson() const;
+    QList<KEduVocLesson *> lessons() const;
 
-    /** sets index of lesson (-1 = none)
-     */
-    void setLesson( int l );
 
     /** reset all grades of the entry
      * @param index     identifier (language)
@@ -119,6 +116,12 @@ public:
 private:
     class KEduVocExpressionPrivate;
     KEduVocExpressionPrivate* const d;
+
+    /** only called by lesson to add itself to the lesson list
+     */
+    void addLesson( KEduVocLesson * l );
+    void removeLesson( KEduVocLesson * l );
+    friend class KEduVocLesson;
 };
 
 #endif // KEduVocExpression_H
index 8a04958a366fca30a3a25b309a99c81279a2a625..7cce7c974df9f6b3a60a61a0fd9c77e9754b694c 100644 (file)
@@ -32,6 +32,8 @@
 #include "keduvockvtmlreader.h"
 #include "keduvoccommon_p.h"
 
+#include <KDebug>
+
 KEduVocKvtml2Reader::KEduVocKvtml2Reader( QIODevice *file )
         : m_inputFile( file )
 {
@@ -56,21 +58,21 @@ bool KEduVocKvtml2Reader::readDoc( KEduVocDocument *doc )
         m_errorMessage = i18n( "This is not a KDE Vocabulary document." );
         return false;
     }
-
-    if ( domElementKvtml.attribute( KVTML_VERSION ).toFloat() < 2.0 ) {
-        // read the file with the old format
-
-        // first reset the file to the beginning
-        m_inputFile->seek( 0 );
-        KEduVocKvtmlReader oldFormat( m_inputFile );
-
-        // get the return value
-        bool retval = oldFormat.readDoc( doc );
-
-        // pass the errormessage up
-        m_errorMessage = oldFormat.errorMessage();
-        return retval;
-    }
+///@todo port me
+//     if ( domElementKvtml.attribute( KVTML_VERSION ).toFloat() < 2.0 ) {
+//         // read the file with the old format
+// 
+//         // first reset the file to the beginning
+//         m_inputFile->seek( 0 );
+//         KEduVocKvtmlReader oldFormat( m_inputFile );
+// 
+//         // get the return value
+//         bool retval = oldFormat.readDoc( doc );
+// 
+//         // pass the errormessage up
+//         m_errorMessage = oldFormat.errorMessage();
+//         return retval;
+//     }
 
     //-------------------------------------------------------------------------
     // Information
@@ -167,11 +169,6 @@ bool KEduVocKvtml2Reader::readGroups( QDomElement &domElementParent )
         readTenses( groupElement );
     }
 
-    groupElement = domElementParent.firstChildElement( KVTML_USAGES );
-    if ( !groupElement.isNull() ) {
-        readUsages( groupElement );
-    }
-
     groupElement = domElementParent.firstChildElement( KVTML_ENTRIES );
     if ( !groupElement.isNull() ) {
         QDomNodeList entryList = groupElement.elementsByTagName( KVTML_ENTRY );
@@ -187,24 +184,23 @@ bool KEduVocKvtml2Reader::readGroups( QDomElement &domElementParent )
 
     groupElement = domElementParent.firstChildElement( KVTML_LESSONS );
     if ( !groupElement.isNull() ) {
-        QDomNodeList entryList = groupElement.elementsByTagName( KVTML_LESSON );
-        if ( entryList.length() <= 0 ) {
-            m_errorMessage = i18n( "no lessons found in 'lessons' tag" );
-            return false; // at least one entry is required
-        }
-
-        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);
     }
 
+
+    kDebug() << "Lessons:";
+    printLesson(m_doc->lesson());
+
     return true;
 }
+void KEduVocKvtml2Reader::printLesson( KEduVocLesson* lesson )
+{
+    kDebug() << "Lesson" << lesson->name();
+    foreach ( KEduVocLesson* child, lesson->childLessons() ) {
+        printLesson(child);
+    }
+
+}
 
 bool KEduVocKvtml2Reader::readIdentifier( QDomElement &identifierElement )
 {
@@ -254,7 +250,7 @@ bool KEduVocKvtml2Reader::readIdentifier( QDomElement &identifierElement )
 
 bool KEduVocKvtml2Reader::readEntry( QDomElement &entryElement )
 {
-    KEduVocExpression expr;
+    KEduVocExpression *expr = new KEduVocExpression;
     QDomElement currentElement;
     bool result = true;
 
@@ -270,9 +266,9 @@ bool KEduVocKvtml2Reader::readEntry( QDomElement &entryElement )
     if ( !currentElement.isNull() ) {
         // set the active state of the expression
         if ( currentElement.text() == KVTML_TRUE ) {
-            expr.setActive( false );
+            expr->setActive( false );
         } else {
-            expr.setActive( true );
+            expr->setActive( true );
         }
     }
 
@@ -280,18 +276,12 @@ bool KEduVocKvtml2Reader::readEntry( QDomElement &entryElement )
 //     if ( !currentElement.isNull() ) {
 //         // set the inquery information
 //         if ( currentElement.text() == KVTML_TRUE ) {
-//             expr.setInPractice( true );
+//             expr->setInPractice( true );
 //         } else {
-//             expr.setInPractice( false );
+//             expr->setInPractice( false );
 //         }
 //     }
 
-    currentElement = entryElement.firstChildElement( KVTML_SIZEHINT );
-    if ( !currentElement.isNull() ) {
-        // set the sizehint
-        expr.setSizeHint( currentElement.text().toInt() );
-    }
-
     // read translation children
     QDomNodeList translationList = entryElement.elementsByTagName( KVTML_TRANSLATION );
     if ( translationList.length() <= 0 ) {
@@ -310,76 +300,76 @@ bool KEduVocKvtml2Reader::readEntry( QDomElement &entryElement )
 
     // TODO: probably should insert at id position with a check to see if it exists
     // may be useful for detecting corrupt documents
-    m_doc->insertEntry( &expr, id );
+    m_allEntries[id] = expr;
     return result;
 }
 
 bool KEduVocKvtml2Reader::readTranslation( QDomElement &translationElement,
-        KEduVocExpression &expr, int index )
+        KEduVocExpression *expr, int index )
 {
     QDomElement currentElement = translationElement.firstChildElement( KVTML_TEXT );
     if ( !currentElement.isNull() ) {
-        expr.translation( index ).setText( currentElement.text() );
+        expr->translation( index ).setText( currentElement.text() );
     }
 
     currentElement = translationElement.firstChildElement( KVTML_COMMENT );
     if ( !currentElement.isNull() ) {
-        expr.translation( index ).setComment( currentElement.text() );
+        expr->translation( index ).setComment( currentElement.text() );
     }
 
     currentElement = translationElement.firstChildElement( KVTML_WORDTYPE );
     if ( !currentElement.isNull() ) {
         QDomElement typeElement = currentElement.firstChildElement( KVTML_TYPENAME );
-        expr.translation( index ).setType( typeElement.text() );
+        expr->translation( index ).setType( typeElement.text() );
         // read subtype if the type is not empty
         typeElement = currentElement.firstChildElement( KVTML_SUBTYPENAME );
         if ( !typeElement.isNull() ) {
-            expr.translation( index ).setSubType( typeElement.text() );
+            expr->translation( index ).setSubType( typeElement.text() );
         }
     }
 
     //<pronunciation></pronunciation>
     currentElement = translationElement.firstChildElement( KVTML_PRONUNCIATION );
     if ( !currentElement.isNull() ) {
-        expr.translation( index ).setPronunciation( currentElement.text() );
+        expr->translation( index ).setPronunciation( currentElement.text() );
     }
 
     //<falsefriend fromid="1"></falsefriend>
     currentElement = translationElement.firstChildElement( KVTML_FALSEFRIEND );
     if ( !currentElement.isNull() ) {
         int fromid = currentElement.attribute( KVTML_FROMID ).toInt();
-        expr.translation( index ).setFalseFriend( fromid, currentElement.text() );
+        expr->translation( index ).setFalseFriend( fromid, currentElement.text() );
     }
 
     //<antonym></antonym>
     currentElement = translationElement.firstChildElement( KVTML_ANTONYM );
     if ( !currentElement.isNull() ) {
-        expr.translation( index ).setAntonym( currentElement.text() );
+        expr->translation( index ).setAntonym( currentElement.text() );
     }
 
     //<synonym></synonym>
     currentElement = translationElement.firstChildElement( KVTML_SYNONYM );
     if ( !currentElement.isNull() ) {
-        expr.translation( index ).setSynonym( currentElement.text() );
+        expr->translation( index ).setSynonym( currentElement.text() );
     }
 
     //<example></example>
     currentElement = translationElement.firstChildElement( KVTML_EXAMPLE );
     if ( !currentElement.isNull() ) {
-        expr.translation( index ).setExample( currentElement.text() );
+        expr->translation( index ).setExample( currentElement.text() );
     }
 
     //<usage></usage> can be as often as there are usage labels
     currentElement = translationElement.firstChildElement( KVTML_USAGE );
     while ( !currentElement.isNull() ) {
-        expr.translation( index ).usages().insert( currentElement.text() );
+        expr->translation( index ).usages().insert( currentElement.text() );
         currentElement = currentElement.nextSiblingElement( KVTML_USAGE );
     }
 
     //<paraphrase></paraphrase>
     currentElement = translationElement.firstChildElement( KVTML_PARAPHRASE );
     if ( !currentElement.isNull() ) {
-        expr.translation( index ).setParaphrase( currentElement.text() );
+        expr->translation( index ).setParaphrase( currentElement.text() );
     }
 
     // conjugations
@@ -390,7 +380,7 @@ bool KEduVocKvtml2Reader::readTranslation( QDomElement &translationElement,
         QDomElement tenseElement = currentElement.firstChildElement( KVTML_TENSE );
         QString tense = tenseElement.text();
 
-        readConjugation( currentElement, expr.translation(index).conjugation(tense) );
+        readConjugation( currentElement, expr->translation(index).conjugation(tense) );
         currentElement = currentElement.nextSiblingElement( KVTML_CONJUGATION );
     }
 
@@ -407,7 +397,7 @@ bool KEduVocKvtml2Reader::readTranslation( QDomElement &translationElement,
     if ( !currentElement.isNull() ) {
         KEduVocComparison comparison;
         readComparison( currentElement, comparison );
-        expr.translation( index ).setComparison( comparison );
+        expr->translation( index ).setComparison( comparison );
     }
 
     // multiple choice
@@ -415,58 +405,53 @@ bool KEduVocKvtml2Reader::readTranslation( QDomElement &translationElement,
     if ( !currentElement.isNull() ) {
         KEduVocMultipleChoice mc;
         readMultipleChoice( currentElement, mc );
-        expr.translation( index ).setMultipleChoice( mc );
+        expr->translation( index ).setMultipleChoice( mc );
     }
 
     // image
     currentElement = translationElement.firstChildElement( KVTML_IMAGE );
     if ( !currentElement.isNull() ) {
-        expr.translation( index ).setImageUrl( KUrl( m_doc->url(), currentElement.text() ) );
+        expr->translation( index ).setImageUrl( KUrl( m_doc->url(), currentElement.text() ) );
     }
 
     // sound
     currentElement = translationElement.firstChildElement( KVTML_SOUND );
     if ( !currentElement.isNull() ) {
-        expr.translation( index ).setSoundUrl( KUrl( m_doc->url(), currentElement.text() ) );
+        expr->translation( index ).setSoundUrl( KUrl( m_doc->url(), currentElement.text() ) );
     }
 
     return true;
 }
 
-bool KEduVocKvtml2Reader::readLesson( QDomElement &lessonElement )
+bool KEduVocKvtml2Reader::readChildLessons( KEduVocLesson* parentLesson, QDomElement &lessonElement )
+{
+    QDomElement currentElement = lessonElement.firstChildElement( KVTML_LESSON );
+    while ( !currentElement.isNull() ) {
+        readLesson(parentLesson, currentElement);
+        currentElement = currentElement.nextSiblingElement( KVTML_LESSON );
+    }
+}
+
+bool KEduVocKvtml2Reader::readLesson( KEduVocLesson* parentLesson, QDomElement &lessonElement )
 {
-    // NOTE: currently this puts an identifier into the last lesson it is in, once support for multiple lessons
-    // is in the entry class, all lessons that include an entry will be in there
-    int lessonId;
     //<name>Lesson name</name>
     QDomElement currentElement = lessonElement.firstChildElement( KVTML_NAME );
-    if ( !currentElement.isNull() ) {
-        lessonId = m_doc->appendLesson( currentElement.text() );
-    } else {
-        m_errorMessage = i18n( "each lesson must have a name" );
-        return false;
-    }
+    KEduVocLesson * lesson = new KEduVocLesson(currentElement.text(), parentLesson);
+    parentLesson->appendChildLesson( lesson );
+
+    kDebug() << "readLesson" << lesson->name();
+
+    readChildLessons( lesson, lessonElement );
 
     //<query>true</query>
     currentElement = lessonElement.firstChildElement( KVTML_QUERY );
-    m_doc->lesson(lessonId).setInPractice(currentElement.text() == KVTML_TRUE);
-
-    //<current>true</current>
-    currentElement = lessonElement.firstChildElement( KVTML_CURRENT );
-    if ( !currentElement.isNull() ) {
-        if ( currentElement.text() == KVTML_TRUE ) {
-            m_doc->setCurrentLesson( lessonId );
-        }
-    }
+    lesson->setInPractice(currentElement.text() == KVTML_TRUE);
 
     //<entryid>0</entryid>
     currentElement = lessonElement.firstChildElement( KVTML_ENTRYID );
     while ( !currentElement.isNull() ) {
         int entryId = currentElement.text().toInt();
-        // TODO: once we have a lesson class, add each of these entryids to the lesson
-        // set this lesson for the given enty
-        m_doc->entry( entryId )->setLesson( lessonId );
-        m_doc->lesson( lessonId ).addEntry( entryId );
+        lesson->addEntry( m_allEntries[entryId] );
         currentElement = currentElement.nextSiblingElement( KVTML_ENTRYID );
     }
 
@@ -613,7 +598,7 @@ bool KEduVocKvtml2Reader::readTenses( QDomElement &tensesElement )
     return true;
 }
 
-
+/*
 bool KEduVocKvtml2Reader::readUsages( QDomElement &usagesElement )
 {
     QStringList usages;
@@ -627,7 +612,7 @@ bool KEduVocKvtml2Reader::readUsages( QDomElement &usagesElement )
     }
 
     return true;
-}
+}*/
 
 
 bool KEduVocKvtml2Reader::readComparison( QDomElement &domElementParent, KEduVocComparison &comp )
@@ -688,7 +673,7 @@ bool KEduVocKvtml2Reader::readMultipleChoice( QDomElement &multipleChoiceElement
     return true;
 }
 
-bool KEduVocKvtml2Reader::readGrade( QDomElement &gradeElement, KEduVocExpression &expr, int index )
+bool KEduVocKvtml2Reader::readGrade( QDomElement &gradeElement, KEduVocExpression *expr, int index )
 {
     bool result = true;
     int id = gradeElement.attribute( KVTML_FROMID ).toInt( &result );
@@ -700,19 +685,19 @@ bool KEduVocKvtml2Reader::readGrade( QDomElement &gradeElement, KEduVocExpressio
     QDomElement currentElement = gradeElement.firstChildElement( KVTML_CURRENTGRADE );
     if ( !currentElement.isNull() ) {
         int value = currentElement.text().toInt();
-        expr.translation( index ).gradeFrom( id ).setGrade( value );
+        expr->translation( index ).gradeFrom( id ).setGrade( value );
     }
 
     currentElement = gradeElement.firstChildElement( KVTML_COUNT );
     if ( !currentElement.isNull() ) {
         int value = currentElement.text().toInt();
-        expr.translation( index ).gradeFrom( id ).setPracticeCount( value );
+        expr->translation( index ).gradeFrom( id ).setPracticeCount( value );
     }
 
     currentElement = gradeElement.firstChildElement( KVTML_ERRORCOUNT );
     if ( !currentElement.isNull() ) {
         int value = currentElement.text().toInt();
-        expr.translation( index ).gradeFrom( id ).setBadCount( value );
+        expr->translation( index ).gradeFrom( id ).setBadCount( value );
     }
 
     currentElement = gradeElement.firstChildElement( KVTML_DATE );
@@ -720,7 +705,7 @@ bool KEduVocKvtml2Reader::readGrade( QDomElement &gradeElement, KEduVocExpressio
         QString dateString = currentElement.text();
         if ( !dateString.isEmpty() ) {
             QDateTime value = QDateTime::fromString( dateString, Qt::ISODate );
-            expr.translation( index ).gradeFrom( id ).setPracticeDate( value );
+            expr->translation( index ).gradeFrom( id ).setPracticeDate( value );
         }
     }
 
index 6feedeb6a0ca3cb16cc09709d50a8b2530dde3b3..275bf5569140dc64e66e76e554f098747569a69d 100644 (file)
@@ -108,7 +108,7 @@ private:
     /** read a translation
      * @param translationElement QDomElement for the translation to read
      */
-    bool readTranslation( QDomElement &translationElement, KEduVocExpression &expr, int index );
+    bool readTranslation( QDomElement &translationElement, KEduVocExpression *expr, int index );
 
     /** read a comparison
      * @param comparisonElement comparison group element
@@ -127,12 +127,22 @@ private:
      * @param expr expression element to add grades to
      * @param index index of the current translation
      */
-    bool readGrade( QDomElement &gradeElement, KEduVocExpression &expr, int index );
+    bool readGrade( QDomElement &gradeElement, KEduVocExpression *expr, int index );
+
+    /**
+     * Read <lesson> tags.
+     * @param parentLesson 
+     * @param lessonElement 
+     * @return 
+     */
+    bool readChildLessons( KEduVocLesson* parentLesson, QDomElement &lessonElement );
 
     /** read a lesson, and append it to the document
      * @param lessonElement element to read from
      */
-    bool readLesson( QDomElement &lessonElement );
+    bool readLesson( KEduVocLesson* parentLesson, QDomElement &lessonElement );
+
+    void printLesson( KEduVocLesson* lesson );
 
     /** pre-opened QIODevice to read from */
     QIODevice *m_inputFile;
@@ -140,6 +150,10 @@ private:
     /** KEduVocDocument to read to */
     KEduVocDocument *m_doc;
 
+    /** because we read the entries first, we store them here temporarily.
+     * later we read the lessons and put the entries there based on the key (their id) */
+    QMap<int, KEduVocExpression*> m_allEntries;
+
     /** error message */
     QString m_errorMessage;
 };
index fc787f96590e92acec702b54e66130073ac68803..c60f601d52ef61bf1ae7f8388d5437fe2b519b02 100644 (file)
@@ -70,13 +70,6 @@ bool KEduVocKvtml2Writer::writeDoc( KEduVocDocument *doc, const QString &generat
         domElementKvtml.appendChild( currentElement );
     }
 
-    // usages
-    currentElement = m_domDoc.createElement( KVTML_USAGES );
-    writeUsages( currentElement );
-    if ( currentElement.hasChildNodes() ) {
-        domElementKvtml.appendChild( currentElement );
-    }
-
     // entries
     currentElement = m_domDoc.createElement( KVTML_ENTRIES );
     if ( !writeEntries( currentElement ) ) {
@@ -87,7 +80,7 @@ bool KEduVocKvtml2Writer::writeDoc( KEduVocDocument *doc, const QString &generat
 
     // lessons
     currentElement = m_domDoc.createElement( KVTML_LESSONS );
-    writeLessons( currentElement );
+    writeLessons( m_doc->lesson(), currentElement );
     if ( currentElement.hasChildNodes() ) {
         domElementKvtml.appendChild( currentElement );
     }
@@ -172,35 +165,32 @@ bool KEduVocKvtml2Writer::writeIdentifiers( QDomElement &identifiersElement )
     return true;
 }
 
-bool KEduVocKvtml2Writer::writeLessons( QDomElement &lessonsElement )
+bool KEduVocKvtml2Writer::writeLessons( KEduVocLesson *parentLesson, QDomElement &lessonsElement )
 {
-    for( int lessonId = 0; lessonId < m_doc->lessonCount(); lessonId++ ) {
+    // iterate over child lessons.
+    // the first time this is called with the root lesson which does not have a <lesson> entry.
+    for( int i = 0; i < parentLesson->childLessonCount(); i++ ) {
+        KEduVocLesson *lesson = parentLesson->childLesson(i);
         // make lesson element
         QDomElement thisLessonElement = m_domDoc.createElement( KVTML_LESSON );
 
         // add a name
-        thisLessonElement.appendChild( newTextElement( KVTML_NAME, m_doc->lesson(lessonId).name() ) );
+        thisLessonElement.appendChild( newTextElement( KVTML_NAME, lesson->name() ) );
 
         // add a inquery tag
-        if ( m_doc->lesson(lessonId).inPractice() ) {
+        if ( lesson->inPractice() ) {
             thisLessonElement.appendChild( newTextElement( KVTML_QUERY, KVTML_TRUE ) );
         }
 
-        // add a current tag
-        if ( lessonId == m_doc->currentLesson() ) {
-            thisLessonElement.appendChild( newTextElement( KVTML_CURRENT, KVTML_TRUE ) );
-        }
+        // child lessons
+        writeLessons(lesson, thisLessonElement);
 
-        // TODO: add the entryids...
-        for ( int i = 0; i < m_doc->entryCount(); ++i ) {
-            if ( m_doc->entry( i )->lesson() == lessonId ) {
-                thisLessonElement.appendChild( newTextElement( KVTML_ENTRYID, QString::number( i ) ) );
-            }
+        // child entries
+        foreach(KEduVocExpression *entry, lesson->entries()) {
+            thisLessonElement.appendChild( newTextElement( KVTML_ENTRYID, QString::number( m_allEntries.indexOf(entry) ) ) );
         }
-
         lessonsElement.appendChild( thisLessonElement );
     }
-
     return true;
 }
 
@@ -334,21 +324,13 @@ bool KEduVocKvtml2Writer::writeTenses( QDomElement &tensesElement )
     return true;
 }
 
-
-bool KEduVocKvtml2Writer::writeUsages( QDomElement &usagesElement )
-{
-    foreach( QString usage, m_doc->usages() ) {
-        usagesElement.appendChild( newTextElement( KVTML_USAGE, usage ) );
-    }
-
-    return true;
-}
-
 bool KEduVocKvtml2Writer::writeEntries( QDomElement &entriesElement )
 {
+    m_allEntries = m_doc->lesson()->entriesRecursive();
+
     // loop through entries
-    for ( int i = 0; i < m_doc->entryCount(); ++i ) {
-        KEduVocExpression *thisEntry = m_doc->entry( i );
+    for ( int i = 0; i < m_allEntries.count(); ++i ) {
+        KEduVocExpression *thisEntry = m_allEntries.value(i);
 
         // write entry tag
         QDomElement entryElement = m_domDoc.createElement( KVTML_ENTRY );
@@ -363,11 +345,6 @@ bool KEduVocKvtml2Writer::writeEntries( QDomElement &entriesElement )
 //         // write inquery
 //         entryElement.appendChild( newTextElement( KVTML_INQUERY, thisEntry->isInQuery() ? KVTML_TRUE : KVTML_FALSE ) );
 
-        // write sizehint
-        if ( thisEntry->sizeHint() > 0 ) {
-            entryElement.appendChild( newTextElement( KVTML_SIZEHINT, QString::number( thisEntry->sizeHint() ) ) );
-        }
-
         // loop through translations
         foreach( int trans, thisEntry->translationIndices() ) {
             // write translations
index 51efe0e3c0769587046cec11de8a93adbb27fd8d..eb5d06c8b53375981e7302e17381b29870e145e9 100644 (file)
@@ -27,6 +27,8 @@
 #include "keduvocpersonalpronoun.h"
 
 class KEduVocDocument;
+class KEduVocExpression;
+class KEduVocLesson;
 
 /**
 * @brief Class to write kvtml2 data files from KEduVocDocument
@@ -92,9 +94,10 @@ public:
     bool writeTranslation( QDomElement &translationElement, KEduVocTranslation &translation );
 
     /** write the lesson group
+     * @param parentLesson the parent lesson of the current lesson
      * @param lessonsElement QDomElement lessons to write to
      */
-    bool writeLessons( QDomElement &lessonsElement );
+    bool writeLessons( KEduVocLesson *parentLesson, QDomElement &lessonsElement );
 
     /** write a comparison
      * @param comparisonElement QDomElement comparison to write to
@@ -116,6 +119,8 @@ private:
     QFile *m_outputFile;
     KEduVocDocument *m_doc;
 
+    QList<KEduVocExpression*>  m_allEntries;
+
     QDomDocument m_domDoc;
 };
 
index 2028c0d7095d1ca10e3a01ff53aefb50aa7508eb..02a4960e4d3f40fdcfc885d07638d02ca5efc00d 100644 (file)
 
 #include "keduvoclesson.h"
 
-#include <QSet>
+#include "keduvocexpression.h"
+
+#include <QList>
 
 /** private class to store information about a lesson */
 class KEduVocLesson::Private
 {
 public:
-    QSet<int> m_entries;
+    ~Private();
+
+    // properties for this lesson
     QString m_name;
     bool m_inPractice;
+
+    // other lessons in the tree
+    KEduVocLesson *m_parentLesson;
+    QList<KEduVocLesson*> m_childLessons;
+
+    // entries
+    QList<KEduVocExpression*> m_entries;
 };
 
-KEduVocLesson::KEduVocLesson()
+KEduVocLesson::Private::~ Private()
+{
+    qDeleteAll(m_childLessons);
+
+    ///@todo delete children here???? is this a 1:1 mapping?
+    qDeleteAll(m_entries);
+}
+
+KEduVocLesson::KEduVocLesson(const QString& name, KEduVocLesson *parent)
         : d( new Private )
-{}
+{
+    d->m_parentLesson = parent;
+    d->m_name = name;
+}
 
 KEduVocLesson::KEduVocLesson( const KEduVocLesson &other )
         : d( new Private )
@@ -48,6 +70,30 @@ KEduVocLesson::~KEduVocLesson()
     delete d;
 }
 
+void KEduVocLesson::appendChildLesson(KEduVocLesson * child)
+{
+    d->m_childLessons.append(child);
+}
+
+KEduVocLesson * KEduVocLesson::childLesson(int row)
+{
+    return d->m_childLessons.value(row);
+}
+
+int KEduVocLesson::childLessonCount() const
+{
+    return d->m_childLessons.count();
+}
+
+int KEduVocLesson::row() const
+{
+    if (d->m_parentLesson) {
+        return d->m_parentLesson->d->m_childLessons.indexOf(const_cast<KEduVocLesson*>(this));
+    }
+    return 0;
+}
+
+
 KEduVocLesson& KEduVocLesson::operator= ( const KEduVocLesson &other )
 {
     d->m_entries = other.d->m_entries;
@@ -73,9 +119,9 @@ QString KEduVocLesson::name()
     return d->m_name;
 }
 
-QList<int> KEduVocLesson::entries()
+QList<KEduVocExpression*> KEduVocLesson::entries()
 {
-    return d->m_entries.toList();
+    return d->m_entries;
 }
 
 int KEduVocLesson::entryCount()
@@ -83,60 +129,64 @@ int KEduVocLesson::entryCount()
     return d->m_entries.count();
 }
 
-void KEduVocLesson::addEntry( int entryid )
+void KEduVocLesson::addEntry(KEduVocExpression* entry)
+{
+    d->m_entries.append( entry );
+    entry->addLesson(this);
+}
+
+void KEduVocLesson::removeEntry(KEduVocExpression* entry)
 {
-    d->m_entries.insert( entryid );
+    d->m_entries.removeAt( d->m_entries.indexOf(entry) );
+    entry->removeLesson(this);
 }
 
-void KEduVocLesson::removeEntry( int entryid )
+
+bool KEduVocLesson::inPractice()
 {
-    d->m_entries.remove( entryid );
+    return d->m_inPractice;
 }
 
-void KEduVocLesson::incrementEntriesAbove( int entryid )
+void KEduVocLesson::setInPractice(bool inPractice)
 {
-    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;
-        }
+    d->m_inPractice = inPractice;
+}
+
+void KEduVocLesson::removeTranslation(int translation)
+{
+    foreach(KEduVocLesson *childLesson, d->m_childLessons) {
+        childLesson->removeTranslation(translation);
     }
-    
-    // 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;
+
+    foreach(KEduVocExpression *entry, d->m_entries ) {
+        entry->removeTranslation( translation );
+    }
+}
+
+QList< KEduVocExpression * > KEduVocLesson::entriesRecursive()
+{
+    QList< KEduVocExpression * > entryList = entries();
+    foreach(KEduVocLesson *childLesson, d->m_childLessons) {
+        foreach(KEduVocExpression *childEntry, childLesson->entriesRecursive()) {
+            if(!entryList.contains(childEntry)) {
+                entryList.append(childEntry);
+            }
         }
     }
-    
-    // then put the new list into the set
-    d->m_entries = entries.toSet();
 }
 
-bool KEduVocLesson::inPractice()
+QList< KEduVocLesson * > KEduVocLesson::childLessons()
 {
-    return d->m_inPractice;
+    return d->m_childLessons;
 }
 
-void KEduVocLesson::setInPractice(bool inPractice)
+KEduVocExpression * KEduVocLesson::entry(int row)
 {
-    d->m_inPractice = inPractice;
+    return d->m_entries.value(row);
+}
+
+KEduVocLesson * KEduVocLesson::parent()
+{
+    return d->m_parentLesson;
 }
+
index 829beab3f275c36cc7c9f8fae7e1bd42728809b1..a6643be7a61f359e305302653323004a56d64d93 100644 (file)
 #include <QtCore/QList>
 #include <QtCore/QString>
 
+class KEduVocExpression;
+
 /** class to store information about a lesson */
 class KEDUVOCDOCUMENT_EXPORT KEduVocLesson
 {
+
 public:
-    /** default constructor */
-    explicit KEduVocLesson();
+     /** default constructor */
+     explicit KEduVocLesson(const QString& name, KEduVocLesson *parent = 0);
+
+     void appendChildLesson(KEduVocLesson *child);
+
+     QList<KEduVocLesson *> childLessons();
+     KEduVocLesson *childLesson(int row);
+     int childLessonCount() const;
+
+     int row() const;
+     KEduVocLesson *parent();
+
 
     /** copy constructor for d-pointer safe copying */
     KEduVocLesson( const KEduVocLesson &other );
@@ -50,31 +63,31 @@ public:
     /** get the lesson name */
     QString name();
 
+    KEduVocExpression* entry(int row);
+
     /** get a list of all entries in the lesson */
-    QList<int> entries();
-    
+    QList < KEduVocExpression* > entries();
+
+    /** get a list of all entries in the lesson and its child lessons */
+    QList < KEduVocExpression* > entriesRecursive();
+
     /** get the number of entries in the lesson */
     int entryCount();
 
     /** add an entry to the lesson
      * @param entryid id of the entry to add
      */
-    void addEntry( int entryid );
+    void addEntry(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
-     */
-    void decrementEntriesAbove( int entryid );
+    void removeEntry(KEduVocExpression* entry);
+
+
+    void removeTranslation(int translation);
+
+    //void resetGrades()?
 
     bool inPractice();
     void setInPractice( bool inPractice );
index 7af9d7fe8c99becb3345cd4627c7419cd947b0b9..34a64216f75e66bad8355511e10d0dd9c16176af 100644 (file)
@@ -79,13 +79,16 @@ void KEduVocDocumentValidatorTest::testDocumentAboutInfo()
 void KEduVocDocumentValidatorTest::testLessons()
 {
     QString lesson1 = QString::fromLatin1( "Lesson 1" );
+    QString lesson1child1 = QString::fromLatin1( "Lesson 1.1" );
+    QString lesson1child2 = QString::fromLatin1( "Lesson 1.2" );
     QString lesson2 = QString::fromLatin1( "Lesson 2" );
     QString lesson3 = QString::fromLatin1( "Lesson 3" );
 
     KEduVocDocument doc;
-    int indexLesson1 = doc.appendLesson(lesson1, true);
-    QCOMPARE(indexLesson1, 0);
-    QCOMPARE(doc.lessonCount(), 1);
+    doc.lesson()->appendChildLesson(new KEduVocLesson(lesson1, doc.lesson()));
+    QCOMPARE(doc.lesson()->childLessonCount(), 1);
+
+    /*
     QCOMPARE(doc.lesson(indexLesson1).name(), lesson1);
     QVERIFY(doc.lesson(indexLesson1).inPractice());
 
@@ -103,7 +106,7 @@ void KEduVocDocumentValidatorTest::testLessons()
     QVERIFY(removed);
     QCOMPARE(doc.lesson(2).name(), lesson3);
 
-    doc.appendLesson(lesson2, true);
+    doc.appendLesson(lesson2, true); */
 // Not yet implemented:
 //     doc.moveLesson(2, 1);
 //     QCOMPARE(doc.lesson(2), lesson2);