File indexing completed on 2024-04-28 04:57:31

0001 /***************************************************************************
0002  *   Copyright (C) 2009 Matthias Fuchs <mat69@gmx.net>                     *
0003  *                                                                         *
0004  *   This program is free software; you can redistribute it and/or modify  *
0005  *   it under the terms of the GNU General Public License as published by  *
0006  *   the Free Software Foundation; either version 2 of the License, or     *
0007  *   (at your option) any later version.                                   *
0008  *                                                                         *
0009  *   This program is distributed in the hope that it will be useful,       *
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0012  *   GNU General Public License for more details.                          *
0013  *                                                                         *
0014  *   You should have received a copy of the GNU General Public License     *
0015  *   along with this program; if not, write to the                         *
0016  *   Free Software Foundation, Inc.,                                       *
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
0018  ***************************************************************************/
0019 
0020 #include "dlgchecksumsearch.h"
0021 
0022 #include "core/verifier.h"
0023 
0024 #include "checksumsearch.h"
0025 #include "checksumsearchsettings.h"
0026 #include "kget_debug.h"
0027 
0028 #include <QSortFilterProxyModel>
0029 #include <QStandardItemModel>
0030 #include <QStringListModel>
0031 
0032 #include <KPluginFactory>
0033 #include <KStandardGuiItem>
0034 
0035 const QUrl ChecksumSearchAddDlg::URL = QUrl("http://www.example.com/file.zip");
0036 
0037 K_PLUGIN_FACTORY(KGetFactory, registerPlugin<DlgChecksumSettingsWidget>();)
0038 
0039 ChecksumSearchAddDlg::ChecksumSearchAddDlg(QStringListModel *modesModel, QStringListModel *typesModel, QWidget *parent, Qt::WindowFlags flags)
0040     : QDialog(parent, flags)
0041     , m_modesModel(modesModel)
0042     , m_typesModel(typesModel)
0043 {
0044     setWindowTitle(i18n("Add item"));
0045 
0046     ui.setupUi(this);
0047 
0048     if (m_modesModel) {
0049         ui.mode->setModel(m_modesModel);
0050     }
0051     if (m_typesModel) {
0052         ui.type->setModel(m_typesModel);
0053     }
0054 
0055     slotUpdate();
0056 
0057     connect(ui.change, &QLineEdit::textChanged, this, &ChecksumSearchAddDlg::slotUpdate);
0058     connect(ui.mode, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdate()));
0059     connect(this, &QDialog::accepted, this, &ChecksumSearchAddDlg::slotAccpeted);
0060     connect(ui.buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0061     connect(ui.buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0062 }
0063 
0064 void ChecksumSearchAddDlg::slotUpdate()
0065 {
0066     ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!ui.change->text().isEmpty());
0067 
0068     const auto mode = static_cast<ChecksumSearch::UrlChangeMode>(ui.mode->currentIndex());
0069     const QUrl modifiedUrl = ChecksumSearch::createUrl(URL, ui.change->text(), mode);
0070     const QString text = i18n("%1 would become %2", URL.toDisplayString(), modifiedUrl.toDisplayString());
0071     ui.label->setText(text);
0072 }
0073 
0074 void ChecksumSearchAddDlg::slotAccpeted()
0075 {
0076     Q_EMIT addItem(ui.change->text(), ui.mode->currentIndex(), ui.type->currentText());
0077 }
0078 
0079 ChecksumDelegate::ChecksumDelegate(QObject *parent)
0080     : QStyledItemDelegate(parent)
0081     , m_modesModel(nullptr)
0082     , m_typesModel(nullptr)
0083 {
0084 }
0085 
0086 ChecksumDelegate::ChecksumDelegate(QStringListModel *modesModel, QStringListModel *typesModel, QObject *parent)
0087     : QStyledItemDelegate(parent)
0088     , m_modesModel(modesModel)
0089     , m_typesModel(typesModel)
0090 {
0091 }
0092 
0093 QWidget *ChecksumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
0094 {
0095     Q_UNUSED(option)
0096 
0097     if (index.isValid()) {
0098         if (index.column() == 0l) {
0099             auto *line = new KLineEdit(parent);
0100 
0101             return line;
0102         } else if (index.column() == 1) {
0103             if (m_modesModel) {
0104                 auto *modesBox = new KComboBox(parent);
0105                 modesBox->setModel(m_modesModel);
0106 
0107                 return modesBox;
0108             }
0109         } else if (index.column() == 2) {
0110             if (m_typesModel) {
0111                 auto *typesBox = new KComboBox(parent);
0112                 typesBox->setModel(m_typesModel);
0113 
0114                 return typesBox;
0115             }
0116         }
0117     }
0118 
0119     return nullptr;
0120 }
0121 
0122 void ChecksumDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
0123 {
0124     if (index.isValid() && editor) {
0125         if (index.column() == 0) {
0126             auto *line = static_cast<KLineEdit *>(editor);
0127             line->setText(index.data(Qt::EditRole).toString());
0128         } else if (index.column() == 1) {
0129             auto *modesBox = static_cast<KComboBox *>(editor);
0130             const QString mode = index.data(Qt::EditRole).toString();
0131             modesBox->setCurrentIndex(modesBox->findText(mode));
0132         } else if (index.column() == 2) {
0133             auto *typesBox = static_cast<KComboBox *>(editor);
0134             const QString type = index.data(Qt::EditRole).toString();
0135             typesBox->setCurrentIndex(typesBox->findText(type));
0136         }
0137     }
0138 }
0139 
0140 void ChecksumDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
0141 {
0142     if (index.isValid() && editor && model) {
0143         if (index.column() == 0) {
0144             auto *line = static_cast<KLineEdit *>(editor);
0145             if (!line->text().isEmpty()) {
0146                 model->setData(index, line->text());
0147             }
0148         } else if (index.column() == 1) {
0149             auto *modesBox = static_cast<KComboBox *>(editor);
0150             model->setData(index, modesBox->currentText());
0151             model->setData(index, modesBox->currentIndex(), Qt::UserRole);
0152         } else if (index.column() == 2) {
0153             auto *typesBox = static_cast<KComboBox *>(editor);
0154             model->setData(index, typesBox->currentText());
0155         }
0156     }
0157 }
0158 
0159 void ChecksumDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
0160 {
0161     Q_UNUSED(index)
0162     editor->setGeometry(option.rect);
0163 }
0164 
0165 DlgChecksumSettingsWidget::DlgChecksumSettingsWidget(QObject *parent, const KPluginMetaData &data)
0166     : KCModule(parent, data)
0167 {
0168     ui.setupUi(widget());
0169 
0170     m_modes = ChecksumSearch::urlChangeModes();
0171     m_modesModel = new QStringListModel(m_modes, this);
0172     QStringList types = Verifier::supportedVerficationTypes();
0173     types.insert(0, QString());
0174     m_typesModel = new QStringListModel(types, this);
0175 
0176     m_model = new QStandardItemModel(0, 3, this);
0177     m_model->setHeaderData(0, Qt::Horizontal, i18nc("the string that is used to modify an url", "Change string"));
0178     m_model->setHeaderData(1, Qt::Horizontal, i18nc("the mode defines how the url should be changed", "Change mode"));
0179     m_model->setHeaderData(2, Qt::Horizontal, i18nc("the type of the checksum e.g. md5", "Checksum type"));
0180 
0181     m_proxy = new QSortFilterProxyModel(this);
0182     m_proxy->setSourceModel(m_model);
0183     m_proxy->setSortCaseSensitivity(Qt::CaseInsensitive);
0184 
0185     ui.treeView->setModel(m_proxy);
0186     auto *delegate = new ChecksumDelegate(m_modesModel, m_typesModel, this);
0187     ui.treeView->setItemDelegate(delegate);
0188     ui.treeView->sortByColumn(2, Qt::AscendingOrder);
0189     KGuiItem::assign(ui.add, KStandardGuiItem::add());
0190     KGuiItem::assign(ui.remove, KStandardGuiItem::remove());
0191     slotUpdate();
0192 
0193     connect(ui.add, &QAbstractButton::clicked, this, &DlgChecksumSettingsWidget::slotAdd);
0194     connect(ui.remove, &QAbstractButton::clicked, this, &DlgChecksumSettingsWidget::slotRemove);
0195     connect(ui.treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &DlgChecksumSettingsWidget::slotUpdate);
0196     connect(m_model, &QStandardItemModel::dataChanged, this, &DlgChecksumSettingsWidget::markAsChanged);
0197     connect(m_model, &QStandardItemModel::rowsInserted, this, &DlgChecksumSettingsWidget::markAsChanged);
0198     connect(m_model, &QStandardItemModel::rowsRemoved, this, &DlgChecksumSettingsWidget::markAsChanged);
0199 }
0200 
0201 DlgChecksumSettingsWidget::~DlgChecksumSettingsWidget()
0202 {
0203 }
0204 
0205 void DlgChecksumSettingsWidget::slotAdd()
0206 {
0207     auto *dialog = new ChecksumSearchAddDlg(m_modesModel, m_typesModel, widget());
0208     connect(dialog, &ChecksumSearchAddDlg::addItem, this, &DlgChecksumSettingsWidget::slotAddItem);
0209 
0210     dialog->show();
0211 }
0212 
0213 void DlgChecksumSettingsWidget::slotRemove()
0214 {
0215     while (ui.treeView->selectionModel()->hasSelection()) {
0216         const QModelIndex index = ui.treeView->selectionModel()->selectedRows().first();
0217         m_model->removeRow(m_proxy->mapToSource(index).row());
0218     }
0219 }
0220 
0221 void DlgChecksumSettingsWidget::slotAddItem(const QString &change, int mode, const QString &type)
0222 {
0223     auto *item = new QStandardItem(m_modes.value(mode));
0224     item->setData(QVariant(mode), Qt::UserRole);
0225 
0226     QList<QStandardItem *> items;
0227     items << new QStandardItem(change);
0228     items << item;
0229     items << new QStandardItem(type);
0230     m_model->insertRow(m_model->rowCount(), items);
0231 }
0232 
0233 void DlgChecksumSettingsWidget::slotUpdate()
0234 {
0235     ui.remove->setEnabled(ui.treeView->selectionModel()->hasSelection());
0236 }
0237 
0238 void DlgChecksumSettingsWidget::load()
0239 {
0240     QStringList changes = ChecksumSearchSettings::self()->searchStrings();
0241     QList<int> modes = ChecksumSearchSettings::self()->urlChangeModeList();
0242     QStringList types = ChecksumSearchSettings::self()->checksumTypeList();
0243 
0244     for (int i = 0; i < changes.size(); ++i) {
0245         slotAddItem(changes.at(i), modes.at(i), types.at(i));
0246     }
0247 }
0248 
0249 void DlgChecksumSettingsWidget::save()
0250 {
0251     qCDebug(KGET_DEBUG);
0252     QStringList changes;
0253     QList<int> modes;
0254     QStringList types;
0255 
0256     for (int row = 0; row < m_model->rowCount(); ++row) {
0257         changes.append(m_model->data(m_model->index(row, 0)).toString());
0258         modes.append(m_model->data(m_model->index(row, 1), Qt::UserRole).toInt());
0259         types.append(m_model->data(m_model->index(row, 2)).toString());
0260     }
0261 
0262     ChecksumSearchSettings::self()->setSearchStrings(changes);
0263     ChecksumSearchSettings::self()->setUrlChangeModeList(modes);
0264     ChecksumSearchSettings::self()->setChecksumTypeList(types);
0265 
0266     ChecksumSearchSettings::self()->save();
0267 }
0268 
0269 #include "dlgchecksumsearch.moc"
0270 #include "moc_dlgchecksumsearch.cpp"