1
mirror of https://invent.kde.org/network/falkon.git synced 2024-09-22 18:22:10 +02:00
falkonOfficial/src/lib/adblock/adblocktreewidget.cpp
nowrep b9476c9bbc AdBlock: Showing different colors for each rule type
- black = normal rules
  green = exceptions
  gray  = disabled rules
  blue  = css rules
2012-06-25 21:01:30 +02:00

209 lines
6.2 KiB
C++

/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "adblocktreewidget.h"
#include "adblocksubscription.h"
#include <QMenu>
#include <QTimer>
#include <QInputDialog>
AdBlockTreeWidget::AdBlockTreeWidget(AdBlockSubscription* subscription, QWidget* parent)
: TreeWidget(parent)
, m_subscription(subscription)
, m_topItem(0)
, m_itemChangingBlock(false)
{
setContextMenuPolicy(Qt::CustomContextMenu);
setDefaultItemShowMode(TreeWidget::ItemsExpanded);
setHeaderHidden(true);
setAlternatingRowColors(true);
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint)));
connect(this, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(itemChanged(QTreeWidgetItem*)));
connect(m_subscription, SIGNAL(subscriptionUpdated()), this, SLOT(subscriptionUpdated()));
QTimer::singleShot(0, this, SLOT(refresh()));
}
AdBlockSubscription* AdBlockTreeWidget::subscription() const
{
return m_subscription;
}
void AdBlockTreeWidget::contextMenuRequested(const QPoint &pos)
{
if (!m_subscription->canEditRules()) {
return;
}
QTreeWidgetItem* item = itemAt(pos);
if (!item) {
return;
}
QMenu menu;
menu.addAction(tr("Add Rule"), this, SLOT(addRule()));
menu.addSeparator();
QAction* deleteAction = menu.addAction(tr("Remove Rule"), this, SLOT(removeRule()));
if (!item->parent()) {
deleteAction->setDisabled(true);
}
menu.exec(viewport()->mapToGlobal(pos));
}
void AdBlockTreeWidget::itemChanged(QTreeWidgetItem* item)
{
if (!item || m_itemChangingBlock) {
return;
}
m_itemChangingBlock = true;
if (item->checkState(0) == Qt::Unchecked && !item->text(0).startsWith("!")) {
// Disable rule
int offset = item->data(0, Qt::UserRole + 10).toInt();
item->setText(0, item->text(0).prepend("!"));
const AdBlockRule* rule = m_subscription->disableRule(offset);
adjustItemColor(item, *rule);
}
else if (item->checkState(0) == Qt::Checked && item->text(0).startsWith("!")) {
// Enable rule
int offset = item->data(0, Qt::UserRole + 10).toInt();
item->setText(0, item->text(0).mid(1));
const AdBlockRule* rule = m_subscription->enableRule(offset);
adjustItemColor(item, *rule);
}
else if (m_subscription->canEditRules()) {
// Custom rule has been changed
int offset = item->data(0, Qt::UserRole + 10).toInt();
const AdBlockRule* rule = m_subscription->replaceRule(AdBlockRule(item->text(0)), offset);
adjustItemColor(item, *rule);
}
m_itemChangingBlock = false;
}
void AdBlockTreeWidget::addRule()
{
if (!m_subscription->canEditRules()) {
return;
}
QString newRule = QInputDialog::getText(this, tr("Add Custom Rule"), tr("Please write your rule here:"));
if (newRule.isEmpty()) {
return;
}
int offset = m_subscription->addRule(AdBlockRule(newRule));
QTreeWidgetItem* item = new QTreeWidgetItem();
item->setText(0, newRule);
item->setData(0, Qt::UserRole + 10, offset);
item->setFlags(item->flags() | Qt::ItemIsEditable);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(0, Qt::Checked);
m_itemChangingBlock = true;
m_topItem->addChild(item);
m_itemChangingBlock = false;
}
void AdBlockTreeWidget::removeRule()
{
QTreeWidgetItem* item = currentItem();
if (!item || !m_subscription->canEditRules() || item == m_topItem) {
return;
}
int offset = item->data(0, Qt::UserRole + 10).toInt();
m_subscription->removeRule(offset);
deleteItem(item);
}
void AdBlockTreeWidget::subscriptionUpdated()
{
refresh();
m_itemChangingBlock = true;
m_topItem->setText(0, tr("%1 (recently updated)").arg(m_subscription->title()));
m_itemChangingBlock = false;
}
void AdBlockTreeWidget::adjustItemColor(QTreeWidgetItem* item, const AdBlockRule &rule)
{
if (!rule.isEnabled()) {
QFont font;
font.setItalic(true);
item->setForeground(0, QColor(Qt::gray));
item->setFont(0, font);
}
else if (rule.isCssRule()) {
item->setForeground(0, QColor(Qt::darkBlue));
item->setFont(0, QFont());
}
else if (rule.isException()) {
item->setForeground(0, QColor(Qt::darkGreen));
item->setFont(0, QFont());
}
else {
item->setForeground(0, QColor());
item->setFont(0, QFont());
}
}
void AdBlockTreeWidget::refresh()
{
m_itemChangingBlock = true;
clear();
QFont boldFont;
boldFont.setBold(true);
m_topItem = new QTreeWidgetItem(this);
m_topItem->setText(0, m_subscription->title());
m_topItem->setFont(0, boldFont);
addTopLevelItem(m_topItem);
const QList<AdBlockRule> &allRules = m_subscription->allRules();
int index = 0;
foreach(const AdBlockRule & rule, allRules) {
QTreeWidgetItem* item = new QTreeWidgetItem(m_topItem);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(0, (rule.isEnabled()) ? Qt::Checked : Qt::Unchecked);
item->setText(0, rule.filter());
item->setData(0, Qt::UserRole + 10, index);
if (m_subscription->canEditRules()) {
item->setFlags(item->flags() | Qt::ItemIsEditable);
}
adjustItemColor(item, rule);
++index;
}
expandAll();
m_itemChangingBlock = false;
}