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"