File indexing completed on 2024-04-28 07:39:26

0001 /*
0002     SPDX-FileCopyrightText: 2008 Frederik Gladhorn <frederik.gladhorn@kdemail.net>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "wordtypeview.h"
0007 
0008 #include <QContextMenuEvent>
0009 #include <QMenu>
0010 
0011 #include <KLocalizedString>
0012 #include <KMessageBox>
0013 #include <KSelectAction>
0014 #include <QAction>
0015 
0016 #include <KEduVocExpression>
0017 #include <KEduVocWordtype>
0018 #include <kmessagebox.h>
0019 
0020 #include "containermodel.h"
0021 #include "editor/editor.h"
0022 
0023 using namespace Editor;
0024 
0025 WordTypeView::WordTypeView(EditorWindow *parent)
0026     : ContainerView(parent)
0027 {
0028     setContextMenuPolicy(Qt::DefaultContextMenu);
0029 
0030     m_actionNewWordType = new QAction(this);
0031     m_actionNewWordType->setText(i18n("New"));
0032     m_actionNewWordType->setIcon(QIcon::fromTheme(QStringLiteral("lesson-add")));
0033     m_actionNewWordType->setWhatsThis(i18n("Add a new word type to your document"));
0034     m_actionNewWordType->setToolTip(m_actionNewWordType->whatsThis());
0035     m_actionNewWordType->setStatusTip(m_actionNewWordType->whatsThis());
0036     m_actionNewWordType->setStatusTip(m_actionNewWordType->whatsThis());
0037 
0038     m_actionRenameWordType = new QAction(this);
0039     m_actionRenameWordType->setText(i18n("Rename"));
0040     m_actionRenameWordType->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename")));
0041     m_actionRenameWordType->setWhatsThis(i18n("Rename the selected word type"));
0042     m_actionRenameWordType->setToolTip(m_actionRenameWordType->whatsThis());
0043     m_actionRenameWordType->setStatusTip(m_actionRenameWordType->whatsThis());
0044     m_actionRenameWordType->setStatusTip(m_actionRenameWordType->whatsThis());
0045 
0046     m_actionDeleteWordType = new QAction(this);
0047     m_actionDeleteWordType->setText(i18n("Delete Word Type"));
0048     m_actionDeleteWordType->setIcon(QIcon::fromTheme(QStringLiteral("lesson-remove")));
0049     m_actionDeleteWordType->setWhatsThis(i18n("Delete the selected word type."));
0050     m_actionDeleteWordType->setToolTip(m_actionDeleteWordType->whatsThis());
0051     m_actionDeleteWordType->setStatusTip(m_actionDeleteWordType->whatsThis());
0052     m_actionDeleteWordType->setStatusTip(m_actionDeleteWordType->whatsThis());
0053 
0054     m_actionSpecialTypeMenu = new KSelectAction(this);
0055     m_actionSpecialTypeMenu->setText(
0056         i18nc("Let the user select what grammatical meaning is connected to a word type (nouns have gender, verbs conjugations etc)", "Grammar"));
0057     // actionSplitWordType->setIcon(QIcon::fromTheme(""));  /// @todo better icon
0058     m_actionSpecialTypeMenu->setWhatsThis(i18n("To let Parley know the grammatical meaning of a word type."));
0059     m_actionSpecialTypeMenu->setToolTip(m_actionSpecialTypeMenu->whatsThis());
0060     m_actionSpecialTypeMenu->setStatusTip(m_actionSpecialTypeMenu->whatsThis());
0061     m_actionSpecialTypeMenu->setStatusTip(m_actionSpecialTypeMenu->whatsThis());
0062 
0063     m_nounAction = new QAction(this);
0064     m_nounAction->setText(i18n("Noun"));
0065     m_nounAction->setCheckable(true);
0066     m_nounAction->setWhatsThis(i18n("This word type folder contains nouns."));
0067     m_nounAction->setToolTip(m_nounAction->whatsThis());
0068     m_nounAction->setStatusTip(m_nounAction->whatsThis());
0069     m_nounAction->setStatusTip(m_nounAction->whatsThis());
0070 
0071     m_nounMaleAction = new QAction(this);
0072     m_nounMaleAction->setText(i18n("Masculine Noun"));
0073     m_nounMaleAction->setCheckable(true);
0074     m_nounMaleAction->setWhatsThis(i18n("This word type folder contains masculine nouns."));
0075     m_nounMaleAction->setToolTip(m_nounMaleAction->whatsThis());
0076     m_nounMaleAction->setStatusTip(m_nounMaleAction->whatsThis());
0077     m_nounMaleAction->setStatusTip(m_nounMaleAction->whatsThis());
0078 
0079     m_nounFemaleAction = new QAction(this);
0080     m_nounFemaleAction->setText(i18n("Feminine Noun"));
0081     m_nounFemaleAction->setCheckable(true);
0082     m_nounFemaleAction->setWhatsThis(i18n("This word type folder contains feminine nouns."));
0083     m_nounFemaleAction->setToolTip(m_nounFemaleAction->whatsThis());
0084     m_nounFemaleAction->setStatusTip(m_nounFemaleAction->whatsThis());
0085     m_nounFemaleAction->setStatusTip(m_nounFemaleAction->whatsThis());
0086 
0087     m_nounNeutralAction = new QAction(this);
0088     m_nounNeutralAction->setText(i18n("Neuter Noun"));
0089     m_nounNeutralAction->setCheckable(true);
0090     m_nounNeutralAction->setWhatsThis(i18n("This word type folder contains neuter nouns."));
0091     m_nounNeutralAction->setToolTip(m_nounNeutralAction->whatsThis());
0092     m_nounNeutralAction->setStatusTip(m_nounNeutralAction->whatsThis());
0093     m_nounNeutralAction->setStatusTip(m_nounNeutralAction->whatsThis());
0094 
0095     m_adjectiveAction = new QAction(this);
0096     m_adjectiveAction->setText(i18n("Adjective"));
0097     m_adjectiveAction->setCheckable(true);
0098     m_adjectiveAction->setWhatsThis(i18n("This word type folder contains adjectives."));
0099     m_adjectiveAction->setToolTip(m_adjectiveAction->whatsThis());
0100     m_adjectiveAction->setStatusTip(m_adjectiveAction->whatsThis());
0101     m_adjectiveAction->setStatusTip(m_adjectiveAction->whatsThis());
0102 
0103     m_adverbAction = new QAction(this);
0104     m_adverbAction->setText(i18n("Adverb"));
0105     m_adverbAction->setCheckable(true);
0106     m_adverbAction->setWhatsThis(i18n("This word type folder contains adverbs."));
0107     m_adverbAction->setToolTip(m_adverbAction->whatsThis());
0108     m_adverbAction->setStatusTip(m_adverbAction->whatsThis());
0109     m_adverbAction->setStatusTip(m_adverbAction->whatsThis());
0110 
0111     m_verbAction = new QAction(this);
0112     m_verbAction->setText(i18n("Verb"));
0113     m_verbAction->setCheckable(true);
0114     m_verbAction->setWhatsThis(i18n("This word type folder contains verbs."));
0115     m_verbAction->setToolTip(m_verbAction->whatsThis());
0116     m_verbAction->setStatusTip(m_verbAction->whatsThis());
0117     m_verbAction->setStatusTip(m_verbAction->whatsThis());
0118 
0119     m_conjunctionAction = new QAction(this);
0120     m_conjunctionAction->setText(i18n("Conjunction"));
0121     m_conjunctionAction->setCheckable(true);
0122     m_conjunctionAction->setWhatsThis(i18n("This word type folder contains conjunctions."));
0123     m_conjunctionAction->setToolTip(m_conjunctionAction->whatsThis());
0124     m_conjunctionAction->setStatusTip(m_conjunctionAction->whatsThis());
0125     m_conjunctionAction->setStatusTip(m_conjunctionAction->whatsThis());
0126 
0127     m_noneAction = new QAction(this);
0128     m_noneAction->setText(i18n("No Special Type"));
0129     m_noneAction->setCheckable(true);
0130     m_noneAction->setChecked(true);
0131     m_noneAction->setWhatsThis(i18n("This word type folder contains no word type with special meaning."));
0132     m_noneAction->setToolTip(m_noneAction->whatsThis());
0133     m_noneAction->setStatusTip(m_noneAction->whatsThis());
0134     m_noneAction->setStatusTip(m_noneAction->whatsThis());
0135 
0136     QAction *separator = new QAction(this);
0137     separator->setSeparator(true);
0138 
0139     m_actionSpecialTypeMenu->addAction(m_noneAction);
0140     m_actionSpecialTypeMenu->addAction(separator);
0141     m_actionSpecialTypeMenu->addAction(m_nounAction);
0142     m_actionSpecialTypeMenu->addAction(m_nounMaleAction);
0143     m_actionSpecialTypeMenu->addAction(m_nounFemaleAction);
0144     m_actionSpecialTypeMenu->addAction(m_nounNeutralAction);
0145     m_actionSpecialTypeMenu->addAction(m_adjectiveAction);
0146     m_actionSpecialTypeMenu->addAction(m_adverbAction);
0147     m_actionSpecialTypeMenu->addAction(m_verbAction);
0148     m_actionSpecialTypeMenu->addAction(m_conjunctionAction);
0149 
0150     connect(m_actionNewWordType, &QAction::triggered, this, &WordTypeView::slotCreateNewWordType);
0151     connect(m_actionRenameWordType, &QAction::triggered, this, &WordTypeView::slotRename);
0152     connect(m_actionDeleteWordType, &QAction::triggered, this, &WordTypeView::slotDeleteWordType);
0153 
0154     // right click menu for the WordType view:
0155     addAction(m_actionNewWordType);
0156     addAction(m_actionRenameWordType);
0157     addAction(m_actionDeleteWordType);
0158     separator = new QAction(this);
0159     separator->setSeparator(true);
0160     addAction(separator);
0161     separator = new QAction(this);
0162     separator->setSeparator(true);
0163     addAction(separator);
0164     addAction(m_actionSpecialTypeMenu);
0165 
0166     connect(m_noneAction, &QAction::triggered, this, &WordTypeView::setWordTypeNone);
0167     connect(m_nounAction, &QAction::triggered, this, &WordTypeView::setWordTypeNoun);
0168     connect(m_nounMaleAction, &QAction::triggered, this, &WordTypeView::setWordTypeNounMale);
0169     connect(m_nounFemaleAction, &QAction::triggered, this, &WordTypeView::setWordTypeNounFemale);
0170     connect(m_nounNeutralAction, &QAction::triggered, this, &WordTypeView::setWordTypeNounNeutral);
0171     connect(m_adjectiveAction, &QAction::triggered, this, &WordTypeView::setWordTypeAdjective);
0172     connect(m_adverbAction, &QAction::triggered, this, &WordTypeView::setWordTypeAdverb);
0173     connect(m_verbAction, &QAction::triggered, this, &WordTypeView::setWordTypeVerb);
0174     connect(m_conjunctionAction, &QAction::triggered, this, &WordTypeView::setWordTypeConjunction);
0175 }
0176 
0177 void WordTypeView::setTranslation(KEduVocExpression *entry, int translation)
0178 {
0179     if (entry == nullptr) {
0180         return;
0181     }
0182 
0183     // attempt to find the container to select
0184     QModelIndex index(m_model->index(entry->translation(translation)->wordType()));
0185     scrollTo(index);
0186     selectionModel()->select(index, QItemSelectionModel::ClearAndSelect);
0187 }
0188 
0189 void WordTypeView::slotCreateNewWordType()
0190 {
0191     QModelIndex selectedIndex = selectionModel()->currentIndex();
0192 
0193     if (!selectedIndex.isValid()) {
0194         selectedIndex = m_model->index(0, 0, QModelIndex());
0195     }
0196 
0197     QModelIndex modelIndex = m_model->appendContainer(selectedIndex);
0198 
0199     scrollTo(modelIndex);
0200     selectionModel()->setCurrentIndex(modelIndex, QItemSelectionModel::ClearAndSelect);
0201     edit(modelIndex); // let the user type a new name for the WordType
0202 }
0203 
0204 void WordTypeView::slotDeleteWordType()
0205 {
0206     QModelIndex selectedIndex = selectionModel()->currentIndex();
0207 
0208     if (selectedIndex.parent() == QModelIndex()) {
0209         KMessageBox::information(this, i18n("The root word type cannot be deleted."));
0210         return;
0211     }
0212 
0213     KEduVocWordType *WordType = static_cast<KEduVocWordType *>(selectedIndex.internalPointer());
0214 
0215     int count = WordType->entryCount();
0216 
0217     if (count == 0
0218         || KMessageBox::warningTwoActions(this,
0219                                           i18np("There is a word left with this word type. It will lose its type. Continue?",
0220                                                 "There are %1 words left with this word type. They will lose their word type. Continue?",
0221                                                 count),
0222                                           QString(),
0223                                           KStandardGuiItem::ok(),
0224                                           KStandardGuiItem::cancel())
0225             == KMessageBox::PrimaryAction) {
0226         m_model->deleteContainer(selectedIndex);
0227     }
0228 }
0229 
0230 void WordTypeView::contextMenuEvent(QContextMenuEvent *event)
0231 {
0232     // check for the root element:
0233     QModelIndex selectedIndex = selectionModel()->currentIndex();
0234     m_actionRenameWordType->setEnabled(selectedIndex.parent() != QModelIndex());
0235     m_actionDeleteWordType->setEnabled(selectedIndex.parent() != QModelIndex());
0236     m_actionSpecialTypeMenu->setEnabled(selectedIndex.parent() != QModelIndex());
0237 
0238     if (selectedIndex.isValid()) {
0239         KEduVocWordFlags t = (static_cast<KEduVocWordType *>(selectionModel()->currentIndex().internalPointer())->wordType());
0240 
0241         if (!t)
0242             m_noneAction->setChecked(true);
0243 
0244         else if (t.testFlag(KEduVocWordFlag::Noun) && t.testFlag(KEduVocWordFlag::Masculine))
0245             m_nounMaleAction->setChecked(true);
0246 
0247         else if (t.testFlag(KEduVocWordFlag::Noun) && t.testFlag(KEduVocWordFlag::Feminine))
0248             m_nounFemaleAction->setChecked(true);
0249 
0250         else if (t.testFlag(KEduVocWordFlag::Noun) && t.testFlag(KEduVocWordFlag::Neuter))
0251             m_nounNeutralAction->setChecked(true);
0252 
0253         else if (t.testFlag(KEduVocWordFlag::Noun))
0254             m_nounAction->setChecked(true);
0255 
0256         else if (t.testFlag(KEduVocWordFlag::Adjective))
0257             m_adjectiveAction->setChecked(true);
0258 
0259         else if (t.testFlag(KEduVocWordFlag::Adverb))
0260             m_adverbAction->setChecked(true);
0261 
0262         else if (t.testFlag(KEduVocWordFlag::Verb))
0263             m_verbAction->setChecked(true);
0264 
0265         else if (t.testFlag(KEduVocWordFlag::Conjunction))
0266             m_conjunctionAction->setChecked(true);
0267     }
0268 
0269     QMenu::exec(actions(), event->globalPos());
0270 }
0271 
0272 void WordTypeView::setWordTypeNone()
0273 {
0274     KEduVocWordType *wordType = static_cast<KEduVocWordType *>(selectionModel()->currentIndex().internalPointer());
0275     wordType->setWordType(KEduVocWordFlag::NoInformation);
0276 }
0277 
0278 void WordTypeView::setWordTypeNoun()
0279 {
0280     KEduVocWordType *wordType = static_cast<KEduVocWordType *>(selectionModel()->currentIndex().internalPointer());
0281     wordType->setWordType(KEduVocWordFlag::Noun);
0282 }
0283 
0284 void WordTypeView::setWordTypeNounMale()
0285 {
0286     KEduVocWordType *wordType = static_cast<KEduVocWordType *>(selectionModel()->currentIndex().internalPointer());
0287     wordType->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Masculine);
0288 }
0289 
0290 void WordTypeView::setWordTypeNounFemale()
0291 {
0292     KEduVocWordType *wordType = static_cast<KEduVocWordType *>(selectionModel()->currentIndex().internalPointer());
0293     wordType->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Feminine);
0294 }
0295 
0296 void WordTypeView::setWordTypeNounNeutral()
0297 {
0298     KEduVocWordType *wordType = static_cast<KEduVocWordType *>(selectionModel()->currentIndex().internalPointer());
0299     wordType->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Neuter);
0300 }
0301 
0302 void WordTypeView::setWordTypeAdjective()
0303 {
0304     KEduVocWordType *wordType = static_cast<KEduVocWordType *>(selectionModel()->currentIndex().internalPointer());
0305     wordType->setWordType(KEduVocWordFlag::Adjective);
0306 }
0307 
0308 void WordTypeView::setWordTypeAdverb()
0309 {
0310     KEduVocWordType *wordType = static_cast<KEduVocWordType *>(selectionModel()->currentIndex().internalPointer());
0311     wordType->setWordType(KEduVocWordFlag::Adverb);
0312 }
0313 
0314 void WordTypeView::setWordTypeVerb()
0315 {
0316     KEduVocWordType *wordType = static_cast<KEduVocWordType *>(selectionModel()->currentIndex().internalPointer());
0317     wordType->setWordType(KEduVocWordFlag::Verb);
0318 }
0319 
0320 void WordTypeView::setWordTypeConjunction()
0321 {
0322     KEduVocWordType *wordType = static_cast<KEduVocWordType *>(selectionModel()->currentIndex().internalPointer());
0323     wordType->setWordType(KEduVocWordFlag::Conjunction);
0324 }
0325 
0326 #include "moc_wordtypeview.cpp"