diff --git a/src/collection/readonlycontainermodel.cpp b/src/collection/readonlycontainermodel.cpp index c9964d83..a43d6653 100644 --- a/src/collection/readonlycontainermodel.cpp +++ b/src/collection/readonlycontainermodel.cpp @@ -1,188 +1,188 @@ /*************************************************************************** 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 "readonlycontainermodel.h" #include #include #include "containermimedata.h" #include "vocabularymimedata.h" #include #include #include #include /** @file * Implementation of ReadonlyContainerModel. * Functions to create the model from the lessons of the vocabulary document. */ ReadonlyContainerModel::ReadonlyContainerModel(KEduVocContainer::EnumContainerType type, QObject * parent) : QAbstractItemModel(parent) , m_type(type) , m_doc(0) { } void ReadonlyContainerModel::setDocument(KEduVocDocument * doc) { beginResetModel(); m_doc = doc; if (m_doc) { //qDebug() << "Set Document: " << m_doc->url(); } else { //qDebug() << "Set Invalid Document"; } endResetModel(); } QModelIndex ReadonlyContainerModel::index(int row, int column, const QModelIndex &parent) const { if (!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 ReadonlyContainerModel::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 ReadonlyContainerModel::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 ReadonlyContainerModel::rowCount(const QModelIndex &parent) const { if (parent.column() > 0) { return 0; } KEduVocContainer *parentItem; if (!parent.isValid()) { // root element if (!m_doc) { return 0; } return 1; } else { parentItem = static_cast(parent.internalPointer()); return parentItem->childContainerCount(); } } QVariant ReadonlyContainerModel::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 ReadonlyContainerModel::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; + return Qt::NoItemFlags; } int ReadonlyContainerModel::columnCount(const QModelIndex & parent) const { Q_UNUSED(parent); if (!m_doc) { return 1; } return 1; } KEduVocContainer::EnumContainerType ReadonlyContainerModel::containerType() { return m_type; } diff --git a/src/editor/editor.cpp b/src/editor/editor.cpp index b355760f..195f77f5 100644 --- a/src/editor/editor.cpp +++ b/src/editor/editor.cpp @@ -1,521 +1,521 @@ /*************************************************************************** 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 "vocabularymodel.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" #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 VocabularyModel(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); + rightLayout->addWidget(m_vocabularyView, 1); 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/practice/writtenpracticevalidator.cpp b/src/practice/writtenpracticevalidator.cpp index 32db6f28..394fca82 100644 --- a/src/practice/writtenpracticevalidator.cpp +++ b/src/practice/writtenpracticevalidator.cpp @@ -1,216 +1,216 @@ /*************************************************************************** Copyright 2010 Benjamin Schleinzer Copyright 2007-2010 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 "writtenpracticevalidator.h" #include "testentry.h" #include "prefs.h" #include #include /// temporary namespace for string manipulation functions /// could move into KStringHandler eventually namespace ParleyStringHandlerOld { QString stripAccents(const QString& original) { QString noAccents; QString decomposed = original.normalized(QString::NormalizationForm_D); for (int i = 0; i < decomposed.length(); ++i) { if (decomposed[i].category() != 1) { noAccents.append(decomposed[i]); } } qDebug() << original << " without accents: " << noAccents; return noAccents; } } using namespace Practice; WrittenPracticeValidator::WrittenPracticeValidator(int translation, KEduVocDocument* doc) : m_entry(0), m_doc(doc), m_error(0), m_speller(0), m_spellerAvailable(false) { setLanguage(translation); } WrittenPracticeValidator::~WrittenPracticeValidator() { delete m_speller; } void WrittenPracticeValidator::setEntry(TestEntry* entry) { m_entry = entry; } void WrittenPracticeValidator::setLanguage(int translation) { m_translation = translation; // default: try locale if (!m_speller) { m_speller = new Sonnet::Speller(m_doc->identifier(translation).locale()); } else { m_speller->setLanguage(m_doc->identifier(translation).locale()); } // we might succeed with language name instead. if (!m_speller->isValid()) { m_speller->setLanguage(m_doc->identifier(translation).name()); } if (!m_speller->isValid()) { qDebug() << "No spellchecker for current language found: " << m_doc->identifier(m_translation).locale(); qDebug() << "Available dictionaries: " << m_speller->availableLanguages() << "\n names: " << m_speller->availableLanguageNames() << "\n backends: " << m_speller->availableBackends(); m_spellerAvailable = false; } else { m_spellerAvailable = true; } } bool WrittenPracticeValidator::spellcheckerAvailable() { return m_spellerAvailable; } void WrittenPracticeValidator::validateAnswer(const QString& answer) { if (m_entry == 0) { qCritical() << "No entry set, cannot verify answer."; return; } QString correct = m_entry->entry()->translation(m_entry->languageTo())->text(); qDebug() << "Correct answer should be: " << correct; - m_error = 0; + m_error = {}; //Check for empty answers and valid answers first if (answer.isEmpty()) { m_error |= TestEntry::Wrong; qDebug() << "Empty answer "; } else if (isCorrect(correct, answer)) { m_error |= TestEntry::Correct; } else { //Check for all valid errors to build a list of //possible mistakes. This provides us with useful information //that we can use to give feedback to the user. if (isPunctuationMistake(correct, answer)) { m_error |= TestEntry::Correct; } else if (isCapitalizationMistake(correct, answer)) { m_error |= TestEntry::Correct; } else if (isAccentMistake(correct, answer)) { m_error |= TestEntry::Correct; } else if (isSynonymMistake(answer)) { m_error |= TestEntry::Correct; } else { m_error |= TestEntry::Wrong; qDebug() << "Wrong answer: " << answer; } } qDebug() << "Error code " << m_error; m_entry->setLastErrors(m_error); } QString WrittenPracticeValidator::getCorrectedAnswer() { return m_correctedAnswer; } bool WrittenPracticeValidator::isCorrect(const QString& correct, const QString& answer) { if (answer == correct ) { qDebug() << "Correct answer was given"; return true; } return false; } bool WrittenPracticeValidator::isSynonymMistake(const QString& answer) { foreach(KEduVocTranslation * synonym, m_entry->entry()->translation(m_entry->languageTo())->synonyms()) { if (synonym->text() == answer || (Prefs::ignoreCapitalizationMistakes() && isCapitalizationMistake(synonym->text(), answer)) || (Prefs::ignoreAccentMistakes() && isAccentMistake(synonym->text(), answer)) || (Prefs::ignorePunctuationMistakes() && isPunctuationMistake(synonym->text(), answer))) { qDebug() << "Synonym entered: " << synonym->text() << " answer: " << answer; m_correctedAnswer = synonym->text(); m_error |= TestEntry::Synonym; //only return true if accept these kinds of mistakes //otherwise just set the error flag if (Prefs::countSynonymsAsCorrect()) { return true; } } } return false; } bool WrittenPracticeValidator::isCapitalizationMistake(const QString& original, const QString& answer) { if (answer.toLower() == original.toLower() || (Prefs::ignorePunctuationMistakes() && isPunctuationMistake(original.toLower(),answer.toLower()))) { qDebug() << "CapitalizationMistake: " << original << " answer: " << answer; m_error |= TestEntry::CapitalizationMistake; m_correctedAnswer = answer; //only return true if accept these kinds of mistakes //otherwise just set the error flag if (Prefs::ignoreCapitalizationMistakes()) return true; } return false; } bool WrittenPracticeValidator::isPunctuationMistake(const QString& original, const QString& answer) { QString ans = answer; QString orig = original; if (ans.remove(QRegExp(QStringLiteral("[^a-zA-ZƒŠŒŽšœžŸÀ-ÿ\\s]"))) == orig.remove(QRegExp(QStringLiteral("[^a-zA-ZƒŠŒŽšœžŸÀ-ÿ\\s]")))) { qDebug() << "PunctuationMistake: " << original << " answer: " << answer; m_error |= TestEntry::PunctuationMistake; m_correctedAnswer = answer; //only return true if accept these kinds of mistakes //otherwise just set the error flag if (Prefs::ignorePunctuationMistakes()) return true; } return false; } bool WrittenPracticeValidator::isAccentMistake(const QString& original, const QString& answer) { QString stripedOriginal = ParleyStringHandlerOld::stripAccents(original); QString stripedAnswer = ParleyStringHandlerOld::stripAccents(answer); if (stripedOriginal == stripedAnswer || (Prefs::ignoreCapitalizationMistakes() && isCapitalizationMistake(stripedOriginal, stripedAnswer)) || (Prefs::ignorePunctuationMistakes() && isPunctuationMistake(stripedOriginal, stripedAnswer))) { qDebug() << "AccentMistake: " << original << " answer: " << answer; m_error |= TestEntry::AccentMistake; m_correctedAnswer = answer; //only return true if accept these kinds of mistakes //otherwise just set the error flag if (Prefs::ignoreAccentMistakes()) { return true; } } return false; }