File indexing completed on 2022-11-29 13:00:35

0001 /*
0002     SPDX-FileCopyrightText: 2008 Frederik Gladhorn <frederik.gladhorn@kdemail.net>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "lessonview.h"
0007 
0008 #include "vocabularymodel.h"
0009 #include "vocabularyview.h"
0010 
0011 #include <KActionCollection>
0012 #include <KLocalizedString>
0013 #include <KMessageBox>
0014 #include <QAction>
0015 #include <QInputDialog>
0016 
0017 #include <KEduVocExpression>
0018 #include <KEduVocLesson>
0019 
0020 #include "editor/editor.h"
0021 #include "prefs.h"
0022 
0023 using namespace Editor;
0024 
0025 LessonView::LessonView(EditorWindow *parent)
0026     : ContainerView(parent)
0027     , m_editorWindow(parent)
0028 {
0029     QAction *actionNewLesson = new QAction(this);
0030     parent->actionCollection()->addAction(QStringLiteral("new_lesson"), actionNewLesson);
0031     actionNewLesson->setText(i18n("New Unit"));
0032     actionNewLesson->setIcon(QIcon::fromTheme(QStringLiteral("lesson-add")));
0033     actionNewLesson->setWhatsThis(i18n("Add a new unit to your document"));
0034     actionNewLesson->setToolTip(actionNewLesson->whatsThis());
0035     actionNewLesson->setStatusTip(actionNewLesson->whatsThis());
0036 
0037     QAction *actionRenameLesson = new QAction(this);
0038     parent->actionCollection()->addAction(QStringLiteral("rename_lesson"), actionRenameLesson);
0039     actionRenameLesson->setText(i18n("Rename Unit"));
0040     actionRenameLesson->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename")));
0041     //    actionRenameLesson->setWhatsThis(i18n("Rename the selected unit"));
0042     actionRenameLesson->setToolTip(actionRenameLesson->whatsThis());
0043     actionRenameLesson->setStatusTip(actionRenameLesson->whatsThis());
0044 
0045     QAction *actionDeleteLesson = new QAction(this);
0046     parent->actionCollection()->addAction(QStringLiteral("delete_lesson"), actionDeleteLesson);
0047     actionDeleteLesson->setText(i18n("Delete Unit"));
0048     actionDeleteLesson->setIcon(QIcon::fromTheme(QStringLiteral("lesson-remove")));
0049     actionDeleteLesson->setWhatsThis(i18n("Delete the selected unit."));
0050     actionDeleteLesson->setToolTip(actionDeleteLesson->whatsThis());
0051     actionDeleteLesson->setStatusTip(actionDeleteLesson->whatsThis());
0052 
0053     QAction *actionSplitLesson = new QAction(this);
0054     parent->actionCollection()->addAction(QStringLiteral("split_lesson"), actionSplitLesson);
0055     actionSplitLesson->setText(i18n("Split Unit into Smaller Units"));
0056     actionSplitLesson->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy"))); /// @todo better icon
0057     actionSplitLesson->setWhatsThis(i18n("Make multiple smaller units out of one big unit."));
0058     actionSplitLesson->setToolTip(actionSplitLesson->whatsThis());
0059     actionSplitLesson->setStatusTip(actionSplitLesson->whatsThis());
0060 
0061     QAction *actionMoveToNewLesson = new QAction(this);
0062     parent->actionCollection()->addAction(QStringLiteral("move_to_new_lesson"), actionMoveToNewLesson);
0063     actionMoveToNewLesson->setText(i18n("Move to new lesson"));
0064     actionMoveToNewLesson->setIcon(QIcon::fromTheme(QStringLiteral("edit-move")));
0065     actionMoveToNewLesson->setWhatsThis(i18n("Moves the selected vocabulary to a new lesson"));
0066     actionMoveToNewLesson->setToolTip(actionMoveToNewLesson->whatsThis());
0067     actionMoveToNewLesson->setStatusTip(actionMoveToNewLesson->whatsThis());
0068 
0069     QAction *actionRemoveGradesLesson = new QAction(this);
0070     parent->actionCollection()->addAction(QStringLiteral("remove_grades_lesson"), actionRemoveGradesLesson);
0071     actionRemoveGradesLesson->setText(i18n("Remove Confidence Levels"));
0072     actionRemoveGradesLesson->setIcon(QIcon::fromTheme(QStringLiteral("edit-clear"))); /// @todo better icon
0073     actionRemoveGradesLesson->setWhatsThis(i18n("Remove confidence levels from this unit."));
0074     actionRemoveGradesLesson->setToolTip(actionRemoveGradesLesson->whatsThis());
0075     actionRemoveGradesLesson->setStatusTip(actionRemoveGradesLesson->whatsThis());
0076 
0077     QAction *actionRemoveGradesLessonChildren = new QAction(this);
0078     parent->actionCollection()->addAction(QStringLiteral("remove_grades_lesson_children"), actionRemoveGradesLessonChildren);
0079     actionRemoveGradesLessonChildren->setText(i18n("Remove Confidence Levels From This Unit And All Subunits"));
0080     actionRemoveGradesLessonChildren->setIcon(QIcon::fromTheme(QStringLiteral("edit-clear")));
0081     actionRemoveGradesLessonChildren->setWhatsThis(i18n("Remove confidence levels from this unit and all subunits."));
0082     actionRemoveGradesLessonChildren->setToolTip(actionRemoveGradesLessonChildren->whatsThis());
0083     actionRemoveGradesLessonChildren->setStatusTip(actionRemoveGradesLessonChildren->whatsThis());
0084 
0085     QAction *actionExpandAll = new QAction(this);
0086     parent->actionCollection()->addAction(QStringLiteral("expand_all_lesson_children"), actionExpandAll);
0087     actionExpandAll->setText(i18n("Expand Units and Subunits"));
0088     actionExpandAll->setIcon(QIcon::fromTheme(QStringLiteral("go-down-search")));
0089     actionExpandAll->setWhatsThis(i18n("Expand all units and subunits."));
0090     actionExpandAll->setToolTip(actionExpandAll->whatsThis());
0091     actionExpandAll->setStatusTip(actionExpandAll->whatsThis());
0092 
0093     QAction *actionCollapseAll = new QAction(this);
0094     parent->actionCollection()->addAction(QStringLiteral("collapse_all_lesson_children"), actionCollapseAll);
0095     actionCollapseAll->setText(i18n("Collapse All Units And Subunits"));
0096     actionCollapseAll->setIcon(QIcon::fromTheme(QStringLiteral("go-up-search")));
0097     actionCollapseAll->setWhatsThis(i18n("Collapse all units and subunits."));
0098     actionCollapseAll->setToolTip(actionCollapseAll->whatsThis());
0099     actionCollapseAll->setStatusTip(actionCollapseAll->whatsThis());
0100 
0101     connect(actionNewLesson, &QAction::triggered, this, &LessonView::slotCreateNewLesson);
0102     connect(actionRenameLesson, &QAction::triggered, this, &LessonView::slotRename);
0103     connect(actionDeleteLesson, &QAction::triggered, this, &LessonView::slotDeleteLesson);
0104     connect(actionSplitLesson, &QAction::triggered, this, &LessonView::slotSplitLesson);
0105     connect(actionMoveToNewLesson, &QAction::triggered, this, &LessonView::moveToNewLesson);
0106     connect(actionRemoveGradesLesson, &QAction::triggered, this, &LessonView::slotRemoveGradesLesson);
0107     connect(actionRemoveGradesLessonChildren, &QAction::triggered, this, &LessonView::slotRemoveGradesLessonChildren);
0108     connect(actionExpandAll, &QAction::triggered, this, &LessonView::expandAllLesson);
0109     connect(actionCollapseAll, &QAction::triggered, this, &LessonView::collapseAllLesson);
0110 
0111     // right click menu for the lesson view:
0112     addAction(actionNewLesson);
0113     addAction(actionRenameLesson);
0114     addAction(actionDeleteLesson);
0115     QAction *separator = new QAction(this);
0116     separator->setSeparator(true);
0117     addAction(separator);
0118     addAction(actionRemoveGradesLesson);
0119     addAction(actionRemoveGradesLessonChildren);
0120     separator = new QAction(this);
0121     separator->setSeparator(true);
0122     addAction(separator);
0123     addAction(actionSplitLesson);
0124     addAction(actionExpandAll);
0125     addAction(actionCollapseAll);
0126 }
0127 
0128 void LessonView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
0129 {
0130     QTreeView::currentChanged(current, previous);
0131 
0132     if (current.isValid()) {
0133         KEduVocLesson *container = static_cast<KEduVocLesson *>(current.internalPointer());
0134         if (container) {
0135             Q_EMIT selectedLessonChanged(container);
0136             Q_EMIT signalShowContainer(container);
0137         }
0138     }
0139 }
0140 
0141 void LessonView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
0142 {
0143     QTreeView::selectionChanged(selected, deselected);
0144 
0145     if (selected.count() == 0) {
0146         return;
0147     }
0148 
0149     KEduVocLesson *container = static_cast<KEduVocLesson *>(selected.indexes().value(0).internalPointer());
0150     if (container) {
0151         Q_EMIT selectedLessonChanged(container);
0152     }
0153 }
0154 
0155 void LessonView::setTranslation(KEduVocExpression *entry, int translation)
0156 {
0157     Q_UNUSED(translation)
0158 
0159     if (entry == 0) {
0160         selectionModel()->clearSelection();
0161         return;
0162     }
0163 
0164     QModelIndex index(m_model->index(entry->lesson()));
0165     selectionModel()->select(index, QItemSelectionModel::ClearAndSelect);
0166     scrollTo(index);
0167 }
0168 
0169 void LessonView::slotCreateNewLesson()
0170 {
0171     QModelIndex selectedIndex = selectionModel()->currentIndex();
0172 
0173     if (!selectedIndex.isValid()) {
0174         selectedIndex = m_model->index(0, 0, QModelIndex());
0175     }
0176 
0177     QModelIndex modelIndex = m_model->appendContainer(selectedIndex);
0178 
0179     scrollTo(modelIndex);
0180     selectionModel()->setCurrentIndex(modelIndex, QItemSelectionModel::ClearAndSelect);
0181     edit(modelIndex); // let the user type a new name for the lesson
0182 }
0183 
0184 void LessonView::slotDeleteLesson()
0185 {
0186     QModelIndex selectedIndex = selectionModel()->currentIndex();
0187 
0188     if (selectedIndex.parent() == QModelIndex()) {
0189         KMessageBox::information(this, i18n("The root lesson cannot be deleted."));
0190         return;
0191     }
0192 
0193     KEduVocLesson *lesson = static_cast<KEduVocLesson *>(selectedIndex.internalPointer());
0194 
0195     int count = lesson->entryCount(KEduVocLesson::Recursive);
0196 
0197     if (count == 0
0198         || KMessageBox::warningYesNo(this,
0199                                      i18np("There is %1 word left in this unit. Do you want to delete it?",
0200                                            "There are %1 words left in this unit. Do you want to delete them?",
0201                                            count))
0202             == KMessageBox::Yes) {
0203         m_model->deleteContainer(selectedIndex);
0204     }
0205 }
0206 
0207 void LessonView::slotSplitLesson()
0208 {
0209     if (!selectionModel()->currentIndex().isValid()) {
0210         return;
0211     }
0212 
0213     /** @todo A nicer dialog would be great.
0214      * Maybe with radio buttons to ask, if the entries should be in random order or as they come. */
0215     bool ok = false;
0216     int numEntries = QInputDialog::getInt(this,
0217                                           i18n("Entries per Unit"),
0218                                           i18n("The unit will be split into smaller unit. How many entries in each unit do you want?"),
0219                                           Prefs::entriesPerLesson(),
0220                                           1,
0221                                           1000,
0222                                           1,
0223                                           &ok);
0224 
0225     if (!ok) {
0226         return;
0227     }
0228     Prefs::setEntriesPerLesson(numEntries);
0229     m_model->splitLesson(selectionModel()->currentIndex(), numEntries, LessonModel::Random);
0230     setExpanded(selectionModel()->currentIndex(), true);
0231 }
0232 
0233 void LessonView::moveToNewLesson()
0234 {
0235     const QModelIndexList indexes = m_editorWindow->vocabularyView()->getSelectedIndexes();
0236     if (indexes.isEmpty()) {
0237         return;
0238     }
0239 
0240     KEduVocDocument *doc = m_model->document();
0241     KEduVocLesson *lesson = new KEduVocLesson(i18n("New Lesson"), doc->lesson());
0242     doc->lesson()->appendChildContainer(lesson);
0243 
0244     for (const QModelIndex &index : indexes) {
0245         lesson->appendEntry(qvariant_cast<KEduVocExpression *>(index.data(VocabularyModel::EntryRole)));
0246     }
0247 }
0248 
0249 void LessonView::slotRemoveGradesLesson()
0250 {
0251     QModelIndex selectedIndex = selectionModel()->currentIndex();
0252     KEduVocLesson *lesson = static_cast<KEduVocLesson *>(selectedIndex.internalPointer());
0253     lesson->resetGrades(-1, KEduVocContainer::NotRecursive);
0254     Q_EMIT signalShowContainer(lesson);
0255 }
0256 
0257 void LessonView::slotRemoveGradesLessonChildren()
0258 {
0259     QModelIndex selectedIndex = selectionModel()->currentIndex();
0260     KEduVocLesson *lesson = static_cast<KEduVocLesson *>(selectedIndex.internalPointer());
0261     lesson->resetGrades(-1, KEduVocContainer::Recursive);
0262     Q_EMIT signalShowContainer(lesson);
0263 }
0264 
0265 void LessonView::setModel(LessonModel *model)
0266 {
0267     m_model = model;
0268     ContainerView::setModel(model);
0269     connect(model, &QAbstractItemModel::columnsInserted, this, &LessonView::columnsInserted);
0270     for (int i = 2; i < model->columnCount(QModelIndex()); i++) {
0271         setColumnHidden(i, true);
0272     }
0273 }
0274 
0275 void LessonView::columnsInserted()
0276 {
0277     for (int i = 2; i < m_model->columnCount(QModelIndex()); i++) {
0278         setColumnHidden(i, true);
0279     }
0280 }
0281 
0282 void LessonView::expandAllLesson()
0283 {
0284     expandAll();
0285 }
0286 
0287 void LessonView::collapseAllLesson()
0288 {
0289     collapseAll();
0290 }