2011-03-27 21:59:40 +02:00
|
|
|
/* ============================================================
|
|
|
|
* QupZilla - WebKit based browser
|
2013-02-20 19:50:59 +01:00
|
|
|
* Copyright (C) 2010-2013 David Rosca <nowrep@gmail.com>
|
2011-03-27 21:59:40 +02:00
|
|
|
*
|
|
|
|
* 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 "adblockmanager.h"
|
|
|
|
#include "adblockdialog.h"
|
|
|
|
#include "adblocksubscription.h"
|
2012-06-15 17:03:37 +02:00
|
|
|
#include "adblockblockednetworkreply.h"
|
2011-03-27 21:59:40 +02:00
|
|
|
#include "mainapplication.h"
|
2012-06-15 17:03:37 +02:00
|
|
|
#include "webpage.h"
|
2013-01-22 19:04:22 +01:00
|
|
|
#include "qztools.h"
|
2011-03-27 21:59:40 +02:00
|
|
|
#include "networkmanager.h"
|
|
|
|
#include "qupzilla.h"
|
2012-01-11 21:58:25 +01:00
|
|
|
#include "settings.h"
|
2011-03-27 21:59:40 +02:00
|
|
|
|
2012-02-29 18:33:50 +01:00
|
|
|
#include <QDateTime>
|
2012-06-24 23:46:32 +02:00
|
|
|
#include <QTextStream>
|
|
|
|
#include <QDir>
|
|
|
|
#include <QTimer>
|
|
|
|
#include <QDebug>
|
2012-02-29 18:33:50 +01:00
|
|
|
|
2013-02-26 12:29:46 +01:00
|
|
|
//#define ADBLOCK_DEBUG
|
|
|
|
|
|
|
|
#ifdef ADBLOCK_DEBUG
|
|
|
|
#include <QElapsedTimer>
|
|
|
|
#endif
|
|
|
|
|
2011-03-27 21:59:40 +02:00
|
|
|
AdBlockManager* AdBlockManager::s_adBlockManager = 0;
|
|
|
|
|
|
|
|
AdBlockManager::AdBlockManager(QObject* parent)
|
|
|
|
: QObject(parent)
|
|
|
|
, m_loaded(false)
|
|
|
|
, m_enabled(true)
|
|
|
|
{
|
2012-06-25 16:07:25 +02:00
|
|
|
load();
|
2011-03-27 21:59:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
AdBlockManager* AdBlockManager::instance()
|
|
|
|
{
|
2011-11-06 17:01:23 +01:00
|
|
|
if (!s_adBlockManager) {
|
2011-03-27 21:59:40 +02:00
|
|
|
s_adBlockManager = new AdBlockManager(mApp->networkManager());
|
2011-11-06 17:01:23 +01:00
|
|
|
}
|
2011-03-29 20:30:05 +02:00
|
|
|
|
2011-03-27 21:59:40 +02:00
|
|
|
return s_adBlockManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AdBlockManager::setEnabled(bool enabled)
|
|
|
|
{
|
2012-07-01 20:38:37 +02:00
|
|
|
if (m_enabled == enabled) {
|
2011-03-27 21:59:40 +02:00
|
|
|
return;
|
2011-11-06 17:01:23 +01:00
|
|
|
}
|
2012-06-24 23:46:32 +02:00
|
|
|
|
2011-03-27 21:59:40 +02:00
|
|
|
m_enabled = enabled;
|
2012-01-21 23:19:38 +01:00
|
|
|
mApp->sendMessages(Qz::AM_SetAdBlockIconEnabled, enabled);
|
2012-07-01 20:38:37 +02:00
|
|
|
|
|
|
|
Settings settings;
|
|
|
|
settings.beginGroup("AdBlock");
|
|
|
|
settings.setValue("enabled", m_enabled);
|
|
|
|
settings.endGroup();
|
|
|
|
|
|
|
|
load();
|
2011-03-27 21:59:40 +02:00
|
|
|
}
|
|
|
|
|
2012-06-24 23:46:32 +02:00
|
|
|
QList<AdBlockSubscription*> AdBlockManager::subscriptions() const
|
2011-03-27 21:59:40 +02:00
|
|
|
{
|
2012-06-24 23:46:32 +02:00
|
|
|
return m_subscriptions;
|
2012-06-15 17:03:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
QNetworkReply* AdBlockManager::block(const QNetworkRequest &request)
|
|
|
|
{
|
2013-02-26 12:29:46 +01:00
|
|
|
#ifdef ADBLOCK_DEBUG
|
|
|
|
QElapsedTimer timer;
|
|
|
|
timer.start();
|
|
|
|
#endif
|
2012-06-15 17:03:37 +02:00
|
|
|
const QString &urlString = request.url().toEncoded();
|
2012-06-25 16:07:25 +02:00
|
|
|
const QString &urlDomain = request.url().host();
|
2012-06-15 17:03:37 +02:00
|
|
|
const QString &urlScheme = request.url().scheme();
|
|
|
|
|
2012-07-04 10:08:55 +02:00
|
|
|
if (!isEnabled() || !canRunOnScheme(urlScheme)) {
|
2012-06-15 17:03:37 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-06-15 17:43:19 +02:00
|
|
|
foreach(AdBlockSubscription * subscription, m_subscriptions) {
|
2012-06-28 01:41:01 +02:00
|
|
|
const AdBlockRule* blockedRule = subscription->match(request, urlDomain, urlString);
|
2012-06-15 17:03:37 +02:00
|
|
|
|
|
|
|
if (blockedRule) {
|
|
|
|
QVariant v = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100));
|
|
|
|
WebPage* webPage = static_cast<WebPage*>(v.value<void*>());
|
|
|
|
if (WebPage::isPointerSafeToUse(webPage)) {
|
2012-07-04 16:00:53 +02:00
|
|
|
if (!canBeBlocked(webPage->url())) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-07-01 18:13:49 +02:00
|
|
|
webPage->addAdBlockRule(blockedRule, request.url());
|
2012-06-15 17:03:37 +02:00
|
|
|
}
|
|
|
|
|
2012-06-21 21:49:41 +02:00
|
|
|
AdBlockBlockedNetworkReply* reply = new AdBlockBlockedNetworkReply(subscription, blockedRule, this);
|
|
|
|
reply->setRequest(request);
|
|
|
|
|
2013-02-26 12:29:46 +01:00
|
|
|
#ifdef ADBLOCK_DEBUG
|
|
|
|
qDebug() << "BLOCKED: " << timer.elapsed() << blockedRule->filter() << request.url();
|
|
|
|
#endif
|
|
|
|
|
2012-06-15 17:03:37 +02:00
|
|
|
return reply;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-26 12:29:46 +01:00
|
|
|
#ifdef ADBLOCK_DEBUG
|
|
|
|
qDebug() << timer.elapsed() << request.url();
|
|
|
|
#endif
|
|
|
|
|
2012-06-15 17:03:37 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-07-01 20:11:37 +02:00
|
|
|
QStringList AdBlockManager::disabledRules() const
|
|
|
|
{
|
|
|
|
return m_disabledRules;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AdBlockManager::addDisabledRule(const QString &filter)
|
|
|
|
{
|
|
|
|
m_disabledRules.append(filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AdBlockManager::removeDisabledRule(const QString &filter)
|
|
|
|
{
|
|
|
|
m_disabledRules.removeOne(filter);
|
|
|
|
}
|
|
|
|
|
2012-06-24 23:46:32 +02:00
|
|
|
AdBlockSubscription* AdBlockManager::addSubscription(const QString &title, const QString &url)
|
|
|
|
{
|
|
|
|
if (title.isEmpty() || url.isEmpty()) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-22 19:04:22 +01:00
|
|
|
QString fileName = QzTools::filterCharsFromFilename(title.toLower()) + ".txt";
|
|
|
|
QString filePath = QzTools::ensureUniqueFilename(mApp->currentProfilePath() + "adblock/" + fileName);
|
2012-06-24 23:46:32 +02:00
|
|
|
|
2012-12-20 14:45:35 +01:00
|
|
|
QByteArray data = QString("Title: %1\nUrl: %2\n[Adblock Plus 1.1.1]").arg(title, url).toLatin1();
|
2012-06-24 23:46:32 +02:00
|
|
|
|
|
|
|
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);
|
2012-07-01 20:11:37 +02:00
|
|
|
subscription->loadSubscription(m_disabledRules);
|
2012-06-24 23:46:32 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2012-08-09 19:02:25 +02:00
|
|
|
AdBlockCustomList* AdBlockManager::customList() const
|
|
|
|
{
|
|
|
|
foreach(AdBlockSubscription * subscription, m_subscriptions) {
|
|
|
|
AdBlockCustomList* list = qobject_cast<AdBlockCustomList*>(subscription);
|
|
|
|
|
|
|
|
if (list) {
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-03-27 21:59:40 +02:00
|
|
|
void AdBlockManager::load()
|
|
|
|
{
|
2012-07-01 20:38:37 +02:00
|
|
|
if (m_loaded) {
|
2011-03-27 21:59:40 +02:00
|
|
|
return;
|
2011-11-06 17:01:23 +01:00
|
|
|
}
|
2011-03-27 21:59:40 +02:00
|
|
|
|
2013-02-26 12:29:46 +01:00
|
|
|
#ifdef ADBLOCK_DEBUG
|
|
|
|
QElapsedTimer timer;
|
|
|
|
timer.start();
|
|
|
|
#endif
|
|
|
|
|
2012-01-11 21:58:25 +01:00
|
|
|
Settings settings;
|
2011-03-27 21:59:40 +02:00
|
|
|
settings.beginGroup("AdBlock");
|
|
|
|
m_enabled = settings.value("enabled", m_enabled).toBool();
|
2012-07-01 20:11:37 +02:00
|
|
|
m_disabledRules = settings.value("disabledRules", QStringList()).toStringList();
|
2011-12-28 19:28:34 +01:00
|
|
|
QDateTime lastUpdate = settings.value("lastUpdate", QDateTime()).toDateTime();
|
2011-03-27 21:59:40 +02:00
|
|
|
settings.endGroup();
|
|
|
|
|
2012-06-25 16:07:25 +02:00
|
|
|
if (!m_enabled) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-06-24 23:46:32 +02:00
|
|
|
QDir adblockDir(mApp->currentProfilePath() + "adblock");
|
|
|
|
// Create if neccessary
|
|
|
|
if (!adblockDir.exists()) {
|
|
|
|
QDir(mApp->currentProfilePath()).mkdir("adblock");
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach(const QString & fileName, adblockDir.entryList(QStringList("*.txt"), QDir::Files)) {
|
2012-09-04 12:42:45 +02:00
|
|
|
if (fileName == QLatin1String("easylist.txt") || fileName == QLatin1String("customlist.txt")) {
|
2012-06-24 23:46:32 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-07-08 00:15:03 +02:00
|
|
|
const QString &absolutePath = adblockDir.absoluteFilePath(fileName);
|
2012-06-24 23:46:32 +02:00
|
|
|
QFile file(absolutePath);
|
|
|
|
if (!file.open(QFile::ReadOnly)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
QTextStream textStream(&file);
|
2013-02-20 19:50:59 +01:00
|
|
|
textStream.setCodec("UTF-8");
|
2012-09-04 12:42:45 +02:00
|
|
|
QString title = textStream.readLine(1024).remove(QLatin1String("Title: "));
|
|
|
|
QUrl url = QUrl(textStream.readLine(1024).remove(QLatin1String("Url: ")));
|
2012-06-24 23:46:32 +02:00
|
|
|
|
|
|
|
if (title.isEmpty() || !url.isValid()) {
|
|
|
|
qWarning() << "AdBlockManager: Invalid subscription file" << absolutePath;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
AdBlockSubscription* subscription = new AdBlockSubscription(title, this);
|
|
|
|
subscription->setUrl(url);
|
|
|
|
subscription->setFilePath(absolutePath);
|
2012-07-04 17:53:49 +02:00
|
|
|
connect(subscription, SIGNAL(subscriptionUpdated()), mApp, SLOT(reloadUserStyleSheet()));
|
|
|
|
|
2012-06-24 23:46:32 +02:00
|
|
|
m_subscriptions.append(subscription);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Prepend EasyList
|
|
|
|
AdBlockSubscription* easyList = new AdBlockEasyList(this);
|
|
|
|
m_subscriptions.prepend(easyList);
|
2012-07-04 17:53:49 +02:00
|
|
|
connect(easyList, SIGNAL(subscriptionUpdated()), mApp, SLOT(reloadUserStyleSheet()));
|
2012-06-24 23:46:32 +02:00
|
|
|
|
|
|
|
// Append CustomList
|
2012-07-04 17:53:49 +02:00
|
|
|
AdBlockCustomList* customList = new AdBlockCustomList(this);
|
2012-06-24 23:46:32 +02:00
|
|
|
m_subscriptions.append(customList);
|
2012-07-04 17:53:49 +02:00
|
|
|
connect(customList, SIGNAL(subscriptionEdited()), mApp, SLOT(reloadUserStyleSheet()));
|
2012-06-15 17:03:37 +02:00
|
|
|
|
2012-06-24 23:46:32 +02:00
|
|
|
// Load all subscriptions
|
|
|
|
foreach(AdBlockSubscription * subscription, m_subscriptions) {
|
2012-07-01 20:11:37 +02:00
|
|
|
subscription->loadSubscription(m_disabledRules);
|
2012-06-24 23:46:32 +02:00
|
|
|
}
|
2011-12-28 19:28:34 +01:00
|
|
|
|
2012-06-24 23:46:32 +02:00
|
|
|
if (lastUpdate.addDays(5) < QDateTime::currentDateTime()) {
|
|
|
|
QTimer::singleShot(1000 * 60, this, SLOT(updateAllSubscriptions()));
|
2011-12-28 19:28:34 +01:00
|
|
|
}
|
2012-06-25 16:07:25 +02:00
|
|
|
|
2013-02-26 12:29:46 +01:00
|
|
|
#ifdef ADBLOCK_DEBUG
|
|
|
|
qDebug() << "AdBlock loaded in" << timer.elapsed();
|
|
|
|
#endif
|
|
|
|
|
2012-06-25 16:07:25 +02:00
|
|
|
m_loaded = true;
|
2011-12-28 19:28:34 +01:00
|
|
|
}
|
|
|
|
|
2012-06-24 23:46:32 +02:00
|
|
|
void AdBlockManager::updateAllSubscriptions()
|
2011-12-28 19:28:34 +01:00
|
|
|
{
|
2012-06-24 23:46:32 +02:00
|
|
|
foreach(AdBlockSubscription * subscription, m_subscriptions) {
|
|
|
|
subscription->updateSubscription();
|
|
|
|
}
|
|
|
|
|
2012-01-11 21:58:25 +01:00
|
|
|
Settings settings;
|
2011-12-28 19:28:34 +01:00
|
|
|
settings.beginGroup("AdBlock");
|
|
|
|
settings.setValue("lastUpdate", QDateTime::currentDateTime());
|
2012-06-15 20:54:58 +02:00
|
|
|
settings.endGroup();
|
2011-03-27 21:59:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void AdBlockManager::save()
|
|
|
|
{
|
2011-11-06 17:01:23 +01:00
|
|
|
if (!m_loaded) {
|
2011-03-27 21:59:40 +02:00
|
|
|
return;
|
2011-11-06 17:01:23 +01:00
|
|
|
}
|
2012-06-15 17:03:37 +02:00
|
|
|
|
2012-06-24 23:46:32 +02:00
|
|
|
foreach(AdBlockSubscription * subscription, m_subscriptions) {
|
|
|
|
subscription->saveSubscription();
|
|
|
|
}
|
2011-03-27 21:59:40 +02:00
|
|
|
|
2012-01-11 21:58:25 +01:00
|
|
|
Settings settings;
|
2012-06-24 23:46:32 +02:00
|
|
|
settings.beginGroup("AdBlock");
|
|
|
|
settings.setValue("enabled", m_enabled);
|
2012-07-01 20:11:37 +02:00
|
|
|
settings.setValue("disabledRules", m_disabledRules);
|
2011-03-27 21:59:40 +02:00
|
|
|
settings.endGroup();
|
|
|
|
}
|
|
|
|
|
2012-06-25 16:07:25 +02:00
|
|
|
bool AdBlockManager::isEnabled()
|
|
|
|
{
|
|
|
|
return m_enabled;
|
|
|
|
}
|
|
|
|
|
2012-07-04 10:08:55 +02:00
|
|
|
bool AdBlockManager::canRunOnScheme(const QString &scheme) const
|
|
|
|
{
|
2012-09-04 11:29:47 +02:00
|
|
|
return !(scheme == QLatin1String("file") || scheme == QLatin1String("qrc")
|
|
|
|
|| scheme == QLatin1String("qupzilla") || scheme == QLatin1String("data")
|
|
|
|
|| scheme == QLatin1String("abp"));
|
2012-07-04 10:08:55 +02:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:00:53 +02:00
|
|
|
bool AdBlockManager::canBeBlocked(const QUrl &url) const
|
|
|
|
{
|
|
|
|
foreach(AdBlockSubscription * subscription, m_subscriptions) {
|
|
|
|
if (subscription->adBlockDisabledForUrl(url)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-06-25 16:07:25 +02:00
|
|
|
QString AdBlockManager::elementHidingRules() const
|
|
|
|
{
|
2012-07-04 17:53:49 +02:00
|
|
|
if (!m_enabled) {
|
|
|
|
return QString();
|
|
|
|
}
|
|
|
|
|
2012-06-25 16:07:25 +02:00
|
|
|
QString rules;
|
|
|
|
|
|
|
|
foreach(AdBlockSubscription * subscription, m_subscriptions) {
|
|
|
|
rules.append(subscription->elementHidingRules());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove last ","
|
|
|
|
if (!rules.isEmpty()) {
|
2012-07-01 18:13:49 +02:00
|
|
|
rules = rules.left(rules.size() - 1);
|
2012-06-25 16:07:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return rules;
|
|
|
|
}
|
|
|
|
|
2012-07-04 16:00:53 +02:00
|
|
|
QString AdBlockManager::elementHidingRulesForDomain(const QUrl &url) const
|
2012-06-25 16:07:25 +02:00
|
|
|
{
|
|
|
|
QString rules;
|
|
|
|
|
|
|
|
foreach(AdBlockSubscription * subscription, m_subscriptions) {
|
2012-07-04 16:00:53 +02:00
|
|
|
if (subscription->elemHideDisabledForUrl(url)) {
|
|
|
|
return QString();
|
|
|
|
}
|
|
|
|
|
|
|
|
rules.append(subscription->elementHidingRulesForDomain(url.host()));
|
2012-06-25 16:07:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Remove last ","
|
|
|
|
if (!rules.isEmpty()) {
|
2012-07-01 18:13:49 +02:00
|
|
|
rules = rules.left(rules.size() - 1);
|
2012-06-25 16:07:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return rules;
|
|
|
|
}
|
|
|
|
|
2012-07-01 18:13:49 +02:00
|
|
|
AdBlockSubscription* AdBlockManager::subscriptionByName(const QString &name) const
|
|
|
|
{
|
|
|
|
foreach(AdBlockSubscription * subscription, m_subscriptions) {
|
|
|
|
if (subscription->title() == name) {
|
|
|
|
return subscription;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-03-27 21:59:40 +02:00
|
|
|
AdBlockDialog* AdBlockManager::showDialog()
|
|
|
|
{
|
2012-01-18 18:36:10 +01:00
|
|
|
if (!m_adBlockDialog) {
|
2011-03-27 21:59:40 +02:00
|
|
|
m_adBlockDialog = new AdBlockDialog(mApp->getWindow());
|
2011-11-06 17:01:23 +01:00
|
|
|
}
|
2011-05-07 12:59:53 +02:00
|
|
|
|
2011-12-09 21:56:01 +01:00
|
|
|
m_adBlockDialog.data()->show();
|
|
|
|
return m_adBlockDialog.data();
|
2011-03-27 21:59:40 +02:00
|
|
|
}
|
|
|
|
|
2011-03-29 20:30:05 +02:00
|
|
|
void AdBlockManager::showRule()
|
|
|
|
{
|
|
|
|
if (QAction* action = qobject_cast<QAction*>(sender())) {
|
2012-07-01 18:13:49 +02:00
|
|
|
const AdBlockRule* rule = static_cast<const AdBlockRule*>(action->data().value<void*>());
|
|
|
|
|
|
|
|
if (rule) {
|
|
|
|
showDialog()->showRule(rule);
|
|
|
|
}
|
2011-03-29 20:30:05 +02:00
|
|
|
}
|
|
|
|
}
|
2013-02-26 10:42:48 +01:00
|
|
|
|
|
|
|
AdBlockManager::~AdBlockManager()
|
|
|
|
{
|
|
|
|
qDeleteAll(m_subscriptions);
|
|
|
|
}
|