Warning, file /education/parley/src/settings/languagepropertiespage.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2008 Frederik Gladhorn <gladhorn@kde.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "languagepropertiespage.h" 0007 0008 #include "documentproperties.h" 0009 #include "languagesettings.h" 0010 #include <KMessageBox> 0011 0012 #include <KLocalizedString> 0013 #include <QCheckBox> 0014 #include <QDBusInterface> 0015 #include <QDBusReply> 0016 #include <QDebug> 0017 #include <QInputDialog> 0018 #include <QLabel> 0019 #include <QLineEdit> 0020 #include <sonnet/speller.h> 0021 0022 #include <KEduVocDocument> 0023 #include <KEduVocExpression> 0024 #include <KEduVocLesson> 0025 0026 #include <parleydocument.h> 0027 0028 #define TENSE_TAG ". " 0029 0030 LanguagePropertiesPage::LanguagePropertiesPage(KEduVocDocument *doc, int identifierIndex, QWidget *parent) 0031 : QWidget(parent) 0032 , m_doc(doc) 0033 , m_identifierIndex(identifierIndex) 0034 { 0035 setupUi(this); 0036 0037 connect(localeComboBox, QOverload<const QString &>::of(&KComboBox::currentTextChanged), this, &LanguagePropertiesPage::localeChanged); 0038 connect(downloadGrammarButton, &QPushButton::clicked, this, &LanguagePropertiesPage::downloadGrammar); 0039 0040 // qmap automatically sorts by keys 0041 QMap<QString, QString> languageCodeMap = DocumentProperties::localeLangsMap(); 0042 0043 // add the language, but also it's code as data 0044 for (auto iter = languageCodeMap.cbegin(); iter != languageCodeMap.cend(); ++iter) { 0045 localeComboBox->addItem(iter.key(), iter.value()); 0046 } 0047 0048 if (m_identifierIndex < m_doc->identifierCount()) { 0049 localeComboBox->setCurrentIndex(localeComboBox->findData(m_doc->identifier(m_identifierIndex).locale())); 0050 0051 identifierNameLineEdit->setText(m_doc->identifier(m_identifierIndex).name()); 0052 } 0053 0054 int index = (m_identifierIndex < m_doc->identifierCount() ? m_identifierIndex : 0); 0055 LanguageSettings settings(m_doc->identifier(index).locale()); 0056 settings.load(); 0057 0058 // fonts 0059 editorFont->setFont(settings.editorFont()); 0060 practiceFont->setFont(settings.practiceFont()); 0061 0062 // keyboard layout 0063 // try to talk to kxbk - get a list of keyboard layouts 0064 QDBusInterface kxbk(QStringLiteral("org.kde.keyboard"), QStringLiteral("/Layouts"), QStringLiteral("org.kde.KeyboardLayouts")); 0065 QDBusReply<QStringList> reply = kxbk.call(QStringLiteral("getLayoutsList")); 0066 if (reply.isValid()) { 0067 QStringList layouts = reply; 0068 layouts.prepend(QString()); 0069 keyboardLayoutComboBox->clear(); 0070 keyboardLayoutComboBox->addItems(layouts); 0071 keyboardLayoutComboBox->setEnabled(true); 0072 0073 QDBusReply<QString> currentLayout = kxbk.call(QStringLiteral("getCurrentLayout")); 0074 keyboardLayoutComboBox->setCurrentIndex(keyboardLayoutComboBox->findText(currentLayout)); 0075 if (m_identifierIndex < m_doc->identifierCount()) { 0076 if (!settings.keyboardLayout().isEmpty()) { 0077 keyboardLayoutComboBox->setCurrentIndex(keyboardLayoutComboBox->findText(settings.keyboardLayout())); 0078 } 0079 } 0080 } else { 0081 qDebug() << "kxkb dbus error"; 0082 keyboardLayoutComboBox->setEnabled(false); 0083 keyboardLayoutComboBox->addItem(i18n("No KDE keyboard selector found.")); 0084 } 0085 0086 Sonnet::Speller speller; 0087 QMap<QString, QString> dicts = speller.availableDictionaries(); 0088 QMap<QString, QString>::const_iterator iter = dicts.constBegin(); 0089 while (iter != dicts.constEnd()) { 0090 spellcheckerComboBox->addItem(iter.key(), iter.value()); 0091 ++iter; 0092 } 0093 spellcheckerComboBox->model()->sort(0); 0094 spellcheckerComboBox->setCurrentIndex(spellcheckerComboBox->findData(settings.spellChecker())); 0095 loadGrammarFromDocument(); 0096 } 0097 0098 void LanguagePropertiesPage::setLanguageIdentifierIndex(int newIndex) 0099 { 0100 m_identifierIndex = newIndex; 0101 } 0102 0103 namespace DocumentHelper 0104 { 0105 void fetchGrammar(KEduVocDocument *doc, int languageIndex); 0106 } 0107 0108 void LanguagePropertiesPage::downloadGrammar() 0109 { 0110 DocumentHelper::fetchGrammar(m_doc, m_identifierIndex); 0111 loadGrammarFromDocument(); 0112 } 0113 0114 void LanguagePropertiesPage::loadGrammarFromDocument() 0115 { 0116 if (m_identifierIndex < m_doc->identifierCount()) { 0117 // articles 0118 KEduVocArticle articles = m_doc->identifier(m_identifierIndex).article(); 0119 0120 def_male->setText(articles.article(KEduVocWordFlag::Singular | KEduVocWordFlag::Definite | KEduVocWordFlag::Masculine)); 0121 indef_male->setText(articles.article(KEduVocWordFlag::Singular | KEduVocWordFlag::Indefinite | KEduVocWordFlag::Masculine)); 0122 0123 def_female->setText(articles.article(KEduVocWordFlag::Singular | KEduVocWordFlag::Definite | KEduVocWordFlag::Feminine)); 0124 indef_female->setText(articles.article(KEduVocWordFlag::Singular | KEduVocWordFlag::Indefinite | KEduVocWordFlag::Feminine)); 0125 0126 def_natural->setText(articles.article(KEduVocWordFlag::Singular | KEduVocWordFlag::Definite | KEduVocWordFlag::Neuter)); 0127 indef_natural->setText(articles.article(KEduVocWordFlag::Singular | KEduVocWordFlag::Indefinite | KEduVocWordFlag::Neuter)); 0128 0129 def_male_plural->setText(articles.article(KEduVocWordFlag::Plural | KEduVocWordFlag::Definite | KEduVocWordFlag::Masculine)); 0130 indef_male_plural->setText(articles.article(KEduVocWordFlag::Plural | KEduVocWordFlag::Indefinite | KEduVocWordFlag::Masculine)); 0131 0132 def_female_plural->setText(articles.article(KEduVocWordFlag::Plural | KEduVocWordFlag::Definite | KEduVocWordFlag::Feminine)); 0133 indef_female_plural->setText(articles.article(KEduVocWordFlag::Plural | KEduVocWordFlag::Indefinite | KEduVocWordFlag::Feminine)); 0134 0135 def_natural_plural->setText(articles.article(KEduVocWordFlag::Plural | KEduVocWordFlag::Definite | KEduVocWordFlag::Neuter)); 0136 indef_natural_plural->setText(articles.article(KEduVocWordFlag::Plural | KEduVocWordFlag::Indefinite | KEduVocWordFlag::Neuter)); 0137 0138 // personal pronouns 0139 const KEduVocWordFlags numS = KEduVocWordFlag::Singular; 0140 const KEduVocWordFlags numD = KEduVocWordFlag::Dual; 0141 const KEduVocWordFlags numP = KEduVocWordFlag::Plural; 0142 0143 KEduVocPersonalPronoun pronoun = m_doc->identifier(m_identifierIndex).personalPronouns(); 0144 0145 first_singular->setText(pronoun.personalPronoun(KEduVocWordFlag::First | numS)); 0146 second_singular->setText(pronoun.personalPronoun(KEduVocWordFlag::Second | numS)); 0147 thirdM_singular->setText(pronoun.personalPronoun(KEduVocWordFlag::Third | KEduVocWordFlag::Masculine | numS)); 0148 thirdF_singular->setText(pronoun.personalPronoun(KEduVocWordFlag::Third | KEduVocWordFlag::Feminine | numS)); 0149 thirdN_singular->setText(pronoun.personalPronoun(KEduVocWordFlag::Third | KEduVocWordFlag::Neuter | numS)); 0150 0151 dualFirstLineEdit->setText(pronoun.personalPronoun(KEduVocWordFlag::First | numD)); 0152 dualSecondLineEdit->setText(pronoun.personalPronoun(KEduVocWordFlag::Second | numD)); 0153 dualThirdMaleLineEdit->setText(pronoun.personalPronoun(KEduVocWordFlag::Third | KEduVocWordFlag::Masculine | numD)); 0154 dualThirdFemaleLineEdit->setText(pronoun.personalPronoun(KEduVocWordFlag::Third | KEduVocWordFlag::Feminine | numD)); 0155 dualThirdNeutralLineEdit->setText(pronoun.personalPronoun(KEduVocWordFlag::Third | KEduVocWordFlag::Neuter | numD)); 0156 0157 first_plural->setText(pronoun.personalPronoun(KEduVocWordFlag::First | numP)); 0158 second_plural->setText(pronoun.personalPronoun(KEduVocWordFlag::Second | numP)); 0159 thirdM_plural->setText(pronoun.personalPronoun(KEduVocWordFlag::Third | KEduVocWordFlag::Masculine | numP)); 0160 thirdF_plural->setText(pronoun.personalPronoun(KEduVocWordFlag::Third | KEduVocWordFlag::Feminine | numP)); 0161 thirdN_plural->setText(pronoun.personalPronoun(KEduVocWordFlag::Third | KEduVocWordFlag::Neuter | numP)); 0162 0163 maleFemaleDifferCheckBox->setChecked(pronoun.maleFemaleDifferent()); 0164 neutralCheckBox->setChecked(pronoun.neutralExists()); 0165 dualCheckBox->setChecked(pronoun.dualExists()); 0166 } 0167 0168 // update shown labels etc... 0169 updateCheckBoxes(); 0170 0171 connect(maleFemaleDifferCheckBox, &QCheckBox::toggled, this, &LanguagePropertiesPage::updateCheckBoxes); 0172 connect(neutralCheckBox, &QCheckBox::toggled, this, &LanguagePropertiesPage::updateCheckBoxes); 0173 connect(dualCheckBox, &QCheckBox::toggled, this, &LanguagePropertiesPage::updateCheckBoxes); 0174 0175 // tenses 0176 connect(tenseList, &QListWidget::currentRowChanged, this, &LanguagePropertiesPage::slotTenseChosen); 0177 connect(deleteButton, &QPushButton::clicked, this, &LanguagePropertiesPage::slotDeleteTense); 0178 connect(modifyButton, &QPushButton::clicked, this, &LanguagePropertiesPage::slotModifyTense); 0179 connect(newButton, &QPushButton::clicked, this, &LanguagePropertiesPage::slotNewTense); 0180 0181 if (m_identifierIndex < m_doc->identifierCount()) { 0182 int i = 1; 0183 const QStringList tenses = m_doc->identifier(m_identifierIndex).tenseList(); 0184 for (const QString &tenseName : tenses) { 0185 tenseList->addItem(QStringLiteral("%1").arg(i++, 2).append(TENSE_TAG).append(tenseName)); 0186 tenseIndex.append(i); 0187 } 0188 } 0189 0190 m_currentTense = 0; 0191 if (tenseList->count() > 0) { 0192 tenseList->setCurrentRow(m_currentTense); 0193 } 0194 0195 modifyButton->setEnabled(tenseList->count() > 0); 0196 deleteButton->setEnabled(tenseList->count() > 0); 0197 tenseList->setFocus(); 0198 } 0199 0200 void LanguagePropertiesPage::accept() 0201 { 0202 if (!isEnabled()) { 0203 // disabled pages are deleted languages 0204 return; 0205 } 0206 0207 // general 0208 QString locale = localeComboBox->itemData(localeComboBox->currentIndex()).toString(); 0209 0210 // if no locales are found (kdebase not installed?) at least fall back to using the language name as locale. 0211 if (locale.isEmpty()) { 0212 locale = identifierNameLineEdit->text(); 0213 } 0214 m_doc->identifier(m_identifierIndex).setLocale(locale); 0215 m_doc->identifier(m_identifierIndex).setName(identifierNameLineEdit->text()); 0216 0217 LanguageSettings settings(locale); 0218 0219 settings.setEditorFont(editorFont->font()); 0220 settings.setPracticeFont(practiceFont->font()); 0221 0222 if (keyboardLayoutComboBox->isEnabled()) { 0223 settings.setKeyboardLayout(keyboardLayoutComboBox->currentText()); 0224 } 0225 int index = spellcheckerComboBox->currentIndex(); 0226 settings.setSpellChecker(spellcheckerComboBox->itemData(index).toString()); 0227 settings.save(); 0228 0229 // articles 0230 const KEduVocWordFlag::Flags artSing = KEduVocWordFlag::Singular; 0231 // const KEduVocWordFlag::Flags artDual = KEduVocWordFlag::Dual; 0232 const KEduVocWordFlag::Flags artPlur = KEduVocWordFlag::Plural; 0233 0234 const KEduVocWordFlag::Flags artDef = KEduVocWordFlag::Definite; 0235 const KEduVocWordFlag::Flags artIndef = KEduVocWordFlag::Indefinite; 0236 0237 KEduVocArticle article; 0238 0239 article.setArticle(def_male->text(), artSing | artDef | KEduVocWordFlag::Masculine); 0240 article.setArticle(indef_male->text(), artSing | artIndef | KEduVocWordFlag::Masculine); 0241 article.setArticle(def_female->text(), artSing | artDef | KEduVocWordFlag::Feminine); 0242 article.setArticle(indef_female->text(), artSing | artIndef | KEduVocWordFlag::Feminine); 0243 article.setArticle(def_natural->text(), artSing | artDef | KEduVocWordFlag::Neuter); 0244 article.setArticle(indef_natural->text(), artSing | artIndef | KEduVocWordFlag::Neuter); 0245 0246 article.setArticle(def_male_plural->text(), artPlur | artDef | KEduVocWordFlag::Masculine); 0247 article.setArticle(indef_male_plural->text(), artPlur | artIndef | KEduVocWordFlag::Masculine); 0248 article.setArticle(def_female_plural->text(), artPlur | artDef | KEduVocWordFlag::Feminine); 0249 article.setArticle(indef_female_plural->text(), artPlur | artIndef | KEduVocWordFlag::Feminine); 0250 article.setArticle(def_natural_plural->text(), artPlur | artDef | KEduVocWordFlag::Neuter); 0251 article.setArticle(indef_natural_plural->text(), artPlur | artIndef | KEduVocWordFlag::Neuter); 0252 0253 m_doc->identifier(m_identifierIndex).setArticle(article); 0254 0255 // personal pronouns 0256 KEduVocPersonalPronoun pronoun; 0257 const KEduVocWordFlags numS = KEduVocWordFlag::Singular; 0258 const KEduVocWordFlags numD = KEduVocWordFlag::Dual; 0259 const KEduVocWordFlags numP = KEduVocWordFlag::Plural; 0260 0261 pronoun.setPersonalPronoun(first_singular->text(), KEduVocWordFlag::First | numS); 0262 pronoun.setPersonalPronoun(second_singular->text(), KEduVocWordFlag::Second | numS); 0263 pronoun.setPersonalPronoun(thirdM_singular->text(), KEduVocWordFlag::Third | KEduVocWordFlag::Masculine | numS); 0264 pronoun.setPersonalPronoun(thirdF_singular->text(), KEduVocWordFlag::Third | KEduVocWordFlag::Feminine | numS); 0265 pronoun.setPersonalPronoun(thirdN_singular->text(), KEduVocWordFlag::Third | KEduVocWordFlag::Neuter | numS); 0266 0267 pronoun.setPersonalPronoun(dualFirstLineEdit->text(), KEduVocWordFlag::First | numD); 0268 pronoun.setPersonalPronoun(dualSecondLineEdit->text(), KEduVocWordFlag::Second | numD); 0269 pronoun.setPersonalPronoun(dualThirdMaleLineEdit->text(), KEduVocWordFlag::Third | KEduVocWordFlag::Masculine | numD); 0270 pronoun.setPersonalPronoun(dualThirdFemaleLineEdit->text(), KEduVocWordFlag::Third | KEduVocWordFlag::Feminine | numD); 0271 pronoun.setPersonalPronoun(dualThirdNeutralLineEdit->text(), KEduVocWordFlag::Third | KEduVocWordFlag::Neuter | numD); 0272 0273 pronoun.setPersonalPronoun(first_plural->text(), KEduVocWordFlag::First | numP); 0274 pronoun.setPersonalPronoun(second_plural->text(), KEduVocWordFlag::Second | numP); 0275 pronoun.setPersonalPronoun(thirdM_plural->text(), KEduVocWordFlag::Third | KEduVocWordFlag::Masculine | numP); 0276 pronoun.setPersonalPronoun(thirdF_plural->text(), KEduVocWordFlag::Third | KEduVocWordFlag::Feminine | numP); 0277 pronoun.setPersonalPronoun(thirdN_plural->text(), KEduVocWordFlag::Third | KEduVocWordFlag::Neuter | numP); 0278 0279 pronoun.setMaleFemaleDifferent(maleFemaleDifferCheckBox->isChecked()); 0280 pronoun.setNeutralExists(neutralCheckBox->isChecked()); 0281 pronoun.setDualExists(dualCheckBox->isChecked()); 0282 0283 m_doc->identifier(m_identifierIndex).setPersonalPronouns(pronoun); 0284 0285 // tenses 0286 QStringList tenses; 0287 0288 QString str; 0289 for (int i = 0; i < (int)tenseList->count(); i++) { 0290 str = tenseList->item(i)->text(); 0291 tenses.append(str.mid(str.indexOf(TENSE_TAG) + QStringLiteral(TENSE_TAG).length())); 0292 } 0293 0294 m_doc->identifier(m_identifierIndex).setTenseList(tenses); 0295 } 0296 0297 void LanguagePropertiesPage::updateCheckBoxes() 0298 { 0299 bool maleFemale = maleFemaleDifferCheckBox->isChecked(); 0300 bool neutral = neutralCheckBox->isChecked(); 0301 bool dual = dualCheckBox->isChecked(); 0302 0303 neutralCheckBox->setVisible(maleFemale); 0304 male_c_label->setVisible(maleFemale); 0305 female_c_label->setVisible(maleFemale); 0306 thirdM_singular->setVisible(maleFemale); 0307 thirdF_singular->setVisible(maleFemale); 0308 thirdM_plural->setVisible(maleFemale); 0309 thirdF_plural->setVisible(maleFemale); 0310 0311 dualLabel->setVisible(dual); 0312 dualFirstLineEdit->setVisible(dual); 0313 dualSecondLineEdit->setVisible(dual); 0314 0315 dualThirdMaleLineEdit->setVisible(dual && maleFemale); 0316 dualThirdFemaleLineEdit->setVisible(dual && maleFemale); 0317 0318 if (!maleFemale) { 0319 natural_c_label->setVisible(false); 0320 thirdN_singular->setVisible(true); 0321 thirdN_plural->setVisible(true); 0322 dualThirdNeutralLineEdit->setVisible(dual); 0323 } else { 0324 natural_c_label->setVisible(neutral); 0325 thirdN_singular->setVisible(neutral); 0326 thirdN_plural->setVisible(neutral); 0327 dualThirdNeutralLineEdit->setVisible(dual && neutral); 0328 } 0329 } 0330 0331 void LanguagePropertiesPage::localeChanged(const QString &locale) 0332 { 0333 identifierNameLineEdit->setText(locale); 0334 } 0335 0336 // ************** TENSES ********************* 0337 0338 void LanguagePropertiesPage::slotTenseChosen(int index) 0339 { 0340 m_currentTense = index; 0341 } 0342 0343 void LanguagePropertiesPage::slotNewTense() 0344 { 0345 bool ok; 0346 QString getTense = QInputDialog::getText(this, i18n("Tense Name"), i18n("Enter name of tense:"), QLineEdit::Normal, QString(), &ok); 0347 if (!ok) { 0348 return; 0349 } 0350 0351 int i = tenseList->count() + 1; 0352 tenseList->addItem(QStringLiteral("%1").arg(i, 2).append(TENSE_TAG).append(getTense.simplified())); 0353 tenseIndex.append(-(i - 1)); 0354 0355 m_currentTense = tenseList->count(); 0356 tenseList->setCurrentRow(i - 1); 0357 modifyButton->setEnabled(true); 0358 deleteButton->setEnabled(true); 0359 } 0360 0361 void LanguagePropertiesPage::slotModifyTense() 0362 { 0363 if (tenseList->count() != 0 && (int)tenseList->count() > m_currentTense) { 0364 QString str = tenseList->item(m_currentTense)->text(); 0365 str = str.mid(str.indexOf(TENSE_TAG) + QStringLiteral(TENSE_TAG).length()); 0366 0367 bool ok; 0368 QString getTense = QInputDialog::getText(this, i18n("Tense Name"), i18n("Enter name of tense:"), QLineEdit::Normal, str, &ok); 0369 if (!ok) 0370 return; 0371 0372 int i = m_currentTense + 1; 0373 tenseList->item(m_currentTense)->setText(QStringLiteral("%1").arg(i, 2).append(TENSE_TAG).append(getTense.simplified())); 0374 } 0375 } 0376 0377 void LanguagePropertiesPage::updateListBox(int start) 0378 { 0379 QString str; 0380 for (int i = start; i < (int)tenseList->count(); i++) { 0381 str = tenseList->item(i)->text(); 0382 str = str.mid(str.indexOf(TENSE_TAG) + QStringLiteral(TENSE_TAG).length()); 0383 tenseList->item(i)->setText(QStringLiteral("%1").arg(i + 1, 2).append(TENSE_TAG).append(str)); 0384 } 0385 } 0386 0387 void LanguagePropertiesPage::slotDeleteTense() 0388 { 0389 int act = m_currentTense; 0390 if (tenseList->count() > 0 && (int)tenseList->count() > act) { 0391 QString t = tenseList->item(act)->text(); 0392 0393 const QList<KEduVocExpression *> entries = m_doc->lesson()->entries(KEduVocLesson::Recursive); 0394 for (KEduVocExpression *exp : entries) { 0395 for (int lang = 0; lang < m_doc->identifierCount(); lang++) { 0396 if (exp->translation(lang)->conjugationTenses().contains(t)) { 0397 KMessageBox::information(this, 0398 i18n("The selected user defined tense could not be deleted\nbecause it is in use."), 0399 i18n("Deleting Tense Description")); 0400 return; 0401 } 0402 } 0403 } 0404 0405 delete tenseList->takeItem(act); 0406 tenseIndex.erase(tenseIndex.begin() + act); 0407 0408 if ((int)tenseList->count() <= act) 0409 act = tenseList->count() - 1; 0410 else 0411 updateListBox(act); // update items after current 0412 0413 if (act >= 0) 0414 tenseList->setCurrentRow(act); 0415 } 0416 modifyButton->setEnabled(tenseList->count() > 0); 0417 deleteButton->setEnabled(tenseList->count() > 0); 0418 }