File indexing completed on 2025-01-19 04:47:00

0001 /*
0002    SPDX-FileCopyrightText: 2023-2024 Laurent Montel <montel.org>
0003 
0004    SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "adblockfiltertreeview.h"
0008 #include "adblockfilter.h"
0009 #include "adblockfilterlistsmodel.h"
0010 #include "adblockmanager.h"
0011 #include "adblockpluginurlinterceptoraddadblocklistdialog.h"
0012 #include "adblockviewfilterdialog.h"
0013 #include "libadblockplugin_debug.h"
0014 #include <KLocalizedString>
0015 #include <KMessageBox>
0016 #include <QContextMenuEvent>
0017 #include <QHeaderView>
0018 #include <QMenu>
0019 #include <QPointer>
0020 #include <QSortFilterProxyModel>
0021 
0022 AdblockFilterTreeView::AdblockFilterTreeView(QWidget *parent)
0023     : QTreeView(parent)
0024     , mAdblockFilterListsModel(new AdblockFilterListsModel(this))
0025     , mSortFilterProxyModel(new QSortFilterProxyModel(this))
0026 {
0027     mAdblockFilterListsModel->setObjectName(QLatin1StringView("mAdblockFilterListsModel"));
0028 
0029     mSortFilterProxyModel->setObjectName(QLatin1StringView("mSortFilterProxyModel"));
0030 
0031     mSortFilterProxyModel->setSourceModel(mAdblockFilterListsModel);
0032     setModel(mSortFilterProxyModel);
0033     setContextMenuPolicy(Qt::DefaultContextMenu);
0034 
0035     for (int c = 0, total = header()->count(); c < total; ++c) {
0036         header()->setSectionResizeMode(c, QHeaderView::Stretch);
0037     }
0038     setRootIsDecorated(false);
0039     setSortingEnabled(true);
0040 
0041     connect(AdblockManager::self(), &AdblockManager::refreshFinished, this, [this]() {
0042         loadSettings();
0043     });
0044 }
0045 
0046 AdblockFilterTreeView::~AdblockFilterTreeView() = default;
0047 
0048 void AdblockFilterTreeView::setFilterString(const QString &str)
0049 {
0050     mSortFilterProxyModel->setFilterFixedString(str);
0051 }
0052 
0053 void AdblockFilterTreeView::contextMenuEvent(QContextMenuEvent *event)
0054 {
0055     QMenu menu;
0056 
0057     const QModelIndexList itemSelected = selectionModel()->selectedRows();
0058 
0059     auto addAction = new QAction(QIcon::fromTheme(QStringLiteral("list-add")), i18n("Add..."), &menu);
0060     connect(addAction, &QAction::triggered, this, &AdblockFilterTreeView::slotAddAdblock);
0061     menu.addAction(addAction);
0062 
0063     const int selectedItemsNumber = itemSelected.count();
0064     // qDebug() <<" selectedItemsNumber " << selectedItemsNumber;
0065     if (selectedItemsNumber == 1) { // Edit only one element
0066         auto modifyAction = new QAction(QIcon::fromTheme(QStringLiteral("edit-rename")), i18n("Modify..."), &menu);
0067         connect(modifyAction, &QAction::triggered, this, [this, itemSelected]() {
0068             slotModifyAdblock(itemSelected.at(0));
0069         });
0070         menu.addAction(modifyAction);
0071         menu.addSeparator();
0072         auto deleteAction = new QAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18n("Delete"), &menu);
0073         connect(deleteAction, &QAction::triggered, this, [this, itemSelected]() {
0074             // For the moment remove only one element
0075             slotDeleteAdblock(itemSelected.at(0));
0076         });
0077         menu.addAction(deleteAction);
0078 
0079         menu.addSeparator();
0080         auto showAdblockAction = new QAction(QIcon::fromTheme(QStringLiteral("document-preview")), i18n("Show"), &menu);
0081         connect(showAdblockAction, &QAction::triggered, this, [this, itemSelected]() {
0082             const QModelIndex modelIndexUrl = mAdblockFilterListsModel->index(itemSelected.at(0).row(), AdblockFilterListsModel::Url);
0083             const QString filterText = AdblockManager::self()->adblockListText(modelIndexUrl.data().toString());
0084             if (filterText.isEmpty()) {
0085                 AdblockViewFilterDialog dlg(this);
0086                 dlg.setFilterText(filterText);
0087                 dlg.exec();
0088             } else {
0089                 qCWarning(LIBADBLOCKPLUGIN_PLUGIN_LOG) << "List is empty. Perhaps we need to refresh lists";
0090             }
0091         });
0092         menu.addAction(showAdblockAction);
0093     }
0094     menu.addSeparator();
0095     auto updateListsAction = new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")), i18n("Update Lists"), &menu);
0096     connect(updateListsAction, &QAction::triggered, this, []() {
0097         AdblockManager::self()->refreshLists();
0098     });
0099     menu.addAction(updateListsAction);
0100 
0101     menu.exec(event->globalPos());
0102 }
0103 
0104 [[nodiscard]] AdblockFilter convertToAdblockFilter(const AdblockPluginUrlInterceptorAddAdblockListWidget::AdBlockListInfo &info)
0105 {
0106     AdblockFilter filter;
0107     filter.setName(info.name);
0108     filter.setUrl(info.url);
0109     return filter;
0110 }
0111 
0112 void AdblockFilterTreeView::slotAddAdblock()
0113 {
0114     QPointer<AdblockPluginUrlInterceptorAddAdblockListDialog> dlg = new AdblockPluginUrlInterceptorAddAdblockListDialog(this);
0115     if (dlg->exec()) {
0116         const AdblockPluginUrlInterceptorAddAdblockListWidget::AdBlockListInfo info = dlg->info();
0117         if (info.isValid()) {
0118             if (mAdblockFilterListsModel->insertList(std::move(convertToAdblockFilter(info)))) {
0119                 mSettingsChanged = true;
0120             }
0121         }
0122     }
0123     delete dlg;
0124 }
0125 
0126 void AdblockFilterTreeView::slotModifyAdblock(const QModelIndex &index)
0127 {
0128     QPointer<AdblockPluginUrlInterceptorAddAdblockListDialog> dlg = new AdblockPluginUrlInterceptorAddAdblockListDialog(this);
0129     AdblockPluginUrlInterceptorAddAdblockListWidget::AdBlockListInfo originalInfo;
0130     const QModelIndex newModelIndex = mSortFilterProxyModel->mapToSource(index);
0131 
0132     const QModelIndex modelIndexUrl = mAdblockFilterListsModel->index(newModelIndex.row(), AdblockFilterListsModel::Url);
0133     const QModelIndex modelIndexName = mAdblockFilterListsModel->index(newModelIndex.row(), AdblockFilterListsModel::Name);
0134     const QString listName = modelIndexName.data().toString();
0135     // qDebug() << " modelIndexUrl " << modelIndexUrl.data() << " modelIndexName " << modelIndexName.data();
0136     originalInfo.name = listName;
0137     originalInfo.url = modelIndexUrl.data().toString();
0138     dlg->setInfo(originalInfo);
0139     if (dlg->exec()) {
0140         const AdblockPluginUrlInterceptorAddAdblockListWidget::AdBlockListInfo info = dlg->info();
0141         if (info != originalInfo) {
0142             if (info.isValid()) {
0143                 mAdblockFilterListsModel->removeList(listName);
0144                 (void)mAdblockFilterListsModel->insertList(std::move(convertToAdblockFilter(info)));
0145                 mSettingsChanged = true;
0146             }
0147         }
0148     }
0149     delete dlg;
0150 }
0151 
0152 void AdblockFilterTreeView::slotDeleteAdblock(const QModelIndex &index)
0153 {
0154     const QModelIndex newModelIndex = mSortFilterProxyModel->mapToSource(index);
0155     const QModelIndex modelIndexName = mAdblockFilterListsModel->index(newModelIndex.row(), AdblockFilterListsModel::Name);
0156     const QString listName = modelIndexName.data().toString();
0157     if (KMessageBox::questionTwoActions(this,
0158                                         i18n("Do you want to remove \'%1\' ?", listName),
0159                                         i18nc("@title:window", "Remove List"),
0160                                         KStandardGuiItem::ok(),
0161                                         KStandardGuiItem::cancel())
0162         == KMessageBox::ButtonCode::PrimaryAction) {
0163         mAdblockFilterListsModel->removeList(listName);
0164         mSettingsChanged = true;
0165     }
0166 }
0167 
0168 void AdblockFilterTreeView::loadSettings()
0169 {
0170     mAdblockFilterListsModel->setAdblockFilter(AdblockManager::self()->adblockFilterLists());
0171 }
0172 
0173 void AdblockFilterTreeView::saveSettings()
0174 {
0175     if (mSettingsChanged) {
0176         AdblockManager::self()->setAdblockFilterLists(mAdblockFilterListsModel->adblockFilter());
0177         Q_EMIT settingsChanged();
0178     }
0179 }
0180 
0181 #include "moc_adblockfiltertreeview.cpp"