From: Frederik Gladhorn Date: Sun, 18 Nov 2007 23:30:20 +0000 (+0000) Subject: This is really a work branch now. X-Git-Tag: v4.0.71~93^2~31 X-Git-Url: https://git.rmz.fi/?a=commitdiff_plain;h=87a5190ade16689b8321e6322dc021c1848da9e2;p=libqmvoc.git This is really a work branch now. 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 --- diff --git a/keduvocdocument/CMakeLists.txt b/keduvocdocument/CMakeLists.txt index bcbe6ce..66e3d3d 100644 --- a/keduvocdocument/CMakeLists.txt +++ b/keduvocdocument/CMakeLists.txt @@ -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}) diff --git a/keduvocdocument/keduvocdocument.cpp b/keduvocdocument/keduvocdocument.cpp index 2b476a7..90ecd58 100644 --- a/keduvocdocument/keduvocdocument.cpp +++ b/keduvocdocument/keduvocdocument.cpp @@ -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 m_vocabulary; QStringList m_tenseDescriptions; QSet 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 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 & 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 ExpRefList; - -int KEduVocDocument::cleanUp() -{ - int count = 0; - KEduVocExpression *kve1, *kve2; - ExpRefList shadow; - QList 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" diff --git a/keduvocdocument/keduvocdocument.h b/keduvocdocument/keduvocdocument.h index 05be0ef..7fa0b4f 100644 --- a/keduvocdocument/keduvocdocument.h +++ b/keduvocdocument/keduvocdocument.h @@ -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 & 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 *** diff --git a/keduvocdocument/keduvocexpression.cpp b/keduvocdocument/keduvocexpression.cpp index edf3bc1..1a28a19 100644 --- a/keduvocdocument/keduvocexpression.cpp +++ b/keduvocdocument/keduvocexpression.cpp @@ -36,10 +36,8 @@ public: KEduVocExpression* q; - int m_sortIndex; - int m_lesson; + QList m_lessons; bool m_active; - int m_sizeHint; QMap 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 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)); +} + diff --git a/keduvocdocument/keduvocexpression.h b/keduvocdocument/keduvocexpression.h index 1f242c6..b072c5f 100644 --- a/keduvocdocument/keduvocexpression.h +++ b/keduvocdocument/keduvocexpression.h @@ -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 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 diff --git a/keduvocdocument/keduvockvtml2reader.cpp b/keduvocdocument/keduvockvtml2reader.cpp index 8a04958..7cce7c9 100644 --- a/keduvocdocument/keduvockvtml2reader.cpp +++ b/keduvocdocument/keduvockvtml2reader.cpp @@ -32,6 +32,8 @@ #include "keduvockvtmlreader.h" #include "keduvoccommon_p.h" +#include + 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() ); } } // currentElement = translationElement.firstChildElement( KVTML_PRONUNCIATION ); if ( !currentElement.isNull() ) { - expr.translation( index ).setPronunciation( currentElement.text() ); + expr->translation( index ).setPronunciation( currentElement.text() ); } // 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() ); } // currentElement = translationElement.firstChildElement( KVTML_ANTONYM ); if ( !currentElement.isNull() ) { - expr.translation( index ).setAntonym( currentElement.text() ); + expr->translation( index ).setAntonym( currentElement.text() ); } // currentElement = translationElement.firstChildElement( KVTML_SYNONYM ); if ( !currentElement.isNull() ) { - expr.translation( index ).setSynonym( currentElement.text() ); + expr->translation( index ).setSynonym( currentElement.text() ); } // currentElement = translationElement.firstChildElement( KVTML_EXAMPLE ); if ( !currentElement.isNull() ) { - expr.translation( index ).setExample( currentElement.text() ); + expr->translation( index ).setExample( currentElement.text() ); } // 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 ); } // 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; //Lesson 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 ); //true currentElement = lessonElement.firstChildElement( KVTML_QUERY ); - m_doc->lesson(lessonId).setInPractice(currentElement.text() == KVTML_TRUE); - - //true - currentElement = lessonElement.firstChildElement( KVTML_CURRENT ); - if ( !currentElement.isNull() ) { - if ( currentElement.text() == KVTML_TRUE ) { - m_doc->setCurrentLesson( lessonId ); - } - } + lesson->setInPractice(currentElement.text() == KVTML_TRUE); //0 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 ); } } diff --git a/keduvocdocument/keduvockvtml2reader.h b/keduvocdocument/keduvockvtml2reader.h index 6feedeb..275bf55 100644 --- a/keduvocdocument/keduvockvtml2reader.h +++ b/keduvocdocument/keduvockvtml2reader.h @@ -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 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 m_allEntries; + /** error message */ QString m_errorMessage; }; diff --git a/keduvocdocument/keduvockvtml2writer.cpp b/keduvocdocument/keduvockvtml2writer.cpp index fc787f9..c60f601 100644 --- a/keduvocdocument/keduvockvtml2writer.cpp +++ b/keduvocdocument/keduvockvtml2writer.cpp @@ -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 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 diff --git a/keduvocdocument/keduvockvtml2writer.h b/keduvocdocument/keduvockvtml2writer.h index 51efe0e..eb5d06c 100644 --- a/keduvocdocument/keduvockvtml2writer.h +++ b/keduvocdocument/keduvockvtml2writer.h @@ -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 m_allEntries; + QDomDocument m_domDoc; }; diff --git a/keduvocdocument/keduvoclesson.cpp b/keduvocdocument/keduvoclesson.cpp index 2028c0d..02a4960 100644 --- a/keduvocdocument/keduvoclesson.cpp +++ b/keduvocdocument/keduvoclesson.cpp @@ -20,20 +20,42 @@ #include "keduvoclesson.h" -#include +#include "keduvocexpression.h" + +#include /** private class to store information about a lesson */ class KEduVocLesson::Private { public: - QSet m_entries; + ~Private(); + + // properties for this lesson QString m_name; bool m_inPractice; + + // other lessons in the tree + KEduVocLesson *m_parentLesson; + QList m_childLessons; + + // entries + QList 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(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 KEduVocLesson::entries() +QList 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 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 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; } + diff --git a/keduvocdocument/keduvoclesson.h b/keduvocdocument/keduvoclesson.h index 829beab..a6643be 100644 --- a/keduvocdocument/keduvoclesson.h +++ b/keduvocdocument/keduvoclesson.h @@ -26,12 +26,25 @@ #include #include +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 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 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 ); diff --git a/keduvocdocument/tests/keduvocdocumentvalidatortest.cpp b/keduvocdocument/tests/keduvocdocumentvalidatortest.cpp index 7af9d7f..34a6421 100644 --- a/keduvocdocument/tests/keduvocdocumentvalidatortest.cpp +++ b/keduvocdocument/tests/keduvocdocumentvalidatortest.cpp @@ -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);