File indexing completed on 2024-05-12 04:57:49

0001 /* ============================================================
0002 * Falkon - Qt web browser
0003 * Copyright (C) 2010-2018 David Rosca <nowrep@gmail.com>
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 3 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, see <http://www.gnu.org/licenses/>.
0017 * ============================================================ */
0018 #include "adblockicon.h"
0019 #include "adblockrule.h"
0020 #include "adblockmanager.h"
0021 #include "adblocksubscription.h"
0022 #include "mainapplication.h"
0023 #include "browserwindow.h"
0024 #include "webview.h"
0025 #include "tabwidget.h"
0026 #include "desktopnotificationsfactory.h"
0027 #include "qztools.h"
0028 
0029 #include <QMenu>
0030 
0031 AdBlockIcon::AdBlockIcon(QObject *parent)
0032     : AbstractButtonInterface(parent)
0033 {
0034     setTitle(tr("AdBlock"));
0035     setIcon(QIcon(QSL(":adblock/data/adblock.png")));
0036 
0037     updateState();
0038 
0039     connect(this, &AbstractButtonInterface::clicked, this, &AdBlockIcon::clicked);
0040     connect(this, &AbstractButtonInterface::webViewChanged, this, &AdBlockIcon::webViewChanged);
0041     connect(AdBlockManager::instance(), &AdBlockManager::enabledChanged, this, &AdBlockIcon::updateState);
0042     connect(AdBlockManager::instance(), &AdBlockManager::blockedRequestsChanged, this, &AdBlockIcon::blockedRequestsChanged);
0043 }
0044 
0045 QString AdBlockIcon::id() const
0046 {
0047     return QSL("adblock-icon");
0048 }
0049 
0050 QString AdBlockIcon::name() const
0051 {
0052     return tr("AdBlock Icon");
0053 }
0054 
0055 void AdBlockIcon::toggleCustomFilter()
0056 {
0057     auto* action = qobject_cast<QAction*>(sender());
0058     if (!action) {
0059         return;
0060     }
0061 
0062     const QString filter = action->data().toString();
0063     AdBlockManager* manager = AdBlockManager::instance();
0064     AdBlockCustomList* customList = manager->customList();
0065 
0066     if (customList->containsFilter(filter)) {
0067         customList->removeFilter(filter);
0068     }
0069     else {
0070         auto* rule = new AdBlockRule(filter, customList);
0071         customList->addRule(rule);
0072     }
0073 }
0074 
0075 void AdBlockIcon::updateState()
0076 {
0077     WebView *view = webView();
0078     if (!view) {
0079         setActive(false);
0080         setToolTip(name());
0081         setBadgeText(QString());
0082         return;
0083     }
0084     if (!AdBlockManager::instance()->isEnabled()) {
0085         setActive(false);
0086         setToolTip(tr("AdBlock is disabled"));
0087         setBadgeText(QString());
0088         return;
0089     }
0090     if (!AdBlockManager::instance()->canRunOnScheme(view->url().scheme())) {
0091         setActive(false);
0092         setToolTip(tr("AdBlock is disabled on this site "));
0093         setBadgeText(QString());
0094         return;
0095     }
0096 
0097     setActive(true);
0098     setToolTip(tr("AdBlock is active"));
0099     updateBadgeText();
0100 }
0101 
0102 void AdBlockIcon::updateBadgeText()
0103 {
0104     WebView *view = webView();
0105     if (!view) {
0106         return;
0107     }
0108     const int count = AdBlockManager::instance()->blockedRequestsForUrl(view->url()).count();
0109     if (count > 0) {
0110         setBadgeText(QString::number(count));
0111     } else {
0112         setBadgeText(QString());
0113     }
0114 }
0115 
0116 void AdBlockIcon::webViewChanged(WebView *view)
0117 {
0118     updateState();
0119 
0120     if (m_view) {
0121         disconnect(m_view.data(), &WebView::urlChanged, this, &AdBlockIcon::updateState);
0122     }
0123 
0124     m_view = view;
0125 
0126     if (m_view) {
0127         connect(m_view.data(), &WebView::urlChanged, this, &AdBlockIcon::updateState);
0128     }
0129 }
0130 
0131 void AdBlockIcon::clicked(ClickController *controller)
0132 {
0133     WebView *view = webView();
0134     if (!view) {
0135         return;
0136     }
0137 
0138     AdBlockManager* manager = AdBlockManager::instance();
0139     AdBlockCustomList* customList = manager->customList();
0140 
0141     const QUrl pageUrl = view->url();
0142 
0143     auto *menu = new QMenu();
0144     menu->setAttribute(Qt::WA_DeleteOnClose);
0145     menu->addAction(tr("Show AdBlock &Settings"), manager, SLOT(showDialog()));
0146     menu->addSeparator();
0147 
0148     if (!pageUrl.host().isEmpty() && manager->isEnabled() && manager->canRunOnScheme(pageUrl.scheme())) {
0149         const QString host = view->url().host().contains(QLatin1String("www.")) ? pageUrl.host().mid(4) : pageUrl.host();
0150         const QString hostFilter = QSL("@@||%1^$document").arg(host);
0151         const QString pageFilter = QSL("@@|%1|$document").arg(pageUrl.toString());
0152 
0153         QAction* act = menu->addAction(tr("Disable on %1").arg(host));
0154         act->setCheckable(true);
0155         act->setChecked(customList->containsFilter(hostFilter));
0156         act->setData(hostFilter);
0157         connect(act, &QAction::triggered, this, &AdBlockIcon::toggleCustomFilter);
0158 
0159         act = menu->addAction(tr("Disable only on this page"));
0160         act->setCheckable(true);
0161         act->setChecked(customList->containsFilter(pageFilter));
0162         act->setData(pageFilter);
0163         connect(act, &QAction::triggered, this, &AdBlockIcon::toggleCustomFilter);
0164     }
0165 
0166     connect(menu, &QMenu::aboutToHide, this, [=]() {
0167         controller->popupClosed();
0168     });
0169 
0170     menu->popup(controller->popupPosition(menu->sizeHint()));
0171 }
0172 
0173 void AdBlockIcon::blockedRequestsChanged(const QUrl &url)
0174 {
0175     WebView *view = webView();
0176     if (!view || url != view->url()) {
0177         return;
0178     }
0179     updateState();
0180 }