File indexing completed on 2024-04-28 03:40:31

0001 /***************************************************************************
0002  *   Copyright (C) 2002 by Gunnar Schmi Dt <kmouth@schmi-dt.de             *
0003  *             (C) 2015 by Jeremy Whiting <jpwhiting@kde.org>              *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
0019  ***************************************************************************/
0020 
0021 #include "wordcompletionwidget.h"
0022 
0023 #include <QFileDialog>
0024 #include <QStandardItemModel>
0025 #include <QStandardPaths>
0026 #include <QUrl>
0027 
0028 #include <KConfigGroup>
0029 #include <KIO/FileCopyJob>
0030 #include <KLocalizedString>
0031 #include <KMessageBox>
0032 #include <KSharedConfig>
0033 
0034 #include "dictionarycreationwizard.h"
0035 #include "wordcompletion.h"
0036 
0037 WordCompletionWidget::WordCompletionWidget(QWidget *parent, const char *name)
0038     : QWidget(parent)
0039 {
0040     setupUi(this);
0041     setObjectName(QLatin1String(name));
0042     model = new QStandardItemModel(0, 2, this);
0043     dictionaryView->setModel(model);
0044 
0045     languageButton->showLanguageCodes(true);
0046     languageButton->loadAllLanguages();
0047 
0048     // Connect the signals from hte KCMKTTSDWidget to this class
0049     connect(addButton, &QAbstractButton::clicked, this, &WordCompletionWidget::addDictionary);
0050     connect(deleteButton, &QAbstractButton::clicked, this, &WordCompletionWidget::deleteDictionary);
0051     connect(moveUpButton, &QAbstractButton::clicked, this, &WordCompletionWidget::moveUp);
0052     connect(moveDownButton, &QAbstractButton::clicked, this, &WordCompletionWidget::moveDown);
0053     connect(exportButton, &QAbstractButton::clicked, this, &WordCompletionWidget::exportDictionary);
0054 
0055     connect(dictionaryView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &WordCompletionWidget::selectionChanged);
0056     connect(dictionaryName, &QLineEdit::textChanged, this, &WordCompletionWidget::nameChanged);
0057     connect(languageButton, &KLanguageButton::activated, this, &WordCompletionWidget::languageSelected);
0058 
0059     // Load the configuration from the file
0060     load();
0061 }
0062 
0063 /**
0064  * Destructor
0065  */
0066 WordCompletionWidget::~WordCompletionWidget()
0067 {
0068 }
0069 
0070 /***************************************************************************/
0071 
0072 void WordCompletionWidget::load()
0073 {
0074     model->clear();
0075 
0076     QStringList labels;
0077     labels << i18n("Dictionary") << i18n("Language");
0078     model->setHorizontalHeaderLabels(labels);
0079 
0080     // Set the group general for the configuration of kttsd itself (no plug ins)
0081     const QStringList groups = KSharedConfig::openConfig()->groupList();
0082     for (QStringList::const_iterator it = groups.constBegin(); it != groups.constEnd(); ++it)
0083         if ((*it).startsWith(QLatin1String("Dictionary "))) {
0084             KConfigGroup cg(KSharedConfig::openConfig(), *it);
0085             QString filename = cg.readEntry("Filename");
0086             QString languageTag = cg.readEntry("Language");
0087             QStandardItem *nameItem = new QStandardItem(cg.readEntry("Name"));
0088             nameItem->setData(filename);
0089             QStandardItem *languageItem = new QStandardItem(languageTag);
0090             QList<QStandardItem *> items;
0091             items.append(nameItem);
0092             items.append(languageItem);
0093             model->appendRow(items);
0094             if (!languageButton->contains(languageTag))
0095                 languageButton->insertLanguage(languageTag, i18n("without name"));
0096         }
0097 
0098     // Clean up disc space
0099     for (QStringList::const_iterator it = newDictionaryFiles.constBegin(); it != newDictionaryFiles.constEnd(); ++it) {
0100         QString filename = QStandardPaths::locate(QStandardPaths::AppDataLocation, *it);
0101         if (!filename.isEmpty() && !filename.isNull())
0102             QFile::remove(filename);
0103     }
0104     newDictionaryFiles.clear();
0105 }
0106 
0107 void WordCompletionWidget::save()
0108 {
0109     const QStringList groups = KSharedConfig::openConfig()->groupList();
0110     for (QStringList::const_iterator it = groups.constBegin(); it != groups.constEnd(); ++it)
0111         if ((*it).startsWith(QLatin1String("Dictionary ")))
0112             KSharedConfig::openConfig()->deleteGroup(*it);
0113 
0114     for (int row = 0; row < model->rowCount(); ++row) {
0115         const QStandardItem *nameItem = model->item(row, 0);
0116         const QStandardItem *languageItem = model->item(row, 1);
0117         KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("Dictionary %1").arg(row));
0118         cg.writeEntry("Filename", nameItem->data().toString());
0119         cg.writeEntry("Name", nameItem->text());
0120         cg.writeEntry("Language", languageItem->text());
0121     }
0122     KSharedConfig::openConfig()->sync();
0123 
0124     // Clean up disc space
0125     for (QStringList::const_iterator it = removedDictionaryFiles.constBegin(); it != removedDictionaryFiles.constEnd(); ++it) {
0126         QString filename = QStandardPaths::locate(QStandardPaths::AppDataLocation, *it);
0127         if (!filename.isEmpty() && !filename.isNull())
0128             QFile::remove(filename);
0129     }
0130     removedDictionaryFiles.clear();
0131 }
0132 
0133 /***************************************************************************/
0134 
0135 void WordCompletionWidget::addDictionary()
0136 {
0137     QStringList dictionaryNames;
0138     QStringList dictionaryFiles;
0139     QStringList dictionaryLanguages;
0140     for (int row = 0; row < model->rowCount(); ++row) {
0141         const QStandardItem *nameItem = model->item(row, 0);
0142         const QStandardItem *languageItem = model->item(row, 1);
0143         dictionaryNames += nameItem->text();
0144         dictionaryFiles += nameItem->data().toString();
0145         dictionaryLanguages += languageItem->text();
0146     }
0147     DictionaryCreationWizard *wizard = new DictionaryCreationWizard(this, dictionaryNames, dictionaryFiles, dictionaryLanguages);
0148     if (wizard->exec() == QDialog::Accepted) {
0149         QString filename = wizard->createDictionary();
0150         newDictionaryFiles += filename;
0151         QString languageTag = wizard->language();
0152         if (!languageButton->contains(languageTag)) {
0153             languageButton->insertLanguage(languageTag, i18n("without name"));
0154         }
0155         QStandardItem *nameItem = new QStandardItem(wizard->name());
0156         nameItem->setData(filename);
0157         QStandardItem *languageItem = new QStandardItem(languageTag);
0158         QList<QStandardItem *> items;
0159         items.append(nameItem);
0160         items.append(languageItem);
0161         model->appendRow(items);
0162     }
0163     delete wizard;
0164 }
0165 
0166 void WordCompletionWidget::deleteDictionary()
0167 {
0168     int row = dictionaryView->currentIndex().row();
0169     const QStandardItem *nameItem = model->item(row, 0);
0170 
0171     if (nameItem != nullptr) {
0172         removedDictionaryFiles += nameItem->data().toString();
0173         qDeleteAll(model->takeRow(row));
0174     }
0175 }
0176 
0177 void WordCompletionWidget::moveUp()
0178 {
0179     int row = dictionaryView->currentIndex().row();
0180     if (row > 0) {
0181         QList<QStandardItem *> items = model->takeRow(row);
0182         model->insertRow(row - 1, items);
0183         dictionaryView->setCurrentIndex(model->index(row - 1, 0));
0184     }
0185 }
0186 
0187 void WordCompletionWidget::moveDown()
0188 {
0189     int row = dictionaryView->currentIndex().row();
0190     if (row < model->rowCount() - 1) {
0191         QList<QStandardItem *> items = model->takeRow(row);
0192         model->insertRow(row + 1, items);
0193         dictionaryView->setCurrentIndex(model->index(row + 1, 0));
0194     }
0195 }
0196 
0197 void WordCompletionWidget::exportDictionary()
0198 {
0199     const QStandardItem *nameItem = model->item(dictionaryView->currentIndex().row(), 0);
0200 
0201     if (nameItem != nullptr) {
0202         QUrl url = QFileDialog::getSaveFileUrl(this, i18n("Export Dictionary"));
0203         if (url.isEmpty() || !url.isValid())
0204             return;
0205 
0206         if (url.isLocalFile() && QFile::exists(url.toLocalFile())) {
0207             if (KMessageBox::warningContinueCancel(nullptr,
0208                                                    QStringLiteral("<qt>%1</qt>")
0209                                                        .arg(i18n("The file %1 already exists. "
0210                                                                  "Do you want to overwrite it?",
0211                                                                  url.url())),
0212                                                    i18n("File Exists"),
0213                                                    KGuiItem(i18n("&Overwrite")))
0214                 == KMessageBox::Cancel) {
0215                 return;
0216             }
0217         }
0218         QUrl src;
0219         src.setPath(QStandardPaths::locate(QStandardPaths::AppDataLocation, nameItem->data().toString()));
0220         KIO::FileCopyJob *job = KIO::file_copy(src, url);
0221         job->exec();
0222     }
0223 }
0224 
0225 void WordCompletionWidget::selectionChanged()
0226 {
0227     QModelIndex current = dictionaryView->currentIndex();
0228     deleteButton->setEnabled(current.isValid());
0229     exportButton->setEnabled(current.isValid());
0230     selectedDictionaryDetails->setEnabled(current.isValid());
0231     moveUpButton->setEnabled(current.isValid() && current.row() > 0);
0232     moveDownButton->setEnabled(current.isValid() && current.row() < model->rowCount() - 1);
0233 
0234     if (current.isValid()) {
0235         const QStandardItem *nameItem = model->item(current.row(), 0);
0236         const QStandardItem *languageItem = model->item(current.row(), 1);
0237 
0238         dictionaryName->setText(nameItem->text());
0239         languageButton->setCurrentItem(languageItem->text());
0240     } else {
0241         dictionaryName->clear();
0242     }
0243 }
0244 
0245 void WordCompletionWidget::nameChanged(const QString &text)
0246 {
0247     const QStandardItem *nameItem = model->item(dictionaryView->currentIndex().row(), 0);
0248 
0249     if (nameItem != nullptr) {
0250         QString old = nameItem->text();
0251 
0252         if (old != text) {
0253             QStandardItem *newItem = new QStandardItem(text);
0254             newItem->setData(nameItem->data());
0255             model->setItem(dictionaryView->currentIndex().row(), 0, newItem);
0256             Q_EMIT changed(true);
0257         }
0258     }
0259 }
0260 
0261 void WordCompletionWidget::languageSelected()
0262 {
0263     const QStandardItem *languageItem = model->item(dictionaryView->currentIndex().row(), 1);
0264 
0265     if (languageItem != nullptr) {
0266         QString old = languageItem->text();
0267         QString text = languageButton->current();
0268 
0269         if (old != text) {
0270             QStandardItem *newItem = new QStandardItem(text);
0271             model->setItem(dictionaryView->currentIndex().row(), 1, newItem);
0272             Q_EMIT changed(true);
0273         }
0274     }
0275 }