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 "adblockdialog.h"
0019 #include "adblockmanager.h"
0020 #include "adblocksubscription.h"
0021 #include "adblocktreewidget.h"
0022 #include "adblockaddsubscriptiondialog.h"
0023 #include "mainapplication.h"
0024 #include "qztools.h"
0025 
0026 #include <QMenu>
0027 #include <QTimer>
0028 #include <QMessageBox>
0029 #include <QInputDialog>
0030 
0031 AdBlockDialog::AdBlockDialog(QWidget* parent)
0032     : QDialog(parent)
0033     , m_manager(AdBlockManager::instance())
0034     , m_currentTreeWidget(nullptr)
0035     , m_currentSubscription(nullptr)
0036     , m_loaded(false)
0037 {
0038     setAttribute(Qt::WA_DeleteOnClose);
0039     setupUi(this);
0040 
0041     QzTools::centerWidgetOnScreen(this);
0042 
0043 #ifdef Q_OS_MACOS
0044     tabWidget->setDocumentMode(false);
0045 #endif
0046     adblockCheckBox->setChecked(m_manager->isEnabled());
0047 
0048     auto* menu = new QMenu(buttonOptions);
0049     m_actionAddRule = menu->addAction(tr("Add Rule"), this, &AdBlockDialog::addRule);
0050     m_actionRemoveRule = menu->addAction(tr("Remove Rule"), this, &AdBlockDialog::removeRule);
0051     menu->addSeparator();
0052     m_actionAddSubscription = menu->addAction(tr("Add Subscription"), this, &AdBlockDialog::addSubscription);
0053     m_actionRemoveSubscription = menu->addAction(tr("Remove Subscription"), this, &AdBlockDialog::removeSubscription);
0054     menu->addAction(tr("Update Subscriptions"), m_manager, &AdBlockManager::updateAllSubscriptions);
0055     menu->addSeparator();
0056     menu->addAction(tr("Learn about writing rules..."), this, &AdBlockDialog::learnAboutRules);
0057 
0058     buttonOptions->setMenu(menu);
0059     connect(menu, &QMenu::aboutToShow, this, &AdBlockDialog::aboutToShowMenu);
0060 
0061     connect(adblockCheckBox, &QAbstractButton::toggled, this, &AdBlockDialog::enableAdBlock);
0062     connect(search, &QLineEdit::textChanged, this, &AdBlockDialog::filterString);
0063     connect(tabWidget, &QTabWidget::currentChanged, this, &AdBlockDialog::currentChanged);
0064     connect(buttonBox, &QDialogButtonBox::accepted, this, &QWidget::close);
0065 
0066     load();
0067 
0068     buttonBox->setFocus();
0069 }
0070 
0071 void AdBlockDialog::showRule(const AdBlockRule* rule) const
0072 {
0073     AdBlockSubscription* subscription = rule->subscription();
0074     if (!subscription) {
0075         return;
0076     }
0077 
0078     for (int i = 0; i < tabWidget->count(); ++i) {
0079         auto* treeWidget = qobject_cast<AdBlockTreeWidget*>(tabWidget->widget(i));
0080 
0081         if (subscription == treeWidget->subscription()) {
0082             treeWidget->showRule(rule);
0083             tabWidget->setCurrentIndex(i);
0084             break;
0085         }
0086     }
0087 }
0088 
0089 void AdBlockDialog::addRule()
0090 {
0091     m_currentTreeWidget->addRule();
0092 }
0093 
0094 void AdBlockDialog::removeRule()
0095 {
0096     m_currentTreeWidget->removeRule();
0097 }
0098 
0099 void AdBlockDialog::addSubscription()
0100 {
0101     AdBlockAddSubscriptionDialog dialog(this);
0102     if (dialog.exec() != QDialog::Accepted) {
0103         return;
0104     }
0105 
0106     QString title = dialog.title();
0107     QString url = dialog.url();
0108 
0109     if (AdBlockSubscription* subscription = m_manager->addSubscription(title, url)) {
0110         auto* tree = new AdBlockTreeWidget(subscription, tabWidget);
0111         int index = tabWidget->insertTab(tabWidget->count() - 1, tree, subscription->title());
0112 
0113         tabWidget->setCurrentIndex(index);
0114     }
0115 }
0116 
0117 void AdBlockDialog::removeSubscription()
0118 {
0119     if (m_manager->removeSubscription(m_currentSubscription)) {
0120         delete m_currentTreeWidget;
0121     }
0122 }
0123 
0124 void AdBlockDialog::currentChanged(int index)
0125 {
0126     if (index != -1) {
0127         m_currentTreeWidget = qobject_cast<AdBlockTreeWidget*>(tabWidget->widget(index));
0128         m_currentSubscription = m_currentTreeWidget->subscription();
0129     }
0130 }
0131 
0132 void AdBlockDialog::filterString(const QString &string)
0133 {
0134     if (m_currentTreeWidget && adblockCheckBox->isChecked()) {
0135         m_currentTreeWidget->filterString(string);
0136     }
0137 }
0138 
0139 void AdBlockDialog::enableAdBlock(bool state)
0140 {
0141     m_manager->setEnabled(state);
0142 
0143     if (state) {
0144         load();
0145     }
0146 }
0147 
0148 void AdBlockDialog::aboutToShowMenu()
0149 {
0150     bool subscriptionEditable = m_currentSubscription && m_currentSubscription->canEditRules();
0151     bool subscriptionRemovable = m_currentSubscription && m_currentSubscription->canBeRemoved();
0152 
0153     m_actionAddRule->setEnabled(subscriptionEditable);
0154     m_actionRemoveRule->setEnabled(subscriptionEditable);
0155     m_actionRemoveSubscription->setEnabled(subscriptionRemovable);
0156 }
0157 
0158 void AdBlockDialog::learnAboutRules()
0159 {
0160     mApp->addNewTab(QUrl(QSL("http://adblockplus.org/en/filters")));
0161 }
0162 
0163 void AdBlockDialog::loadSubscriptions()
0164 {
0165     for (int i = 0; i < tabWidget->count(); ++i) {
0166         auto* treeWidget = qobject_cast<AdBlockTreeWidget*>(tabWidget->widget(i));
0167         treeWidget->refresh();
0168     }
0169 }
0170 
0171 void AdBlockDialog::load()
0172 {
0173     if (m_loaded || !adblockCheckBox->isChecked()) {
0174         return;
0175     }
0176 
0177     const auto subscriptions = m_manager->subscriptions();
0178     for (AdBlockSubscription* subscription : subscriptions) {
0179         auto* tree = new AdBlockTreeWidget(subscription, tabWidget);
0180         tabWidget->addTab(tree, subscription->title());
0181     }
0182 
0183     m_loaded = true;
0184 
0185     QTimer::singleShot(50, this, &AdBlockDialog::loadSubscriptions);
0186 }