From a9537495c7271d2cc330013a2d394ed0a90e7cc5 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Sun, 26 Aug 2007 01:19:56 +0000 Subject: [PATCH] Complete rewrite of the type handling. This means the addition of a new class to keduvocdocument: KEduVocWordType. Word types are handled by getting a pointer KEduVocWordType* KEduVocDocument::wordTypes(). The class provides functions for adding types and subtypes and also has a special type QString to prevent users from deleting types necessary for certain query types (verb for conjugation etc.). These types can be renamed still. Within KVocTrain a few type_relation and other curious functions go away. When this is done with usages as well, a few more interdependencies will go away. To handle types in KVocTrain a new model and treeview has been added. Note: next step is to adapt the old reader/writer. And move the compability maps and functions away from KEduVocWordType. At document creation time a good preset (maybe the old types) should also be created. Also the old typeDescription QStringList has to be removed. svn path=/trunk/KDE/kdeedu/libkdeedu/; revision=704715 --- keduvocdocument/CMakeLists.txt | 2 + keduvocdocument/keduvocdocument.cpp | 15 +- keduvocdocument/keduvocdocument.h | 6 + keduvocdocument/keduvockvtml2reader.cpp | 204 +++++++----- keduvocdocument/keduvockvtml2writer.cpp | 44 ++- keduvocdocument/keduvoclesson.h | 20 +- keduvocdocument/keduvocwordtype.cpp | 421 ++++++++++++++++++++++++ keduvocdocument/keduvocwordtype.h | 131 ++++++++ keduvocdocument/kvtml2.dtd | 18 +- keduvocdocument/kvtml2defs.h | 23 +- 10 files changed, 779 insertions(+), 105 deletions(-) create mode 100644 keduvocdocument/keduvocwordtype.cpp create mode 100644 keduvocdocument/keduvocwordtype.h diff --git a/keduvocdocument/CMakeLists.txt b/keduvocdocument/CMakeLists.txt index d8c29d3..9f816f4 100644 --- a/keduvocdocument/CMakeLists.txt +++ b/keduvocdocument/CMakeLists.txt @@ -11,6 +11,7 @@ set(keduvocdocument_LIB_SRCS keduvoclesson.cpp keduvocgrade.cpp keduvocgrammar.cpp + keduvocwordtype.cpp keduvockvtmlreader.cpp keduvockvtml2reader.cpp keduvockvtmlwriter.cpp @@ -50,6 +51,7 @@ install(FILES keduvoclesson.h keduvocmultiplechoice.h keduvoctranslation.h + keduvocwordtype.h leitnerbox.h leitnersystem.h leitnersystemview.h diff --git a/keduvocdocument/keduvocdocument.cpp b/keduvocdocument/keduvocdocument.cpp index 6bc8118..9ad9d44 100644 --- a/keduvocdocument/keduvocdocument.cpp +++ b/keduvocdocument/keduvocdocument.cpp @@ -75,7 +75,9 @@ public: QList m_vocabulary; QList m_lessonsInQuery; //QStringList m_lessonDescriptions; + QStringList m_typeDescriptions; + QStringList m_tenseDescriptions; QStringList m_usageDescriptions; QString m_title; @@ -91,6 +93,8 @@ public: // make this a map so removals don't require renumbering :) QMap m_lessons; + KEduVocWordType* m_wordTypes; + LeitnerSystem* m_leitnerSystem; bool m_activeLeitnerSystem; }; @@ -122,6 +126,10 @@ void KEduVocDocument::KEduVocDocumentPrivate::init() m_csvDelimiter = QString('\t'); m_activeLeitnerSystem = false; m_leitnerSystem = NULL; + + m_wordTypes = new KEduVocWordType(); + ///@todo delete this: it only creates the sample entries for word types: + //m_wordTypes->createSampleData(); } @@ -133,7 +141,8 @@ KEduVocDocument::KEduVocDocument(QObject *parent) KEduVocDocument::~KEduVocDocument() { - delete d; + delete d->m_wordTypes; + delete d; } @@ -1426,4 +1435,8 @@ QString KEduVocDocument::pattern(Mode mode) } +KEduVocWordType* KEduVocDocument::wordTypes() { + return d->m_wordTypes; +} + #include "keduvocdocument.moc" diff --git a/keduvocdocument/keduvocdocument.h b/keduvocdocument/keduvocdocument.h index b2d9c1d..9a33b5c 100644 --- a/keduvocdocument/keduvocdocument.h +++ b/keduvocdocument/keduvocdocument.h @@ -36,11 +36,13 @@ #include #include "keduvocgrammar.h" +#include "keduvocwordtype.h" class QStringList; class KEduVocExpression; class KEduVocLesson; class LeitnerSystem; +class KEduVocWordType; /** * This class contains the expressions of your vocabulary @@ -288,6 +290,10 @@ public: // *** type methods *** + KEduVocWordType* wordTypes(); + + +///@todo delete the type methods below /** * Sets attribute string * diff --git a/keduvocdocument/keduvockvtml2reader.cpp b/keduvocdocument/keduvockvtml2reader.cpp index 0158b4f..4bc49da 100644 --- a/keduvocdocument/keduvockvtml2reader.cpp +++ b/keduvocdocument/keduvockvtml2reader.cpp @@ -56,18 +56,18 @@ 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; @@ -103,21 +103,21 @@ bool KEduVocKvtml2Reader::readInformation(QDomElement &informationElement) m_doc->setVersion(m_doc->generator().remove(0, pos + 2)); } } - + // read the title currentElement = informationElement.firstChildElement(KVTML_TITLE); if (!currentElement.isNull()) { m_doc->setTitle(currentElement.text()); } - + // read the author currentElement = informationElement.firstChildElement(KVTML_AUTHOR); if (!currentElement.isNull()) { m_doc->setAuthor(currentElement.text()); } - + // read the license currentElement = informationElement.firstChildElement(KVTML_LICENSE); if (!currentElement.isNull()) @@ -134,11 +134,11 @@ bool KEduVocKvtml2Reader::readInformation(QDomElement &informationElement) return true; } - + bool KEduVocKvtml2Reader::readGroups(QDomElement &domElementParent) { bool result = false; - + QDomElement currentElement; QDomElement groupElement = domElementParent.firstChildElement(KVTML_IDENTIFIERS); @@ -151,30 +151,30 @@ bool KEduVocKvtml2Reader::readGroups(QDomElement &domElementParent) return false; } - for (int i = 0; i < entryList.count(); ++i) + for (int i = 0; i < entryList.count(); ++i) { currentElement = entryList.item(i).toElement(); - if (currentElement.parentNode() == groupElement) + if (currentElement.parentNode() == groupElement) { result = readIdentifier(currentElement); if (!result) return false; } - } + } } - - groupElement = domElementParent.firstChildElement(KVTML_TYPES); + + groupElement = domElementParent.firstChildElement(KVTML_WORDTYPEDEFINITIONS); if (!groupElement.isNull()) { readTypes(groupElement); } - + groupElement = domElementParent.firstChildElement(KVTML_TENSES); if (!groupElement.isNull()) { readTenses(groupElement); } - + groupElement = domElementParent.firstChildElement(KVTML_USAGES); if (!groupElement.isNull()) { @@ -190,7 +190,7 @@ bool KEduVocKvtml2Reader::readGroups(QDomElement &domElementParent) m_errorMessage = i18n("no entries found in 'entries' tag"); return false; // at least one entry is required } - + for (int i = 0; i < entryList.count(); ++i) { currentElement = entryList.item(i).toElement(); @@ -212,7 +212,7 @@ bool KEduVocKvtml2Reader::readGroups(QDomElement &domElementParent) 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(); @@ -237,13 +237,13 @@ bool KEduVocKvtml2Reader::readIdentifier(QDomElement &identifierElement) m_errorMessage = i18n("identifier missing id"); return false; } - - QDomElement currentElement = identifierElement.firstChildElement(KVTML_TYPE); + + QDomElement currentElement = identifierElement.firstChildElement(KVTML_IDENTIFIERTYPE); if (!currentElement.isNull()) { // TODO: do something with the type } - + currentElement = identifierElement.firstChildElement(KVTML_LOCALE); if (!currentElement.isNull()) { @@ -255,26 +255,26 @@ bool KEduVocKvtml2Reader::readIdentifier(QDomElement &identifierElement) return false; } } - + currentElement = identifierElement.firstChildElement(KVTML_NAME); if (!currentElement.isNull()) { // TODO: do something with the name } - + currentElement = identifierElement.firstChildElement(KVTML_SIZEHINT); if (!currentElement.isNull()) { // TODO: do something with the sizehint } - + // read sub-parts currentElement = identifierElement.firstChildElement(KVTML_ARTICLE); if (!currentElement.isNull()) { readArticle(currentElement, id); } - + currentElement = identifierElement.firstChildElement(KVTML_PERSONALPRONOUNS); if (!currentElement.isNull()) { @@ -298,7 +298,7 @@ bool KEduVocKvtml2Reader::readEntry(QDomElement &entryElement) m_errorMessage = i18n("entry missing id"); return false; } - + // read info tags: inactive, inquery, and sizehint currentElement = entryElement.firstChildElement(KVTML_INACTIVE); if (!currentElement.isNull()) @@ -313,7 +313,7 @@ bool KEduVocKvtml2Reader::readEntry(QDomElement &entryElement) expr.setActive(true); } } - + currentElement = entryElement.firstChildElement(KVTML_INQUERY); if (!currentElement.isNull()) { @@ -327,14 +327,14 @@ bool KEduVocKvtml2Reader::readEntry(QDomElement &entryElement) expr.setInQuery(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) @@ -342,7 +342,7 @@ bool KEduVocKvtml2Reader::readEntry(QDomElement &entryElement) m_errorMessage = i18n("no translations found"); return false; // at least one translation is required } - + for (int i = 0; i < translationList.count(); ++i) { currentElement = translationList.item(i).toElement(); @@ -353,14 +353,14 @@ bool KEduVocKvtml2Reader::readEntry(QDomElement &entryElement) return false; } } - + // 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); return result; } -bool KEduVocKvtml2Reader::readTranslation(QDomElement &translationElement, +bool KEduVocKvtml2Reader::readTranslation(QDomElement &translationElement, KEduVocExpression &expr, int index) { QDomElement currentElement = translationElement.firstChildElement(KVTML_TEXT); @@ -368,26 +368,33 @@ bool KEduVocKvtml2Reader::readTranslation(QDomElement &translationElement, { expr.translation(index).setTranslation(currentElement.text()); } - + currentElement = translationElement.firstChildElement(KVTML_COMMENT); if (!currentElement.isNull()) { expr.translation(index).setComment(currentElement.text()); } - - currentElement = translationElement.firstChildElement(KVTML_TYPE); + + currentElement = translationElement.firstChildElement(KVTML_WORDTYPE); if (!currentElement.isNull()) { - expr.translation(index).setType(currentElement.text()); + QDomElement typeElement = currentElement.firstChildElement(KVTML_TYPENAME); + 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()); + } } - + // currentElement = translationElement.firstChildElement(KVTML_PRONUNCIATION); if (!currentElement.isNull()) { expr.translation(index).setPronunciation(currentElement.text()); } - + // currentElement = translationElement.firstChildElement(KVTML_FALSEFRIEND); if (!currentElement.isNull()) @@ -438,7 +445,7 @@ bool KEduVocKvtml2Reader::readTranslation(QDomElement &translationElement, { // read any conjugations (NOTE: this will overwrite any conjugations of the same type for this // translation, as the type is used as the key - readConjugation(currentElement, conjugation); + readConjugation(currentElement, conjugation); currentElement = currentElement.nextSiblingElement(KVTML_CONJUGATION); } if (conjugation.entryCount() > 0) @@ -495,7 +502,7 @@ bool KEduVocKvtml2Reader::readLesson(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 = 0; - + //Lesson name QDomElement currentElement = lessonElement.firstChildElement(KVTML_NAME); if (!currentElement.isNull()) @@ -507,7 +514,7 @@ bool KEduVocKvtml2Reader::readLesson(QDomElement &lessonElement) m_errorMessage = i18n("each lesson must have a name"); return false; } - + //true currentElement = lessonElement.firstChildElement(KVTML_QUERY); if (!currentElement.isNull()) @@ -517,7 +524,7 @@ bool KEduVocKvtml2Reader::readLesson(QDomElement &lessonElement) m_doc->addLessonToQuery(lessonId); } } - + //true currentElement = lessonElement.firstChildElement(KVTML_CURRENT); if (!currentElement.isNull()) @@ -527,7 +534,7 @@ bool KEduVocKvtml2Reader::readLesson(QDomElement &lessonElement) m_doc->setCurrentLesson(lessonId); } } - + //0 currentElement = lessonElement.firstChildElement(KVTML_ENTRYID); while (!currentElement.isNull()) @@ -539,7 +546,7 @@ bool KEduVocKvtml2Reader::readLesson(QDomElement &lessonElement) m_doc->lesson(lessonId)->addEntry(entryId); currentElement = currentElement.nextSiblingElement(KVTML_ENTRYID); } - + return true; } @@ -559,7 +566,7 @@ bool KEduVocKvtml2Reader::readArticle(QDomElement &articleElement, int identifie */ -{ +{ QString fem_def = ""; QString mal_def = ""; QString nat_def = ""; @@ -575,20 +582,20 @@ bool KEduVocKvtml2Reader::readArticle(QDomElement &articleElement, int identifie { mal_def = subElement.text(); } - + subElement = currentElement.firstChildElement(KVTML_FEMALE); if (!subElement.isNull()) { fem_def = subElement.text(); } - + subElement = currentElement.firstChildElement(KVTML_NEUTRAL); if (!subElement.isNull()) { nat_def = subElement.text(); } } - + currentElement = articleElement.firstChildElement(KVTML_INDEFINITE); if (!currentElement.isNull()) { @@ -597,13 +604,13 @@ bool KEduVocKvtml2Reader::readArticle(QDomElement &articleElement, int identifie { mal_indef = subElement.text(); } - + subElement = currentElement.firstChildElement(KVTML_FEMALE); if (!subElement.isNull()) { fem_indef = subElement.text(); } - + subElement = currentElement.firstChildElement(KVTML_NEUTRAL); if (!subElement.isNull()) { @@ -653,13 +660,13 @@ bool KEduVocKvtml2Reader::readConjugation(QDomElement &conjugElement, KEduVocCon QString plurthirdfemale; QString plurthirdneutral; QString type; - - QDomElement typeElement = conjugElement.firstChildElement(KVTML_TYPE); + + QDomElement typeElement = conjugElement.firstChildElement(KVTML_CONJUGATIONTYPE); if (!typeElement.isNull()) { type = typeElement.text(); } - + // TODO: add something here to link and/or store tense information QDomElement currentGroup = conjugElement.firstChildElement(KVTML_SINGULAR); @@ -670,13 +677,13 @@ bool KEduVocKvtml2Reader::readConjugation(QDomElement &conjugElement, KEduVocCon { singfirst = currentElement.text(); } - + currentElement = currentGroup.firstChildElement(KVTML_2NDPERSON); if (!currentElement.isNull()) { singsecond = currentElement.text(); } - + currentGroup = currentGroup.firstChildElement(KVTML_3RDPERSON); if (!currentGroup.isNull()) { @@ -696,20 +703,20 @@ bool KEduVocKvtml2Reader::readConjugation(QDomElement &conjugElement, KEduVocCon { singthirdmale = currentElement.text(); } - + currentElement = currentGroup.firstChildElement(KVTML_FEMALE); if (!currentElement.isNull()) { singthirdfemale = currentElement.text(); } - + currentElement = currentGroup.firstChildElement(KVTML_NEUTRAL); if (!currentElement.isNull()) { singthirdneutral = currentElement.text(); } } - + } } @@ -721,13 +728,13 @@ bool KEduVocKvtml2Reader::readConjugation(QDomElement &conjugElement, KEduVocCon { plurfirst = currentElement.text(); } - + currentElement = currentGroup.firstChildElement(KVTML_2NDPERSON); if (!currentElement.isNull()) { plursecond = currentElement.text(); } - + currentGroup = currentGroup.firstChildElement(KVTML_3RDPERSON); if (!currentGroup.isNull()) { @@ -747,23 +754,23 @@ bool KEduVocKvtml2Reader::readConjugation(QDomElement &conjugElement, KEduVocCon { plurthirdmale = currentElement.text(); } - + currentElement = currentGroup.firstChildElement(KVTML_FEMALE); if (!currentElement.isNull()) { plurthirdfemale = currentElement.text(); } - + currentElement = currentGroup.firstChildElement(KVTML_NEUTRAL); if (!currentElement.isNull()) { plurthirdneutral = currentElement.text(); } } - + } } - + curr_conjug.setPers3SingularCommon(type, s3_common); curr_conjug.setPers3PluralCommon(type, p3_common); curr_conjug.setPers1Singular(type, singfirst); @@ -782,19 +789,64 @@ bool KEduVocKvtml2Reader::readConjugation(QDomElement &conjugElement, KEduVocCon bool KEduVocKvtml2Reader::readTypes(QDomElement &typesElement) { - QStringList types; + QString mainTypeName; + + QDomElement currentTypeElement = typesElement.firstChildElement(KVTML_WORDTYPEDEFINITION); + // go over elements + while ( !currentTypeElement.isNull() ) { + // set type and specialtype + mainTypeName = + currentTypeElement.firstChildElement(KVTML_TYPENAME).text(); + m_doc->wordTypes()->addType( mainTypeName, + currentTypeElement.firstChildElement(KVTML_SPECIALWORDTYPE).text()); + + // iterate sub type elements + QDomElement currentSubTypeElement = currentTypeElement.firstChildElement(KVTML_SUBWORDTYPEDEFINITION); + while ( !currentSubTypeElement.isNull() ) { + // set type and specialtype + m_doc->wordTypes()->addSubType( mainTypeName, + currentSubTypeElement.firstChildElement(KVTML_SUBTYPENAME).text(), + currentSubTypeElement.firstChildElement(KVTML_SPECIALWORDTYPE).text()); + + + currentSubTypeElement = currentSubTypeElement.nextSiblingElement(KVTML_SUBWORDTYPEDEFINITION); + } + + - QDomNodeList typeNodes = typesElement.elementsByTagName(KVTML_TYPE); + + + currentTypeElement = currentTypeElement.nextSiblingElement(KVTML_WORDTYPEDEFINITION); + } + + + /* for (int i = 0; i < typeNodes.count(); ++i) { QDomElement currentElement = typeNodes.item(i).toElement(); if (currentElement.parentNode() == typesElement) { - types.append(currentElement.text()); + m_doc->wordTypes()->addType(currentElement.text()); } - } + }*/ + + + + - m_doc->setTypeDescriptions(types); + + +// QDomNodeList typeNodes = typesElement.elementsByTagName(KVTML_WORDTYPEDEFINITION); +// for (int i = 0; i < typeNodes.count(); ++i) +// { +// QDomElement currentElement = typeNodes.item(i).toElement(); +// if (currentElement.parentNode() == typesElement) +// { +// m_doc->wordTypes()->addType(currentElement.text()); +// } +// } + +// m_doc->setTypeDescriptions(types); return true; } @@ -854,13 +906,13 @@ bool KEduVocKvtml2Reader::readComparison(QDomElement &domElementParent, KEduVocC } currentElement = domElementParent.firstChildElement(KVTML_COMPARATIVE); - if (!currentElement.isNull()) + if (!currentElement.isNull()) { comp.setL2(currentElement.text()); } currentElement = domElementParent.firstChildElement(KVTML_SUPERLATIVE); - if (!currentElement.isNull()) + if (!currentElement.isNull()) { comp.setL3(currentElement.text()); } @@ -905,35 +957,35 @@ bool KEduVocKvtml2Reader::readGrade(QDomElement &gradeElement, KEduVocExpression m_errorMessage = i18n("identifier missing id"); return false; } - + QDomElement currentElement = gradeElement.firstChildElement(KVTML_CURRENTGRADE); if (!currentElement.isNull()) { int value = currentElement.text().toInt(); 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).setQueryCount(value); } - + currentElement = gradeElement.firstChildElement(KVTML_ERRORCOUNT); if (!currentElement.isNull()) { int value = currentElement.text().toInt(); expr.translation(index).gradeFrom(id).setBadCount(value); } - + currentElement = gradeElement.firstChildElement(KVTML_DATE); if (!currentElement.isNull()) { QDateTime value = QDateTime::fromTime_t(currentElement.text().toUInt()); expr.translation(index).gradeFrom(id).setQueryDate(value); } - + return true; } diff --git a/keduvocdocument/keduvockvtml2writer.cpp b/keduvocdocument/keduvockvtml2writer.cpp index 4730a3d..b536103 100644 --- a/keduvocdocument/keduvockvtml2writer.cpp +++ b/keduvocdocument/keduvockvtml2writer.cpp @@ -55,7 +55,7 @@ bool KEduVocKvtml2Writer::writeDoc(KEduVocDocument *doc, const QString &generato domElementKvtml.appendChild(currentElement); // types - currentElement = m_domDoc.createElement(KVTML_TYPES); + currentElement = m_domDoc.createElement(KVTML_WORDTYPEDEFINITIONS); writeTypes(currentElement); if (currentElement.hasChildNodes()) { @@ -494,13 +494,39 @@ bool KEduVocKvtml2Writer::writeArticle(QDomElement &articleElement, int article) bool KEduVocKvtml2Writer::writeTypes(QDomElement &typesElement) { + KEduVocWordType* wt = m_doc->wordTypes(); + foreach ( QString mainTypeName, wt->typeNameList() ) { +kDebug() << "Writing type: " << mainTypeName; + QDomElement typeDefinitionElement = m_domDoc.createElement(KVTML_WORDTYPEDEFINITION); + typeDefinitionElement.appendChild(newTextElement(KVTML_TYPENAME, mainTypeName)); + if ( !wt->specialType(mainTypeName).isEmpty() ) { + typeDefinitionElement.appendChild(newTextElement(KVTML_SPECIALWORDTYPE, wt->specialType(mainTypeName))); + } + + // subtypes + foreach ( QString subTypeName, wt->subTypeNameList(mainTypeName) ) { + QDomElement subTypeDefinitionElement = m_domDoc.createElement(KVTML_SUBWORDTYPEDEFINITION); + subTypeDefinitionElement.appendChild(newTextElement(KVTML_SUBTYPENAME, subTypeName)); + if ( !wt->specialSubType(mainTypeName, subTypeName).isEmpty() ) { + subTypeDefinitionElement.appendChild(newTextElement(KVTML_SPECIALWORDTYPE, wt->specialSubType(mainTypeName, subTypeName))); + } + typeDefinitionElement.appendChild(subTypeDefinitionElement); + } + typesElement.appendChild(typeDefinitionElement); + } + + + + + +/* foreach(QString type, m_doc->typeDescriptions()) { if (!(type.isNull()) ) { - typesElement.appendChild(newTextElement(KVTML_TYPE, type)); + typesElement.appendChild(newTextElement(KVTML_WORDTYPE, type)); } - } + }*/ return true; } @@ -578,10 +604,18 @@ bool KEduVocKvtml2Writer::writeTranslation(QDomElement &translationElement, KEdu // Kniebeugen translationElement.appendChild(newTextElement(KVTML_TEXT, translation.translation())); - // + // if (!translation.type().isEmpty()) { - translationElement.appendChild(newTextElement(KVTML_TYPE, translation.type())); + QDomElement wordTypeElement = m_domDoc.createElement(KVTML_WORDTYPE); + translationElement.appendChild(wordTypeElement); + //noun + wordTypeElement.appendChild(newTextElement(KVTML_TYPENAME, translation.type())); + // male + if (!translation.subType().isEmpty()) + { + wordTypeElement.appendChild(newTextElement(KVTML_SUBTYPENAME, translation.subType())); + } } // diff --git a/keduvocdocument/keduvoclesson.h b/keduvocdocument/keduvoclesson.h index 18e4f6e..4dc2179 100644 --- a/keduvocdocument/keduvoclesson.h +++ b/keduvocdocument/keduvoclesson.h @@ -32,37 +32,37 @@ class KEDUVOCDOCUMENT_EXPORT KEduVocLesson public: /** default constructor */ explicit KEduVocLesson(); - + /** copy constructor for d-pointer safe copying */ KEduVocLesson(const KEduVocLesson &other); - + /** destructor */ ~KEduVocLesson(); - + /** assignment operator */ KEduVocLesson& operator=(const KEduVocLesson&); - + /** set the lesson description - * @param description text to set for the description + * @param description text to set for the description */ void setDescription(const QString &description); - + /** get the lesson description */ QString description(); - + /** get a list of all entries in the lesson */ QList entries(); - + /** add an entry to the lesson * @param entryid id of the entry to add */ void addEntry(int entryid); - + /** remove an entry from the lesson * @param entryid id of the entry to remove */ void removeEntry(int entryid); - + private: class Private; Private * const d; diff --git a/keduvocdocument/keduvocwordtype.cpp b/keduvocdocument/keduvocwordtype.cpp new file mode 100644 index 0000000..7016179 --- /dev/null +++ b/keduvocdocument/keduvocwordtype.cpp @@ -0,0 +1,421 @@ +/*************************************************************************** + + C++ Implementation: keduvocwordtype + + ----------------------------------------------------------------------- + + begin : Mi Aug 22 2007 + + copyright : (C) 2007 Frederik Gladhorn + + ----------------------------------------------------------------------- + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "keduvocwordtype.h" + +#include + +// #define QM_VERB "v" // go +// #define QM_VERB_IRR "ir" +// #define QM_VERB_REG "re" +// #define QM_NOUN "n" // table, coffee +// #define QM_NOUN_F "f" +// #define QM_NOUN_M "m" +// #define QM_NOUN_S "s" +// #define QM_NAME "nm" +// #define QM_ART "ar" // article +// #define QM_ART_DEF "def" // definite a/an +// #define QM_ART_IND "ind" // indefinite the +// #define QM_ADJ "aj" // adjective expensive, good +// #define QM_ADV "av" // adverb today, strongly +// #define QM_PRON "pr" // pronoun you, she +// #define QM_PRON_POS "pos" // possessive my, your +// #define QM_PRON_PER "per" // personal +// #define QM_PHRASE "ph" +// #define QM_NUM "num" // numeral +// #define QM_NUM_ORD "ord" // ordinal first, second +// #define QM_NUM_CARD "crd" // cardinal one, two +// #define QM_INFORMAL "ifm" +// #define QM_FIG "fig" +// #define QM_CON "con" // conjuncton and, but +// #define QM_PREP "pre" // preposition behind, between +// #define QM_QUEST "qu" // question who, what + +// type delimiters + +// #define QM_USER_TYPE "#" // designates number of user type +// #define QM_TYPE_DIV ":" // divide main from subtype + +const QString KEduVocWordType::KVTML_1_TYPE_USER = QString("#"); +const QString KEduVocWordType::KVTML_1_TYPE_DIV = QString(":"); + + +class KEduVocWordType::Private { + +public: + struct subWordType{ + QString m_subTypeName; + QString m_specialType; + QString m_specialTypeExplanation; + }; + struct wordType{ + QString m_typeName; + QString m_specialType; + QString m_specialTypeExplanation; + QList m_subWordTypeList; + }; + + /// Map containing the word type name and its properties. + QList m_wordTypeList; +}; + + + + +KEduVocWordType::KEduVocWordType() +: d(new Private) +{ +} + +KEduVocWordType::~KEduVocWordType() +{ + delete d; +} + + +KEduVocWordType & KEduVocWordType::operator =(const KEduVocWordType & other) +{ + d->m_wordTypeList = other.d->m_wordTypeList; + return *this; +} + +KEduVocWordType::KEduVocWordType(const KEduVocWordType & other) +: d(new Private) +{ + d->m_wordTypeList = other.d->m_wordTypeList; +} + + + +/* +QString KEduVocWordType::mainTypeFromOldFormat(const QString & typeSubtypeString) const +{ + QString mainType; + int i; + + if ((i = typeSubtypeString.indexOf(KVTML_1_TYPE_DIV)) >= 0) + mainType = typeSubtypeString.left(i); + else + mainType = typeSubtypeString; + + if ( mainType.startsWith(KVTML_1_TYPE_USER) ) { + mainType.remove(0, 1); + i = mainType.toInt()-1; + if (i >= 0 && i < m_userTypeDescriptions.count()) + return m_userTypeDescriptions[i]; + else + return QString(); + } + + QString wt = m_oldMainTypeNames.value( mainType ); + if ( wt == QString() ) { + kDebug() << "Unknown old maintype: " << typeSubtypeString; + return typeSubtypeString; + } + return wt; +} + + +QString KEduVocWordType::subTypeFromOldFormat(const QString & typeSubtypeString) const +{ + int i; + QString t = typeSubtypeString; + if ((i = t.indexOf(KVTML_1_TYPE_DIV)) >= 0) { + t.remove(0, i+1); + } else { + return QString(); + } + + QString wt = m_oldSubTypeNames.value( t ); + if ( wt == QString() ) { + kDebug() << "Unknown old maintype: " << typeSubtypeString; + return typeSubtypeString; + } + return wt; +} +*/ + + +void KEduVocWordType::initOldTypeLists() +{ + m_oldMainTypeNames.clear(); + m_oldMainTypeNames.insert("v", i18n("Verb")); + m_oldMainTypeNames.insert("n", i18n("Noun")); + m_oldMainTypeNames.insert("nm", i18n("Name")); + m_oldMainTypeNames.insert("ar", i18n("Article")); + m_oldMainTypeNames.insert("aj", i18n("Adjective")); + m_oldMainTypeNames.insert("av", i18n("Adverb")); + m_oldMainTypeNames.insert("pr", i18n("Pronoun")); + m_oldMainTypeNames.insert("ph", i18n("Phrase")); + m_oldMainTypeNames.insert("num", i18n("Numeral")); + m_oldMainTypeNames.insert("con", i18n("Conjunction")); + m_oldMainTypeNames.insert("pre", i18n("Preposition")); + m_oldMainTypeNames.insert("qu", i18n("Question")); + m_oldMainTypeNames.insert("ifm", i18n("Informal")); + m_oldMainTypeNames.insert("fig", i18n("Figuratively")); + + m_oldSubTypeNames.clear(); + m_oldSubTypeNames.insert("ord", i18n("Numeral Ordinal")); + m_oldSubTypeNames.insert("crd", i18n("Numeral Cardinal")); + m_oldSubTypeNames.insert("def", i18n("Article Definite")); + m_oldSubTypeNames.insert("ind", i18n("Article Indefinite")); + m_oldSubTypeNames.insert("re", i18n("Verb Regular")); + m_oldSubTypeNames.insert("ir", i18n("Verb Irregular")); + m_oldSubTypeNames.insert("pos", i18n("Pronoun Possessive")); + m_oldSubTypeNames.insert("per", i18n("Pronoun Personal")); + m_oldSubTypeNames.insert("m", i18n("Noun Male")); + m_oldSubTypeNames.insert("f", i18n("Noun Female")); + m_oldSubTypeNames.insert("s", i18n("Noun Neutral")); + +} + +/* +QStringList KEduVocWordType::subTypeList(const QString & mainType) const +{ + return d->m_wordTypeList.value( mainType ); +} + + + +QStringList KEduVocWordType::mainTypeList() const +{ + QStringList mainTypeList = d->m_wordTypeList.keys(); + mainTypeList << m_userTypeDescriptions; + kDebug() << "m_userTypeDescriptions: " << m_userTypeDescriptions; + return mainTypeList; +} + +QString KEduVocWordType::oldType(const QString & mainType, const QString & subType) const +{ + QString oldType; + oldType = m_oldMainTypeNames.key(mainType); + if ( subType != QString() ) { + oldType.append(KVTML_1_TYPE_DIV); + oldType.append(m_oldSubTypeNames.key(subType)); + } + + if ( oldType.isEmpty() ) { + kDebug() << "Not found in preset types."; + int index = m_userTypeDescriptions.indexOf(mainType); + if ( index >= 0 ) { + kDebug() << "Found user type."; + // for some reason we count from one + oldType = KVTML_1_TYPE_USER; + oldType.append(QString::number(index + 1)); + } + } + + kDebug() << "KEduVocWordType::getOldType(): " << mainType << ", "<< subType << " gives: " << oldType; + return oldType; +} +*/ + + +void KEduVocWordType::createSampleData() +{ + //d->m_wordTypeList.clear(); + + // for now let's create some fantasy word types: + + addType("Noun", "noun", "This holds the words of type noun. You can rename it but not delete since the article training relies on it!"); + + int noun = mainTypeIndex("Noun"); + addSubType("Noun", "Male", "noun male", "This holds the words of type noun male. You can rename it but not delete since the article training relies on it!"); + + addSubType("Noun", "Female", "noun female", "This holds the words of type noun female. You can rename it but not delete since the article training relies on it!"); + + addSubType("Noun", "Neutral", "noun neutral", "This holds the words of type noun neutral. You can rename it but not delete since the article training relies on it!"); + + + addType("Verb", "verb", "This holds the words of type verb. You can rename it but not delete since the article training relies on it!"); + + addSubType("Verb", "Regular", "regular", "This holds the words of type regular verbs. You can rename it but not delete since the article training relies on it!"); + + addSubType("Verb", "Irregular", "irregular", "This holds the words of type irregular verbs. You can rename it but not delete since the article training relies on it!"); + + + addType("Adjective", "adjective", "This holds the words of type adjective. You can rename it but not delete since the article training relies on it!"); + + addType("Adverb", "adverb", "This holds the words of type adverb. You can rename it but not delete since the article training relies on it!"); + + addType("Question"); + addType("Name"); + + addType("Rot"); + addType("Blau"); + addType("Violett"); + addType("Rosa"); + addType("Gelb"); + +} + + +QString KEduVocWordType::mainTypeName(int index) const +{ + return d->m_wordTypeList[index].m_typeName; +} + +int KEduVocWordType::mainTypeIndex(const QString& name) const +{ + for ( int i=0; i < d->m_wordTypeList.count(); i++ ) { + if ( d->m_wordTypeList.value(i).m_typeName == name ) { + return i; + } + } + return -1; +} + +QStringList KEduVocWordType::typeNameList() const +{ + QStringList list; + foreach (Private::wordType wt, d->m_wordTypeList) { + list.append(wt.m_typeName); + } + return list; +} + +QStringList KEduVocWordType::subTypeNameList(const QString & mainType) const +{ + int mainIndex = mainTypeIndex( mainType ); +kDebug() << "Get subtypes for " << mainType << " = " << mainIndex; + QStringList list; + foreach (Private::subWordType wt, d->m_wordTypeList.value(mainIndex).m_subWordTypeList) { + list.append(wt.m_subTypeName); + } + return list; +} + + +void KEduVocWordType::addType(const QString & typeName, const QString & specialType, const QString & specialTypeExplanation) +{ + d->m_wordTypeList.append(Private::wordType()); + d->m_wordTypeList[d->m_wordTypeList.count()-1].m_typeName = typeName; + d->m_wordTypeList[d->m_wordTypeList.count()-1].m_specialType = specialType; + d->m_wordTypeList[d->m_wordTypeList.count()-1].m_specialTypeExplanation = specialTypeExplanation; +} + +void KEduVocWordType::addSubType(const QString & mainType, const QString & typeName, const QString & specialType, const QString & specialTypeExplanation) +{ + int mt = mainTypeIndex(mainType); + + d->m_wordTypeList[mt].m_subWordTypeList.append(Private::subWordType()); + + d->m_wordTypeList[mt].m_subWordTypeList[d->m_wordTypeList[mt].m_subWordTypeList.count()-1].m_subTypeName = typeName; + d->m_wordTypeList[mt].m_subWordTypeList[d->m_wordTypeList[mt].m_subWordTypeList.count()-1].m_specialType = specialType; + d->m_wordTypeList[mt].m_subWordTypeList[d->m_wordTypeList[mt].m_subWordTypeList.count()-1].m_specialTypeExplanation = specialTypeExplanation; +} + +void KEduVocWordType::renameType(const QString & oldTypeName, const QString & newTypeName) +{ + int index = mainTypeIndex( oldTypeName ); + d->m_wordTypeList[index].m_typeName= newTypeName; +} + +void KEduVocWordType::renameSubType(const QString & mainTypeName, const QString & oldTypeName, const QString & newTypeName) +{ +kDebug() << "Rename subtype: " << mainTypeName << oldTypeName << newTypeName; + int mainIndex = mainTypeIndex( mainTypeName ); + if (mainIndex < 0) { + kDebug() << "Renaming of subtype faild - parent not found"; + return; + } + int subIndex = subTypeIndex( mainTypeName, oldTypeName ); + if (subIndex < 0) { + kDebug() << "Renaming of subtype faild - old subtype not found"; + return; + } + + d->m_wordTypeList[mainIndex].m_subWordTypeList[subIndex].m_subTypeName= newTypeName; +} + +bool KEduVocWordType::removeType(const QString & typeName) +{ + // only if NOT special type + int index = mainTypeIndex( typeName ); + if ( d->m_wordTypeList[index].m_specialType.isEmpty() ) { + d->m_wordTypeList.removeAt( index ); + return true; + } + return false; +} + +bool KEduVocWordType::removeSubType(const QString & mainTypeName, const QString & typeName) +{ + kDebug() << " delete subtype: " << mainTypeName << "/" << typeName; + // only if NOT special type + int mainIndex = mainTypeIndex( mainTypeName ); + int subIndex = subTypeIndex( mainTypeName, typeName ); + kDebug() << "Index: " << mainIndex << "/" << subIndex; + if ( d->m_wordTypeList[mainIndex].m_subWordTypeList[subIndex].m_specialType.isEmpty() ) { + d->m_wordTypeList[mainIndex].m_subWordTypeList.removeAt( subIndex ); + return true; + } + return false; +} + +int KEduVocWordType::subTypeIndex(const QString & mainTypeName, const QString & subTypeName) const +{ + int main = mainTypeIndex( mainTypeName ); + if ( main < 0 ) { + kDebug() << "Main word type not found (" << mainTypeName << ")"; + return -1; + } + for ( int i=0; i < d->m_wordTypeList[main].m_subWordTypeList.count(); i++ ) { + if ( d->m_wordTypeList[main].m_subWordTypeList.value(i).m_subTypeName == subTypeName ) { + return i; + } + } + return -1; +} + +void KEduVocWordType::printDebugWordTypes() +{ + foreach ( Private::wordType wt, d->m_wordTypeList ) { + kDebug() << wt.m_typeName; + foreach ( Private::subWordType swt, wt.m_subWordTypeList ) { + kDebug() << " " << swt.m_subTypeName; + } + } +} + +QString KEduVocWordType::specialType(const QString & typeName) +{ + int index = mainTypeIndex( typeName ); + if (index >= 0) { + return d->m_wordTypeList[index].m_specialType; + } + return QString(); +} + +QString KEduVocWordType::specialSubType(const QString & mainTypeName, const QString & subTypeName) +{ + int mainIndex = mainTypeIndex( mainTypeName ); + if (mainIndex >= 0) { + int subIndex = subTypeIndex( mainTypeName, subTypeName ); + if (subIndex >= 0) { + return d->m_wordTypeList[mainIndex].m_subWordTypeList[subIndex].m_specialType; + } + } + return QString(); +} + diff --git a/keduvocdocument/keduvocwordtype.h b/keduvocdocument/keduvocwordtype.h new file mode 100644 index 0000000..99a4d5d --- /dev/null +++ b/keduvocdocument/keduvocwordtype.h @@ -0,0 +1,131 @@ +/*************************************************************************** + + C++ Interface: keduvocwordtype + + ----------------------------------------------------------------------- + + begin : Mi Aug 22 2007 + + copyright : (C) 2007 Frederik Gladhorn + + ----------------------------------------------------------------------- + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KEDUVOCWORDTYPE_H +#define KEDUVOCWORDTYPE_H + +#include "libkeduvocdocument_export.h" + +#include +#include + +/** + Word type handling including subtypes (noun - male/female) etc. + Special types: To let KVocTrain decide which word type is a verb for example the + special tag is used. + @author Frederik Gladhorn +*/ +class KEDUVOCDOCUMENT_EXPORT KEduVocWordType { + +public: + /** default constructor */ + explicit KEduVocWordType(); + + /** copy constructor for d-pointer safe copying */ + KEduVocWordType(const KEduVocWordType& other); + + /** destructor */ + ~KEduVocWordType(); + + /** assignment operator */ + KEduVocWordType& operator=(const KEduVocWordType& other); + + /** will be gone when we have it inside the lib */ +// void setDocument(KEduVocDocument *doc); + void createSampleData(); + + + /** + * Create a new word type in the list of known types + * @param typeName Name of the word type + * @param specialType Name of the special type - this is used internally to identify which types are use for special queries - verb query needs special == "verb" for example. + * @param specialTypeExplanation An explanation which can be shown to the user. Since the type can be renamed if it's special, but not deleted this is necessary. + */ + void addType(const QString& typeName, const QString& specialType = QString(), const QString& specialTypeExplanation = QString()); + + + /** + * Same as above but for a sub word type (male/female/nutral for noun for example) + * @param mainType The word type to which the subtype belongs. + * @param typeName Sub type name + * @param specialType See above + * @param specialTypeExplanation See above + */ + void addSubType(const QString& mainType, const QString& typeName, const QString& specialType = QString(), const QString& specialTypeExplanation = QString()); + + QStringList typeNameList() const; + QStringList subTypeNameList(const QString& mainType) const; + + +//should we rather use strings instead of index below? yes probably... + + void renameType( const QString& oldTypeName, const QString& newTypeName); + void renameSubType( const QString& mainTypeName, const QString& oldTypeName, const QString& newTypeName); + + bool removeType( const QString& typeName ); + bool removeSubType( const QString& mainTypeName, const QString& typeName ); + + /** + * Get the special type, if any. + * @param typeName Name whos special type is requested + * @return the special type or an empty string. + */ + QString specialType( const QString& typeName ); + /** + * Same as above for a subtype + * @param typeName Main type name + * @param typeName Sub type name + * @return the special type or an empty string. + */ + QString specialSubType( const QString& mainTypeName, const QString& subTypeName ); + + void printDebugWordTypes(); + +private: + static const QString KVTML_1_TYPE_USER; + static const QString KVTML_1_TYPE_DIV; + + void initOldTypeLists(); + + + /// user defined types of old documents + QStringList m_userTypeDescriptions; + + QMap m_oldMainTypeNames; + QMap m_oldSubTypeNames; + + + + QString mainTypeName(int index) const; + int mainTypeIndex(const QString& name) const; + int subTypeIndex( const QString& mainTypeName, const QString& subTypeName ) const; + + QString mainTypeFromOldFormat(const QString& typeSubtypeString) const; + QString subTypeFromOldFormat(const QString& typeSubtypeString) const; + QString oldType(const QString& mainType, const QString& subType) const; + + class Private; + Private * const d; +}; + +#endif diff --git a/keduvocdocument/kvtml2.dtd b/keduvocdocument/kvtml2.dtd index 6e6d46f..8c69da9 100644 --- a/keduvocdocument/kvtml2.dtd +++ b/keduvocdocument/kvtml2.dtd @@ -1,4 +1,4 @@ - + @@ -30,12 +30,14 @@ - - - - - - + + + + + + + + @@ -55,7 +57,7 @@ - + diff --git a/keduvocdocument/kvtml2defs.h b/keduvocdocument/kvtml2defs.h index f2e3fe2..0bcd529 100644 --- a/keduvocdocument/kvtml2defs.h +++ b/keduvocdocument/kvtml2defs.h @@ -30,17 +30,24 @@ #define KVTML_IDENTIFIERS "identifiers" #define KVTML_IDENTIFIER "identifier" -#define KVTML_TYPE "type" +#define KVTML_IDENTIFIERTYPE "identifiertype" #define KVTML_LOCALE "locale" #define KVTML_NAME "name" #define KVTML_SIZEHINT "sizehint" + +// articles #define KVTML_ARTICLE "article" #define KVTML_DEFINITE "definite" #define KVTML_INDEFINITE "indefinite" + +// conjugation and personal pronouns +#define KVTML_CONJUGATION "conjugation" +#define KVTML_CONJUGATIONTYPE "conjugationtype" +#define KVTML_PERSONALPRONOUNS "personalpronouns" + #define KVTML_MALE "male" #define KVTML_FEMALE "female" #define KVTML_NEUTRAL "neutral" -#define KVTML_PERSONALPRONOUNS "personalpronouns" #define KVTML_SINGULAR "singular" #define KVTML_PLURAL "plural" #define KVTML_1STPERSON "firstperson" @@ -48,9 +55,15 @@ #define KVTML_3RDPERSON "thirdperson" #define KVTML_COMMON "common" -#define KVTML_CONJUGATION "conjugation" +// word types +#define KVTML_WORDTYPEDEFINITIONS "wordtypedefinitions" +#define KVTML_WORDTYPEDEFINITION "wordtypedefinition" +#define KVTML_SUBWORDTYPEDEFINITION "subwordtypedefinition" -#define KVTML_TYPES "types" +#define KVTML_WORDTYPE "wordtype" +#define KVTML_TYPENAME "typename" +#define KVTML_SUBTYPENAME "subtypename" +#define KVTML_SPECIALWORDTYPE "specialwordtype" #define KVTML_TENSES "tenses" #define KVTML_TENSE "tense" @@ -98,7 +111,7 @@ #define KVTML_DATE "date" #define KVTML_TRUE "true" -#define KVTML_FALSE "false" +#define KVTML_FALSE "false" #endif -- 2.47.3