diff --git a/keduvocdocument/keduvoccontainermimedata.h b/keduvocdocument/keduvoccontainermimedata.h index 4ccbd66..c0fa1e3 100644 --- a/keduvocdocument/keduvoccontainermimedata.h +++ b/keduvocdocument/keduvoccontainermimedata.h @@ -1,43 +1,43 @@ /*************************************************************************** Copyright 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 KEDUVOCCONTAINERMIMEDATA_H #define KEDUVOCCONTAINERMIMEDATA_H -#include "keduvoccontainer.h" +#include #include class KEduVocContainer; class KEDUVOCDOCUMENT_EXPORT KEduVocContainerMimeData : public QMimeData { Q_OBJECT public: void addContainer(KEduVocContainer* container); QList containerList() const; KEduVocContainerMimeData(); ~KEduVocContainerMimeData(); private: class Private; Private * const d; }; #endif diff --git a/keduvocdocument/keduvoccontainermodel.cpp b/keduvocdocument/keduvoccontainermodel.cpp index f9f5943..8ac57c7 100644 --- a/keduvocdocument/keduvoccontainermodel.cpp +++ b/keduvocdocument/keduvoccontainermodel.cpp @@ -1,341 +1,341 @@ /*************************************************************************** Copyright 2007-2008 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 "keduvoccontainermodel.h" -#include "keduvoccontainer.h" +#include -#include "keduvoccontainermimedata.h" -#include "keduvocvocabularymimedata.h" +#include +#include #include #include #include #include #include #include /** @file * Implementation of ContainerModel. * Functions to create the model from the lessons of the vocabulary document. */ KEduVocContainerModel::KEduVocContainerModel(KEduVocContainer::EnumContainerType type, QObject * parent) : KEduVocReadonlyContainerModel(type, parent) , d(0) { } KEduVocContainerModel::~KEduVocContainerModel() { delete d; } QModelIndex KEduVocContainerModel::appendContainer(const QModelIndex& parent, const QString & containerName) { KEduVocContainer* parentContainer; if (parent.isValid()) { parentContainer = static_cast(parent.internalPointer()); } else { return QModelIndex(); } beginInsertRows(parent, parentContainer->childContainerCount(), parentContainer->childContainerCount()); switch (containerType()) { case (KEduVocContainer::Lesson): parentContainer->appendChildContainer(new KEduVocLesson(containerName, static_cast(parentContainer))); break; case (KEduVocContainer::WordType): { KEduVocWordType* parentWordType = static_cast(parentContainer); KEduVocWordType* wordTypeContainer = new KEduVocWordType(containerName, parentWordType); wordTypeContainer->setWordType(parentWordType->wordType()); parentContainer->appendChildContainer(wordTypeContainer); break; } default: break; } endInsertRows(); return index(parentContainer->childContainerCount() - 1, 0, parent); } QVariant KEduVocContainerModel::data(const QModelIndex & index, int role) const { if (!index.isValid()) { return QVariant(); } KEduVocContainer *container = static_cast(index.internalPointer()); switch (index.column()) { case ContainerNameColumn: if (role == Qt::DisplayRole || role == Qt::EditRole) { return container->name(); } if (role == Qt::TextAlignmentRole) { return Qt::AlignLeft; } break; case TotalCountColumn: if (role == Qt::DisplayRole) { return container->entryCount(KEduVocContainer::Recursive); } if (role == Qt::TextAlignmentRole) { return Qt::AlignRight; } break; default: if (role == Qt::TextAlignmentRole) { return Qt::AlignRight; } } return QVariant(); } bool KEduVocContainerModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (!index.isValid()) { return false; } if (index.column() == ContainerNameColumn) { KEduVocContainer *container = static_cast(index.internalPointer()); // rename a lesson if (role == Qt::EditRole) { container->setName(value.toString()); emit dataChanged(index, index); emit documentModified(); return true; } // checkboxes if (role == Qt::CheckStateRole) { bool newState = value.toBool(); for (int i = 0; i < rowCount(index); i++) { setData(index.child(i, 0), newState, Qt::CheckStateRole); } container->setInPractice(newState); emit dataChanged(index, index); emit documentModified(); return true; } } return false; } Qt::ItemFlags KEduVocContainerModel::flags(const QModelIndex &index) const { if (index.isValid()) { // the root element, not editable for now if (index.parent() == QModelIndex()) { return (Qt::ItemIsEnabled | Qt::ItemIsSelectable); } // the name column if (index.column() == ContainerNameColumn) { return (Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled); } else { // every other element return (Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled); } } return Qt::ItemIsDropEnabled; } QVariant KEduVocContainerModel::headerData(int section, Qt::Orientation orientation, int role) const { // statically two columns for now if (orientation == Qt::Horizontal) { switch (section) { case ContainerNameColumn: if (role == Qt::DisplayRole) { return i18n("Unit"); } break; case TotalCountColumn: if (role == Qt::DisplayRole) { return QVariant(); } if (role == Qt::ToolTipRole) { return i18n("Number of entries in this lesson."); } break; } } return QVariant(); } int KEduVocContainerModel::columnCount(const QModelIndex & parent) const { Q_UNUSED(parent); if (!document()) { return FirstDataColumn; } // for now one grade per language return FirstDataColumn; } void KEduVocContainerModel::deleteContainer(const QModelIndex & containerIndex) { KEduVocContainer* container = static_cast(containerIndex.internalPointer()); KEduVocContainer* parent = container->parent(); if (!parent) { // never delete the root container return; } beginRemoveRows(containerIndex.parent(), containerIndex.row(), containerIndex.row()); parent->deleteChildContainer(container->row()); endRemoveRows(); } Qt::DropActions KEduVocContainerModel::supportedDropActions() const { return Qt::MoveAction | Qt::CopyAction; } QStringList KEduVocContainerModel::mimeTypes() const { return QStringList() << "text/plain"; } QMimeData * KEduVocContainerModel::mimeData(const QModelIndexList &indexes) const { KEduVocContainerMimeData *mimeData = new KEduVocContainerMimeData(); foreach(const QModelIndex & index, indexes) { mimeData->addContainer(static_cast(index.internalPointer())); } mimeData->setText("Lesson"); return mimeData; } bool KEduVocContainerModel::dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) { Q_UNUSED(column) if (action == Qt::IgnoreAction) { return true; } // if it's internal, get the pointers const KEduVocContainerMimeData * containerData = qobject_cast(data); if (containerData) { foreach(KEduVocContainer * container, containerData->containerList()) { // no way to move a word type to a lesson for now if (container->containerType() != containerType()) { return false; } if (action == Qt::MoveAction || action == Qt::CopyAction) { //qDebug() << "Move container: " << container->name(); KEduVocContainer* parentContainer = 0; if (parent.isValid()) { parentContainer = static_cast(parent.internalPointer()); } if (!parentContainer) { // drop into root parentContainer = rootContainer(); } else { //make sure a container cannot be dropped into one of its child containers! KEduVocContainer* childTest = parentContainer; while (childTest != 0) { if (childTest == container) { //qDebug() << "Cannot drop a container into one of its child containers!"; return false; } childTest = childTest->parent(); } } QModelIndex oldParent = index(container->parent()); beginRemoveRows(oldParent, container->row(), container->row()); container->parent()->removeChildContainer(container->row()); endRemoveRows(); // if we get to choose, append seems sane. if (row < 0) { row = parentContainer->childContainerCount(); } // use index because we sometimes reparent to the root container instead of dropping into nowhere beginInsertRows(index(parentContainer), row, row); parentContainer->insertChildContainer(row, container); endInsertRows(); return true; } } } // if it's a translation, get the pointers const KEduVocVocabularyMimeData * translationData = qobject_cast(data); if (translationData) { if (!parent.isValid()) { return false; } if (containerType() == KEduVocContainer::Lesson) { // Create a list of the entries associated with the translations being copied. This prevents duplicates if they highlighted several columns. QList entries; foreach(KEduVocTranslation * translation, translationData->translationList()) { if (!entries.contains(translation->entry())) { entries << translation->entry(); } } foreach(KEduVocExpression * entry, entries) { static_cast(parent.internalPointer())->appendEntry(new KEduVocExpression(*entry)); } } if (containerType() == KEduVocContainer::WordType) { foreach(KEduVocTranslation * translation, translationData->translationList()) { translation->setWordType( static_cast(parent.internalPointer())); } } return false; } // qDebug() << data->formats(); return false; } Qt::DropActions KEduVocContainerModel::supportedDragActions() const { return (Qt::CopyAction | Qt::MoveAction); } \ No newline at end of file diff --git a/keduvocdocument/keduvoccontainermodel.h b/keduvocdocument/keduvoccontainermodel.h index 043e814..fee355b 100644 --- a/keduvocdocument/keduvoccontainermodel.h +++ b/keduvocdocument/keduvoccontainermodel.h @@ -1,87 +1,87 @@ /*************************************************************************** Copyright 2007-2008 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 KEDUVOCCONTAINERMODEL_H #define KEDUVOCCONTAINERMODEL_H -#include "keduvocreadonlycontainermodel.h" +#include #include #include #include #include #include /** * Model for the tree of containers (lessons, word types). */ class KEDUVOCDOCUMENT_EXPORT KEduVocContainerModel : public KEduVocReadonlyContainerModel { Q_OBJECT public: enum ColumnType { ContainerNameColumn = 0, TotalCountColumn, FirstDataColumn }; explicit KEduVocContainerModel(KEduVocContainer::EnumContainerType type, QObject *parent = 0); ~KEduVocContainerModel(); virtual QVariant data(const QModelIndex &index, int role) const; virtual Qt::ItemFlags flags(const QModelIndex &index) const; virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; virtual Qt::DropActions supportedDropActions() const; virtual QStringList mimeTypes() const; virtual QMimeData * mimeData(const QModelIndexList &indexes) const; virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); /** Change the name or checkbox of a lesson. * @param index which lesson * @param value new name * @param role * @return bool @c true it worked */ virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); QModelIndex appendContainer(const QModelIndex& parent, const QString & containerName = QString()); void deleteContainer(const QModelIndex& containerIndex); /** Indicate supported drag actions @return enum of actions supported **/ virtual Qt::DropActions supportedDragActions() const ; signals: /** * emitted when the inPractice state or name of a lesson changed. */ void documentModified(); private: class Private; Private * const d; }; #endif diff --git a/keduvocdocument/keduvoclessonmodel.h b/keduvocdocument/keduvoclessonmodel.h index b316e4e..6d6848e 100644 --- a/keduvocdocument/keduvoclessonmodel.h +++ b/keduvocdocument/keduvoclessonmodel.h @@ -1,60 +1,60 @@ /*************************************************************************** Copyright 2008-2009 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 KEDUVOCLESSONMODEL_H #define KEDUVOCLESSONMODEL_H -#include "keduvoccontainermodel.h" +#include /** * Model for the tree of lessons. */ class KEDUVOCDOCUMENT_EXPORT KEduVocLessonModel : public KEduVocContainerModel { Q_OBJECT public: /** When splitting a lesson into smaller ones - how to sort the entries into lessons.*/ enum SplitLessonOrder { Sorted, /**< The order of the entries in the document */ Random /**< Randomized */ }; explicit KEduVocLessonModel(QObject *parent = 0); ~KEduVocLessonModel(); virtual Qt::ItemFlags flags(const QModelIndex &index) const; virtual QVariant data(const QModelIndex &index, int role) const; virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); /** * Divide a lesson into smaller ones. * Tip: If you create a lesson that is >= the original one and use random order, you get your lesson reshuffled. Maybe that is sometimes useful. For now the lessons are appended at the end. * @param lessonIndex lesson to split * @param entriesPerLesson number of entries in each new lesson * @param order one of SplitLessonOrder */ void splitLesson(const QModelIndex& containerIndex, int entriesPerLesson, SplitLessonOrder order); protected: KEduVocContainer * rootContainer() const; private: class Private; Private * const d; }; #endif diff --git a/keduvocdocument/keduvocreadonlycontainermodel.cpp b/keduvocdocument/keduvocreadonlycontainermodel.cpp index d4372a7..aa7c9a5 100644 --- a/keduvocdocument/keduvocreadonlycontainermodel.cpp +++ b/keduvocdocument/keduvocreadonlycontainermodel.cpp @@ -1,212 +1,212 @@ /*************************************************************************** Copyright 2007-2008 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 "keduvocreadonlycontainermodel.h" #include #include -#include "keduvoccontainermimedata.h" -#include "keduvocvocabularymimedata.h" +#include +#include #include #include #include #include class KEduVocReadonlyContainerModel::Private { public: KEduVocContainer::EnumContainerType m_type; KEduVocDocument *m_doc; Private(KEduVocContainer::EnumContainerType type); }; KEduVocReadonlyContainerModel::Private::Private(KEduVocContainer::EnumContainerType type) : m_type(type) , m_doc(0) { } /** @file * Implementation of ReadonlyContainerModel. * Functions to create the model from the lessons of the vocabulary document. */ KEduVocReadonlyContainerModel::KEduVocReadonlyContainerModel(KEduVocContainer::EnumContainerType type, QObject * parent) : QAbstractItemModel( parent ) , d( new Private( type )) { } KEduVocReadonlyContainerModel::~KEduVocReadonlyContainerModel() { delete d; } KEduVocContainer::EnumContainerType KEduVocReadonlyContainerModel::containerType() const { return d->m_type; } KEduVocDocument* KEduVocReadonlyContainerModel::document() const { return d->m_doc; } void KEduVocReadonlyContainerModel::setDocument(KEduVocDocument * doc) { beginResetModel(); d->m_doc = doc; if (d->m_doc) { //qDebug() << "Set Document: " << d->m_doc->url(); } else { //qDebug() << "Set Invalid Document"; } endResetModel(); } QModelIndex KEduVocReadonlyContainerModel::index(int row, int column, const QModelIndex &parent) const { if (!d->m_doc || !hasIndex(row, column, parent)) { return QModelIndex(); } KEduVocContainer *parentContainer; if (!parent.isValid()) { parentContainer = 0; } else { parentContainer = static_cast(parent.internalPointer()); } KEduVocContainer *childContainer = 0; if (!parentContainer) { childContainer = rootContainer(); if (!childContainer) { return QModelIndex(); } } else { childContainer = parentContainer->childContainer(row); } return createIndex(row, column, childContainer); } QModelIndex KEduVocReadonlyContainerModel::index(KEduVocContainer * container) const { if (!container) { return QModelIndex(); } QModelIndex currentIndex = index(container->row(), 0, index(container->parent())); Q_ASSERT(container == currentIndex.internalPointer()); return currentIndex; } QModelIndex KEduVocReadonlyContainerModel::parent(const QModelIndex &index) const { if (!index.isValid()) { return QModelIndex(); } KEduVocContainer *childItem = static_cast(index.internalPointer()); if (!childItem) { return QModelIndex(); } KEduVocContainer *parentItem = childItem->parent(); if (!parentItem) { return QModelIndex(); } QModelIndex parentIndex = createIndex(parentItem->row(), 0, parentItem); return parentIndex; } int KEduVocReadonlyContainerModel::rowCount(const QModelIndex &parent) const { if (parent.column() > 0) { return 0; } KEduVocContainer *parentItem; if (!parent.isValid()) { // root element if (!d->m_doc) { return 0; } return 1; } else { parentItem = static_cast(parent.internalPointer()); return parentItem->childContainerCount(); } } QVariant KEduVocReadonlyContainerModel::data(const QModelIndex & index, int role) const { if (!index.isValid()) { return QVariant(); } KEduVocContainer *container = static_cast(index.internalPointer()); switch (index.column()) { case 0: // Container name if (role == Qt::DisplayRole || role == Qt::EditRole) { if (index.parent() == QModelIndex()) { return i18n("None"); } return container->name(); } if (role == Qt::TextAlignmentRole) { return Qt::AlignLeft; } break; } return QVariant(); } Qt::ItemFlags KEduVocReadonlyContainerModel::flags(const QModelIndex &index) const { if (index.isValid()) { // the root element, not editable for now if (index.parent() == QModelIndex()) { return (Qt::ItemIsEnabled | Qt::ItemIsSelectable); } // the name column if (index.column() == 0) { return (Qt::ItemIsEnabled | Qt::ItemIsSelectable); } else { // every other element return (Qt::ItemIsEnabled | Qt::ItemIsSelectable); } } return 0; } int KEduVocReadonlyContainerModel::columnCount(const QModelIndex & parent) const { Q_UNUSED(parent); if (!d->m_doc) { return 1; } return 1; } \ No newline at end of file diff --git a/keduvocdocument/keduvocvocabularymimedata.cpp b/keduvocdocument/keduvocvocabularymimedata.cpp index 789ccf6..3ca5df6 100644 --- a/keduvocdocument/keduvocvocabularymimedata.cpp +++ b/keduvocdocument/keduvocvocabularymimedata.cpp @@ -1,110 +1,110 @@ /*************************************************************************** Copyright 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 "keduvocvocabularymimedata.h" -#include "keduvoctranslation.h" -#include "keduvocwordtype.h" +#include +#include class KEduVocVocabularyMimeData::Private { public: QList m_translations; QList m_expressions; QString m_text; }; KEduVocVocabularyMimeData::KEduVocVocabularyMimeData() : d( new Private ) { } KEduVocVocabularyMimeData::~KEduVocVocabularyMimeData() { delete d; } void KEduVocVocabularyMimeData::setTranslations(QList translations) { // list of pointers for drag and drop - for example to assign word types d->m_translations = translations; // sort the translations into entries to make deep copies for real copy and paste // to only include each expression once QList expressions; foreach(KEduVocTranslation * translation, d->m_translations) { if (!expressions.contains(translation->entry())) { expressions.append(translation->entry()); } } foreach(KEduVocExpression * expression, expressions) { MimeExpression exp; // deep copy exp.expression = KEduVocExpression(*expression); // copy word types // this sucks but there is not really a better was. copying pointers is not a good idea because copy and paste can be done between different documents. foreach(int i, expression->translationIndices()) { // generate text string representation d->m_text.append(expression->translation(i)->text()); d->m_text.append(" - "); // fill in word types independent of pointers KEduVocWordType *type = expression->translation(i)->wordType(); if (type) { // check if it has a type != 0 exp.wordTypes[i].grammarType = expression->translation(i)->wordType()->wordType(); // this may seem weird, but the root element is "word types" so no need to copy that one. while (type->parent()) { exp.wordTypes[i].wordType.prepend(type->name()); type = static_cast(type->parent()); } } } d->m_expressions.append(exp); d->m_text.append('\n'); } } QList< KEduVocTranslation * > KEduVocVocabularyMimeData::translationList() const { return d->m_translations; } QVariant KEduVocVocabularyMimeData::retrieveData(const QString & mimeType, QVariant::Type type) const { Q_UNUSED(type) // only use the expression list.expressions // the translation list may be invalid (eg when cut it is no longer valid. // translations can only be used internally for drag and drop!!! if (mimeType == "text/plain") { return d->m_text; } return QVariant(); } QStringList KEduVocVocabularyMimeData::formats() const { return QStringList() << "text/plain"; } QList< KEduVocVocabularyMimeData::MimeExpression > KEduVocVocabularyMimeData::expressionList() const { return d->m_expressions; } diff --git a/keduvocdocument/keduvocvocabularymodel.cpp b/keduvocdocument/keduvocvocabularymodel.cpp index 8844750..1a694f2 100644 --- a/keduvocdocument/keduvocvocabularymodel.cpp +++ b/keduvocdocument/keduvocvocabularymodel.cpp @@ -1,421 +1,421 @@ /*************************************************************************** Copyright 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 "keduvocvocabularymodel.h" #include #include -#include "keduvocvocabularymimedata.h" -#include "keduvocdocument.h" +#include +#include #include #include #include #include #include #include #include class KEduVocVocabularyModel::Private { public: Private(); KEduVocContainer *m_container; KEduVocLesson *m_lesson; KEduVocDocument *m_document; KEduVocContainer::EnumEntriesRecursive m_recursive; // stores the font-type for each language as specified by the application QHash m_fontList; }; KEduVocVocabularyModel::Private::Private() { m_container = 0; m_document = 0; m_lesson = 0; } KEduVocVocabularyModel::KEduVocVocabularyModel(bool show, QObject *parent) : QAbstractTableModel(parent), d( new Private ) { setRecursive(show); qRegisterMetaType("KEduVocTranslationPointer"); } KEduVocVocabularyModel::~KEduVocVocabularyModel() { delete d; } void KEduVocVocabularyModel::setDocument(KEduVocDocument * doc) { d->m_document = doc; beginResetModel(); if (d->m_document) { showContainer(d->m_document->lesson()); } else { showContainer(0); } endResetModel(); } void KEduVocVocabularyModel::showContainer(KEduVocContainer * container) { // use remove and insert rows. using reset resets all table headers too. if (rowCount(QModelIndex()) > 0) { beginRemoveRows(QModelIndex(), 0, rowCount(QModelIndex()) - 1); d->m_container = 0; endRemoveRows(); } if (container) { if (container->entryCount(d->m_recursive) > 0) { beginInsertRows(QModelIndex(), 0, container->entryCount(d->m_recursive) - 1); d->m_container = container; endInsertRows(); } else { d->m_container = container; } } } void KEduVocVocabularyModel::setLesson(KEduVocLesson * lessonContainer) { d->m_lesson = lessonContainer; } KEduVocLesson * KEduVocVocabularyModel::lesson() { return d->m_lesson; } KEduVocContainer::EnumEntriesRecursive KEduVocVocabularyModel::recursive() { return d->m_recursive; } int KEduVocVocabularyModel::rowCount(const QModelIndex &index) const { // no lesson set - zarro rows if (!d->m_container) { return 0; } // only the root index has children because we have no hierarchical model. if (index == QModelIndex()) { return d->m_container->entryCount(d->m_recursive); } return 0; } int KEduVocVocabularyModel::columnCount(const QModelIndex &) const { if (!d->m_document) { return 0; } return d->m_document->identifierCount() * EntryColumnsMAX; } QFont KEduVocVocabularyModel::font(int translation) const { return d->m_fontList[translation]; } void KEduVocVocabularyModel::setFont(QFont & font, int translation) { d->m_fontList[translation] = font; emit dataChanged(createIndex(translation, translation), createIndex(translation, translation)); } QVariant KEduVocVocabularyModel::data(const QModelIndex & index, int role) const { if (!d->m_document || !d->m_container) { return QVariant(); } int translationId = translation(index.column()); int entryColumn = columnType(index.column()); switch (role) { case Qt::DisplayRole: switch (entryColumn) { case Translation: return QVariant(d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->text()); case Pronunciation: return QVariant(d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->pronunciation()); case WordClass: // if no word type is set, we get a null pointer if (d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->wordType()) { return QVariant(d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->wordType()->name()); } return QVariant(QString()); case Synonym: { QStringList displayElements; foreach(KEduVocTranslation * synonym, d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->synonyms()) { displayElements.append(synonym->text()); } return QVariant(displayElements.join("; ")); } case Antonym: { QStringList displayElements; foreach(KEduVocTranslation * antonym, d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->antonyms()) { displayElements.append(antonym->text()); } return QVariant(displayElements.join("; ")); } case Example: { QString example = d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->example(); return QVariant(example); } case Comment: return QVariant(d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->comment()); case Paraphrase: return QVariant(d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->paraphrase()); default: return QVariant(); } break; case Qt::FontRole: if (entryColumn == Translation) { if( d->m_fontList.contains(translationId) ) return QVariant( d->m_fontList[translationId] ); return QFont(); } return QVariant(); case LocaleRole: return QVariant(d->m_document->identifier(translationId).locale()); case AudioRole: return QVariant(d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->soundUrl()); case ImageRole: return QVariant(d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->imageUrl()); case EntryRole: { QVariant v; v.setValue(d->m_container->entry(index.row(), d->m_recursive)); return v; } case Qt::ToolTipRole: { ///@todo more tooltips? switch (entryColumn) { case WordClass: return i18n("You can drag and drop words onto their word type."); case Synonym: return i18n("Enable the synonym view to edit synonyms."); case Antonym: return i18n("Enable the antonym view to edit antonyms."); } } } return QVariant(); } bool KEduVocVocabularyModel::setData(const QModelIndex &index, const QVariant &value, int role) { if ((!index.isValid()) || (role != Qt::EditRole)) { return false; } int translationId = translation(index.column()); int column = columnType(index.column()); switch (column) { case Translation: d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->setText(value.toString()); break; case Pronunciation: d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->setPronunciation(value.toString()); break; case WordClass: break; case Example: d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->setExample(value.toString()); break; case Comment: d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->setComment(value.toString()); break; case Paraphrase: d->m_container->entry(index.row(), d->m_recursive)->translation(translationId)->setParaphrase(value.toString()); break; default: return false; } emit(dataChanged(index, index)); ///@todo trust dirty bit d->m_document->setModified(); return true; } Qt::ItemFlags KEduVocVocabularyModel::flags(const QModelIndex & index) const { if (!index.isValid()) { return Qt::ItemIsDropEnabled; } switch (columnType(index.column())) { case Translation: return QAbstractItemModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; case WordClass: return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; case Synonym: case Antonym: return QAbstractItemModel::flags(index) | Qt::ItemIsDropEnabled; default: return QAbstractItemModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsDropEnabled; } } QVariant KEduVocVocabularyModel::headerData(int section, Qt::Orientation orientation, int role) const { if (!d->m_document) { return QVariant(); } if (orientation == Qt::Horizontal) { int translationId = section / EntryColumnsMAX; int entryColumn = section % EntryColumnsMAX; switch (role) { case Qt::DisplayRole: return KEduVocVocabularyModel::columnTitle(d->m_document, translationId, entryColumn); break; } // switch role } // if horizontal return QVariant(); } QString KEduVocVocabularyModel::columnTitle(KEduVocDocument *document, int translation, int column) { switch (column) { case Translation: if (document->identifierCount() - 1 < translation) { return QString(); } return document->identifier(translation).name(); //returns "English", "German", etc case Pronunciation: return i18n("Pronunciation"); case WordClass: return i18n("Word Type"); case Synonym: return i18n("Synonym"); case Antonym: return i18n("Antonym"); case Example: return i18n("Example"); case Comment: return i18n("Comment"); case Paraphrase: return i18n("Paraphrase"); } return QString(); } int KEduVocVocabularyModel::translation(int column) { return column / EntryColumnsMAX; } int KEduVocVocabularyModel::columnType(int column) { return column % EntryColumnsMAX; } QModelIndex KEduVocVocabularyModel::appendEntry(KEduVocExpression *expression) { if (d->m_document->identifierCount() == 0) { return QModelIndex(); } if (!d->m_lesson || !d->m_lesson->parent()) { return QModelIndex(); } beginInsertRows(QModelIndex(), rowCount(QModelIndex()), rowCount(QModelIndex())); if (!expression) { expression = new KEduVocExpression; } d->m_lesson->appendEntry(expression); endInsertRows(); return index(rowCount(QModelIndex()) - 1, 0, QModelIndex()); } bool KEduVocVocabularyModel::removeRows(int row, int count, const QModelIndex & parent) { Q_UNUSED(parent); if (count < 1 || row < 0 || row + count > d->m_container->entryCount(d->m_recursive)) { return false; } int bottomRow = row + count - 1; beginRemoveRows(QModelIndex(), row, bottomRow); for (int i = bottomRow; i >= row; i--) { delete d->m_container->entry(i, d->m_recursive); } endRemoveRows(); return true; } QStringList KEduVocVocabularyModel::mimeTypes() const { return QStringList() << "text/plain"; } QMimeData * KEduVocVocabularyModel::mimeData(const QModelIndexList & indexes) const { KEduVocVocabularyMimeData *mimeData = new KEduVocVocabularyMimeData(); QModelIndexList sortedIndexes = indexes; qSort(sortedIndexes); //qDebug() << "mimeData for " << indexes.count() << "indexes"; QList translations; foreach(const QModelIndex & index, sortedIndexes) { // only add if it's a translation. other cells like word type are being ignored for now. if (columnType(index.column()) == Translation) { translations.append(d->m_container->entry(index.row(), d->m_recursive)->translation(translation(index.column()))); } } mimeData->setTranslations(translations); return mimeData; } void KEduVocVocabularyModel::setRecursive(bool show) { beginResetModel(); if (show) { d->m_recursive = KEduVocContainer::Recursive; } else { d->m_recursive = KEduVocContainer::NotRecursive; } endResetModel(); } void KEduVocVocabularyModel::resetLanguages() { // play it save - this happens seldom enough to warrant a reload setDocument(d->m_document); } \ No newline at end of file diff --git a/keduvocdocument/keduvocwordclassmodel.h b/keduvocdocument/keduvocwordclassmodel.h index f5f11cd..6c7993b 100644 --- a/keduvocdocument/keduvocwordclassmodel.h +++ b/keduvocdocument/keduvocwordclassmodel.h @@ -1,47 +1,47 @@ /*************************************************************************** Copyright 2008 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 KEDUVOCWORDCLASSMODEL_H #define KEDUVOCWORDCLASSMODEL_H -#include "keduvoccontainermodel.h" +#include /** * Model for the tree of word types. */ class KEDUVOCDOCUMENT_EXPORT KEduVocWordClassModel : public KEduVocContainerModel { Q_OBJECT public: explicit KEduVocWordClassModel(QObject *parent = 0); ~KEduVocWordClassModel(); // TODO implement this function QModelIndex appendWordClass(const QModelIndex& parent, const QString & wordTypeName = QString()); // TODO implement this function void deleteWordClass(const QModelIndex& wordTypeIndex); protected: KEduVocContainer * rootContainer() const; private: class Private; Private * const d; }; #endif