File indexing completed on 2024-11-24 04:16:54

0001 /*
0002   SPDX-FileCopyrightText: 2023-2024 Laurent Montel <montel.org>
0003 
0004   SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "bergamotenginelanguagewidget.h"
0008 #include "libbergamot_debug.h"
0009 #include "translatormodel.h"
0010 #include "translatorproxymodel.h"
0011 #include <KLocalizedString>
0012 #include <KMessageBox>
0013 #include <QLabel>
0014 #include <QLineEdit>
0015 #include <QProgressBar>
0016 #include <QPushButton>
0017 #include <QTreeView>
0018 #include <QVBoxLayout>
0019 
0020 #if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
0021 #include <TextAddonsWidgets/LineEditCatchReturnKey>
0022 #else
0023 #include <KLineEditEventHandler>
0024 #endif
0025 
0026 BergamotEngineLanguageWidget::BergamotEngineLanguageWidget(QWidget *parent)
0027     : QWidget{parent}
0028     , mTreeView(new QTreeView(this))
0029     , mSearchLineEdit(new QLineEdit(this))
0030     , mTranslatorModel(new TranslatorModel(this))
0031     , mTranslatorProxyModel(new TranslatorProxyModel(this))
0032     , mProgressBar(new QProgressBar(this))
0033     , mProgressBarLabel(new QLabel(this))
0034     , mProgressBarWidget(new QWidget(this))
0035 {
0036     auto mainLayout = new QVBoxLayout(this);
0037     mainLayout->setObjectName(QStringLiteral("mainLayout"));
0038     mainLayout->setContentsMargins({});
0039 
0040     auto hboxLayout = new QHBoxLayout;
0041     hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
0042     hboxLayout->setContentsMargins({});
0043     mainLayout->addLayout(hboxLayout);
0044 
0045     auto vboxLayout = new QVBoxLayout;
0046     vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
0047     vboxLayout->setContentsMargins({});
0048 
0049     mSearchLineEdit->setObjectName(QStringLiteral("mSearchLineEdit"));
0050     vboxLayout->addWidget(mSearchLineEdit);
0051     mSearchLineEdit->setPlaceholderText(i18n("Search..."));
0052     mSearchLineEdit->setClearButtonEnabled(true);
0053 
0054 #if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
0055     new TextAddonsWidgets::LineEditCatchReturnKey(mSearchLineEdit, this);
0056 #else
0057     KLineEditEventHandler::catchReturnKey(mSearchLineEdit);
0058 #endif
0059 
0060     mTreeView->setObjectName(QStringLiteral("mTreeView"));
0061     connect(ManagerModelTranslator::self(), &ManagerModelTranslator::errorText, this, &BergamotEngineLanguageWidget::slotError);
0062     connect(ManagerModelTranslator::self(), &ManagerModelTranslator::progress, this, &BergamotEngineLanguageWidget::slotProgressInfo);
0063     connect(ManagerModelTranslator::self(), &ManagerModelTranslator::extractDone, mTranslatorModel, &TranslatorModel::updateInstalledLanguage);
0064     connect(ManagerModelTranslator::self(), &ManagerModelTranslator::downLoadModelListDone, this, &BergamotEngineLanguageWidget::updateListModel);
0065 
0066     // TODO store list on local.
0067     if (ManagerModelTranslator::self()->needDownloadModelList()) {
0068         ManagerModelTranslator::self()->downloadListModels();
0069     } else {
0070         mTranslatorModel->insertTranslators(ManagerModelTranslator::self()->translators());
0071     }
0072 
0073     mTranslatorProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
0074     mTranslatorProxyModel->setSourceModel(mTranslatorModel);
0075     mTreeView->setModel(mTranslatorProxyModel);
0076     mTreeView->setRootIsDecorated(false);
0077     mTreeView->setSortingEnabled(true);
0078     vboxLayout->addWidget(mTreeView);
0079 
0080     hboxLayout->addLayout(vboxLayout);
0081 
0082     auto buttonLayout = new QVBoxLayout;
0083     buttonLayout->setObjectName(QStringLiteral("buttonLayout"));
0084     hboxLayout->addLayout(buttonLayout);
0085 
0086     auto downLoadLanguage = new QPushButton(QIcon::fromTheme(QStringLiteral("download-symbolic")), i18n("Download"), this);
0087     downLoadLanguage->setObjectName(QStringLiteral("downLoadLanguage"));
0088     buttonLayout->addWidget(downLoadLanguage);
0089     connect(downLoadLanguage, &QPushButton::clicked, this, [this]() {
0090         const auto currentlySelectedIndex = mTranslatorProxyModel->mapToSource(mTreeView->selectionModel()->currentIndex());
0091         const QModelIndex modelIndex = mTranslatorModel->index(currentlySelectedIndex.row(), TranslatorModel::Url);
0092         const QModelIndex modelIndexCheckSum = mTranslatorModel->index(currentlySelectedIndex.row(), TranslatorModel::CheckSum);
0093 
0094         const QString url = modelIndex.data().toString();
0095         const QString checkSum = modelIndexCheckSum.data().toString();
0096         qCDebug(TRANSLATOR_LIBBERGAMOT_LOG) << " url " << url << " checksum " << checkSum;
0097         slotDownLoad(url, checkSum);
0098     });
0099 
0100     auto deleteLanguage = new QPushButton(QIcon::fromTheme(QStringLiteral("edit-delete")), i18n("Delete"), this);
0101     deleteLanguage->setObjectName(QStringLiteral("downLoadLanguage"));
0102     buttonLayout->addWidget(deleteLanguage);
0103 
0104     auto updateListLanguage = new QPushButton(i18n("Update List"), this);
0105     updateListLanguage->setToolTip(i18n("Update list of languages from network"));
0106     updateListLanguage->setObjectName(QStringLiteral("updateListLanguage"));
0107     buttonLayout->addWidget(updateListLanguage);
0108     buttonLayout->addStretch(1); // spacer
0109     connect(updateListLanguage, &QPushButton::clicked, this, &BergamotEngineLanguageWidget::slotUpdateListLanguage);
0110 
0111     connect(mSearchLineEdit, &QLineEdit::textChanged, this, &BergamotEngineLanguageWidget::slotTextChanged);
0112 
0113     auto progressBarLayout = new QHBoxLayout;
0114     progressBarLayout->setObjectName(QStringLiteral("progressBarLayout"));
0115 
0116     mProgressBarLabel->setObjectName(QStringLiteral("mProgressBarLabel"));
0117     progressBarLayout->addWidget(mProgressBarLabel);
0118 
0119     mProgressBar->setObjectName(QStringLiteral("mProgressBar"));
0120     progressBarLayout->addWidget(mProgressBar);
0121 
0122     mProgressBarWidget->setObjectName(QStringLiteral("mProgressBarWidget"));
0123     mProgressBarWidget->setLayout(progressBarLayout);
0124 
0125     mainLayout->addWidget(mProgressBarWidget);
0126     mProgressBarWidget->setVisible(false);
0127 
0128     mTreeView->setColumnHidden(TranslatorModel::Url, true);
0129     mTreeView->setColumnHidden(TranslatorModel::CheckSum, true);
0130     mTreeView->setColumnHidden(TranslatorModel::Identifier, true);
0131     mTreeView->setColumnHidden(TranslatorModel::NeedToUpdateLanguage, true);
0132     auto updateButton = [this, downLoadLanguage, deleteLanguage]() {
0133         const bool hasSelectedItem = mTreeView->currentIndex().isValid();
0134         const auto currentlySelectedIndex = mTranslatorProxyModel->mapToSource(mTreeView->selectionModel()->currentIndex());
0135         const QModelIndex modelIndex = mTranslatorModel->index(currentlySelectedIndex.row(), TranslatorModel::Installed);
0136         const QModelIndex modelIndexNeedToUpdate = mTranslatorModel->index(currentlySelectedIndex.row(), TranslatorModel::NeedToUpdateLanguage);
0137         const bool isInstalled = modelIndex.data().toBool();
0138         const bool needToUpdate = modelIndexNeedToUpdate.data().toBool();
0139 
0140         if (needToUpdate) {
0141             downLoadLanguage->setEnabled(hasSelectedItem && needToUpdate);
0142         } else {
0143             downLoadLanguage->setEnabled(hasSelectedItem && !isInstalled);
0144         }
0145         deleteLanguage->setEnabled(hasSelectedItem && isInstalled);
0146     };
0147 
0148     connect(deleteLanguage, &QPushButton::clicked, this, [this, updateButton]() {
0149         const auto currentlySelectedIndex = mTranslatorProxyModel->mapToSource(mTreeView->selectionModel()->currentIndex());
0150         const QModelIndex modelIndex = mTranslatorModel->index(currentlySelectedIndex.row(), TranslatorModel::Identifier);
0151         const QString identifier = modelIndex.data().toString();
0152         slotDelete(identifier);
0153         updateButton();
0154     });
0155 
0156     connect(mTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [updateButton]() {
0157         updateButton();
0158     });
0159     downLoadLanguage->setEnabled(false);
0160     deleteLanguage->setEnabled(false);
0161 }
0162 
0163 BergamotEngineLanguageWidget::~BergamotEngineLanguageWidget() = default;
0164 
0165 void BergamotEngineLanguageWidget::slotProgressInfo(const ManagerModelTranslator::ProgressInfo &info)
0166 {
0167     if (info.bytesReceived != info.bytesTotal) {
0168         mProgressBarWidget->setVisible(true);
0169     } else {
0170         mProgressBarWidget->setVisible(false);
0171     }
0172     mProgressBarLabel->setText(info.languageName);
0173     mProgressBar->setRange(0, 100);
0174     mProgressBar->setValue((info.bytesReceived * 100) / info.bytesTotal);
0175 }
0176 
0177 void BergamotEngineLanguageWidget::slotError(const QString &str)
0178 {
0179     KMessageBox::error(this, i18n("Error: %1", str), i18n("Bergamot"));
0180 }
0181 
0182 void BergamotEngineLanguageWidget::slotTextChanged(const QString &str)
0183 {
0184     mTranslatorProxyModel->setSearchString(str);
0185 }
0186 
0187 void BergamotEngineLanguageWidget::slotDownLoad(const QString &url, const QString &checkSum)
0188 {
0189     ManagerModelTranslator::self()->downloadLanguage(url, checkSum);
0190 }
0191 
0192 void BergamotEngineLanguageWidget::slotDelete(const QString &identifier)
0193 {
0194     mTranslatorModel->removeLanguage(identifier);
0195 }
0196 
0197 void BergamotEngineLanguageWidget::slotUpdateListLanguage()
0198 {
0199     ManagerModelTranslator::self()->downloadListModels();
0200 }
0201 
0202 void BergamotEngineLanguageWidget::updateListModel()
0203 {
0204     mTranslatorModel->insertTranslators(ManagerModelTranslator::self()->translators());
0205 }
0206 
0207 #include "moc_bergamotenginelanguagewidget.cpp"