24#include <QApplication> 
   25#include <QInputDialog> 
   29    , m_subscription(subscription)
 
   31    , m_itemChangingBlock(false)
 
   33    setContextMenuPolicy(Qt::CustomContextMenu);
 
   35    setHeaderHidden(
true);
 
   36    setAlternatingRowColors(
true);
 
   37    setLayoutDirection(Qt::LeftToRight);
 
   39    connect(
this, &QWidget::customContextMenuRequested, 
this, &AdBlockTreeWidget::contextMenuRequested);
 
   40    connect(
this, SIGNAL(itemChanged(QTreeWidgetItem*,
int)), 
this, SLOT(itemChanged(QTreeWidgetItem*)));
 
   47    return m_subscription;
 
   52    if (!m_topItem && rule) {
 
   53        m_ruleToBeSelected = rule->
filter();
 
   55    else if (!m_ruleToBeSelected.isEmpty()) {
 
   56        QList<QTreeWidgetItem*> items = findItems(m_ruleToBeSelected, Qt::MatchRecursive);
 
   57        if (!items.isEmpty()) {
 
   58            QTreeWidgetItem* item = items.at(0);
 
   61            scrollToItem(item, QAbstractItemView::PositionAtCenter);
 
   64        m_ruleToBeSelected.clear();
 
   68void AdBlockTreeWidget::contextMenuRequested(
const QPoint &pos)
 
   74    QTreeWidgetItem* item = itemAt(pos);
 
   84    if (!item->parent()) {
 
   85        deleteAction->setDisabled(
true);
 
   88    menu.exec(viewport()->mapToGlobal(pos));
 
   91void AdBlockTreeWidget::itemChanged(QTreeWidgetItem* item)
 
   93    if (!item || m_itemChangingBlock) {
 
   97    m_itemChangingBlock = 
true;
 
   99    int offset = item->data(0, Qt::UserRole + 10).toInt();
 
  102    if (item->checkState(0) == Qt::Unchecked && oldRule->
isEnabled()) {
 
  106        adjustItemFeatures(item, rule);
 
  108    else if (item->checkState(0) == Qt::Checked && !oldRule->
isEnabled()) {
 
  112        adjustItemFeatures(item, rule);
 
  116        auto* newRule = 
new AdBlockRule(item->text(0), m_subscription);
 
  119        adjustItemFeatures(item, rule);
 
  122    m_itemChangingBlock = 
false;
 
  125void AdBlockTreeWidget::copyFilter()
 
  127    QTreeWidgetItem* item = currentItem();
 
  132    QApplication::clipboard()->setText(item->text(0));
 
  141    QString newRule = QInputDialog::getText(
this, tr(
"Add Custom Rule"), tr(
"Please write your rule here:"));
 
  142    if (newRule.isEmpty()) {
 
  146    auto* rule = 
new AdBlockRule(newRule, m_subscription);
 
  147    int offset = m_subscription->
addRule(rule);
 
  149    auto* item = 
new QTreeWidgetItem();
 
  150    item->setText(0, newRule);
 
  151    item->setData(0, Qt::UserRole + 10, offset);
 
  152    item->setFlags(item->flags() | Qt::ItemIsEditable);
 
  154    m_itemChangingBlock = 
true;
 
  155    m_topItem->addChild(item);
 
  156    m_itemChangingBlock = 
false;
 
  158    adjustItemFeatures(item, rule);
 
  163    QTreeWidgetItem* item = currentItem();
 
  164    if (!item || !m_subscription->
canEditRules() || item == m_topItem) {
 
  168    int offset = item->data(0, Qt::UserRole + 10).toInt();
 
  174void AdBlockTreeWidget::subscriptionUpdated()
 
  178    m_itemChangingBlock = 
true;
 
  179    m_topItem->setText(0, tr(
"%1 (recently updated)").arg(m_subscription->
title()));
 
  180    m_itemChangingBlock = 
false;
 
  183void AdBlockTreeWidget::subscriptionError(
const QString &message)
 
  187    m_itemChangingBlock = 
true;
 
  188    m_topItem->setText(0, tr(
"%1 (Error: %2)").arg(m_subscription->
title(), message));
 
  189    m_itemChangingBlock = 
false;
 
  192void AdBlockTreeWidget::adjustItemFeatures(QTreeWidgetItem* item, 
const AdBlockRule* rule)
 
  195        item->setForeground(0, QColor(Qt::gray));
 
  200            item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
 
  201            item->setCheckState(0, Qt::Unchecked);
 
  208    item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
 
  209    item->setCheckState(0, Qt::Checked);
 
  210    item->setForeground(0, palette().windowText());
 
  211    item->setFont(0, font());
 
  214        item->setForeground(0, QColor(Qt::gray));
 
  215        item->setFont(0, QFont());
 
  217        item->setForeground(0, QColor(Qt::darkGreen));
 
  218        item->setFont(0, QFont());
 
  221        item->setForeground(0, QColor(Qt::darkBlue));
 
  222        item->setFont(0, QFont());
 
  226void AdBlockTreeWidget::keyPressEvent(QKeyEvent* event)
 
  228    if (event->key() == Qt::Key_C && event->modifiers() & Qt::ControlModifier) {
 
  232    if (event->key() == Qt::Key_Delete) {
 
  236    TreeWidget::keyPressEvent(event);
 
  241    m_itemChangingBlock = 
true;
 
  245    boldFont.setBold(
true);
 
  247    m_topItem = 
new QTreeWidgetItem(
this);
 
  248    m_topItem->setText(0, m_subscription->
title());
 
  249    m_topItem->setFont(0, boldFont);
 
  250    m_topItem->setExpanded(
true);
 
  253    const QVector<AdBlockRule*> &allRules = m_subscription->
allRules();
 
  257        auto* item = 
new QTreeWidgetItem(m_topItem);
 
  258        item->setText(0, rule->
filter());
 
  259        item->setData(0, Qt::UserRole + 10, index);
 
  262            item->setFlags(item->flags() | Qt::ItemIsEditable);
 
  265        adjustItemFeatures(item, rule);
 
  270    m_itemChangingBlock = 
false;
 
bool isUnsupportedRule() const
 
virtual const AdBlockRule * replaceRule(AdBlockRule *rule, int offset)
 
virtual bool canEditRules() const
 
const AdBlockRule * rule(int offset) const
 
virtual int addRule(AdBlockRule *rule)
 
void subscriptionError(const QString &message)
 
void subscriptionUpdated()
 
const AdBlockRule * disableRule(int offset)
 
virtual bool removeRule(int offset)
 
const AdBlockRule * enableRule(int offset)
 
QVector< AdBlockRule * > allRules() const