diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 86a65993..7e72cb8d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,199 +1,199 @@ include_directories( ${parley_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/collection ${CMAKE_CURRENT_SOURCE_DIR}/editor # FIXME: Remove when moving the rest of the files in vocabulary/ ) # installation of kconfig files .kcfg containing app settings add_subdirectory( settings ) set(parley_LIB_SRCS parleyactions.cpp parleydocument.cpp parleymainwindow.cpp utils.cpp collection/collection.cpp collection/testentry.cpp collection/entryfilter.cpp collection/entryfilterdialog.cpp collection/vocabularymimedata.cpp collection/containermimedata.cpp #collection/readonlycontainermodel.cpp - collection/containermodel.cpp + #collection/containermodel.cpp collection/lessonmodel.cpp #collection/vocabularymodel.cpp collection/vocabularyfilter.cpp collection/wordclassmodel.cpp collection/containerview.cpp editor/editor.cpp editor/vocabularycolumnsdialog.cpp editor/lessonview.cpp editor/vocabularydelegate.cpp editor/vocabularyheaderview.cpp editor/vocabularyview.cpp editor/wordtypeview.cpp editor/audiowidget.cpp editor/browserwidget.cpp editor/comparisonwidget.cpp editor/inflectionwidget.cpp editor/conjugationwidget.cpp editor/declensionwidget.cpp editor/imagechooserwidget.cpp editor/multiplechoicewidget.cpp editor/summarywordwidget.cpp editor/synonymwidget.cpp editor/latexwidget.cpp practice/abstractwidget.cpp practice/sessionmanagerbase.cpp practice/sessionmanagercontinuous.cpp practice/sessionmanagerfixed.cpp practice/abstractfrontend.cpp practice/abstractbackendmode.cpp practice/practicestatemachine.cpp practice/comparisonbackendmode.cpp practice/comparisonmodewidget.cpp practice/conjugationbackendmode.cpp practice/conjugationmodewidget.cpp practice/guifrontend.cpp practice/writtenpracticewidget.cpp practice/writtenpracticevalidator.cpp practice/writtenbackendmode.cpp practice/examplesentencebackendmode.cpp practice/flashcardmodewidget.cpp practice/flashcardbackendmode.cpp practice/multiplechoicemodewidget.cpp practice/multiplechoicebackendmode.cpp practice/genderbackendmode.cpp practice/mixedlettersmodewidget.cpp practice/imagewidget.cpp practice/practicemainwindow.cpp practice/practicesummarycomponent.cpp practice/boxeswidget.cpp practice/audiobutton.cpp practice/summarybarwidget.cpp practice/themedbackgroundrenderer.cpp practice/imagecache.cpp practice/statustoggle.cpp practice/statustogglebutton.cpp practice/latexrenderer.cpp practice/configure/configurepracticedialog.cpp practice/configure/generalpracticeoptions.cpp practice/configure/blockoptions.cpp practice/configure/thresholdoptions.cpp practice/configure/specificpracticeoptions.cpp scripts/scriptdialog.cpp scripts/scriptmanager.cpp scripts/scripting/parley.cpp scripts/scripting/document.cpp scripts/scripting/lesson.cpp scripts/scripting/expression.cpp scripts/scripting/translation.cpp scripts/scripting/text.cpp scripts/scripting/container.cpp scripts/scripting/identifier.cpp scripts/script.cpp scripts/translator.cpp settings/generaloptions.cpp settings/parleyprefs.cpp settings/viewoptions.cpp settings/documentproperties.cpp settings/languageproperties.cpp settings/languagepropertiespage.cpp settings/kgametheme/kgametheme.cpp settings/kgametheme/kgamethemeselector.cpp statistics/conjugationoptions.cpp statistics/lessonstatisticsview.cpp statistics/statisticsmodel.cpp statistics/statisticsmainwindow.cpp statistics/statisticslegendwidget.cpp dashboard/dashboard.cpp dashboard/buttondelegate.cpp dashboard/gradereferencewidget.cpp dashboard/barwidget.cpp dashboard/collectionwidget.cpp ) ki18n_wrap_ui(parley_LIB_SRCS collection/entryfilterdialog.ui editor/multiplechoicewidget.ui editor/comparisonwidget.ui editor/conjugationwidget.ui editor/declensionwidget.ui editor/imagechooserwidget.ui editor/audiowidget.ui editor/synonymwidget.ui editor/browserwidget.ui editor/summarywordwidget.ui editor/latexwidget.ui practice/practicesummarywidget.ui practice/practice_mainwindow.ui practice/practice_widget_comparison.ui practice/practice_widget_conjugation.ui practice/practice_widget_flashcard.ui practice/practice_widget_multiplechoice.ui practice/practice_widget_written.ui practice/configure/generalpracticeoptions.ui practice/configure/blockoptions.ui practice/configure/thresholdoptions.ui practice/configure/specificpracticeoptions.ui settings/optionlistform.ui settings/viewoptionsbase.ui settings/generaloptionsbase.ui settings/languagepropertiespage.ui settings/documentproperties.ui settings/kgametheme/kgamethemeselector.ui statistics/statisticsmainwindow.ui dashboard/dashboard.ui ) kconfig_add_kcfg_files(parley_LIB_SRCS settings/prefs.kcfgc settings/documentsettings.kcfgc settings/languagesettings.kcfgc ) qt5_add_dbus_adaptor(parley_LIB_SRCS editor/org.kde.parley.xml editor/editor.h Editor::EditorWindow) #### XSLT Support #### # to transform the document xml to html or other if(HAVE_LIBXSLT) set(parley_LIB_SRCS ${parley_LIB_SRCS} exportdialog.cpp ) ki18n_wrap_ui(parley_LIB_SRCS exportdialog.ui ) endif(HAVE_LIBXSLT) #### End XSLT Support #### # This library is used both by parley itself and the unit tests. add_library(parley_LIB STATIC ${parley_LIB_SRCS}) set(parley_SRCS main.cpp) add_executable(parley ${parley_SRCS}) target_link_libraries(parley parley_LIB ${parley_LINK_LIBS}) target_link_libraries(parley_LIB ${parley_LINK_LIBS}) ########### install files ############### install(TARGETS parley ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} ) # desktop files appear in the menus install( PROGRAMS org.kde.parley.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) # hot new stuff config install( FILES parley.knsrc parley-themes.knsrc DESTINATION ${KDE_INSTALL_CONFDIR} ) # UI files - define menus and toolbars # @todo frameworks find a definitive locations for files and then use KXMLGUI_INSTALL_DIR install( FILES parleyui.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/parley ) #install( FILES editor/editorui.rc DESTINATION ${KDE_INSTALL_DATADIR}/parley ) install( FILES editor/editorui.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/parley ) install( FILES dashboard/dashboardui.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/parley ) # install( FILES statistics/statisticsui.rc DESTINATION ${KDE_INSTALL_DATADIR}/parley ) # install( FILES practice/practiceui.rc DESTINATION ${KDE_INSTALL_DATADIR}/parley ) # install( FILES practice/practicesummaryui.rc DESTINATION ${KDE_INSTALL_DATADIR}/parley ) install( FILES statistics/statisticsui.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/parley ) install( FILES practice/practiceui.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/parley ) install( FILES practice/practicesummaryui.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/parley ) diff --git a/src/collection/containerview.cpp b/src/collection/containerview.cpp index d599ed67..8e063440 100644 --- a/src/collection/containerview.cpp +++ b/src/collection/containerview.cpp @@ -1,54 +1,54 @@ /*************************************************************************** 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. * * * ***************************************************************************/ // Own #include "containerview.h" // Qt #include -// Parley/collection -#include "containermodel.h" +// KEduVoc +#include ContainerView::ContainerView(QWidget *parent) : QTreeView(parent) { header()->setStretchLastSection(false); header()->setVisible(false); setAlternatingRowColors(true); // show the actions added by addAction() as right click menu. setContextMenuPolicy(Qt::ActionsContextMenu); setDragEnabled(true); setAcceptDrops(true); setDropIndicatorShown(true); setDragDropMode(QAbstractItemView::DragDrop); } -void ContainerView::setModel(ContainerModel *model) +void ContainerView::setModel(KEduVocContainerModel *model) { QTreeView::setModel(model); m_model = model; header()->setSectionResizeMode(0, QHeaderView::Stretch); header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); } void ContainerView::slotRename() { edit(selectionModel()->currentIndex()); } diff --git a/src/collection/containerview.h b/src/collection/containerview.h index 7b85de83..eaf7f4cf 100644 --- a/src/collection/containerview.h +++ b/src/collection/containerview.h @@ -1,58 +1,58 @@ /*************************************************************************** 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 CONTAINERVIEW_H #define CONTAINERVIEW_H #include class KEduVocContainer; -class ContainerModel; +class KEduVocContainerModel; /** * View for containers (KEduVocContainer). * @author Frederik Gladhorn */ class ContainerView : public QTreeView { Q_OBJECT public: /** Set up the lesson list widget. * Also creates the menu to manipulate the lessons. * @param parent parent widget */ explicit ContainerView(QWidget *parent = 0); /** Set the model for the view. * @param model the model */ - virtual void setModel(ContainerModel *model); + virtual void setModel(KEduVocContainerModel *model); public slots: /** let the user type a new name for the container */ void slotRename(); protected: /** ContainerModel for this view. */ - ContainerModel *m_model; + KEduVocContainerModel *m_model; private: // intentionally hide this to make sure a proper model is passed void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE { Q_UNUSED(model) } }; #endif diff --git a/src/collection/lessonmodel.cpp b/src/collection/lessonmodel.cpp index 68d77686..548d6e11 100644 --- a/src/collection/lessonmodel.cpp +++ b/src/collection/lessonmodel.cpp @@ -1,117 +1,117 @@ /*************************************************************************** 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. * * * ***************************************************************************/ #include "lessonmodel.h" #include "parleydocument.h" #include #include #include /** @file * Implementation of LessonModel. * Functions to create the model from the lessons of the vocabulary document. */ LessonModel::LessonModel(QObject * parent) - : ContainerModel(KEduVocContainer::Lesson, parent) + : KEduVocContainerModel(KEduVocContainer::Lesson, parent) { } KEduVocContainer * LessonModel::rootContainer() const { if (!document()) { return 0; } return document()->lesson(); } Qt::ItemFlags LessonModel::flags(const QModelIndex &index) const { if (index.isValid() && index.parent() == QModelIndex()) { return (Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable); } // the name column should be checkable to select lessons for practice - return ContainerModel::flags(index); + return KEduVocContainerModel::flags(index); } QVariant LessonModel::data(const QModelIndex & index, int role) const { if (index.isValid() && !index.parent().isValid()) { if (index.column() == 0) { switch (role) { case Qt::DisplayRole: - return i18nc("display of the name of the vocabulary collection", "Collection: %1", ContainerModel::data(index, role).toString()); + return i18nc("display of the name of the vocabulary collection", "Collection: %1", KEduVocContainerModel::data(index, role).toString()); case Qt::FontRole: QFont f; f.setBold(true); return f; } } } - return ContainerModel::data(index, role); + return KEduVocContainerModel::data(index, role); } bool LessonModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (index.isValid() && !index.parent().isValid()) { if (index.column() == ContainerNameColumn && role == Qt::EditRole) { ///@todo decouple the root lesson and document title document()->setTitle(value.toString()); } } - return ContainerModel::setData(index, value, role); + return KEduVocContainerModel::setData(index, value, role); } void LessonModel::splitLesson(const QModelIndex& containerIndex, int entriesPerLesson, SplitLessonOrder order) { if (!containerIndex.isValid()) { return; } if (static_cast(containerIndex.internalPointer())->containerType() != KEduVocContainer::Lesson) { return; } KEduVocLesson* parentLesson = static_cast(containerIndex.internalPointer()); int numNewLessons = parentLesson->entryCount() / entriesPerLesson; // modulo - fraction lesson if not 0 we need one more if (parentLesson->entryCount() % entriesPerLesson) { numNewLessons++; } while (parentLesson->entryCount() > 0) { beginInsertRows(containerIndex, parentLesson->entryCount(), parentLesson->entryCount()); KEduVocLesson* child = new KEduVocLesson(parentLesson->name() + QStringLiteral(" %1").arg(parentLesson->childContainerCount() + 1), parentLesson); parentLesson->appendChildContainer(child); endInsertRows(); while (parentLesson->entryCount() > 0 && child->entryCount() < entriesPerLesson) { // next entry to be assigned to one of the new lessons int nextEntry = 0; if (order == Random) { nextEntry = KRandom::random() % parentLesson->entryCount(); child->appendEntry(parentLesson->entry(nextEntry)); } } } } diff --git a/src/collection/lessonmodel.h b/src/collection/lessonmodel.h index 70a760e1..745b8a6f 100644 --- a/src/collection/lessonmodel.h +++ b/src/collection/lessonmodel.h @@ -1,55 +1,55 @@ /*************************************************************************** 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 LESSONMODEL_H #define LESSONMODEL_H -#include "containermodel.h" +#include /** * Model for the tree of lessons. */ -class LessonModel : public ContainerModel +class LessonModel : 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 LessonModel(QObject *parent = 0); Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) Q_DECL_OVERRIDE; /** * 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 containerIndex 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 Q_DECL_OVERRIDE; }; #endif diff --git a/src/collection/wordclassmodel.cpp b/src/collection/wordclassmodel.cpp index 6f5eb29f..a4e21e2f 100644 --- a/src/collection/wordclassmodel.cpp +++ b/src/collection/wordclassmodel.cpp @@ -1,34 +1,34 @@ /*************************************************************************** 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. * * * ***************************************************************************/ // Own #include "wordclassmodel.h" #include WordClassModel::WordClassModel(QObject * parent) - : ContainerModel(KEduVocContainer::WordType, parent) + : KEduVocContainerModel(KEduVocContainer::WordType, parent) { } KEduVocContainer * WordClassModel::rootContainer() const { if (!document()) { return 0; } return document()->wordTypeContainer(); } diff --git a/src/collection/wordclassmodel.h b/src/collection/wordclassmodel.h index 1bd629df..1590a7ad 100644 --- a/src/collection/wordclassmodel.h +++ b/src/collection/wordclassmodel.h @@ -1,40 +1,40 @@ /*************************************************************************** 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 WORDCLASSMODEL_H #define WORDCLASSMODEL_H -#include "containermodel.h" +#include /** * Model for the tree of word types. */ -class WordClassModel : public ContainerModel +class WordClassModel : public KEduVocContainerModel { Q_OBJECT public: explicit WordClassModel(QObject *parent = 0); QModelIndex appendWordClass(const QModelIndex& parent, const QString & wordTypeName = QString()); void deleteWordClass(const QModelIndex& wordTypeIndex); protected: KEduVocContainer * rootContainer() const Q_DECL_OVERRIDE; }; #endif diff --git a/src/editor/editor.cpp b/src/editor/editor.cpp index e1e9df1d..f5de16a2 100644 --- a/src/editor/editor.cpp +++ b/src/editor/editor.cpp @@ -1,523 +1,524 @@ /*************************************************************************** Copyright 1999-2001 Ewald Arnold Copyright 2004-2007 Peter Hedlund Copyright 2007-2009 Frederik Gladhorn Copyright 2008 Daniel Laidig ***************************************************************************/ /*************************************************************************** * * * 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 "editor.h" #include // Qt models on top of the KEduVocDocument -#include "containermodel.h" + #include "lessonmodel.h" #include "vocabularyfilter.h" #include "wordclassmodel.h" // Views #include "vocabularyview.h" #include "containerview.h" #include "lessonview.h" #include "wordtypeview.h" #include "multiplechoicewidget.h" #include "comparisonwidget.h" #include "inflectionwidget.h" #include "imagechooserwidget.h" #include "audiowidget.h" #include "browserwidget.h" #include "synonymwidget.h" #include "summarywordwidget.h" #include "latexwidget.h" #include "settings/parleyprefs.h" #include "prefs.h" #include "scripts/scriptdialog.h" #include "scripts/translator.h" #include "parleyactions.h" #include "parleyadaptor.h" //KEduVoc #include +#include #include #include #include #include #include #include #include #include #include #include using namespace Editor; EditorWindow::EditorWindow(ParleyMainWindow* parent) : KXmlGuiWindow(parent), m_mainWindow(parent) { // KXmlGui setXMLFile(QStringLiteral("editorui.rc")); setObjectName(QStringLiteral("Editor")); setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); initView(); initModel(); initDockWidgets(); initActions(); KConfigGroup cfg(KSharedConfig::openConfig(QStringLiteral("parleyrc")), objectName()); applyMainWindowSettings(cfg); connect(parent->parleyDocument(), &ParleyDocument::documentChanged, this, &EditorWindow::updateDocument); connect(parent->parleyDocument(), &ParleyDocument::languagesChanged, this, &EditorWindow::slotLanguagesChanged); connect(parent->parleyDocument(), SIGNAL(statesNeedSaving()), this, SLOT(saveState())); connect(parent, &ParleyMainWindow::preferencesChanged, this, &EditorWindow::applyPrefs); QTimer::singleShot(0, this, &EditorWindow::initScripts); } EditorWindow::~EditorWindow() { saveState(); KConfigGroup cfg(KSharedConfig::openConfig(QStringLiteral("parleyrc")), objectName()); saveMainWindowSettings(cfg); } void EditorWindow::updateDocument(KEduVocDocument *doc) { m_vocabularyView->setDocument(doc); m_vocabularyModel->setDocument(doc); m_lessonModel->setDocument(doc); m_wordTypeModel->setDocument(doc); m_summaryWordWidget->slotDocumentChanged(doc); m_inflectionWidget->setDocument(doc); m_comparisonWidget->setDocument(doc); m_synonymWidget->setDocument(doc); m_antonymWidget->setDocument(doc); m_falseFriendWidget->setDocument(doc); if (!m_mainWindow->parleyDocument()->document()) { return; } if (!doc) { return; } // expand the root items m_lessonView->expandToDepth(0); m_wordTypeView->expandToDepth(0); connect(m_vocabularyView->selectionModel(), &QItemSelectionModel::selectionChanged, m_summaryWordWidget, &SummaryWordWidget::slotSelectionChanged); connect(m_vocabularyView->selectionModel(), &QItemSelectionModel::selectionChanged, m_latexWidget, &LatexWidget::slotSelectionChanged); m_spellCheckMenu->menu()->clear(); for (int i = 0; i < doc->identifierCount(); ++i) { QAction* languageSpellCheck = new QAction(doc->identifier(i).name(), m_spellCheckMenu->menu()); m_spellCheckMenu->menu()->addAction(languageSpellCheck); connect(languageSpellCheck, &QAction::triggered, this, [=] {m_vocabularyView->checkSpelling(i);}); } } void EditorWindow::initDockWidgets() { // Lesson dockwidget QDockWidget *lessonDockWidget = new QDockWidget(i18n("Units"), this); lessonDockWidget->setObjectName(QStringLiteral("LessonDock")); m_lessonView = new LessonView(this); lessonDockWidget->setWidget(m_lessonView); addDockWidget(Qt::LeftDockWidgetArea, lessonDockWidget); m_dockWidgets.append(lessonDockWidget); actionCollection()->addAction(QStringLiteral("show_units_dock"), lessonDockWidget->toggleViewAction()); m_lessonModel = new LessonModel(this); m_lessonView->setModel(m_lessonModel); m_lessonView->setToolTip(i18n("Right click to add, delete, or rename units. \n" "With the checkboxes you can select which units you want to practice. \n" "Only checked units [x] will be asked in the practice!")); connect(m_lessonView, &LessonView::selectedLessonChanged, m_vocabularyModel, &VocabularyModel::setLesson); connect(m_lessonView, &LessonView::signalShowContainer, m_vocabularyModel, &VocabularyModel::showContainer); connect(m_vocabularyView, &VocabularyView::translationChanged, m_lessonView, &LessonView::setTranslation); // Word classes dock widget QDockWidget* wordTypeDockWidget = new QDockWidget(i18n("Word Types"), this); wordTypeDockWidget->setObjectName(QStringLiteral("WordTypeDock")); m_wordTypeView = new WordTypeView(this); wordTypeDockWidget->setWidget(m_wordTypeView); addDockWidget(Qt::LeftDockWidgetArea, wordTypeDockWidget); m_dockWidgets.append(wordTypeDockWidget); m_wordTypeModel = new WordClassModel(this); wordTypeDockWidget->setVisible(false); actionCollection()->addAction(QStringLiteral("show_wordtype_dock"), wordTypeDockWidget->toggleViewAction()); ///@todo test, should be fixed with the lesson one though ///@todo remove before release // new ModelTest(m_wordTypeModel, this); m_wordTypeView->setModel(m_wordTypeModel); connect(m_vocabularyView, &VocabularyView::translationChanged, m_wordTypeView, &WordTypeView::setTranslation); // Inflections QDockWidget *inflectionDock = new QDockWidget(i18n("Inflection (verbs, adjectives, nouns)"), this); inflectionDock->setObjectName(QStringLiteral("InflectionDock")); m_inflectionWidget = new InflectionWidget(this); QScrollArea *inflectionScrollArea = new QScrollArea(this); inflectionScrollArea->setWidgetResizable(true); inflectionScrollArea->setWidget(m_inflectionWidget); inflectionDock->setWidget(inflectionScrollArea); addDockWidget(Qt::RightDockWidgetArea, inflectionDock); m_dockWidgets.append(inflectionDock); actionCollection()->addAction(QStringLiteral("show_inflection_dock"), inflectionDock->toggleViewAction()); connect(m_mainWindow->parleyDocument(), &ParleyDocument::documentChanged, m_inflectionWidget, &InflectionWidget::setDocument); connect(m_vocabularyView, &VocabularyView::translationChanged, m_inflectionWidget, &InflectionWidget::setTranslation); // Comparison forms QDockWidget *comparisonDock = new QDockWidget(i18n("Comparison forms"), this); comparisonDock->setObjectName(QStringLiteral("ComparisonDock")); m_comparisonWidget = new ComparisonWidget(this); QScrollArea *comparisonScrollArea = new QScrollArea(this); comparisonScrollArea->setWidgetResizable(true); comparisonScrollArea->setWidget(m_comparisonWidget); comparisonDock->setWidget(comparisonScrollArea); addDockWidget(Qt::RightDockWidgetArea, comparisonDock); m_dockWidgets.append(comparisonDock); actionCollection()->addAction(QStringLiteral("show_comparison_dock"), comparisonDock->toggleViewAction()); comparisonDock->setVisible(false); connect(m_vocabularyView, &VocabularyView::translationChanged, m_comparisonWidget, &ComparisonWidget::setTranslation); tabifyDockWidget(comparisonDock,inflectionDock); // Multiple choice QDockWidget *multipleChoiceDock = new QDockWidget(i18n("Multiple Choice"), this); multipleChoiceDock->setObjectName(QStringLiteral("MultipleChoiceDock")); MultipleChoiceWidget *multipleChoiceWidget = new MultipleChoiceWidget(this); QScrollArea *multipleChoiceScrollArea = new QScrollArea(this); multipleChoiceScrollArea->setWidgetResizable(true); multipleChoiceScrollArea->setWidget(multipleChoiceWidget); multipleChoiceDock->setWidget(multipleChoiceScrollArea); addDockWidget(Qt::RightDockWidgetArea, multipleChoiceDock); m_dockWidgets.append(multipleChoiceDock); actionCollection()->addAction(QStringLiteral("show_multiplechoice_dock"), multipleChoiceDock->toggleViewAction()); multipleChoiceDock->setVisible(false); connect(m_vocabularyView, &VocabularyView::translationChanged, multipleChoiceWidget, &MultipleChoiceWidget::setTranslation); // Synonym (and the same for antonym and false friends) QDockWidget *synonymDock = new QDockWidget(i18n("Synonyms"), this); synonymDock->setObjectName(QStringLiteral("SynonymDock")); m_synonymWidget = new SynonymWidget(SynonymWidget::Synonym, this); QScrollArea *synonymScrollArea = new QScrollArea(this); synonymScrollArea->setWidgetResizable(true); synonymScrollArea->setWidget(m_synonymWidget); synonymDock->setWidget(synonymScrollArea); addDockWidget(Qt::RightDockWidgetArea, synonymDock); m_dockWidgets.append(synonymDock); actionCollection()->addAction(QStringLiteral("show_synonym_dock"), synonymDock->toggleViewAction()); synonymDock->setVisible(false); connect(m_vocabularyView, &VocabularyView::translationChanged, m_synonymWidget, &SynonymWidget::setTranslation); QDockWidget *antonymDock = new QDockWidget(i18n("Antonyms"), this); antonymDock->setObjectName(QStringLiteral("AntonymDock")); m_antonymWidget = new SynonymWidget(SynonymWidget::Antonym, this); QScrollArea *antonymScrollArea = new QScrollArea(this); antonymScrollArea->setWidgetResizable(true); antonymScrollArea->setWidget(m_antonymWidget); antonymDock->setWidget(antonymScrollArea); addDockWidget(Qt::RightDockWidgetArea, antonymDock); m_dockWidgets.append(antonymDock); actionCollection()->addAction(QStringLiteral("show_antonym_dock"), antonymDock->toggleViewAction()); antonymDock->setVisible(false); connect(m_vocabularyView, &VocabularyView::translationChanged, m_antonymWidget, &SynonymWidget::setTranslation); tabifyDockWidget(synonymDock,antonymDock); QDockWidget *falseFriendDock = new QDockWidget(i18n("False Friends"), this); falseFriendDock->setObjectName(QStringLiteral("FalseFriendDock")); m_falseFriendWidget = new SynonymWidget(SynonymWidget::FalseFriend, this); QScrollArea *falseFriendScrollArea = new QScrollArea(this); falseFriendScrollArea->setWidgetResizable(true); falseFriendScrollArea->setWidget(m_falseFriendWidget); falseFriendDock->setWidget(falseFriendScrollArea); addDockWidget(Qt::RightDockWidgetArea, falseFriendDock); m_dockWidgets.append(falseFriendDock); actionCollection()->addAction(QStringLiteral("show_falsefriend_dock"), falseFriendDock->toggleViewAction()); falseFriendDock->setVisible(false); connect(m_vocabularyView, &VocabularyView::translationChanged, m_falseFriendWidget, &SynonymWidget::setTranslation); tabifyDockWidget(antonymDock,falseFriendDock); // Pronunciation symbols - Use KCharSelect QDockWidget *charSelectDock = new QDockWidget(i18n("Phonetic Symbols"), this); charSelectDock->setObjectName(QStringLiteral("IPADock")); KCharSelect *charSelectWidget = new KCharSelect(this, 0, KCharSelect::SearchLine | KCharSelect::BlockCombos | KCharSelect::CharacterTable); charSelectWidget->setCurrentChar(0x0250); QScrollArea *charSelectScrollArea = new QScrollArea(this); charSelectScrollArea->setWidgetResizable(true); charSelectScrollArea->setWidget(charSelectWidget); charSelectDock->setWidget(charSelectScrollArea); addDockWidget(Qt::BottomDockWidgetArea, charSelectDock); m_dockWidgets.append(charSelectDock); actionCollection()->addAction(QStringLiteral("show_pronunciation_dock"), charSelectDock->toggleViewAction()); charSelectDock->setVisible(false); connect(charSelectWidget, &KCharSelect::charSelected, m_vocabularyView, &VocabularyView::appendChar); // Image QDockWidget *imageDock = new QDockWidget(i18n("Image"), this); imageDock->setObjectName(QStringLiteral("ImageDock")); ImageChooserWidget *imageChooserWidget = new ImageChooserWidget(this); QScrollArea *imageScrollArea = new QScrollArea(this); imageScrollArea->setWidgetResizable(true); imageScrollArea->setWidget(imageChooserWidget); imageDock->setWidget(imageScrollArea); addDockWidget(Qt::RightDockWidgetArea, imageDock); m_dockWidgets.append(imageDock); actionCollection()->addAction(QStringLiteral("show_image_dock"), imageDock->toggleViewAction()); imageDock->setVisible(false); connect(m_vocabularyView, &VocabularyView::translationChanged, imageChooserWidget, &ImageChooserWidget::setTranslation); tabifyDockWidget(multipleChoiceDock,imageDock); // Summary word QDockWidget *summaryDock = new QDockWidget(i18n("Summary"), this); summaryDock->setObjectName(QStringLiteral("SummaryDock")); m_summaryWordWidget = new SummaryWordWidget(m_vocabularyFilter, m_mainWindow->parleyDocument()->document(), this); QScrollArea *summaryScrollArea = new QScrollArea(this); summaryScrollArea->setWidgetResizable(true); summaryScrollArea->setWidget(m_summaryWordWidget); summaryDock->setWidget(summaryScrollArea); addDockWidget(Qt::BottomDockWidgetArea, summaryDock); actionCollection()->addAction(QStringLiteral("show_summary_dock"), summaryDock->toggleViewAction()); summaryDock->setVisible(false); m_dockWidgets.append(summaryDock); connect(m_vocabularyView, &VocabularyView::translationChanged, m_summaryWordWidget, &SummaryWordWidget::setTranslation); // Sound QDockWidget *audioDock = new QDockWidget(i18n("Sound"), this); audioDock->setObjectName(QStringLiteral("AudioDock")); AudioWidget *audioWidget = new AudioWidget(this); QScrollArea *audioScrollArea = new QScrollArea(this); audioScrollArea->setWidgetResizable(true); audioScrollArea->setWidget(audioWidget); audioDock->setWidget(audioScrollArea); addDockWidget(Qt::RightDockWidgetArea, audioDock); m_dockWidgets.append(audioDock); actionCollection()->addAction(QStringLiteral("show_audio_dock"), audioDock->toggleViewAction()); audioDock->setVisible(false); connect(m_vocabularyView, &VocabularyView::translationChanged, audioWidget, &AudioWidget::setTranslation); tabifyDockWidget(imageDock,audioDock); // browser QDockWidget *browserDock = new QDockWidget(i18n("Internet"), this); browserDock->setObjectName(QStringLiteral("BrowserDock")); BrowserWidget *htmlPart = new BrowserWidget(browserDock); QScrollArea *browserScrollArea = new QScrollArea(this); browserScrollArea->setWidgetResizable(true); browserScrollArea->setWidget(htmlPart); browserDock->setWidget(browserScrollArea); addDockWidget(Qt::BottomDockWidgetArea, browserDock); m_dockWidgets.append(browserDock); actionCollection()->addAction(QStringLiteral("show_browser_dock"), browserDock->toggleViewAction()); browserDock->setVisible(false); connect(m_vocabularyView, &VocabularyView::translationChanged, htmlPart, &BrowserWidget::setTranslation); tabifyDockWidget(summaryDock,browserDock); // LaTeX QDockWidget *latexDock = new QDockWidget(i18n("LaTeX"), this); latexDock->setObjectName(QStringLiteral("LatexDock")); m_latexWidget = new LatexWidget(m_vocabularyFilter, m_mainWindow->parleyDocument()->document(), this); QScrollArea *latexScrollArea = new QScrollArea(this); latexScrollArea->setWidgetResizable(true); latexScrollArea->setWidget(m_latexWidget); latexDock->setWidget(latexScrollArea); addDockWidget(Qt::RightDockWidgetArea, latexDock); actionCollection()->addAction(QStringLiteral("show_latex_dock"), latexDock->toggleViewAction()); latexDock->setVisible(false); m_dockWidgets.append(latexDock); connect(m_vocabularyView, &VocabularyView::translationChanged, m_latexWidget, &LatexWidget::setTranslation); tabifyDockWidget(audioDock,latexDock); // Grades // QDockWidget *gradeDock = new QDockWidget(i18n("Grade"), this); // gradeDock->setObjectName("gradeDock"); // QLabel *gradeWidget = new QLabel("grade placeholder", this); // gradeDock->setWidget(gradeWidget); // addDockWidget(Qt::RightDockWidgetArea, gradeDock); // connect(this, SIGNAL(signalSetData(KEduVocTranslation*)), m_declensionWidget, SLOT(setTranslation(KEduVocTranslation*))); } void EditorWindow::initActions() { ParleyActions::create(ParleyActions::RemoveGrades, this, SLOT(removeGrades()), actionCollection()); m_spellCheckMenu = ParleyActions::create(ParleyActions::CheckSpelling, 0, "", actionCollection()); m_spellCheckMenu->setMenu(new QMenu(this)); ParleyActions::create(ParleyActions::ToggleShowSublessons, m_vocabularyModel, SLOT(showEntriesOfSubcontainers(bool)), actionCollection()); ParleyActions::create(ParleyActions::AutomaticTranslation, m_vocabularyModel, SLOT(automaticTranslation(bool)), actionCollection()); ParleyActions::create(ParleyActions::StartPractice, m_mainWindow, SLOT(showPracticeConfiguration()), actionCollection()); actionCollection()->action(QStringLiteral("practice_start"))->setText(i18n("Practice")); actionCollection()->action(QStringLiteral("practice_start"))->setToolTip(i18n("Practice")); ParleyActions::create(ParleyActions::ConfigurePractice, m_mainWindow, SLOT(configurePractice()), actionCollection()); ParleyActions::create(ParleyActions::ToggleSearchBar, this, SLOT(slotConfigShowSearch()), actionCollection()); ParleyActions::create(ParleyActions::SearchVocabulary, this, SLOT(startSearch()), actionCollection()); ParleyActions::create(ParleyActions::ShowScriptManager, this, SLOT(slotShowScriptManager()), actionCollection()); ParleyActions::create(ParleyActions::LanguagesProperties, m_mainWindow->parleyDocument(), SLOT(languageProperties()), actionCollection()); ParleyActions::createUploadAction(m_mainWindow->parleyDocument(), SLOT(uploadFile()), actionCollection()); new EditorWindowAdaptor(this); QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.registerObject(QStringLiteral("/AddWithTranslation"), this); } void EditorWindow::addWordWithTranslation(const QStringList &w) { KEduVocExpression *kexpr = new KEduVocExpression(w); m_vocabularyModel->appendEntry(kexpr); } void EditorWindow::initModel() { m_vocabularyModel = new KEduVocVocabularyModel(Prefs::showSublessonentries(), this); m_vocabularyFilter = new VocabularyFilter(this); m_vocabularyFilter->setSourceModel(m_vocabularyModel); m_vocabularyView->setFilter(m_vocabularyFilter); // connect(m_mainWindow->parleyDocument(), SIGNAL(documentChanged(KEduVocDocument*)), m_vocabularyModel, SLOT(setDocument(KEduVocDocument*))); // connect(m_mainWindow->parleyDocument(), SIGNAL(documentChanged(KEduVocDocument*)), m_vocabularyView, SLOT(setDocument(KEduVocDocument*))); connect(m_searchLine, &QLineEdit::textChanged, m_vocabularyFilter, &VocabularyFilter::setSearchString); } /** * This initializes the main widgets and table. */ void EditorWindow::initView() { QWidget *mainWidget = new QWidget(this); setCentralWidget(mainWidget); QVBoxLayout *topLayout = new QVBoxLayout(mainWidget); m_searchLine = new QLineEdit(this); m_searchLine->show(); m_searchLine->setFocusPolicy(Qt::ClickFocus); m_searchLine->setClearButtonEnabled(true); m_searchLine->setPlaceholderText(i18n("Enter search terms here")); m_searchLine->setToolTip(i18n("Search your vocabulary")); QLabel *label = new QLabel(i18n("S&earch:"), this); label->setBuddy(m_searchLine); label->show(); m_searchWidget = new QWidget(this); QHBoxLayout* layout = new QHBoxLayout(m_searchWidget); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(label); layout->addWidget(m_searchLine); ///@todo centralWidget()-> delete layout QVBoxLayout * rightLayout = new QVBoxLayout(); rightLayout->setContentsMargins(0, 0, 0, 0); rightLayout->addWidget(m_searchWidget); m_searchWidget->setVisible(Prefs::showSearch()); m_vocabularyView = new VocabularyView(this); rightLayout->addWidget(m_vocabularyView, 1, 0); topLayout->addLayout(rightLayout); } void EditorWindow::slotConfigShowSearch() { m_searchWidget->setVisible(m_searchWidget->isHidden()); Prefs::setShowSearch(m_searchWidget->isVisible()); } void EditorWindow::startSearch() { m_searchWidget->setVisible(true); m_searchLine->setFocus(); } void EditorWindow::slotShowScriptManager() { ScriptDialog * dialog = new ScriptDialog(m_scriptManager); dialog->show(); } void EditorWindow::applyPrefs() { m_vocabularyView->reset(); } void EditorWindow::removeGrades() { m_mainWindow->parleyDocument()->document()->lesson()->resetGrades(-1, KEduVocContainer::Recursive); } void EditorWindow::initScripts() { m_scriptManager = new ScriptManager(this); m_vocabularyView->setTranslator(m_scriptManager->translator()); //Load scripts m_scriptManager->loadScripts(); } void EditorWindow::saveState() { m_vocabularyView->saveColumnVisibility(); } void EditorWindow::slotLanguagesChanged() { m_vocabularyModel->resetLanguages(); } diff --git a/src/editor/lessonview.h b/src/editor/lessonview.h index d63d3cce..1832c14b 100644 --- a/src/editor/lessonview.h +++ b/src/editor/lessonview.h @@ -1,98 +1,98 @@ /*************************************************************************** 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 LESSONVIEW_H #define LESSONVIEW_H #include "containerview.h" #include "lessonmodel.h" namespace Editor { class EditorWindow; /** * View for the lesson list. * @author Frederik Gladhorn */ class LessonView : public ContainerView { Q_OBJECT public: explicit LessonView(EditorWindow *parent); /** Set the model for the view. * @param model the model */ virtual void setModel(LessonModel *model); signals: /** A lesson was selected */ void selectedLessonChanged(KEduVocLesson* lesson); /** Emitted when a new container is selected. Indicates the selected container. */ void signalShowContainer(KEduVocContainer* selected); /** Emitted when any of the checkboxes for the query change. */ void lessonsInPracticeChanged(); public slots: /** Append a lesson to the model and automatically set an edit up so the user can change "New unit" into something meaningful.*/ void slotCreateNewLesson(); /** Remove a lesson. Ask if it's not empty. */ void slotDeleteLesson(); /** Creates many small lessons with the contents of the original lesson. * @todo Let the user select if entries are taken by random or order. */ void slotSplitLesson(); /** Remove the grades for the selected lesson. */ void slotRemoveGradesLesson(); /** Remove the grades for the selected lesson and its children. */ void slotRemoveGradesLessonChildren(); /** * get notified of new columns only to hide them (grades not shown by default). */ void columnsInserted(); void setTranslation(KEduVocExpression* entry, int translationId); /** Expand all the lessons and its corresponding sub-lessons **/ void expandAllLesson(); /** Collapse all the lessons and its corresponding sub-lessons **/ void collapseAllLesson(); protected slots: void selectionChanged(const QItemSelection & selected, const QItemSelection & deselected) Q_DECL_OVERRIDE; void currentChanged(const QModelIndex & current, const QModelIndex & previous) Q_DECL_OVERRIDE; private: - void setModel(ContainerModel *model) Q_DECL_OVERRIDE { + virtual void setModel(KEduVocContainerModel *model) Q_DECL_OVERRIDE { Q_UNUSED(model) } void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE { Q_UNUSED(model) } LessonModel *m_model; }; } #endif diff --git a/src/editor/wordtypeview.cpp b/src/editor/wordtypeview.cpp index cd77eb01..9bae70b9 100644 --- a/src/editor/wordtypeview.cpp +++ b/src/editor/wordtypeview.cpp @@ -1,328 +1,328 @@ /*************************************************************************** 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. * * * ***************************************************************************/ #include "wordtypeview.h" #include #include #include #include #include #include #include #include +#include #include "editor/editor.h" -#include "containermodel.h" #include "containerview.h" using namespace Editor; WordTypeView::WordTypeView(EditorWindow* parent) : ContainerView(parent) { setContextMenuPolicy(Qt::DefaultContextMenu); m_actionNewWordType = new QAction(this); m_actionNewWordType->setText(i18n("New")); m_actionNewWordType->setIcon(QIcon::fromTheme(QStringLiteral("lesson-add"))); m_actionNewWordType->setWhatsThis(i18n("Add a new word type to your document")); m_actionNewWordType->setToolTip(m_actionNewWordType->whatsThis()); m_actionNewWordType->setStatusTip(m_actionNewWordType->whatsThis()); m_actionNewWordType->setStatusTip(m_actionNewWordType->whatsThis()); m_actionRenameWordType = new QAction(this); m_actionRenameWordType->setText(i18n("Rename")); m_actionRenameWordType->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename"))); m_actionRenameWordType->setWhatsThis(i18n("Rename the selected word type")); m_actionRenameWordType->setToolTip(m_actionRenameWordType->whatsThis()); m_actionRenameWordType->setStatusTip(m_actionRenameWordType->whatsThis()); m_actionRenameWordType->setStatusTip(m_actionRenameWordType->whatsThis()); m_actionDeleteWordType = new QAction(this); m_actionDeleteWordType->setText(i18n("Delete Word Type")); m_actionDeleteWordType->setIcon(QIcon::fromTheme(QStringLiteral("lesson-remove"))); m_actionDeleteWordType->setWhatsThis(i18n("Delete the selected word type.")); m_actionDeleteWordType->setToolTip(m_actionDeleteWordType->whatsThis()); m_actionDeleteWordType->setStatusTip(m_actionDeleteWordType->whatsThis()); m_actionDeleteWordType->setStatusTip(m_actionDeleteWordType->whatsThis()); m_actionSpecialTypeMenu = new KSelectAction(this); m_actionSpecialTypeMenu->setText(i18nc("Let the user select what grammatical meaning is connected to a word type (nouns have gender, verbs conjugations etc)", "Grammar")); //actionSplitWordType->setIcon(QIcon::fromTheme("")); /// @todo better icon m_actionSpecialTypeMenu->setWhatsThis(i18n("To let Parley know the grammatical meaning of a word type.")); m_actionSpecialTypeMenu->setToolTip(m_actionSpecialTypeMenu->whatsThis()); m_actionSpecialTypeMenu->setStatusTip(m_actionSpecialTypeMenu->whatsThis()); m_actionSpecialTypeMenu->setStatusTip(m_actionSpecialTypeMenu->whatsThis()); m_nounAction = new QAction(this); m_nounAction->setText(i18n("Noun")); m_nounAction->setCheckable(true); m_nounAction->setWhatsThis(i18n("This word type folder contains nouns.")); m_nounAction->setToolTip(m_nounAction->whatsThis()); m_nounAction->setStatusTip(m_nounAction->whatsThis()); m_nounAction->setStatusTip(m_nounAction->whatsThis()); m_nounMaleAction = new QAction(this); m_nounMaleAction->setText(i18n("Masculine Noun")); m_nounMaleAction->setCheckable(true); m_nounMaleAction->setWhatsThis(i18n("This word type folder contains masculine nouns.")); m_nounMaleAction->setToolTip(m_nounMaleAction->whatsThis()); m_nounMaleAction->setStatusTip(m_nounMaleAction->whatsThis()); m_nounMaleAction->setStatusTip(m_nounMaleAction->whatsThis()); m_nounFemaleAction = new QAction(this); m_nounFemaleAction->setText(i18n("Feminine Noun")); m_nounFemaleAction->setCheckable(true); m_nounFemaleAction->setWhatsThis(i18n("This word type folder contains feminine nouns.")); m_nounFemaleAction->setToolTip(m_nounFemaleAction->whatsThis()); m_nounFemaleAction->setStatusTip(m_nounFemaleAction->whatsThis()); m_nounFemaleAction->setStatusTip(m_nounFemaleAction->whatsThis()); m_nounNeutralAction = new QAction(this); m_nounNeutralAction->setText(i18n("Neuter Noun")); m_nounNeutralAction->setCheckable(true); m_nounNeutralAction->setWhatsThis(i18n("This word type folder contains neuter nouns.")); m_nounNeutralAction->setToolTip(m_nounNeutralAction->whatsThis()); m_nounNeutralAction->setStatusTip(m_nounNeutralAction->whatsThis()); m_nounNeutralAction->setStatusTip(m_nounNeutralAction->whatsThis()); m_adjectiveAction = new QAction(this); m_adjectiveAction->setText(i18n("Adjective")); m_adjectiveAction->setCheckable(true); m_adjectiveAction->setWhatsThis(i18n("This word type folder contains adjectives.")); m_adjectiveAction->setToolTip(m_adjectiveAction->whatsThis()); m_adjectiveAction->setStatusTip(m_adjectiveAction->whatsThis()); m_adjectiveAction->setStatusTip(m_adjectiveAction->whatsThis()); m_adverbAction = new QAction(this); m_adverbAction->setText(i18n("Adverb")); m_adverbAction->setCheckable(true); m_adverbAction->setWhatsThis(i18n("This word type folder contains adverbs.")); m_adverbAction->setToolTip(m_adverbAction->whatsThis()); m_adverbAction->setStatusTip(m_adverbAction->whatsThis()); m_adverbAction->setStatusTip(m_adverbAction->whatsThis()); m_verbAction = new QAction(this); m_verbAction->setText(i18n("Verb")); m_verbAction->setCheckable(true); m_verbAction->setWhatsThis(i18n("This word type folder contains verbs.")); m_verbAction->setToolTip(m_verbAction->whatsThis()); m_verbAction->setStatusTip(m_verbAction->whatsThis()); m_verbAction->setStatusTip(m_verbAction->whatsThis()); m_conjunctionAction = new QAction(this); m_conjunctionAction->setText(i18n("Conjunction")); m_conjunctionAction->setCheckable(true); m_conjunctionAction->setWhatsThis(i18n("This word type folder contains conjunctions.")); m_conjunctionAction->setToolTip(m_conjunctionAction->whatsThis()); m_conjunctionAction->setStatusTip(m_conjunctionAction->whatsThis()); m_conjunctionAction->setStatusTip(m_conjunctionAction->whatsThis()); m_noneAction = new QAction(this); m_noneAction->setText(i18n("No Special Type")); m_noneAction->setCheckable(true); m_noneAction->setChecked(true); m_noneAction->setWhatsThis(i18n("This word type folder contains no word type with special meaning.")); m_noneAction->setToolTip(m_noneAction->whatsThis()); m_noneAction->setStatusTip(m_noneAction->whatsThis()); m_noneAction->setStatusTip(m_noneAction->whatsThis()); QAction* separator = new QAction(this); separator->setSeparator(true); m_actionSpecialTypeMenu->addAction(m_noneAction); m_actionSpecialTypeMenu->addAction(separator); m_actionSpecialTypeMenu->addAction(m_nounAction); m_actionSpecialTypeMenu->addAction(m_nounMaleAction); m_actionSpecialTypeMenu->addAction(m_nounFemaleAction); m_actionSpecialTypeMenu->addAction(m_nounNeutralAction); m_actionSpecialTypeMenu->addAction(m_adjectiveAction); m_actionSpecialTypeMenu->addAction(m_adverbAction); m_actionSpecialTypeMenu->addAction(m_verbAction); m_actionSpecialTypeMenu->addAction(m_conjunctionAction); connect(m_actionNewWordType, &QAction::triggered, this, &WordTypeView::slotCreateNewWordType); connect(m_actionRenameWordType, &QAction::triggered, this, &WordTypeView::slotRename); connect(m_actionDeleteWordType, &QAction::triggered, this, &WordTypeView::slotDeleteWordType); // right click menu for the WordType view: addAction(m_actionNewWordType); addAction(m_actionRenameWordType); addAction(m_actionDeleteWordType); separator = new QAction(this); separator->setSeparator(true); addAction(separator); separator = new QAction(this); separator->setSeparator(true); addAction(separator); addAction(m_actionSpecialTypeMenu); connect(m_noneAction, &QAction::triggered, this, &WordTypeView::setWordTypeNone); connect(m_nounAction, &QAction::triggered, this, &WordTypeView::setWordTypeNoun); connect(m_nounMaleAction, &QAction::triggered, this, &WordTypeView::setWordTypeNounMale); connect(m_nounFemaleAction, &QAction::triggered, this, &WordTypeView::setWordTypeNounFemale); connect(m_nounNeutralAction, &QAction::triggered, this, &WordTypeView::setWordTypeNounNeutral); connect(m_adjectiveAction, &QAction::triggered, this, &WordTypeView::setWordTypeAdjective); connect(m_adverbAction, &QAction::triggered, this, &WordTypeView::setWordTypeAdverb); connect(m_verbAction, &QAction::triggered, this, &WordTypeView::setWordTypeVerb); connect(m_conjunctionAction, &QAction::triggered, this, &WordTypeView::setWordTypeConjunction); } void WordTypeView::setTranslation(KEduVocExpression * entry, int translation) { if (entry == 0) { return; } // attempt to find the container to select QModelIndex index(m_model->index(entry->translation(translation)->wordType())); scrollTo(index); selectionModel()->select(index, QItemSelectionModel::ClearAndSelect); } void WordTypeView::slotCreateNewWordType() { QModelIndex selectedIndex = selectionModel()->currentIndex(); if (!selectedIndex.isValid()) { selectedIndex = m_model->index(0, 0, QModelIndex()); } QModelIndex modelIndex = m_model->appendContainer(selectedIndex); scrollTo(modelIndex); selectionModel()->setCurrentIndex(modelIndex, QItemSelectionModel::ClearAndSelect); edit(modelIndex); // let the user type a new name for the WordType } void WordTypeView::slotDeleteWordType() { QModelIndex selectedIndex = selectionModel()->currentIndex(); if (selectedIndex.parent() == QModelIndex()) { KMessageBox::information(this, i18n("The root word type cannot be deleted.")); return; } KEduVocWordType* WordType = static_cast(selectedIndex.internalPointer()); int count = WordType->entryCount(); if (count == 0 || KMessageBox::warningYesNo(this, i18np("There is a word left with this word type. It will lose its type. Continue?", "There are %1 words left with this word type. They will lose their word type. Continue?", count)) == KMessageBox::Yes) { m_model->deleteContainer(selectedIndex); } } void WordTypeView::contextMenuEvent(QContextMenuEvent * event) { // check for the root element: QModelIndex selectedIndex = selectionModel()->currentIndex(); m_actionRenameWordType->setEnabled(selectedIndex.parent() != QModelIndex()); m_actionDeleteWordType->setEnabled(selectedIndex.parent() != QModelIndex()); m_actionSpecialTypeMenu->setEnabled(selectedIndex.parent() != QModelIndex()); if (selectedIndex.isValid()) { KEduVocWordFlags t = (static_cast(selectionModel()->currentIndex().internalPointer())->wordType()); if (!t) m_noneAction->setChecked(true); else if (t.testFlag(KEduVocWordFlag::Noun) && t.testFlag(KEduVocWordFlag::Masculine)) m_nounMaleAction->setChecked(true); else if (t.testFlag(KEduVocWordFlag::Noun) && t.testFlag(KEduVocWordFlag::Feminine)) m_nounFemaleAction->setChecked(true); else if (t.testFlag(KEduVocWordFlag::Noun) && t.testFlag(KEduVocWordFlag::Neuter)) m_nounNeutralAction->setChecked(true); else if (t.testFlag(KEduVocWordFlag::Noun)) m_nounAction->setChecked(true); else if (t.testFlag(KEduVocWordFlag::Adjective)) m_adjectiveAction->setChecked(true); else if (t.testFlag(KEduVocWordFlag::Adverb)) m_adverbAction->setChecked(true); else if (t.testFlag(KEduVocWordFlag::Verb)) m_verbAction->setChecked(true); else if (t.testFlag(KEduVocWordFlag::Conjunction)) m_conjunctionAction->setChecked(true); } QMenu::exec(actions(), event->globalPos()); } void WordTypeView::setWordTypeNone() { KEduVocWordType* wordType = static_cast(selectionModel()->currentIndex().internalPointer()); wordType->setWordType(KEduVocWordFlag::NoInformation); } void WordTypeView::setWordTypeNoun() { KEduVocWordType* wordType = static_cast(selectionModel()->currentIndex().internalPointer()); wordType->setWordType(KEduVocWordFlag::Noun); } void WordTypeView::setWordTypeNounMale() { KEduVocWordType* wordType = static_cast(selectionModel()->currentIndex().internalPointer()); wordType->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Masculine); } void WordTypeView::setWordTypeNounFemale() { KEduVocWordType* wordType = static_cast(selectionModel()->currentIndex().internalPointer()); wordType->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Feminine); } void WordTypeView::setWordTypeNounNeutral() { KEduVocWordType* wordType = static_cast(selectionModel()->currentIndex().internalPointer()); wordType->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Neuter); } void WordTypeView::setWordTypeAdjective() { KEduVocWordType* wordType = static_cast(selectionModel()->currentIndex().internalPointer()); wordType->setWordType(KEduVocWordFlag::Adjective); } void WordTypeView::setWordTypeAdverb() { KEduVocWordType* wordType = static_cast(selectionModel()->currentIndex().internalPointer()); wordType->setWordType(KEduVocWordFlag::Adverb); } void WordTypeView::setWordTypeVerb() { KEduVocWordType* wordType = static_cast(selectionModel()->currentIndex().internalPointer()); wordType->setWordType(KEduVocWordFlag::Verb); } void WordTypeView::setWordTypeConjunction() { KEduVocWordType* wordType = static_cast(selectionModel()->currentIndex().internalPointer()); wordType->setWordType(KEduVocWordFlag::Conjunction); } diff --git a/src/editor/wordtypeview.h b/src/editor/wordtypeview.h index 9c81262c..0fddec2b 100644 --- a/src/editor/wordtypeview.h +++ b/src/editor/wordtypeview.h @@ -1,82 +1,81 @@ /*************************************************************************** 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 WORDTYPEVIEW_H #define WORDTYPEVIEW_H -#include "wordtypeview.h" #include "containerview.h" class QAction; class KSelectAction; class KEduVocWordType; class KEduVocExpression; namespace Editor { class EditorWindow; class WordTypeView : public ContainerView { Q_OBJECT public: explicit WordTypeView(EditorWindow *parent); public slots: /** Append a word type to the model and automatically set an edit up so the user can change "New lesson" into something meaningful.*/ void slotCreateNewWordType(); /** Remove a word type. */ void slotDeleteWordType(); void setTranslation(KEduVocExpression* entry, int translationId); signals: void selectedWordTypeChanged(KEduVocWordType* wordType); protected: void contextMenuEvent(QContextMenuEvent * event) Q_DECL_OVERRIDE; private slots: void setWordTypeNone(); void setWordTypeNoun(); void setWordTypeNounMale(); void setWordTypeNounFemale(); void setWordTypeNounNeutral(); void setWordTypeAdjective(); void setWordTypeAdverb(); void setWordTypeVerb(); void setWordTypeConjunction(); private: QAction *m_actionNewWordType; QAction *m_actionDeleteWordType; QAction *m_actionRenameWordType; KSelectAction *m_actionSpecialTypeMenu; QAction *m_noneAction; QAction *m_separator; QAction *m_nounAction; QAction *m_nounMaleAction; QAction *m_nounFemaleAction; QAction *m_nounNeutralAction; QAction *m_adjectiveAction; QAction *m_adverbAction; QAction *m_verbAction; QAction *m_conjunctionAction; }; } #endif diff --git a/src/statistics/lessonstatisticsview.cpp b/src/statistics/lessonstatisticsview.cpp index d1b59f5e..31f8f04b 100644 --- a/src/statistics/lessonstatisticsview.cpp +++ b/src/statistics/lessonstatisticsview.cpp @@ -1,254 +1,254 @@ /*************************************************************************** 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. * * * ***************************************************************************/ // Own #include "lessonstatisticsview.h" // Qt #include #include #include #include // KDE #include #include #include #include #include // Parley #include "statisticslegendwidget.h" #include "statisticsmodel.h" #include "keduvoclesson.h" #include "utils.h" #include "documentsettings.h" // GradeDelegate shows the graphic colored bar in the statistics, // showing how far the student has come on the way to enlightenment. class GradeDelegate: public QItemDelegate { public: GradeDelegate(QObject *parent = 0) : QItemDelegate(parent) { } void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE { QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, 0); // empty lesson? If so, paint nothing. if (!index.data(StatisticsModel::TotalCount).toInt()) { return; } // Draw the colored bar. KEduVocContainer *container = index.data(StatisticsModel::Container) .value(); QStringList activeConjugationTenses = index.data(StatisticsModel::ActiveConjugationTenses) .toStringList(); WordCount wordCount; wordCount.fillFromContainerForPracticeMode( *container, - index.column() - ContainerModel::FirstDataColumn, + index.column() - KEduVocContainerModel::FirstDataColumn, activeConjugationTenses ); ConfidenceColors colors(ConfidenceColors::ProgressiveColorScheme); paintColorBar(*painter, option.rect, wordCount, colors); // in utils // Draw the text telling the percentage on top of the bar. painter->drawText(option.rect, Qt::AlignCenter, QStringLiteral("%1%").arg(index.data(StatisticsModel::TotalPercent).toInt())); } }; // ---------------------------------------------------------------- LessonStatisticsView::LessonStatisticsView(QWidget *parent) : ContainerView(parent) { header()->setVisible(true); header()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignBottom); header()->setSectionsMovable( true ); // inherits context menu policy - so action will show up in right click menu QAction *removeGradesAction = new QAction(this); removeGradesAction->setText(i18n("Remove confidence levels from this unit")); removeGradesAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-clear"))); removeGradesAction->setWhatsThis(i18n("Remove confidence levels from this unit")); removeGradesAction->setToolTip(removeGradesAction->whatsThis()); removeGradesAction->setStatusTip(removeGradesAction->whatsThis()); connect(removeGradesAction, &QAction::triggered, this, &LessonStatisticsView::removeGrades); addAction(removeGradesAction); QAction *removeGradesChildrenAction = new QAction(this); removeGradesChildrenAction->setText(i18n("Remove confidence levels from this unit and all sub-units")); removeGradesChildrenAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-clear"))); removeGradesChildrenAction->setWhatsThis(i18n("Remove confidence level from this unit and all sub-units")); removeGradesChildrenAction->setToolTip(removeGradesChildrenAction->whatsThis()); removeGradesChildrenAction->setStatusTip(removeGradesChildrenAction->whatsThis()); connect(removeGradesChildrenAction, &QAction::triggered, this, &LessonStatisticsView::removeGradesChildren); addAction(removeGradesChildrenAction); connect(header(), &QHeaderView::geometriesChanged, this, &LessonStatisticsView::adjustColumnWidths); connect(header(), &QHeaderView::sectionResized, this, &LessonStatisticsView::sectionResized); } LessonStatisticsView::~LessonStatisticsView() { saveExpandedStatus(); } -void LessonStatisticsView::setModel(ContainerModel *model) +void LessonStatisticsView::setModel(KEduVocContainerModel *model) { ContainerView::setModel(model); GradeDelegate *delegate = new GradeDelegate(this); - for (int i = ContainerModel::FirstDataColumn; i < model->columnCount(QModelIndex()); i++) { + for (int i = KEduVocContainerModel::FirstDataColumn; i < model->columnCount(QModelIndex()); i++) { setItemDelegateForColumn(i, delegate); } adjustColumnWidths(); } void LessonStatisticsView::resizeEvent(QResizeEvent *event) { adjustColumnWidths(); ContainerView::resizeEvent(event); } void LessonStatisticsView::sectionResized(int index, int /*oldSize*/, int /*newSize*/) { - if (index < ContainerModel::FirstDataColumn) { + if (index < KEduVocContainerModel::FirstDataColumn) { adjustColumnWidths(); } } void LessonStatisticsView::adjustColumnWidths() { int firstWidth = columnWidth(0) + columnWidth(1); int totalWidth = viewport()->width() - firstWidth; int columnCount = model()->columnCount(QModelIndex()); int visibleColumns = 0; - for (int i = ContainerModel::FirstDataColumn; i < columnCount; ++i) { + for (int i = KEduVocContainerModel::FirstDataColumn; i < columnCount; ++i) { if (!isColumnHidden(i)) visibleColumns++; } int columnWidth = visibleColumns > 0 ? totalWidth / visibleColumns : 150; - for (int i = ContainerModel::FirstDataColumn; i < model()->columnCount(QModelIndex()); i++) { + for (int i = KEduVocContainerModel::FirstDataColumn; i < model()->columnCount(QModelIndex()); i++) { setColumnWidth(i, columnWidth); } // header()->resizeSections(QHeaderView::ResizeToContents); header()->setSectionResizeMode(QHeaderView::Interactive); header()->setStretchLastSection(true); } void LessonStatisticsView::removeGrades() { QModelIndex selectedIndex = selectionModel()->currentIndex(); KEduVocLesson *lesson = static_cast(selectedIndex.internalPointer()); lesson->resetGrades(-1, KEduVocContainer::NotRecursive); } void LessonStatisticsView::removeGradesChildren() { QModelIndex selectedIndex = selectionModel()->currentIndex(); KEduVocLesson *lesson = static_cast(selectedIndex.internalPointer()); lesson->resetGrades(-1, KEduVocContainer::Recursive); } void LessonStatisticsView::saveExpandedStatus() const { auto statisticsModel = qobject_cast(model()); Q_ASSERT(statisticsModel != nullptr); QStringList collapsedItems; getCollapsedItems(collapsedItems, statisticsModel->index(0, 0, QModelIndex()), QString()); const KEduVocDocument *doc = statisticsModel->document(); if (doc != nullptr) { DocumentSettings documentSettings(doc->url().url()); documentSettings.setCollapsedStatisticsViewItems(collapsedItems); documentSettings.save(); } } void LessonStatisticsView::getCollapsedItems(QStringList &collapsedItems, const QModelIndex &item, QString name) const { if (!item.isValid()) { return; } int rowCount = model()->rowCount(item); if (rowCount > 0) { // Item has children and therefore expandable name += item.data().toString(); if (!isExpanded(item)) { collapsedItems << name; } for (int row = 0; row < rowCount; ++row) { getCollapsedItems(collapsedItems, model()->index(row, 0, item), name + '/'); } } } void LessonStatisticsView::restoreExpandedStatus() { auto statisticsModel = qobject_cast(model()); Q_ASSERT(statisticsModel != nullptr); const KEduVocDocument *doc = statisticsModel->document(); if (doc != nullptr) { DocumentSettings documentSettings(doc->url().url()); documentSettings.load(); QStringList collapsedItems = documentSettings.collapsedStatisticsViewItems(); setCollapsedItems(collapsedItems, statisticsModel->index(0, 0, QModelIndex()), QString()); } } void LessonStatisticsView::setCollapsedItems(const QStringList &collapsedItems, const QModelIndex &item, QString name) { if (!item.isValid()) { return; } int rowCount = model()->rowCount(item); if (rowCount > 0) { // Item has children and therefore expandable name += item.data().toString(); if (collapsedItems.contains(name)) { collapse(item); } else { expand(item); } for (int row = 0; row < rowCount; ++row) { setCollapsedItems(collapsedItems, model()->index(row, 0, item), name + '/'); } } } diff --git a/src/statistics/lessonstatisticsview.h b/src/statistics/lessonstatisticsview.h index ca26b357..73b56fcd 100644 --- a/src/statistics/lessonstatisticsview.h +++ b/src/statistics/lessonstatisticsview.h @@ -1,57 +1,57 @@ /*************************************************************************** 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 LESSONSTATISTICSVIEW_H #define LESSONSTATISTICSVIEW_H #include "containerview.h" /** * View for the lesson list. * @author Frederik Gladhorn */ class LessonStatisticsView : public ContainerView { Q_OBJECT public: explicit LessonStatisticsView(QWidget *parent); ~LessonStatisticsView(); - void setModel(ContainerModel *model) Q_DECL_OVERRIDE; + void setModel(KEduVocContainerModel *model) Q_DECL_OVERRIDE; void saveExpandedStatus() const; void restoreExpandedStatus(); public Q_SLOTS: void adjustColumnWidths(); protected: void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; private Q_SLOTS: void removeGrades(); void removeGradesChildren(); void sectionResized(int index, int /*oldSize*/, int /*newSize*/); private: void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE { Q_UNUSED(model) } void getCollapsedItems(QStringList &collapsedItems, const QModelIndex &item, QString name) const; void setCollapsedItems(const QStringList &collapsedItems, const QModelIndex &item, QString name); }; #endif diff --git a/src/statistics/statisticsmainwindow.cpp b/src/statistics/statisticsmainwindow.cpp index 016b1297..ee74dfe0 100644 --- a/src/statistics/statisticsmainwindow.cpp +++ b/src/statistics/statisticsmainwindow.cpp @@ -1,335 +1,335 @@ /*************************************************************************** Copyright 2008-2010 Frederik Gladhorn Copyright 2008 Daniel Laidig *************************************************************************** *************************************************************************** * * * 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 "statisticsmainwindow.h" #include #include #include #include #include #include "practice/configure/configurepracticedialog.h" #include "lessonstatisticsview.h" #include "statisticsmodel.h" #include "parleymainwindow.h" #include "parleyactions.h" #include "prefs.h" #include "ui_statisticsmainwindow.h" #include "conjugationoptions.h" StatisticsMainWindow::StatisticsMainWindow(KEduVocDocument *doc, ParleyMainWindow *parent) : KXmlGuiWindow(parent) , m_mainWindow(parent) , m_doc(doc) , m_ui(new Ui::StatisticsMainWindow) , m_conjugationOptions(0) { // KXmlGui setXMLFile(QStringLiteral("statisticsui.rc")); setObjectName(QStringLiteral("Statistics")); QWidget *mainWidget = new QWidget(this); setCentralWidget(mainWidget); m_ui->setupUi(mainWidget); //m_ui->caption->setText(i18nc("caption for an overview of the confidence levels for a document" // "Statistics for \"%1\"", m_doc->title())); m_statisticsModel = new StatisticsModel(this); setDocument(doc); initActions(); initPracticeModeSelection(); initLanguages(); initPracticeMode(); KConfigGroup cfg(KSharedConfig::openConfig(QStringLiteral("parleyrc")), objectName()); applyMainWindowSettings(cfg); } StatisticsMainWindow::~StatisticsMainWindow() { if (m_conjugationOptions) { m_conjugationOptions->updateSettings(); } KConfigGroup cfg(KSharedConfig::openConfig(QStringLiteral("parleyrc")), objectName()); saveMainWindowSettings(cfg); delete m_ui; } void StatisticsMainWindow::syncConfig() { //qDebug() << "save tenses"; if (m_conjugationOptions) { m_conjugationOptions->updateSettings(); } } void StatisticsMainWindow::setDocument(KEduVocDocument* doc) { m_doc = doc; m_statisticsModel->setDocument(doc); m_ui->lessonStatistics->setModel(m_statisticsModel); m_ui->lessonStatistics->restoreExpandedStatus(); m_ui->lessonStatistics->resizeColumnToContents(0); } void StatisticsMainWindow::initActions() { ParleyActions::create(ParleyActions::EnterEditMode, m_mainWindow, SLOT(showEditor()), actionCollection()); ParleyActions::create(ParleyActions::StartPractice, m_mainWindow, SLOT(startPractice()), actionCollection()); ParleyActions::create(ParleyActions::ConfigurePractice, m_mainWindow, SLOT(configurePractice()), actionCollection()); } void StatisticsMainWindow::initPracticeModeSelection() { switch (Prefs::practiceMode()) { case Prefs::EnumPracticeMode::FlashCardsPractice: m_ui->flashCard->setChecked(true); break; case Prefs::EnumPracticeMode::MixedLettersPractice: m_ui->mixedLetters->setChecked(true); break; case Prefs::EnumPracticeMode::MultipleChoicePractice: m_ui->multipleChoice->setChecked(true); break; case Prefs::EnumPracticeMode::WrittenPractice: m_ui->written->setChecked(true); break; case Prefs::EnumPracticeMode::ExampleSentencesPractice: m_ui->exampleSentence->setChecked(true); break; case Prefs::EnumPracticeMode::GenderPractice: m_ui->gender->setChecked(true); break; case Prefs::EnumPracticeMode::ComparisonPractice: m_ui->comparisonForms->setChecked(true); break; case Prefs::EnumPracticeMode::ConjugationPractice: m_ui->conjugations->setChecked(true); showConjugationOptions(); break; default: break; } connect(m_ui->flashCard, &QRadioButton::clicked, this, [=] {practiceModeSelected(Prefs::EnumPracticeMode::FlashCardsPractice);}); connect(m_ui->mixedLetters, &QRadioButton::clicked, this, [=] {practiceModeSelected(Prefs::EnumPracticeMode::MixedLettersPractice);}); connect(m_ui->multipleChoice, &QRadioButton::clicked, this, [=] {practiceModeSelected(Prefs::EnumPracticeMode::MultipleChoicePractice);}); connect(m_ui->written, &QRadioButton::clicked, this, [=] {practiceModeSelected(Prefs::EnumPracticeMode::WrittenPractice);}); connect(m_ui->exampleSentence, &QRadioButton::clicked, this, [=] {practiceModeSelected(Prefs::EnumPracticeMode::ExampleSentencesPractice);}); connect(m_ui->gender, &QRadioButton::clicked, this, [=] {practiceModeSelected(Prefs::EnumPracticeMode::GenderPractice);}); connect(m_ui->comparisonForms, &QRadioButton::clicked, this, [=] {practiceModeSelected(Prefs::EnumPracticeMode::ComparisonPractice);}); connect(m_ui->conjugations, &QRadioButton::clicked, this, [=] {practiceModeSelected(Prefs::EnumPracticeMode::ConjugationPractice);}); } void StatisticsMainWindow::initLanguages() { //qDebug() << "init languages: " << Prefs::learningLanguage() << Prefs::knownLanguage(); const int totalNumLanguages = m_doc->identifierCount(); if ( Prefs::knownLanguage() < 0 || totalNumLanguages <= Prefs::knownLanguage() ) { Prefs::setKnownLanguage(0); } if ( Prefs::learningLanguage() < 0 || totalNumLanguages <= Prefs::learningLanguage() ) { Prefs::setLearningLanguage(0); } if (Prefs::knownLanguage() >= totalNumLanguages || Prefs::learningLanguage() >= totalNumLanguages || Prefs::learningLanguage() == Prefs::knownLanguage()) { Prefs::setKnownLanguage(0); Prefs::setLearningLanguage(1); //qDebug() << "Invalid language selection."; } // Insert data into the comboboxes. for (int i = 0; i < totalNumLanguages; ++i) { m_ui->learnedLanguage->insertItem(i, m_doc->identifier(i).name()); m_ui->knownLanguage->insertItem(i, m_doc->identifier(i).name()); } m_ui->learnedLanguage->setCurrentIndex(Prefs::learningLanguage()); m_ui->knownLanguage->setCurrentIndex(Prefs::knownLanguage()); connect(m_ui->learnedLanguage, SIGNAL(currentIndexChanged(int)), SLOT(languagesChanged())); connect(m_ui->knownLanguage, SIGNAL(currentIndexChanged(int)), SLOT(languagesChanged())); languagesChanged(); } void StatisticsMainWindow::languagesChanged() { int knownLanguage = m_ui->knownLanguage->currentIndex(); int learningLanguage = m_ui->learnedLanguage->currentIndex(); Prefs::setLearningLanguage(learningLanguage); Prefs::setKnownLanguage(knownLanguage); emit languagesChanged(knownLanguage, learningLanguage); updateVisibleColumns(); updateModelSettings(); } void StatisticsMainWindow::initPracticeMode() { m_ui->practiceDirection->insertItem(0, i18n("Known to Learning")); m_ui->practiceDirection->insertItem(1, i18n("Learning to Known")); m_ui->practiceDirection->insertItem(2, i18n("Mixed Directions")); //m_ui->practiceDirection->insertItem(3, i18n("Mixed Directions with Sound")); int practiceDirection(Prefs::rememberPracticeDirection() ? practiceDirectionForPracticeMode(Prefs::practiceMode()) : Prefs::practiceDirection()); if (practiceDirection < 0 || 3 < practiceDirection) Prefs::setPracticeDirection(Prefs::EnumPracticeDirection::MixedDirectionsWordsOnly); m_ui->practiceDirection->setCurrentIndex(practiceDirection); connect(m_ui->practiceDirection, static_cast(&QComboBox::currentIndexChanged), this, &StatisticsMainWindow::practiceDirectionChanged); m_ui->rememberPracticeDirection->setChecked(Prefs::rememberPracticeDirection()); connect(m_ui->rememberPracticeDirection, &QCheckBox::toggled, this, &StatisticsMainWindow::rememberPracticeDirectionChanged); } void StatisticsMainWindow::practiceModeSelected(int mode) { int previousPracticeMode = Prefs::practiceMode(); Prefs::setPracticeMode(static_cast(mode)); //qDebug() << "mode: " << mode << Prefs::practiceMode(); showConjugationOptions(mode == Prefs::EnumPracticeMode::ConjugationPractice); if (Prefs::rememberPracticeDirection()) { setPracticeDirectionForPracticeMode(Prefs::practiceDirection(), previousPracticeMode); m_ui->practiceDirection->setCurrentIndex(practiceDirectionForPracticeMode(mode)); } updateModelSettings(); } void StatisticsMainWindow::practiceDirectionChanged(int mode) { //qDebug() << "new practice direction:" << mode; Prefs::setPracticeDirection(static_cast(mode)); if (Prefs::rememberPracticeDirection()) { setPracticeDirectionForPracticeMode(mode, Prefs::practiceMode()); } updateVisibleColumns(); updateModelSettings(); } void StatisticsMainWindow::rememberPracticeDirectionChanged(bool checked) { // qDebug() << "remember practice direction changed to: " << checked; Prefs::setRememberPracticeDirection(checked); if (checked) { setPracticeDirectionForPracticeMode(Prefs::practiceDirection(), Prefs::practiceMode()); } } void StatisticsMainWindow::updateVisibleColumns() { bool isHidden; - for (int i = ContainerModel::FirstDataColumn; i < m_ui->lessonStatistics->header()->count(); i++) { - int iLang = i - ContainerModel::FirstDataColumn; + for (int i = KEduVocContainerModel::FirstDataColumn; i < m_ui->lessonStatistics->header()->count(); i++) { + int iLang = i - KEduVocContainerModel::FirstDataColumn; switch (Prefs::practiceDirection()) { case Prefs::EnumPracticeDirection::LearningToKnown: isHidden = iLang != Prefs::knownLanguage(); break; case Prefs::EnumPracticeDirection::MixedDirectionsWordsOnly: case Prefs::EnumPracticeDirection::MixedDirectionsWithSound: isHidden = iLang != Prefs::knownLanguage() && iLang != Prefs::learningLanguage(); break; case Prefs::EnumPracticeDirection::KnownToLearning: // Use KnownToLearning as default. default: isHidden = iLang != Prefs::learningLanguage(); break; } m_ui->lessonStatistics->setColumnHidden(i, isHidden); m_ui->lessonStatistics->adjustColumnWidths(); } } void StatisticsMainWindow::showConjugationOptions(bool visible) { if (!m_conjugationOptions && !visible) { return; } if (!m_conjugationOptions) { m_conjugationOptions = new ConjugationOptions(m_doc, m_ui->modeSpecificOptions); QHBoxLayout* layout = new QHBoxLayout(m_ui->modeSpecificOptions); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(m_conjugationOptions); connect(this, QOverload::of(&StatisticsMainWindow::languagesChanged), m_conjugationOptions, &ConjugationOptions::setLanguages); m_conjugationOptions->setLanguages(Prefs::knownLanguage(), Prefs::learningLanguage()); connect(m_conjugationOptions, &ConjugationOptions::checkBoxChanged, this, &StatisticsMainWindow::updateModelSettings); } m_conjugationOptions->setVisible(visible); } void StatisticsMainWindow::configurePractice() { ConfigurePracticeDialog dialog(m_doc, this, QStringLiteral("practice settings"), Prefs::self()); dialog.exec(); } int StatisticsMainWindow::practiceDirectionForPracticeMode(int mode) const { int direction = Prefs::practiceDirectionsByPracticeMode().value(mode, Prefs::practiceDirection()); if ((direction < 0) || (direction > Prefs::EnumPracticeDirection::MixedDirectionsWordsOnly)) { direction = Prefs::EnumPracticeDirection::MixedDirectionsWordsOnly; } return direction; } void StatisticsMainWindow::setPracticeDirectionForPracticeMode(int direction, int mode) { QList directions = Prefs::practiceDirectionsByPracticeMode(); // Expand list if fields not used before for (int i = directions.size() - 1; i < mode; ++i) { directions.append(Prefs::practiceDirection()); } directions[mode] = direction; Prefs::setPracticeDirectionsByPracticeMode(directions); } void StatisticsMainWindow::updateModelSettings() { m_ui->lessonStatistics->saveExpandedStatus(); m_statisticsModel->updateDocumentSettings(); m_ui->lessonStatistics->restoreExpandedStatus(); } diff --git a/src/statistics/statisticsmodel.cpp b/src/statistics/statisticsmodel.cpp index c2d791b4..4a827666 100644 --- a/src/statistics/statisticsmodel.cpp +++ b/src/statistics/statisticsmodel.cpp @@ -1,207 +1,207 @@ /*************************************************************************** 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. * * * ***************************************************************************/ #include "statisticsmodel.h" #include "statisticslegendwidget.h" #include "utils.h" #include #include #include #include #include #include StatisticsModel::StatisticsModel(QObject *parent) - : ContainerModel(KEduVocContainer::Lesson, parent) + : KEduVocContainerModel(KEduVocContainer::Lesson, parent) { } QVariant StatisticsModel::headerData(int section, Qt::Orientation orientation, int role) const { if (section >= FirstDataColumn) { if (role == Qt::DisplayRole && document()->identifierCount() > (section - FirstDataColumn) ) { return i18nc("Confidence level in language, table header", "Confidence (%1)" , document()->identifier(section - FirstDataColumn).name()); } } - return ContainerModel::headerData(section, orientation, role); + return KEduVocContainerModel::headerData(section, orientation, role); } QVariant StatisticsModel::data(const QModelIndex &index, int role) const { Q_ASSERT(!m_documentSettings.isEmpty()); KEduVocContainer *container = static_cast(index.internalPointer()); // Entrie count if (index.column() == TotalCountColumn) { if (role == Qt::DisplayRole) { switch (Prefs::practiceDirection()) { case Prefs::EnumPracticeDirection::KnownToLearning: return entryCountForPracticeMode(container, Prefs::learningLanguage()); case Prefs::EnumPracticeDirection::LearningToKnown: return entryCountForPracticeMode(container, Prefs::knownLanguage()); case Prefs::EnumPracticeDirection::MixedDirectionsWordsOnly: case Prefs::EnumPracticeDirection::MixedDirectionsWithSound: return entryCountForPracticeMode(container, Prefs::knownLanguage()) + entryCountForPracticeMode(container, Prefs::learningLanguage()); default: return entryCountForPracticeMode(container, Prefs::learningLanguage()); } } if (role == Qt::TextAlignmentRole) { return Qt::AlignRight; } } // Colorbars if (index.column() >= FirstDataColumn) { int translation = index.column() - FirstDataColumn; switch (role) { case Container: { // Return a pointer to the container we are working on. QVariant var; var.setValue(container); return var; } case TotalPercent: // Average grade return averageGradeForPracticeMode(container, translation); case TotalCount: return entryCountForPracticeMode(container, translation); case ActiveConjugationTenses: return m_documentSettings.at(translation)->conjugationTenses(); default: if ((role >= Grade0) && (role <= Grade7)) { return expressionsOfGradeForPracticeMode(container, translation, role - Grade0); } } } // Checkboxes if (index.column() == 0 && role == Qt::CheckStateRole) { if (container->inPractice()) { return Qt::Checked; } else { return Qt::Unchecked; } } - return ContainerModel::data(index, role); + return KEduVocContainerModel::data(index, role); } int StatisticsModel::averageGradeForPracticeMode(KEduVocContainer *container, int translation) const { WordCount wordCount; wordCount.fillFromContainerForPracticeMode( *container, translation, m_documentSettings.at(translation)->conjugationTenses() ); return wordCount.percentageCompleted(); } int StatisticsModel::entryCountForPracticeMode(KEduVocContainer *container, int translation) const { WordCount wordCount; wordCount.fillFromContainerForPracticeMode( *container, translation, m_documentSettings.at(translation)->conjugationTenses() ); return wordCount.totalWords - wordCount.invalid; } int StatisticsModel::expressionsOfGradeForPracticeMode(KEduVocContainer *container, int translation, grade_t grade) const { WordCount wordCount; wordCount.fillFromContainerForPracticeMode( *container, translation, m_documentSettings.at(translation)->conjugationTenses() ); return wordCount.grades[grade]; } Qt::ItemFlags StatisticsModel::flags(const QModelIndex &index) const { if (index.isValid()) { if (index.column() == 0) { return (Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); } return (Qt::ItemIsEnabled | Qt::ItemIsSelectable); } return 0; } int StatisticsModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent) return document()->identifierCount() + FirstDataColumn; } Qt::DropActions StatisticsModel::supportedDragActions() const { return 0; } KEduVocContainer *StatisticsModel::rootContainer() const { if (!document()) { return 0; } return document()->lesson(); } void StatisticsModel::loadDocumentsSettings() { m_documentSettings.clear(); if (m_doc == nullptr) { return; } for (int i = 0 ; i < m_doc->identifierCount(); ++i) { m_documentSettings << QSharedPointer( new DocumentSettings(m_doc->url().url() + QString::number(i)) ); m_documentSettings.last()->load(); } } void StatisticsModel::setDocument(KEduVocDocument *doc) { beginResetModel(); m_doc = doc; loadDocumentsSettings(); endResetModel(); } void StatisticsModel::updateDocumentSettings() { beginResetModel(); loadDocumentsSettings(); endResetModel(); } const KEduVocDocument *StatisticsModel::document() const { return m_doc; } diff --git a/src/statistics/statisticsmodel.h b/src/statistics/statisticsmodel.h index 902efbaa..76e4498e 100644 --- a/src/statistics/statisticsmodel.h +++ b/src/statistics/statisticsmodel.h @@ -1,81 +1,81 @@ /*************************************************************************** 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 STATISTICSMODEL_H #define STATISTICSMODEL_H -#include "containermodel.h" +#include #include "prefs.h" #include "documentsettings.h" -class StatisticsModel : public ContainerModel +class StatisticsModel : public KEduVocContainerModel { Q_OBJECT public: enum GradeRoles { TotalPercent = Qt::UserRole, TotalCount, Grade0, Grade1, Grade2, Grade3, Grade4, Grade5, Grade6, Grade7, Container, ActiveConjugationTenses }; explicit StatisticsModel(QObject *parent = 0); QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE; Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; /** Indicate supported drag actions @return enum of actions supported **/ Qt::DropActions supportedDragActions() const Q_DECL_OVERRIDE; void updateDocumentSettings(); const KEduVocDocument *document() const; public slots: virtual void setDocument(KEduVocDocument *doc) Q_DECL_OVERRIDE; protected: KEduVocContainer *rootContainer() const Q_DECL_OVERRIDE; private: int averageGradeForPracticeMode(KEduVocContainer *container, int translation) const; int entryCountForPracticeMode(KEduVocContainer *container, int translation) const; int expressionsOfGradeForPracticeMode(KEduVocContainer *container, int translation, grade_t grade) const; void loadDocumentsSettings(); private: QList> m_documentSettings; }; // For index.data() Q_DECLARE_METATYPE(KEduVocContainer*) #endif