diff --git a/src/lib/3rdparty/msvc2008.h b/src/lib/3rdparty/msvc2008.h index 209d8866e..062384832 100644 --- a/src/lib/3rdparty/msvc2008.h +++ b/src/lib/3rdparty/msvc2008.h @@ -38,66 +38,66 @@ typedef interface IObjectCollection IObjectCollection; #ifdef __cplusplus extern "C" { #endif - /* - **************************************************************************************************** - IObjectArray +/* + **************************************************************************************************** + IObjectArray - - **************************************************************************************************** - */ + + **************************************************************************************************** +*/ #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 diff --git a/src/lib/adblock/adblockaddsubscriptiondialog.cpp b/src/lib/adblock/adblockaddsubscriptiondialog.cpp new file mode 100644 index 000000000..b631e7045 --- /dev/null +++ b/src/lib/adblock/adblockaddsubscriptiondialog.cpp @@ -0,0 +1,72 @@ +/* ============================================================ +* QupZilla - WebKit based browser +* Copyright (C) 2010-2012 David Rosca +* +* 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 . +* ============================================================ */ +#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; +} diff --git a/src/lib/adblock/adblockaddsubscriptiondialog.h b/src/lib/adblock/adblockaddsubscriptiondialog.h new file mode 100644 index 000000000..bf90d70b4 --- /dev/null +++ b/src/lib/adblock/adblockaddsubscriptiondialog.h @@ -0,0 +1,61 @@ +/* ============================================================ +* QupZilla - WebKit based browser +* Copyright (C) 2010-2012 David Rosca +* +* 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 . +* ============================================================ */ +#ifndef ADBLOCKADDSUBSCRIPTIONDIALOG_H +#define ADBLOCKADDSUBSCRIPTIONDIALOG_H + +#include +#include + +#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 m_knownSubscriptions; +}; + +#endif // ADBLOCKADDSUBSCRIPTIONDIALOG_H diff --git a/src/lib/adblock/adblockaddsubscriptiondialog.ui b/src/lib/adblock/adblockaddsubscriptiondialog.ui new file mode 100644 index 000000000..88b77db8a --- /dev/null +++ b/src/lib/adblock/adblockaddsubscriptiondialog.ui @@ -0,0 +1,94 @@ + + + AdBlockAddSubscriptionDialog + + + + 0 + 0 + 557 + 162 + + + + Add Subscription + + + + + + + + + Title: + + + + + + + + + + Address: + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Add new subscription to AdBlock: + + + + + + + + + buttonBox + accepted() + AdBlockAddSubscriptionDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AdBlockAddSubscriptionDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/lib/adblock/adblockdialog.cpp b/src/lib/adblock/adblockdialog.cpp index 0aafaec32..a6bef2b83 100644 --- a/src/lib/adblock/adblockdialog.cpp +++ b/src/lib/adblock/adblockdialog.cpp @@ -15,36 +15,11 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ -/** - * Copyright (c) 2009, Benjamin C. Meyer - * - * 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 @@ -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(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 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")); } diff --git a/src/lib/adblock/adblockdialog.h b/src/lib/adblock/adblockdialog.h index 64ce31c14..b4f82aacd 100644 --- a/src/lib/adblock/adblockdialog.h +++ b/src/lib/adblock/adblockdialog.h @@ -15,34 +15,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ -/** - * Copyright (c) 2009, Benjamin C. Meyer - * - * 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 diff --git a/src/lib/adblock/adblockdialog.ui b/src/lib/adblock/adblockdialog.ui index 6beabfee6..dc54e5e78 100644 --- a/src/lib/adblock/adblockdialog.ui +++ b/src/lib/adblock/adblockdialog.ui @@ -13,8 +13,8 @@ AdBlock Configuration - - + + Enable AdBlock @@ -24,7 +24,34 @@ - + + + + + + Search... + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 50 + 20 + + + + + + + true @@ -33,54 +60,22 @@ 0 - - - - Search... - - - - - - - true - - - - Rule - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 40 - 20 - - - - - + - + - Add Rule + Options - - - - - - Update EasyList + + + :/icons/other/adblock.png:/icons/other/adblock.png + + + QToolButton::InstantPopup + + + Qt::ToolButtonTextBesideIcon @@ -97,25 +92,35 @@ + + + + + 0 + 0 + + + + AdBlock + + + + + + + -1 + + + true + + + - - - - - 0 - 0 - - - - AdBlock - - - - + Qt::Horizontal @@ -127,14 +132,9 @@ - - - TreeWidget - QTreeWidget -
treewidget.h
-
-
- + + + buttonBox diff --git a/src/lib/adblock/adblockicon.cpp b/src/lib/adblock/adblockicon.cpp index cab060d9b..b6b1649e0 100644 --- a/src/lib/adblock/adblockicon.cpp +++ b/src/lib/adblock/adblockicon.cpp @@ -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; diff --git a/src/lib/adblock/adblockicon.h b/src/lib/adblock/adblockicon.h index bff8e9fa3..64c384958 100644 --- a/src/lib/adblock/adblockicon.h +++ b/src/lib/adblock/adblockicon.h @@ -45,7 +45,6 @@ public slots: private slots: void showMenu(const QPoint &pos); - void learnAboutRules(); void animateIcon(); void stopAnimation(); diff --git a/src/lib/adblock/adblockmanager.cpp b/src/lib/adblock/adblockmanager.cpp index 734e6365f..0bf046a67 100644 --- a/src/lib/adblock/adblockmanager.cpp +++ b/src/lib/adblock/adblockmanager.cpp @@ -15,33 +15,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ -/** - * Copyright (c) 2009, Benjamin C. Meyer - * - * 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 +#include +#include +#include +#include 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 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() -{ -} diff --git a/src/lib/adblock/adblockmanager.h b/src/lib/adblock/adblockmanager.h index 142ec363a..fa9aca365 100644 --- a/src/lib/adblock/adblockmanager.h +++ b/src/lib/adblock/adblockmanager.h @@ -15,33 +15,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ -/** - * Copyright (c) 2009, Benjamin C. Meyer - * - * 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 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 m_adBlockDialog; - AdBlockNetwork* m_adBlockNetwork; - AdBlockPage* m_adBlockPage; QList m_subscriptions; }; diff --git a/src/lib/adblock/adblockschemehandler.cpp b/src/lib/adblock/adblockschemehandler.cpp new file mode 100644 index 000000000..ed86b9fdc --- /dev/null +++ b/src/lib/adblock/adblockschemehandler.cpp @@ -0,0 +1,67 @@ +/* ============================================================ +* QupZilla - WebKit based browser +* Copyright (C) 2010-2012 David Rosca +* +* 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 . +* ============================================================ */ +#include "adblockschemehandler.h" +#include "adblockmanager.h" +#include "emptynetworkreply.h" + +#include +#include + +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 > queryItems = url.queryItems(); + + QString subscriptionTitle; + QString subscriptionUrl; + + for (int i = 0; i < queryItems.count(); ++i) { + QPair 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 %1 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; +} diff --git a/src/lib/network/schemehandler.cpp b/src/lib/adblock/adblockschemehandler.h similarity index 71% rename from src/lib/network/schemehandler.cpp rename to src/lib/adblock/adblockschemehandler.h index 7e4b93780..4e9720af3 100644 --- a/src/lib/network/schemehandler.cpp +++ b/src/lib/adblock/adblockschemehandler.h @@ -15,8 +15,18 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ +#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 diff --git a/src/lib/adblock/adblocksubscription.cpp b/src/lib/adblock/adblocksubscription.cpp index b2873eca6..61c46b9f1 100644 --- a/src/lib/adblock/adblocksubscription.cpp +++ b/src/lib/adblock/adblocksubscription.cpp @@ -45,6 +45,7 @@ #include "adblocksubscription.h" #include "mainapplication.h" #include "networkmanager.h" +#include "globalfunctions.h" #include #include @@ -52,124 +53,93 @@ #include // #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(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(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 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; +} diff --git a/src/lib/adblock/adblocksubscription.h b/src/lib/adblock/adblocksubscription.h index 411d8087a..df7e1bf4b 100644 --- a/src/lib/adblock/adblocksubscription.h +++ b/src/lib/adblock/adblocksubscription.h @@ -47,6 +47,7 @@ #define ADBLOCKSUBSCRIPTION_H #include +#include #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 pageRules() const { return m_pageRules; } + QString elementHidingRules(); QList 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 m_rules; + QString m_elementHidingRules; // sorted list QList m_networkExceptionRules; QList m_networkBlockRules; - QList 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 diff --git a/src/lib/adblock/adblocktreewidget.cpp b/src/lib/adblock/adblocktreewidget.cpp new file mode 100644 index 000000000..49aad5b2f --- /dev/null +++ b/src/lib/adblock/adblocktreewidget.cpp @@ -0,0 +1,194 @@ +/* ============================================================ +* QupZilla - WebKit based browser +* Copyright (C) 2010-2012 David Rosca +* +* 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 . +* ============================================================ */ +#include "adblocktreewidget.h" +#include "adblocksubscription.h" + +#include +#include +#include + +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 &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; +} diff --git a/src/lib/adblock/adblocktreewidget.h b/src/lib/adblock/adblocktreewidget.h new file mode 100644 index 000000000..fffaa0495 --- /dev/null +++ b/src/lib/adblock/adblocktreewidget.h @@ -0,0 +1,57 @@ +/* ============================================================ +* QupZilla - WebKit based browser +* Copyright (C) 2010-2012 David Rosca +* +* 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 . +* ============================================================ */ +#ifndef ADBLOCKTREEWIDGET_H +#define ADBLOCKTREEWIDGET_H + +#include + +#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 diff --git a/src/lib/lib.pro b/src/lib/lib.pro index 5475fc2d0..5060bd85a 100644 --- a/src/lib/lib.pro +++ b/src/lib/lib.pro @@ -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 \ diff --git a/src/lib/network/networkmanager.cpp b/src/lib/network/networkmanager.cpp index 8dfca395e..90de2bde6 100644 --- a/src/lib/network/networkmanager.cpp +++ b/src/lib/network/networkmanager.cpp @@ -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); diff --git a/src/lib/network/qupzillaschemehandler.h b/src/lib/network/qupzillaschemehandler.h index 0c322f48c..9fd40b3f3 100644 --- a/src/lib/network/qupzillaschemehandler.h +++ b/src/lib/network/qupzillaschemehandler.h @@ -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(); diff --git a/src/lib/network/schemehandler.h b/src/lib/network/schemehandler.h index 5f8cdf973..5b929066f 100644 --- a/src/lib/network/schemehandler.h +++ b/src/lib/network/schemehandler.h @@ -25,8 +25,7 @@ class QT_QUPZILLA_EXPORT SchemeHandler { public: - SchemeHandler(); - + SchemeHandler() { } virtual QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice* outgoingData) = 0; }; diff --git a/src/lib/plugins/clicktoflash.cpp b/src/lib/plugins/clicktoflash.cpp index aee5a8515..824138da2 100644 --- a/src/lib/plugins/clicktoflash.cpp +++ b/src/lib/plugins/clicktoflash.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #include 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; } diff --git a/src/lib/tools/emptynetworkreply.cpp b/src/lib/tools/emptynetworkreply.cpp new file mode 100644 index 000000000..ba3e47505 --- /dev/null +++ b/src/lib/tools/emptynetworkreply.cpp @@ -0,0 +1,42 @@ +/* ============================================================ +* QupZilla - WebKit based browser +* Copyright (C) 2010-2012 David Rosca +* +* 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 . +* ============================================================ */ +#include "emptynetworkreply.h" + +#include + +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; +} diff --git a/src/lib/tools/emptynetworkreply.h b/src/lib/tools/emptynetworkreply.h new file mode 100644 index 000000000..c84fbc98a --- /dev/null +++ b/src/lib/tools/emptynetworkreply.h @@ -0,0 +1,39 @@ +/* ============================================================ +* QupZilla - WebKit based browser +* Copyright (C) 2010-2012 David Rosca +* +* 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 . +* ============================================================ */ +#ifndef EMPTYNETWORKREPLY_H +#define EMPTYNETWORKREPLY_H + +#include + +#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 diff --git a/src/lib/tools/globalfunctions.cpp b/src/lib/tools/globalfunctions.cpp index d2ecff106..d902c5138 100644 --- a/src/lib/tools/globalfunctions.cpp +++ b/src/lib/tools/globalfunctions.cpp @@ -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(":"); diff --git a/src/lib/tools/globalfunctions.h b/src/lib/tools/globalfunctions.h index d9fec5842..94efe9276 100644 --- a/src/lib/tools/globalfunctions.h +++ b/src/lib/tools/globalfunctions.h @@ -18,6 +18,8 @@ #ifndef GLOBALFUNCTIONS_H #define GLOBALFUNCTIONS_H +#include + #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 +bool QT_QUPZILLA_EXPORT qz_listContainsIndex(const QList &list, int index) +{ + return (index >= 0 && list.count() > index); +} + #endif // GLOBALFUNCTIONS_H diff --git a/src/lib/tools/treewidget.cpp b/src/lib/tools/treewidget.cpp index 959813c6b..a0ea9ca7d 100644 --- a/src/lib/tools/treewidget.cpp +++ b/src/lib/tools/treewidget.cpp @@ -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())); } diff --git a/src/lib/webview/webpage.cpp b/src/lib/webview/webpage.cpp index e0981cfd3..48cd0bf80 100644 --- a/src/lib/webview/webpage.cpp +++ b/src/lib/webview/webpage.cpp @@ -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; } }