1
mirror of https://invent.kde.org/network/falkon.git synced 2024-09-21 17:52:10 +02:00

AdBlock: Support for adding new subscriptions.

- you can add subscriptions in AdBlock dialog or with
  abp: scheme links

- however, AdBlock rules are not yet optimized for performance
  so you shouldn't add too much subscriptions
  performance optimizations will come in next commits
- support for element hiding is still yet to come too

closes #266
This commit is contained in:
nowrep 2012-06-24 23:46:32 +02:00
parent daa50e2ca5
commit e471bfd5d4
28 changed files with 1326 additions and 625 deletions

View File

@ -38,66 +38,66 @@ typedef interface IObjectCollection IObjectCollection;
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************************************
IObjectArray
/*
****************************************************************************************************
IObjectArray
<from ObjectArray.h>
****************************************************************************************************
*/
<from ObjectArray.h>
****************************************************************************************************
*/
#ifndef __IObjectArray_INTERFACE_DEFINED__
#define __IObjectArray_INTERFACE_DEFINED__
/* interface IObjectArray */
/* [unique][object][uuid][helpstring] */
/* interface IObjectArray */
/* [unique][object][uuid][helpstring] */
EXTERN_C const IID IID_IObjectArray;
EXTERN_C const IID IID_IObjectArray;
MIDL_INTERFACE("92CA9DCD-5622-4bba-A805-5E9F541BD8C9")
MIDL_INTERFACE("92CA9DCD-5622-4bba-A805-5E9F541BD8C9")
IObjectArray : public IUnknown {
public:
virtual HRESULT STDMETHODCALLTYPE GetCount(
/* [out] */ __RPC__out UINT * pcObjects) = 0;
public:
virtual HRESULT STDMETHODCALLTYPE GetCount(
/* [out] */ __RPC__out UINT * pcObjects) = 0;
virtual HRESULT STDMETHODCALLTYPE GetAt(
/* [in] */ UINT uiIndex,
/* [in] */ __RPC__in REFIID riid,
/* [iid_is][out] */ __RPC__deref_out_opt void** ppv) = 0;
virtual HRESULT STDMETHODCALLTYPE GetAt(
/* [in] */ UINT uiIndex,
/* [in] */ __RPC__in REFIID riid,
/* [iid_is][out] */ __RPC__deref_out_opt void** ppv) = 0;
};
};
#endif /* __IObjectArray_INTERFACE_DEFINED__ */
#ifndef __IObjectCollection_INTERFACE_DEFINED__
#define __IObjectCollection_INTERFACE_DEFINED__
/* interface IObjectCollection */
/* [unique][object][uuid] */
/* interface IObjectCollection */
/* [unique][object][uuid] */
EXTERN_C const IID IID_IObjectCollection;
EXTERN_C const IID IID_IObjectCollection;
MIDL_INTERFACE("5632b1a4-e38a-400a-928a-d4cd63230295")
MIDL_INTERFACE("5632b1a4-e38a-400a-928a-d4cd63230295")
IObjectCollection : public IObjectArray {
public:
virtual HRESULT STDMETHODCALLTYPE AddObject(
/* [in] */ __RPC__in_opt IUnknown * punk) = 0;
public:
virtual HRESULT STDMETHODCALLTYPE AddObject(
/* [in] */ __RPC__in_opt IUnknown * punk) = 0;
virtual HRESULT STDMETHODCALLTYPE AddFromArray(
/* [in] */ __RPC__in_opt IObjectArray * poaSource) = 0;
virtual HRESULT STDMETHODCALLTYPE AddFromArray(
/* [in] */ __RPC__in_opt IObjectArray * poaSource) = 0;
virtual HRESULT STDMETHODCALLTYPE RemoveObjectAt(
/* [in] */ UINT uiIndex) = 0;
virtual HRESULT STDMETHODCALLTYPE RemoveObjectAt(
/* [in] */ UINT uiIndex) = 0;
virtual HRESULT STDMETHODCALLTYPE Clear(void) = 0;
virtual HRESULT STDMETHODCALLTYPE Clear(void) = 0;
};
};
#endif /* __IObjectCollection_INTERFACE_DEFINED__ */
/* Additional Prototypes for ALL interfaces */
/* end of Additional Prototypes */
/* Additional Prototypes for ALL interfaces */
/* end of Additional Prototypes */
#ifdef __cplusplus
}
@ -189,13 +189,13 @@ class DECLSPEC_UUID("77f10cf0-3db5-4966-b520-b7c54fd35ed6")
*/
#define DEFINE_ENUM_FLAG_OPERATORS(ENUMTYPE) \
extern "C++" { \
inline ENUMTYPE operator | (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) | ((int)b)); } \
inline ENUMTYPE &operator |= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) |= ((int)b)); } \
inline ENUMTYPE operator & (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) & ((int)b)); } \
inline ENUMTYPE &operator &= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) &= ((int)b)); } \
inline ENUMTYPE operator ~ (ENUMTYPE a) { return ENUMTYPE(~((int)a)); } \
inline ENUMTYPE operator ^ (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) ^ ((int)b)); } \
inline ENUMTYPE &operator ^= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) ^= ((int)b)); } \
inline ENUMTYPE operator | (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) | ((int)b)); } \
inline ENUMTYPE &operator |= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) |= ((int)b)); } \
inline ENUMTYPE operator & (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) & ((int)b)); } \
inline ENUMTYPE &operator &= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) &= ((int)b)); } \
inline ENUMTYPE operator ~ (ENUMTYPE a) { return ENUMTYPE(~((int)a)); } \
inline ENUMTYPE operator ^ (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) ^ ((int)b)); } \
inline ENUMTYPE &operator ^= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) ^= ((int)b)); } \
}
#ifdef MIDL_PASS
@ -261,57 +261,57 @@ EXTERN_C const IID IID_ITaskbarList3;
MIDL_INTERFACE("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")
ITaskbarList3 : public ITaskbarList2 {
public:
virtual HRESULT STDMETHODCALLTYPE SetProgressValue(
/* [in] */ __RPC__in HWND hwnd,
/* [in] */ ULONGLONG ullCompleted,
/* [in] */ ULONGLONG ullTotal) = 0;
virtual HRESULT STDMETHODCALLTYPE SetProgressValue(
/* [in] */ __RPC__in HWND hwnd,
/* [in] */ ULONGLONG ullCompleted,
/* [in] */ ULONGLONG ullTotal) = 0;
virtual HRESULT STDMETHODCALLTYPE SetProgressState(
/* [in] */ __RPC__in HWND hwnd,
/* [in] */ TBPFLAG tbpFlags) = 0;
virtual HRESULT STDMETHODCALLTYPE SetProgressState(
/* [in] */ __RPC__in HWND hwnd,
/* [in] */ TBPFLAG tbpFlags) = 0;
virtual HRESULT STDMETHODCALLTYPE RegisterTab(
/* [in] */ __RPC__in HWND hwndTab,
/* [in] */ __RPC__in HWND hwndMDI) = 0;
virtual HRESULT STDMETHODCALLTYPE RegisterTab(
/* [in] */ __RPC__in HWND hwndTab,
/* [in] */ __RPC__in HWND hwndMDI) = 0;
virtual HRESULT STDMETHODCALLTYPE UnregisterTab(
/* [in] */ __RPC__in HWND hwndTab) = 0;
virtual HRESULT STDMETHODCALLTYPE UnregisterTab(
/* [in] */ __RPC__in HWND hwndTab) = 0;
virtual HRESULT STDMETHODCALLTYPE SetTabOrder(
/* [in] */ __RPC__in HWND hwndTab,
/* [in] */ __RPC__in HWND hwndInsertBefore) = 0;
virtual HRESULT STDMETHODCALLTYPE SetTabOrder(
/* [in] */ __RPC__in HWND hwndTab,
/* [in] */ __RPC__in HWND hwndInsertBefore) = 0;
virtual HRESULT STDMETHODCALLTYPE SetTabActive(
/* [in] */ __RPC__in HWND hwndTab,
/* [in] */ __RPC__in HWND hwndMDI,
/* [in] */ DWORD dwReserved) = 0;
virtual HRESULT STDMETHODCALLTYPE SetTabActive(
/* [in] */ __RPC__in HWND hwndTab,
/* [in] */ __RPC__in HWND hwndMDI,
/* [in] */ DWORD dwReserved) = 0;
virtual HRESULT STDMETHODCALLTYPE ThumbBarAddButtons(
/* [in] */ __RPC__in HWND hwnd,
/* [in] */ UINT cButtons,
/* [size_is][in] */ __RPC__in_ecount_full(cButtons) LPTHUMBBUTTON pButton) = 0;
virtual HRESULT STDMETHODCALLTYPE ThumbBarAddButtons(
/* [in] */ __RPC__in HWND hwnd,
/* [in] */ UINT cButtons,
/* [size_is][in] */ __RPC__in_ecount_full(cButtons) LPTHUMBBUTTON pButton) = 0;
virtual HRESULT STDMETHODCALLTYPE ThumbBarUpdateButtons(
/* [in] */ __RPC__in HWND hwnd,
/* [in] */ UINT cButtons,
/* [size_is][in] */ __RPC__in_ecount_full(cButtons) LPTHUMBBUTTON pButton) = 0;
virtual HRESULT STDMETHODCALLTYPE ThumbBarUpdateButtons(
/* [in] */ __RPC__in HWND hwnd,
/* [in] */ UINT cButtons,
/* [size_is][in] */ __RPC__in_ecount_full(cButtons) LPTHUMBBUTTON pButton) = 0;
virtual HRESULT STDMETHODCALLTYPE ThumbBarSetImageList(
/* [in] */ __RPC__in HWND hwnd,
/* [in] */ __RPC__in_opt HIMAGELIST himl) = 0;
virtual HRESULT STDMETHODCALLTYPE ThumbBarSetImageList(
/* [in] */ __RPC__in HWND hwnd,
/* [in] */ __RPC__in_opt HIMAGELIST himl) = 0;
virtual HRESULT STDMETHODCALLTYPE SetOverlayIcon(
/* [in] */ __RPC__in HWND hwnd,
/* [in] */ __RPC__in HICON hIcon,
/* [string][unique][in] */ __RPC__in_opt_string LPCWSTR pszDescription) = 0;
virtual HRESULT STDMETHODCALLTYPE SetOverlayIcon(
/* [in] */ __RPC__in HWND hwnd,
/* [in] */ __RPC__in HICON hIcon,
/* [string][unique][in] */ __RPC__in_opt_string LPCWSTR pszDescription) = 0;
virtual HRESULT STDMETHODCALLTYPE SetThumbnailTooltip(
/* [in] */ __RPC__in HWND hwnd,
/* [string][unique][in] */ __RPC__in_opt_string LPCWSTR pszTip) = 0;
virtual HRESULT STDMETHODCALLTYPE SetThumbnailTooltip(
/* [in] */ __RPC__in HWND hwnd,
/* [string][unique][in] */ __RPC__in_opt_string LPCWSTR pszTip) = 0;
virtual HRESULT STDMETHODCALLTYPE SetThumbnailClip(
/* [in] */ __RPC__in HWND hwnd,
/* [in] */ __RPC__in RECT * prcClip) = 0;
virtual HRESULT STDMETHODCALLTYPE SetThumbnailClip(
/* [in] */ __RPC__in HWND hwnd,
/* [in] */ __RPC__in RECT * prcClip) = 0;
};
#endif //_MSC_VER >= 1500 && _MSC_VER < 1600

View File

@ -0,0 +1,72 @@
/* ============================================================
* 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 "adblockaddsubscriptiondialog.h"
#include "ui_adblockaddsubscriptiondialog.h"
AdBlockAddSubscriptionDialog::AdBlockAddSubscriptionDialog(QWidget* parent)
: QDialog(parent)
, ui(new Ui::AdBlockAddSubscriptionDialog)
{
ui->setupUi(this);
m_knownSubscriptions << Subscription("Fanboy's List (English)", "http://www.fanboy.co.nz/adblock/fanboy-adblock.txt")
<< Subscription("Adversity (English)", "http://adversity.googlecode.com/hg/Adversity.txt")
<< Subscription("BSI Lista Polska (Polish)", "http://www.bsi.info.pl/filtrABP.txt")
<< Subscription("Czech List (Czech)", "http://adblock.dajbych.net/adblock.txt")
<< Subscription("dutchblock (Dutch)", "http://groenewoudt.net/dutchblock/list.txt")
<< Subscription("Filtros Nauscopicos (Spanish)", "http://abp.mozilla-hispano.org/nauscopio/filtros.txt")
<< Subscription("hufilter (Hungarian)", "http://www.hufilter.hu/hufilter.txt")
<< Subscription("IsraelList (Hebrew)", "http://secure.fanboy.co.nz/israelilist/IsraelList.txt")
<< Subscription("Lista Basa (Polish)", "http://plok.studentlive.pl/abp.txt")
<< Subscription("NLBlock (Dutch)", "http://www.verzijlbergh.com/adblock/nlblock.txt")
<< Subscription("Peter Lowe's list (English)", "http://pgl.yoyo.org/adservers/serverlist.php?hostformat=adblockplus&mimetype=plaintext")
<< Subscription("PLgeneral (Polish)", "http://www.niecko.pl/adblock/adblock.txt")
<< Subscription("Schacks Adblock Plus liste (Danish)", "http://adblock.schack.dk/block.txt")
<< Subscription("Xfiles (Italian)", "http://mozilla.gfsolone.com/filtri.txt")
<< Subscription("Antisocial (English)", "http://adversity.googlecode.com/hg/Antisocial.txt");
foreach(const Subscription & subscription, m_knownSubscriptions) {
ui->comboBox->addItem(subscription.title);
}
connect(ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(indexChanged(int)));
indexChanged(0);
}
QString AdBlockAddSubscriptionDialog::title() const
{
return ui->title->text();
}
QString AdBlockAddSubscriptionDialog::url() const
{
return ui->url->text();
}
void AdBlockAddSubscriptionDialog::indexChanged(int index)
{
const Subscription &subscription = m_knownSubscriptions.at(index);
ui->title->setText(subscription.title);
ui->url->setText(subscription.url);
}
AdBlockAddSubscriptionDialog::~AdBlockAddSubscriptionDialog()
{
delete ui;
}

View File

@ -0,0 +1,61 @@
/* ============================================================
* 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/>.
* ============================================================ */
#ifndef ADBLOCKADDSUBSCRIPTIONDIALOG_H
#define ADBLOCKADDSUBSCRIPTIONDIALOG_H
#include <QDialog>
#include <QList>
#include "qz_namespace.h"
namespace Ui
{
class AdBlockAddSubscriptionDialog;
}
class QT_QUPZILLA_EXPORT AdBlockAddSubscriptionDialog : public QDialog
{
Q_OBJECT
public:
explicit AdBlockAddSubscriptionDialog(QWidget* parent = 0);
~AdBlockAddSubscriptionDialog();
QString title() const;
QString url() const;
private slots:
void indexChanged(int index);
private:
Ui::AdBlockAddSubscriptionDialog* ui;
struct Subscription {
QString title;
QString url;
Subscription(const QString &t, const QString &u) {
title = t;
url = u;
}
};
QList<Subscription> m_knownSubscriptions;
};
#endif // ADBLOCKADDSUBSCRIPTIONDIALOG_H

View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AdBlockAddSubscriptionDialog</class>
<widget class="QDialog" name="AdBlockAddSubscriptionDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>557</width>
<height>162</height>
</rect>
</property>
<property name="windowTitle">
<string>Add Subscription</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="1" column="0" colspan="2">
<widget class="QComboBox" name="comboBox"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Title:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="title"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Address:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="url"/>
</item>
<item row="4" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Add new subscription to AdBlock:</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>AdBlockAddSubscriptionDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AdBlockAddSubscriptionDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -15,36 +15,11 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
/**
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Benjamin Meyer nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "adblockdialog.h"
#include "adblockmanager.h"
#include "adblocksubscription.h"
#include "adblocktreewidget.h"
#include "adblockaddsubscriptiondialog.h"
#include "mainapplication.h"
#include <QMenu>
@ -53,181 +28,103 @@
AdBlockDialog::AdBlockDialog(QWidget* parent)
: QDialog(parent)
, m_itemChangingBlock(false)
, m_manager(AdBlockManager::instance())
, m_currentTreeWidget(0)
, m_currentSubscription(0)
{
setAttribute(Qt::WA_DeleteOnClose);
setupUi(this);
adblockCheckBox->setChecked(m_manager->isEnabled());
treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
treeWidget->setDefaultItemShowMode(TreeWidget::ItemsExpanded);
QMenu* menu = new QMenu(buttonMenu);
m_actionAddRule = menu->addAction(tr("Add Rule"), this, SLOT(addRule()));
m_actionRemoveRule = menu->addAction(tr("Remove Rule"), this, SLOT(removeRule()));
menu->addSeparator();
m_actionAddSubscription = menu->addAction(tr("Add Subscription"), this, SLOT(addSubscription()));
m_actionRemoveSubscription = menu->addAction(tr("Remove Subscription"), this, SLOT(removeSubscription()));
menu->addAction(tr("Update Subscriptions"), m_manager, SLOT(updateAllSubscriptions()));
menu->addSeparator();
menu->addAction(tr("Learn about writing rules..."), this, SLOT(learnAboutRules()));
buttonMenu->setMenu(menu);
connect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowMenu()));
connect(adblockCheckBox, SIGNAL(toggled(bool)), m_manager, SLOT(setEnabled(bool)));
connect(addButton, SIGNAL(clicked()), this, SLOT(addCustomRule()));
connect(reloadButton, SIGNAL(clicked()), this, SLOT(updateSubscription()));
connect(search, SIGNAL(textChanged(QString)), treeWidget, SLOT(filterString(QString)));
connect(m_manager->subscription(), SIGNAL(rulesUpdated()), this, SLOT(refreshAfterUpdate()));
connect(treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint)));
connect(search, SIGNAL(textChanged(QString)), this, SLOT(filterString(QString)));
connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int)));
// QTimer::singleShot(0, this, SLOT(firstRefresh()));
firstRefresh();
foreach(AdBlockSubscription * subscription, m_manager->subscriptions()) {
AdBlockTreeWidget* tree = new AdBlockTreeWidget(subscription, tabWidget);
tabWidget->addTab(tree, subscription->title());
}
buttonBox->setFocus();
}
void AdBlockDialog::editRule()
void AdBlockDialog::addRule()
{
QTreeWidgetItem* item = treeWidget->currentItem();
if (!item || !(item->flags() & Qt::ItemIsEditable)) {
m_currentTreeWidget->addRule();
}
void AdBlockDialog::removeRule()
{
m_currentTreeWidget->removeRule();
}
void AdBlockDialog::addSubscription()
{
AdBlockAddSubscriptionDialog dialog(this);
if (dialog.exec() != QDialog::Accepted) {
return;
}
item->setSelected(true);
}
QString title = dialog.title();
QString url = dialog.url();
void AdBlockDialog::deleteRule()
{
QTreeWidgetItem* item = treeWidget->currentItem();
if (!item) {
return;
if (AdBlockSubscription* subscription = m_manager->addSubscription(title, url)) {
AdBlockTreeWidget* tree = new AdBlockTreeWidget(subscription, tabWidget);
int index = tabWidget->insertTab(tabWidget->count() - 1, tree, subscription->title());
tabWidget->setCurrentIndex(index);
}
int offset = item->data(0, Qt::UserRole + 10).toInt();
m_manager->subscription()->removeRule(offset);
treeWidget->deleteItem(item);
refresh();
}
void AdBlockDialog::contextMenuRequested(const QPoint &pos)
void AdBlockDialog::removeSubscription()
{
QMenu menu;
menu.addAction(tr("Add Rule"), this, SLOT(addCustomRule()));
menu.addSeparator();
menu.addAction(tr("Delete Rule"), this, SLOT(deleteRule()));
menu.exec(treeWidget->viewport()->mapToGlobal(pos));
if (m_manager->removeSubscription(m_currentSubscription)) {
delete m_currentTreeWidget;
}
}
void AdBlockDialog::firstRefresh()
void AdBlockDialog::currentChanged(int index)
{
refresh();
connect(treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(itemChanged(QTreeWidgetItem*)));
}
if (index != -1) {
m_currentTreeWidget = qobject_cast<AdBlockTreeWidget*>(tabWidget->widget(index));
m_currentSubscription = m_currentTreeWidget->subscription();
void AdBlockDialog::refreshAfterUpdate()
{
QMessageBox::information(this, tr("Update completed"), tr("EasyList has been successfully updated."));
refresh();
}
void AdBlockDialog::refresh()
{
m_itemChangingBlock = true;
treeWidget->setUpdatesEnabled(false);
treeWidget->clear();
QFont boldFont;
boldFont.setBold(true);
QFont italicFont;
italicFont.setItalic(true);
m_customRulesItem = new QTreeWidgetItem(treeWidget);
m_customRulesItem->setText(0, tr("Custom Rules"));
m_customRulesItem->setFont(0, boldFont);
treeWidget->addTopLevelItem(m_customRulesItem);
m_easyListItem = new QTreeWidgetItem(treeWidget);
m_easyListItem->setText(0, "EasyList");
m_easyListItem->setFont(0, boldFont);
treeWidget->addTopLevelItem(m_easyListItem);
bool customRulesStarted = false;
QList<AdBlockRule> allRules = m_manager->subscription()->allRules();
int index = 0;
foreach(const AdBlockRule & rule, allRules) {
index++;
if (rule.filter().contains("*******- user custom filters")) {
customRulesStarted = true;
continue;
}
QTreeWidgetItem* item = new QTreeWidgetItem(customRulesStarted ? m_customRulesItem : m_easyListItem);
if (item->parent() == m_customRulesItem) {
item->setFlags(item->flags() | Qt::ItemIsEditable);
}
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(0, (rule.filter().startsWith("!")) ? Qt::Unchecked : Qt::Checked);
item->setText(0, rule.filter());
item->setData(0, Qt::UserRole + 10, index - 1);
if (rule.filter().startsWith("!")) {
item->setFont(0, italicFont);
if (!search->text().isEmpty()) {
filterString(search->text());
}
}
treeWidget->expandAll();
treeWidget->setUpdatesEnabled(true);
m_itemChangingBlock = false;
}
void AdBlockDialog::itemChanged(QTreeWidgetItem* item)
void AdBlockDialog::filterString(const QString &string)
{
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();
QFont italicFont;
italicFont.setItalic(true);
item->setFont(0, italicFont);
item->setText(0, item->text(0).prepend("!"));
AdBlockRule rul(item->text(0));
m_manager->subscription()->replaceRule(rul, offset);
}
else if (item->checkState(0) == Qt::Checked && item->text(0).startsWith("!")) { //Enable rule
int offset = item->data(0, Qt::UserRole + 10).toInt();
item->setFont(0, QFont());
QString newText = item->text(0).mid(1);
item->setText(0, newText);
AdBlockRule rul(newText);
m_manager->subscription()->replaceRule(rul, offset);
}
else { //Custom rule has been changed
int offset = item->data(0, Qt::UserRole + 10).toInt();
AdBlockRule rul(item->text(0));
m_manager->subscription()->replaceRule(rul, offset);
}
m_itemChangingBlock = false;
m_currentTreeWidget->filterString(string);
}
void AdBlockDialog::addCustomRule()
void AdBlockDialog::aboutToShowMenu()
{
QString newRule = QInputDialog::getText(this, tr("Add Custom Rule"), tr("Please write your rule here:"));
if (newRule.isEmpty()) {
return;
}
bool subscriptionEditable = m_currentSubscription->canEditRules();
bool subscriptionRemovable = m_currentSubscription->canBeRemoved();
AdBlockSubscription* subscription = m_manager->subscription();
int offset = subscription->addRule(AdBlockRule(newRule));
m_itemChangingBlock = true;
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);
treeWidget->appendToParentItem(m_customRulesItem, item);
m_itemChangingBlock = false;
m_actionAddRule->setEnabled(subscriptionEditable);
m_actionRemoveRule->setEnabled(subscriptionEditable);
m_actionRemoveSubscription->setEnabled(subscriptionRemovable);
}
void AdBlockDialog::updateSubscription()
void AdBlockDialog::learnAboutRules()
{
AdBlockSubscription* subscription = m_manager->subscription();
subscription->updateNow();
mApp->addNewTab(QUrl("http://adblockplus.org/en/filters"));
}

View File

@ -15,34 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
/**
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Benjamin Meyer nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef ADBLOCKDIALOG_H
#define ADBLOCKDIALOG_H
@ -51,9 +23,9 @@
#include "qz_namespace.h"
#include "ui_adblockdialog.h"
class AdBlockModel;
class AdBlockSubscription;
class AdBlockTreeWidget;
class AdBlockManager;
class TreeSortFilterProxyModel;
class QT_QUPZILLA_EXPORT AdBlockDialog : public QDialog, public Ui_AdBlockDialog
{
@ -63,24 +35,27 @@ public:
AdBlockDialog(QWidget* parent = 0);
private slots:
void itemChanged(QTreeWidgetItem* item);
void updateSubscription();
void addCustomRule();
void firstRefresh();
void refreshAfterUpdate();
void contextMenuRequested(const QPoint &pos);
void addRule();
void removeRule();
void editRule();
void deleteRule();
void addSubscription();
void removeSubscription();
void currentChanged(int index);
void filterString(const QString &string);
void aboutToShowMenu();
void learnAboutRules();
private:
void refresh();
bool m_itemChangingBlock;
QTreeWidgetItem* m_customRulesItem;
QTreeWidgetItem* m_easyListItem;
AdBlockManager* m_manager;
AdBlockTreeWidget* m_currentTreeWidget;
AdBlockSubscription* m_currentSubscription;
QAction* m_actionAddRule;
QAction* m_actionRemoveRule;
QAction* m_actionAddSubscription;
QAction* m_actionRemoveSubscription;
};
#endif // ADBLOCKDIALOG_H

View File

@ -13,8 +13,8 @@
<property name="windowTitle">
<string>AdBlock Configuration</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="adblockCheckBox">
<property name="text">
<string>Enable AdBlock</string>
@ -24,7 +24,34 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLineEdit" name="search">
<property name="placeholderText">
<string>Search...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>50</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="adblockWidget" native="true">
<property name="enabled">
<bool>true</bool>
@ -33,54 +60,22 @@
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLineEdit" name="search">
<property name="placeholderText">
<string>Search...</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="5">
<widget class="TreeWidget" name="treeWidget">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>Rule</string>
</property>
</column>
</widget>
</item>
<item row="0" column="1" colspan="3">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" colspan="4">
<item row="4" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="addButton">
<widget class="QToolButton" name="buttonMenu">
<property name="text">
<string>Add Rule</string>
<string>Options</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="reloadButton">
<property name="text">
<string>Update EasyList</string>
<property name="icon">
<iconset resource="../data/icons.qrc">
<normaloff>:/icons/other/adblock.png</normaloff>:/icons/other/adblock.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
@ -97,25 +92,35 @@
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>AdBlock</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>-1</number>
</property>
<property name="documentMode">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>AdBlock</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -127,14 +132,9 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>TreeWidget</class>
<extends>QTreeWidget</extends>
<header>treewidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<resources>
<include location="../data/icons.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>

View File

@ -115,8 +115,6 @@ void AdBlockIcon::createMenu(QMenu* menu)
menu->addAction(tr("%1 with (%2)").arg(address, entry.rule).replace("&", "&&"), manager, SLOT(showRule()))->setData(entry.rule);
}
}
menu->addSeparator();
menu->addAction(tr("Learn About Writing &Rules"), this, SLOT(learnAboutRules()));
}
void AdBlockIcon::showMenu(const QPoint &pos)
@ -127,11 +125,6 @@ void AdBlockIcon::showMenu(const QPoint &pos)
menu.exec(pos);
}
void AdBlockIcon::learnAboutRules()
{
p_QupZilla->tabWidget()->addView(QUrl("http://adblockplus.org/en/filters"), Qz::NT_SelectedTab);
}
void AdBlockIcon::animateIcon()
{
++m_timerTicks;

View File

@ -45,7 +45,6 @@ public slots:
private slots:
void showMenu(const QPoint &pos);
void learnAboutRules();
void animateIcon();
void stopAnimation();

View File

@ -15,33 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
/**
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Benjamin Meyer nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "adblockmanager.h"
#include "adblockdialog.h"
#include "adblockpage.h"
@ -49,11 +22,16 @@
#include "adblockblockednetworkreply.h"
#include "mainapplication.h"
#include "webpage.h"
#include "globalfunctions.h"
#include "networkmanager.h"
#include "qupzilla.h"
#include "settings.h"
#include <QDateTime>
#include <QTextStream>
#include <QDir>
#include <QTimer>
#include <QDebug>
AdBlockManager* AdBlockManager::s_adBlockManager = 0;
@ -61,8 +39,6 @@ AdBlockManager::AdBlockManager(QObject* parent)
: QObject(parent)
, m_loaded(false)
, m_enabled(true)
, m_adBlockNetwork(0)
, m_adBlockPage(0)
{
}
@ -80,22 +56,14 @@ void AdBlockManager::setEnabled(bool enabled)
if (isEnabled() == enabled) {
return;
}
m_enabled = enabled;
emit rulesChanged();
mApp->sendMessages(Qz::AM_SetAdBlockIconEnabled, enabled);
}
AdBlockPage* AdBlockManager::page()
QList<AdBlockSubscription*> AdBlockManager::subscriptions() const
{
if (!m_adBlockPage) {
m_adBlockPage = new AdBlockPage(this);
}
return m_adBlockPage;
}
AdBlockSubscription* AdBlockManager::subscription()
{
return m_subscriptions.at(0);
return m_subscriptions;
}
QNetworkReply* AdBlockManager::block(const QNetworkRequest &request)
@ -135,6 +103,49 @@ QNetworkReply* AdBlockManager::block(const QNetworkRequest &request)
return 0;
}
AdBlockSubscription* AdBlockManager::addSubscription(const QString &title, const QString &url)
{
if (title.isEmpty() || url.isEmpty()) {
return 0;
}
QString fileName = qz_filterCharsFromFilename(title.toLower()) + ".txt";
QString filePath = qz_ensureUniqueFilename(mApp->currentProfilePath() + "adblock/" + fileName);
QByteArray data = QString("Title: %1\nUrl: %2\n[Adblock Plus 1.1.1]").arg(title, url).toAscii();
QFile file(filePath);
if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
qWarning() << "AdBlockManager: Cannot write to file" << filePath;
return 0;
}
file.write(data);
file.close();
AdBlockSubscription* subscription = new AdBlockSubscription(title, this);
subscription->setUrl(QUrl(url));
subscription->setFilePath(filePath);
subscription->loadSubscription();
m_subscriptions.insert(m_subscriptions.count() - 1, subscription);
return subscription;
}
bool AdBlockManager::removeSubscription(AdBlockSubscription* subscription)
{
if (!m_subscriptions.contains(subscription) || !subscription->canBeRemoved()) {
return false;
}
QFile(subscription->filePath()).remove();
m_subscriptions.removeOne(subscription);
delete subscription;
return true;
}
void AdBlockManager::load()
{
if (m_loaded) {
@ -148,26 +159,66 @@ void AdBlockManager::load()
QDateTime lastUpdate = settings.value("lastUpdate", QDateTime()).toDateTime();
settings.endGroup();
AdBlockSubscription* easyList = new AdBlockSubscription();
easyList->setTitle("EasyList");
connect(easyList, SIGNAL(rulesChanged()), this, SIGNAL(rulesChanged()));
connect(easyList, SIGNAL(rulesUpdated()), this, SLOT(rulesUpdated()));
QDir adblockDir(mApp->currentProfilePath() + "adblock");
// Create if neccessary
if (!adblockDir.exists()) {
QDir(mApp->currentProfilePath()).mkdir("adblock");
}
m_subscriptions.append(easyList);
foreach(const QString & fileName, adblockDir.entryList(QStringList("*.txt"), QDir::Files)) {
if (fileName == "easylist.txt" || fileName == "customlist.txt") {
continue;
}
if (lastUpdate.addDays(3) < QDateTime::currentDateTime()) {
easyList->scheduleUpdate();
const QString absolutePath = adblockDir.absoluteFilePath(fileName);
QFile file(absolutePath);
if (!file.open(QFile::ReadOnly)) {
continue;
}
QTextStream textStream(&file);
QString title = textStream.readLine(1024).remove("Title: ");
QUrl url = QUrl(textStream.readLine(1024).remove("Url: "));
if (title.isEmpty() || !url.isValid()) {
qWarning() << "AdBlockManager: Invalid subscription file" << absolutePath;
continue;
}
AdBlockSubscription* subscription = new AdBlockSubscription(title, this);
subscription->setUrl(url);
subscription->setFilePath(absolutePath);
m_subscriptions.append(subscription);
}
// Prepend EasyList
AdBlockSubscription* easyList = new AdBlockEasyList(this);
m_subscriptions.prepend(easyList);
// Append CustomList
AdBlockSubscription* customList = new AdBlockCustomList(this);
m_subscriptions.append(customList);
// Load all subscriptions
foreach(AdBlockSubscription * subscription, m_subscriptions) {
subscription->loadSubscription();
}
if (lastUpdate.addDays(5) < QDateTime::currentDateTime()) {
QTimer::singleShot(1000 * 60, this, SLOT(updateAllSubscriptions()));
}
}
void AdBlockManager::rulesUpdated()
void AdBlockManager::updateAllSubscriptions()
{
foreach(AdBlockSubscription * subscription, m_subscriptions) {
subscription->updateSubscription();
}
Settings settings;
settings.beginGroup("AdBlock");
settings.setValue("lastUpdate", QDateTime::currentDateTime());
settings.endGroup();
emit rulesChanged();
}
void AdBlockManager::save()
@ -176,11 +227,13 @@ void AdBlockManager::save()
return;
}
subscription()->saveRules();
foreach(AdBlockSubscription * subscription, m_subscriptions) {
subscription->saveSubscription();
}
Settings settings;
settings.beginGroup(QLatin1String("AdBlock"));
settings.setValue(QLatin1String("enabled"), m_enabled);
settings.beginGroup("AdBlock");
settings.setValue("enabled", m_enabled);
settings.endGroup();
}
@ -200,7 +253,3 @@ void AdBlockManager::showRule()
showDialog()->search->setText(action->data().toString());
}
}
AdBlockManager::~AdBlockManager()
{
}

View File

@ -15,33 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
/**
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Benjamin Meyer nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef ADBLOCKMANAGER_H
#define ADBLOCKMANAGER_H
@ -55,8 +28,6 @@ class QNetworkReply;
class QNetworkRequest;
class AdBlockDialog;
class AdBlockNetwork;
class AdBlockPage;
class AdBlockSubscription;
class QT_QUPZILLA_EXPORT AdBlockManager : public QObject
@ -65,39 +36,34 @@ class QT_QUPZILLA_EXPORT AdBlockManager : public QObject
public:
AdBlockManager(QObject* parent = 0);
~AdBlockManager();
static AdBlockManager* instance();
void load();
void save();
static AdBlockManager* instance();
bool isEnabled() { if (!m_loaded) load(); return m_enabled; }
AdBlockPage* page();
// FIXME: Remove when completely changed to multi-subscription model
AdBlockSubscription* subscription();
QList<AdBlockSubscription*> subscriptions() const;
QNetworkReply* block(const QNetworkRequest &request);
AdBlockSubscription* addSubscription(const QString &title, const QString &url);
bool removeSubscription(AdBlockSubscription* subscription);
public slots:
void setEnabled(bool enabled);
void showRule();
void updateAllSubscriptions();
AdBlockDialog* showDialog();
private slots:
void rulesUpdated();
signals:
void rulesChanged();
private:
static AdBlockManager* s_adBlockManager;
bool m_loaded;
bool m_enabled;
QWeakPointer<AdBlockDialog> m_adBlockDialog;
AdBlockNetwork* m_adBlockNetwork;
AdBlockPage* m_adBlockPage;
QList<AdBlockSubscription*> m_subscriptions;
};

View File

@ -0,0 +1,67 @@
/* ============================================================
* 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 "adblockschemehandler.h"
#include "adblockmanager.h"
#include "emptynetworkreply.h"
#include <QNetworkRequest>
#include <QMessageBox>
AdBlockSchemeHandler::AdBlockSchemeHandler()
: SchemeHandler()
{
}
QNetworkReply* AdBlockSchemeHandler::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice* outgoingData)
{
Q_UNUSED(outgoingData)
if (op != QNetworkAccessManager::GetOperation) {
return 0;
}
const QUrl &url = request.url();
const QList<QPair<QString, QString> > queryItems = url.queryItems();
QString subscriptionTitle;
QString subscriptionUrl;
for (int i = 0; i < queryItems.count(); ++i) {
QPair<QString, QString> pair = queryItems.at(i);
if (pair.first == "location") {
subscriptionUrl = pair.second;
}
else if (pair.first == "title") {
subscriptionTitle = pair.second;
}
}
if (subscriptionTitle.isEmpty() || subscriptionUrl.isEmpty()) {
return 0;
}
QString message = AdBlockManager::tr("Do you want to add <b>%1</b> subscription?").arg(subscriptionTitle);
QMessageBox::StandardButton result = QMessageBox::question(0, AdBlockManager::tr("AdBlock Subscription"), message, QMessageBox::Yes | QMessageBox::No);
if (result == QMessageBox::Yes) {
AdBlockManager::instance()->addSubscription(subscriptionTitle, subscriptionUrl);
AdBlockManager::instance()->showDialog();
}
return new EmptyNetworkReply;
}

View File

@ -15,8 +15,18 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef ADBLOCKSCHEMEHANDLER_H
#define ADBLOCKSCHEMEHANDLER_H
#include "qz_namespace.h"
#include "schemehandler.h"
SchemeHandler::SchemeHandler()
class QT_QUPZILLA_EXPORT AdBlockSchemeHandler : public SchemeHandler
{
}
public:
AdBlockSchemeHandler();
QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice* outgoingData);
};
#endif // ADBLOCKSCHEMEHANDLER_H

View File

@ -45,6 +45,7 @@
#include "adblocksubscription.h"
#include "mainapplication.h"
#include "networkmanager.h"
#include "globalfunctions.h"
#include <QFile>
#include <QTimer>
@ -52,124 +53,93 @@
#include <QDebug>
// #define ADBLOCKSUBSCRIPTION_DEBUG
AdBlockSubscription::AdBlockSubscription(QObject* parent)
AdBlockSubscription::AdBlockSubscription(const QString &title, QObject* parent)
: QObject(parent)
, m_downloading(0)
, m_reply(0)
, m_title(title)
{
loadRules();
}
void AdBlockSubscription::loadRules()
QString AdBlockSubscription::title() const
{
QString fileName = mApp->currentProfilePath() + "adblocklist.txt";
QFile file(fileName);
if (file.exists()) {
if (!file.open(QFile::ReadOnly)) {
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for reading" << fileName;
}
else {
QTextStream textStream(&file);
QString header = textStream.readLine(1024);
if (!header.startsWith("[Adblock")) {
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "adblock file does not start with [Adblock" << fileName << "Header:" << header;
file.close();
file.remove();
}
else {
m_rules.clear();
while (!textStream.atEnd()) {
QString line = textStream.readLine();
m_rules.append(AdBlockRule(line));
}
populateCache();
emit rulesChanged();
}
}
}
if (m_rules.isEmpty()) {
// Initial update
QTimer::singleShot(0, this, SLOT(updateNow()));
}
return m_title;
}
void AdBlockSubscription::scheduleUpdate()
QString AdBlockSubscription::filePath() const
{
QTimer::singleShot(1000 * 30, this, SLOT(updateNow()));
return m_filePath;
}
void AdBlockSubscription::updateNow()
void AdBlockSubscription::setFilePath(const QString &path)
{
if (m_downloading) {
m_filePath = path;
}
QUrl AdBlockSubscription::url() const
{
return m_url;
}
void AdBlockSubscription::setUrl(const QUrl &url)
{
m_url = url;
}
void AdBlockSubscription::loadSubscription()
{
QFile file(m_filePath);
if (!file.exists()) {
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "File does not exists" << m_filePath;
QTimer::singleShot(0, this, SLOT(updateSubscription()));
return;
}
QNetworkRequest request(QUrl("https://easylist-downloads.adblockplus.org/easylist.txt"));
QNetworkReply* reply = mApp->networkManager()->get(request);
m_downloading = reply;
connect(reply, SIGNAL(finished()), this, SLOT(rulesDownloaded()));
}
void AdBlockSubscription::rulesDownloaded()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
if (!reply) {
return;
}
QByteArray response = reply->readAll();
reply->close();
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError || response.isEmpty()) {
return;
}
QString fileName = mApp->currentProfilePath() + "adblocklist.txt";
QFile file(fileName);
if (!file.open(QFile::ReadWrite | QFile::Truncate)) {
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for writing:" << fileName;
return;
}
response = response.left(response.indexOf("General element hiding rules"));
bool customRules = false;
foreach(const AdBlockRule & rule, allRules()) {
if (rule.filter().contains("*******- user custom filters")) {
customRules = true;
response.append("\n! *******- user custom filters -*************\n");
continue;
}
if (!customRules) {
continue;
}
response.append(rule.filter() + "\n");
}
if (!customRules) {
response.append("\n! *******- user custom filters -*************\n");
}
file.write(response);
file.close();
loadRules();
emit rulesUpdated();
m_downloading = 0;
}
void AdBlockSubscription::saveRules()
{
QString fileName = mApp->currentProfilePath() + "adblocklist.txt";
QFile file(fileName);
if (!file.open(QFile::ReadWrite | QFile::Truncate)) {
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for writing:" << fileName;
if (!file.open(QFile::ReadOnly)) {
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for reading" << m_filePath;
QTimer::singleShot(0, this, SLOT(updateSubscription()));
return;
}
QTextStream textStream(&file);
// Header is on 3rd line
textStream.readLine(1024);
textStream.readLine(1024);
QString header = textStream.readLine(1024);
if (!header.startsWith("[Adblock") || m_title.isEmpty()) {
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "invalid format of adblock file" << m_filePath;
QTimer::singleShot(0, this, SLOT(updateSubscription()));
return;
}
m_rules.clear();
while (!textStream.atEnd()) {
const QString &line = textStream.readLine();
m_rules.append(AdBlockRule(line));
}
populateCache();
// Initial update
if (m_rules.isEmpty()) {
QTimer::singleShot(0, this, SLOT(updateSubscription()));
}
}
void AdBlockSubscription::saveSubscription()
{
QFile file(m_filePath);
if (!file.open(QFile::ReadWrite | QFile::Truncate)) {
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for writing:" << m_filePath;
return;
}
QTextStream textStream(&file);
textStream << "Title: " << m_title << endl;
textStream << "Url: " << m_url.toString() << endl;
textStream << "[Adblock Plus 1.1.1]" << endl;
foreach(const AdBlockRule & rule, m_rules) {
@ -177,6 +147,54 @@ void AdBlockSubscription::saveRules()
}
}
void AdBlockSubscription::updateSubscription()
{
if (m_reply || !m_url.isValid()) {
return;
}
QNetworkRequest request(m_url);
m_reply = mApp->networkManager()->get(request);
connect(m_reply, SIGNAL(finished()), this, SLOT(subscriptionDownloaded()));
}
void AdBlockSubscription::subscriptionDownloaded()
{
if (m_reply != qobject_cast<QNetworkReply*>(sender())) {
return;
}
QByteArray response = m_reply->readAll();
if (m_reply->error() == QNetworkReply::NoError && !response.isEmpty()) {
// Prepend subscription info
response.prepend(QString("Title: %1\nUrl: %2\n").arg(title(), url().toString()).toUtf8());
saveDownloadedData(response);
loadSubscription();
emit subscriptionUpdated();
}
m_reply->close();
m_reply->deleteLater();
m_reply = 0;
}
void AdBlockSubscription::saveDownloadedData(QByteArray &data)
{
QFile file(m_filePath);
if (!file.open(QFile::ReadWrite | QFile::Truncate)) {
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for writing:" << m_filePath;
return;
}
file.write(data);
file.close();
}
const AdBlockRule* AdBlockSubscription::allow(const QString &urlString) const
{
foreach(const AdBlockRule * rule, m_networkExceptionRules) {
@ -202,39 +220,66 @@ QList<AdBlockRule> AdBlockSubscription::allRules() const
return m_rules;
}
void AdBlockSubscription::enableRule(int offset)
{
if (!qz_listContainsIndex(m_rules, offset)) {
return;
}
const AdBlockRule &rule = m_rules.at(offset);
if (rule.filter().startsWith("!")) {
m_rules[offset].setFilter(rule.filter().mid(1));
}
}
void AdBlockSubscription::disableRule(int offset)
{
if (!qz_listContainsIndex(m_rules, offset)) {
return;
}
const AdBlockRule &rule = m_rules.at(offset);
if (!rule.filter().startsWith("!")) {
m_rules[offset].setFilter("!" + rule.filter());
}
}
bool AdBlockSubscription::canEditRules() const
{
return false;
}
bool AdBlockSubscription::canBeRemoved() const
{
return true;
}
int AdBlockSubscription::addRule(const AdBlockRule &rule)
{
m_rules.append(rule);
populateCache();
emit rulesChanged();
return m_rules.count() - 1;
Q_UNUSED(rule)
return -1;
}
void AdBlockSubscription::removeRule(int offset)
bool AdBlockSubscription::removeRule(int offset)
{
if (offset < 0 || offset >= m_rules.count()) {
return;
}
m_rules.removeAt(offset);
populateCache();
emit rulesChanged();
Q_UNUSED(offset)
return false;
}
void AdBlockSubscription::replaceRule(const AdBlockRule &rule, int offset)
bool AdBlockSubscription::replaceRule(const AdBlockRule &rule, int offset)
{
if (offset < 0 || offset >= m_rules.count()) {
return;
}
m_rules[offset] = rule;
populateCache();
emit rulesChanged();
Q_UNUSED(rule)
Q_UNUSED(offset)
return false;
}
void AdBlockSubscription::populateCache()
{
m_networkExceptionRules.clear();
m_networkBlockRules.clear();
m_pageRules.clear();
m_elementHidingRules.clear();
for (int i = 0; i < m_rules.count(); ++i) {
const AdBlockRule* rule = &m_rules.at(i);
@ -243,7 +288,7 @@ void AdBlockSubscription::populateCache()
}
if (rule->isCSSRule()) {
m_pageRules.append(rule);
m_elementHidingRules.append(rule->filter() + ",");
continue;
}
@ -256,3 +301,82 @@ void AdBlockSubscription::populateCache()
}
}
// AdBlockEasyList
AdBlockEasyList::AdBlockEasyList(QObject* parent)
: AdBlockSubscription(tr("EasyList"), parent)
{
setUrl(QUrl("https://easylist-downloads.adblockplus.org/easylist.txt"));
setFilePath(mApp->currentProfilePath() + "adblock/easylist.txt");
}
bool AdBlockEasyList::canBeRemoved() const
{
return false;
}
void AdBlockEasyList::saveDownloadedData(QByteArray &data)
{
QFile file(filePath());
if (!file.open(QFile::ReadWrite | QFile::Truncate)) {
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for writing:" << filePath();
return;
}
// We do not support more than standard blocking, so remove element hiding rules, etc...
data = data.left(data.indexOf("General element hiding rules"));
file.write(data);
file.close();
}
// AdBlockCustomList
AdBlockCustomList::AdBlockCustomList(QObject* parent)
: AdBlockSubscription(tr("Custom Rules"), parent)
{
setFilePath(mApp->currentProfilePath() + "adblock/customlist.txt");
}
bool AdBlockCustomList::canEditRules() const
{
return true;
}
bool AdBlockCustomList::canBeRemoved() const
{
return false;
}
int AdBlockCustomList::addRule(const AdBlockRule &rule)
{
m_rules.append(rule);
populateCache();
return m_rules.count() - 1;
}
bool AdBlockCustomList::removeRule(int offset)
{
if (!qz_listContainsIndex(m_rules, offset)) {
return false;
}
m_rules.removeAt(offset);
populateCache();
return true;
}
bool AdBlockCustomList::replaceRule(const AdBlockRule &rule, int offset)
{
if (!qz_listContainsIndex(m_rules, offset)) {
return false;
}
m_rules[offset] = rule;
populateCache();
return true;
}

View File

@ -47,6 +47,7 @@
#define ADBLOCKSUBSCRIPTION_H
#include <QList>
#include <QUrl>
#include "qz_namespace.h"
#include "adblockrule.h"
@ -57,48 +58,89 @@ class QUrl;
class QT_QUPZILLA_EXPORT AdBlockSubscription : public QObject
{
Q_OBJECT
public:
AdBlockSubscription(QObject* parent = 0);
explicit AdBlockSubscription(const QString &title, QObject* parent = 0);
QString title() const { return m_title; }
void setTitle(const QString &title) { m_title = title; }
QString title() const;
void scheduleUpdate();
void saveRules();
QString filePath() const;
void setFilePath(const QString &path);
QUrl url() const;
void setUrl(const QUrl &url);
virtual void loadSubscription();
virtual void saveSubscription();
const AdBlockRule* allow(const QString &urlString) const;
const AdBlockRule* block(const QString &urlString) const;
QList<const AdBlockRule*> pageRules() const { return m_pageRules; }
QString elementHidingRules();
QList<AdBlockRule> allRules() const;
int addRule(const AdBlockRule &rule);
void removeRule(int offset);
void replaceRule(const AdBlockRule &rule, int offset);
signals:
void rulesUpdated();
void rulesChanged();
void enableRule(int offset);
void disableRule(int offset);
virtual bool canEditRules() const;
virtual bool canBeRemoved() const;
virtual int addRule(const AdBlockRule &rule);
virtual bool removeRule(int offset);
virtual bool replaceRule(const AdBlockRule &rule, int offset);
public slots:
void updateNow();
void updateSubscription();
private slots:
void loadRules();
void rulesDownloaded();
signals:
void subscriptionUpdated();
protected slots:
void subscriptionDownloaded();
protected:
virtual void saveDownloadedData(QByteArray &data);
private:
void populateCache();
QString m_title;
QNetworkReply* m_reply;
QNetworkReply* m_downloading;
QList<AdBlockRule> m_rules;
QString m_elementHidingRules;
// sorted list
QList<const AdBlockRule*> m_networkExceptionRules;
QList<const AdBlockRule*> m_networkBlockRules;
QList<const AdBlockRule*> m_pageRules;
private:
QString m_title;
QString m_filePath;
QUrl m_url;
};
class AdBlockEasyList : public AdBlockSubscription
{
Q_OBJECT
public:
explicit AdBlockEasyList(QObject* parent = 0);
bool canBeRemoved() const;
protected:
void saveDownloadedData(QByteArray &data);
};
class AdBlockCustomList : public AdBlockSubscription
{
Q_OBJECT
public:
explicit AdBlockCustomList(QObject* parent = 0);
bool canEditRules() const;
bool canBeRemoved() const;
int addRule(const AdBlockRule &rule);
bool removeRule(int offset);
bool replaceRule(const AdBlockRule &rule, int offset);
};
#endif // ADBLOCKSUBSCRIPTION_H

View File

@ -0,0 +1,194 @@
/* ============================================================
* 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();
QFont italicFont;
italicFont.setItalic(true);
item->setFont(0, italicFont);
item->setText(0, item->text(0).prepend("!"));
m_subscription->disableRule(offset);
}
else if (item->checkState(0) == Qt::Checked && item->text(0).startsWith("!")) {
// Enable rule
int offset = item->data(0, Qt::UserRole + 10).toInt();
item->setFont(0, QFont());
QString newText = item->text(0).mid(1);
item->setText(0, newText);
m_subscription->enableRule(offset);
}
else if (m_subscription->canEditRules()) {
// Custom rule has been changed
int offset = item->data(0, Qt::UserRole + 10).toInt();
AdBlockRule rul(item->text(0));
m_subscription->replaceRule(rul, offset);
}
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::refresh()
{
m_itemChangingBlock = true;
clear();
QFont boldFont;
boldFont.setBold(true);
QFont italicFont;
italicFont.setItalic(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);
}
if (!rule.isEnabled()) {
item->setFont(0, italicFont);
}
++index;
}
expandAll();
m_itemChangingBlock = false;
}

View File

@ -0,0 +1,57 @@
/* ============================================================
* 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/>.
* ============================================================ */
#ifndef ADBLOCKTREEWIDGET_H
#define ADBLOCKTREEWIDGET_H
#include <QTreeWidget>
#include "qz_namespace.h"
#include "treewidget.h"
class AdBlockSubscription;
class QT_QUPZILLA_EXPORT AdBlockTreeWidget : public TreeWidget
{
Q_OBJECT
public:
explicit AdBlockTreeWidget(AdBlockSubscription* subscription, QWidget* parent = 0);
AdBlockSubscription* subscription() const;
signals:
public slots:
void addRule();
void removeRule();
private slots:
void contextMenuRequested(const QPoint &pos);
void itemChanged(QTreeWidgetItem* item);
void refresh();
void subscriptionUpdated();
private:
AdBlockSubscription* m_subscription;
QTreeWidgetItem* m_topItem;
bool m_itemChangingBlock;
};
#endif // ADBLOCKTREEWIDGET_H

View File

@ -164,7 +164,6 @@ SOURCES += \
other/licenseviewer.cpp \
bookmarksimport/bookmarksimporticonfetcher.cpp \
other/checkboxdialog.cpp \
network/schemehandler.cpp \
tools/plaineditwithlines.cpp \
webview/websettings.cpp \
tools/focusselectlineedit.cpp \
@ -177,7 +176,11 @@ SOURCES += \
history/historyview.cpp \
history/historyitem.cpp \
tools/headerview.cpp \
other/iconchooser.cpp
other/iconchooser.cpp \
adblock/adblocktreewidget.cpp \
adblock/adblockaddsubscriptiondialog.cpp \
adblock/adblockschemehandler.cpp \
tools/emptynetworkreply.cpp
HEADERS += \
webview/tabpreview.h \
@ -326,7 +329,11 @@ HEADERS += \
history/historyview.h \
history/historyitem.h \
tools/headerview.h \
other/iconchooser.h
other/iconchooser.h \
adblock/adblocktreewidget.h \
adblock/adblockaddsubscriptiondialog.h \
adblock/adblockschemehandler.h \
tools/emptynetworkreply.h
FORMS += \
preferences/autofillmanager.ui \
@ -368,7 +375,8 @@ FORMS += \
opensearch/editsearchengine.ui \
bookmarksimport/bookmarksimportdialog.ui \
other/checkboxdialog.ui \
other/iconchooser.ui
other/iconchooser.ui \
adblock/adblockaddsubscriptiondialog.ui
RESOURCES += \
data/icons.qrc \

View File

@ -23,6 +23,7 @@
#include "webpage.h"
#include "pluginproxy.h"
#include "adblockmanager.h"
#include "adblockschemehandler.h"
#include "networkproxyfactory.h"
#include "qupzillaschemehandler.h"
#include "certificateinfowidget.h"
@ -68,6 +69,7 @@ NetworkManager::NetworkManager(QupZilla* mainClass, QObject* parent)
connect(this, SIGNAL(finished(QNetworkReply*)), this, SLOT(setSSLConfiguration(QNetworkReply*)));
m_schemeHandlers["qupzilla"] = new QupZillaSchemeHandler();
m_schemeHandlers["abp"] = new AdBlockSchemeHandler();
m_proxyFactory = new NetworkProxyFactory();
setProxyFactory(m_proxyFactory);

View File

@ -38,11 +38,11 @@ class QT_QUPZILLA_EXPORT QupZillaSchemeReply : public QNetworkReply
public:
explicit QupZillaSchemeReply(const QNetworkRequest &req, QObject* parent = 0);
virtual qint64 bytesAvailable() const;
qint64 bytesAvailable() const;
protected:
virtual qint64 readData(char* data, qint64 maxSize);
virtual void abort() { }
qint64 readData(char* data, qint64 maxSize);
void abort() { }
private slots:
void delayedFinish();

View File

@ -25,8 +25,7 @@
class QT_QUPZILLA_EXPORT SchemeHandler
{
public:
SchemeHandler();
SchemeHandler() { }
virtual QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice* outgoingData) = 0;
};

View File

@ -54,6 +54,7 @@
#include <QFormLayout>
#include <QMenu>
#include <QTimer>
#include <QNetworkRequest>
#include <QWebHitTestResult>
QUrl ClickToFlash::acceptedUrl;
@ -74,9 +75,7 @@ ClickToFlash::ClickToFlash(const QUrl &pluginUrl, const QStringList &argumentNam
//AdBlock
AdBlockManager* manager = AdBlockManager::instance();
if (manager->isEnabled()) {
QString urlString = pluginUrl.toEncoded();
AdBlockSubscription* subscription = manager->subscription();
if (!subscription->allow(urlString) && subscription->block(urlString)) {
if (manager->block(QNetworkRequest(pluginUrl))) {
QTimer::singleShot(200, this, SLOT(hideAdBlocked()));
return;
}

View File

@ -0,0 +1,42 @@
/* ============================================================
* 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 "emptynetworkreply.h"
#include <QTimer>
EmptyNetworkReply::EmptyNetworkReply(QObject* parent)
: QNetworkReply(parent)
{
setOperation(QNetworkAccessManager::GetOperation);
setError(QNetworkReply::OperationCanceledError, "QupZilla:No Error");
QTimer::singleShot(0, this, SLOT(delayedFinish()));
}
void EmptyNetworkReply::delayedFinish()
{
emit finished();
}
qint64 EmptyNetworkReply::readData(char* data, qint64 maxSize)
{
Q_UNUSED(data)
Q_UNUSED(maxSize)
return 0;
}

View File

@ -0,0 +1,39 @@
/* ============================================================
* 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/>.
* ============================================================ */
#ifndef EMPTYNETWORKREPLY_H
#define EMPTYNETWORKREPLY_H
#include <QNetworkReply>
#include "qz_namespace.h"
class QT_QUPZILLA_EXPORT EmptyNetworkReply : public QNetworkReply
{
Q_OBJECT
public:
explicit EmptyNetworkReply(QObject* parent = 0);
private slots:
void delayedFinish();
protected:
qint64 readData(char* data, qint64 maxSize);
void abort() { }
};
#endif // EMPTYNETWORKREPLY_H

View File

@ -114,7 +114,6 @@ void qz_removeDir(const QString &d)
}
}
QString qz_samePartOfStrings(const QString &one, const QString &other)
{
int i = 0;
@ -221,6 +220,7 @@ QString qz_getFileNameFromUrl(const QUrl &url)
QString qz_filterCharsFromFilename(const QString &name)
{
QString value = name;
value.replace("/", "-");
value.remove("\\");
value.remove(":");

View File

@ -18,6 +18,8 @@
#ifndef GLOBALFUNCTIONS_H
#define GLOBALFUNCTIONS_H
#include <QList>
#include "qz_namespace.h"
class QFontMetrics;
@ -51,4 +53,10 @@ QPixmap QT_QUPZILLA_EXPORT qz_createPixmapForSite(const QIcon &icon, const QStri
QString QT_QUPZILLA_EXPORT qz_buildSystem();
template <typename T>
bool QT_QUPZILLA_EXPORT qz_listContainsIndex(const QList<T> &list, int index)
{
return (index >= 0 && list.count() > index);
}
#endif // GLOBALFUNCTIONS_H

View File

@ -24,6 +24,8 @@ TreeWidget::TreeWidget(QWidget* parent)
, m_refreshAllItemsNeeded(true)
, m_showMode(ItemsCollapsed)
{
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
connect(this, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(sheduleRefresh()));
}

View File

@ -660,7 +660,9 @@ bool WebPage::extension(Extension extension, const ExtensionOption* option, Exte
errorString = tr("Content Access Denied");
break;
default:
qDebug() << "Content error: " << exOption->errorString << exOption->error;
if (exOption->errorString != "QupZilla:No Error") {
qDebug() << "Content error: " << exOption->errorString << exOption->error;
}
return false;
}
}