File indexing completed on 2024-05-19 04:59:14

0001 /* ============================================================
0002 * FlashCookieManager plugin for Falkon
0003 * Copyright (C) 2014  S. Razi Alavizadeh <s.r.alavizadeh@gmail.com>
0004 * Copyright (C) 2010-2016  David Rosca <nowrep@gmail.com>
0005 *
0006 * some codes and ideas are taken from cookiemanager.cpp and cookiemanager.ui
0007 *
0008 * This program is free software: you can redistribute it and/or modify
0009 * it under the terms of the GNU General Public License as published by
0010 * the Free Software Foundation, either version 3 of the License, or
0011 * (at your option) any later version.
0012 *
0013 * This program is distributed in the hope that it will be useful,
0014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0016 * GNU General Public License for more details.
0017 *
0018 * You should have received a copy of the GNU General Public License
0019 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0020 * ============================================================ */
0021 #include "fcm_dialog.h"
0022 #include "ui_fcm_dialog.h"
0023 #include "qztools.h"
0024 #include "iconprovider.h"
0025 #include "fcm_plugin.h"
0026 
0027 #include <QMessageBox>
0028 #include <QShortcut>
0029 #include <QTimer>
0030 #include <QInputDialog>
0031 #include <QCloseEvent>
0032 #include <QMenu>
0033 
0034 FCM_Dialog::FCM_Dialog(FCM_Plugin* manager, QWidget* parent)
0035     : QDialog(parent, Qt::WindowStaysOnTopHint)
0036     , ui(new Ui::FCM_Dialog)
0037     , m_manager(manager)
0038 {
0039     ui->setupUi(this);
0040     QzTools::centerWidgetOnScreen(this);
0041 
0042     ui->path->hide();
0043     ui->labelPath->hide();
0044 
0045     if (isRightToLeft()) {
0046         ui->flashCookieTree->headerItem()->setTextAlignment(0, Qt::AlignRight | Qt::AlignVCenter);
0047         ui->flashCookieTree->setLayoutDirection(Qt::LeftToRight);
0048         ui->whiteList->setLayoutDirection(Qt::LeftToRight);
0049         ui->blackList->setLayoutDirection(Qt::LeftToRight);
0050     }
0051 
0052     connect(ui->flashCookieTree, &QTreeWidget::currentItemChanged, this, &FCM_Dialog::currentItemChanged);
0053     connect(ui->removeAll, &QAbstractButton::clicked, this, &FCM_Dialog::removeAll);
0054     connect(ui->removeOne, &QAbstractButton::clicked, this, &FCM_Dialog::removeCookie);
0055     connect(ui->close, &QDialogButtonBox::clicked, this, &QWidget::close);
0056     connect(ui->close2, &QDialogButtonBox::clicked, this, &QWidget::close);
0057     connect(ui->close3, &QDialogButtonBox::clicked, this, &QWidget::close);
0058     connect(ui->search, &QLineEdit::textChanged, this, &FCM_Dialog::filterString);
0059     connect(ui->reloadFromDisk, &QAbstractButton::clicked, this, &FCM_Dialog::reloadFromDisk);
0060 
0061     connect(ui->whiteAdd, SIGNAL(clicked()), this, SLOT(addWhitelist()));
0062     connect(ui->whiteRemove, &QAbstractButton::clicked, this, &FCM_Dialog::removeWhitelist);
0063     connect(ui->blackAdd, SIGNAL(clicked()), this, SLOT(addBlacklist()));
0064     connect(ui->blackRemove, &QAbstractButton::clicked, this, &FCM_Dialog::removeBlacklist);
0065 
0066     connect(ui->autoMode, &QAbstractButton::toggled, ui->notification, &QWidget::setEnabled);
0067     connect(ui->autoMode, &QAbstractButton::toggled, ui->labelNotification, &QWidget::setEnabled);
0068 
0069     ui->autoMode->setChecked(m_manager->readSettings().value(QL1S("autoMode")).toBool());
0070     ui->notification->setEnabled(m_manager->readSettings().value(QL1S("autoMode")).toBool());
0071     ui->notification->setChecked(m_manager->readSettings().value(QL1S("notification")).toBool());
0072     ui->deleteAllOnStartExit->setChecked(m_manager->readSettings().value(QL1S("deleteAllOnStartExit")).toBool());
0073 
0074     ui->labelNotification->setEnabled(ui->autoMode->isChecked());
0075 
0076     ui->search->setPlaceholderText(tr("Search"));
0077     ui->flashCookieTree->setDefaultItemShowMode(TreeWidget::ItemsCollapsed);
0078     ui->flashCookieTree->sortItems(0, Qt::AscendingOrder);
0079     ui->flashCookieTree->header()->setDefaultSectionSize(220);
0080     ui->flashCookieTree->setFocus();
0081 
0082     ui->flashCookieTree->setContextMenuPolicy(Qt::CustomContextMenu);
0083     connect(ui->flashCookieTree, &QWidget::customContextMenuRequested, this, &FCM_Dialog::cookieTreeContextMenuRequested);
0084 
0085     auto* removeShortcut = new QShortcut(QKeySequence(QSL("Del")), this);
0086     connect(removeShortcut, &QShortcut::activated, this, &FCM_Dialog::deletePressed);
0087 
0088     QzTools::setWmClass(QSL("FlashCookies"), this);
0089 }
0090 
0091 void FCM_Dialog::removeAll()
0092 {
0093     QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Confirmation"),
0094                                          tr("Are you sure you want to delete all flash cookies on your computer?"), QMessageBox::Yes | QMessageBox::No);
0095     if (button != QMessageBox::Yes) {
0096         return;
0097     }
0098 
0099     const QList<FlashCookie> &flashCookies = m_manager->flashCookies();
0100     for (const FlashCookie &flashCookie : flashCookies) {
0101          m_manager->removeCookie(flashCookie);
0102     }
0103 
0104     ui->flashCookieTree->clear();
0105     m_manager->clearNewOrigins();
0106     m_manager->clearCache();
0107 }
0108 
0109 void FCM_Dialog::removeCookie()
0110 {
0111     QTreeWidgetItem* current = ui->flashCookieTree->currentItem();
0112     if (!current) {
0113         return;
0114     }
0115 
0116     const QVariant data = current->data(0, Qt::UserRole + 10);
0117 
0118     if (data.isNull()) {     //Remove whole cookie group
0119         const QString origin = current->text(0);
0120         const QList<FlashCookie> &flashCookies = m_manager->flashCookies();
0121         for (const FlashCookie &flashCookie : flashCookies) {
0122             if (flashCookie.origin == origin) {
0123                 m_manager->removeCookie(flashCookie);
0124             }
0125         }
0126 
0127         ui->flashCookieTree->deleteItem(current);
0128     }
0129     else {
0130         const FlashCookie flashCookie = qvariant_cast<FlashCookie>(data);
0131         m_manager->removeCookie(flashCookie);
0132 
0133         QTreeWidgetItem* parentItem = current->parent();
0134         ui->flashCookieTree->deleteItem(current);
0135 
0136         if (parentItem->childCount() == 0) {
0137             ui->flashCookieTree->deleteItem(parentItem);
0138         }
0139     }
0140 }
0141 
0142 void FCM_Dialog::currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* parent)
0143 {
0144     Q_UNUSED(parent);
0145     if (!current) {
0146         return;
0147     }
0148     ui->textEdit->clear();
0149     const QVariant data = current->data(0, Qt::UserRole + 10);
0150     if (data.isNull()) {
0151         ui->name->setText(tr("<flash cookie not selected>"));
0152         ui->size->setText(tr("<flash cookie not selected>"));
0153         ui->server->setText(tr("<flash cookie not selected>"));
0154         ui->lastModified->setText(tr("<flash cookie not selected>"));
0155 
0156         ui->removeOne->setText(tr("Remove flash cookies"));
0157         ui->path->hide();
0158         ui->labelPath->hide();
0159         return;
0160     }
0161 
0162     const FlashCookie flashCookie = qvariant_cast<FlashCookie>(data);
0163 
0164     QString suffix;
0165     if (flashCookie.path.startsWith(m_manager->flashPlayerDataPath() + QL1S("/macromedia.com/support/flashplayer/sys"))) {
0166         suffix = tr(" (settings)");
0167     }
0168     ui->name->setText(flashCookie.name + suffix);
0169     ui->size->setText(QString::number(flashCookie.size) + tr(" Byte"));
0170     ui->textEdit->setPlainText(flashCookie.contents);
0171     ui->server->setText(flashCookie.origin);
0172     ui->path->setText(QSL("<a href=\"%1\">%2</a>").arg(QUrl::fromLocalFile(flashCookie.path).toString(), QDir::toNativeSeparators(flashCookie.path)));
0173     ui->lastModified->setText(flashCookie.lastModification.toString());
0174 
0175     ui->removeOne->setText(tr("Remove flash cookie"));
0176 
0177     ui->labelPath->show();
0178     ui->path->show();
0179 }
0180 
0181 void FCM_Dialog::refreshView(bool forceReload)
0182 {
0183     disconnect(ui->search, &QLineEdit::textChanged, this, &FCM_Dialog::filterString);
0184     ui->search->clear();
0185     ui->textEdit->clear();
0186     connect(ui->search, &QLineEdit::textChanged, this, &FCM_Dialog::filterString);
0187 
0188     if (forceReload) {
0189         m_manager->clearCache();
0190         m_manager->clearNewOrigins();
0191     }
0192 
0193     QTimer::singleShot(0, this, &FCM_Dialog::refreshFlashCookiesTree);
0194     QTimer::singleShot(0, this, &FCM_Dialog::refreshFilters);
0195 }
0196 
0197 void FCM_Dialog::showPage(int index)
0198 {
0199     ui->tabWidget->setCurrentIndex(index);
0200 }
0201 
0202 void FCM_Dialog::refreshFlashCookiesTree()
0203 {
0204     const QList<FlashCookie> &flashCookies = m_manager->flashCookies();
0205 
0206     QApplication::setOverrideCursor(Qt::WaitCursor);
0207     ui->flashCookieTree->clear();
0208 
0209     int counter = 0;
0210     QPointer<FCM_Dialog> guard = this;
0211     QHash<QString, QTreeWidgetItem*> hash;
0212     for (int i = 0; i < flashCookies.count(); ++i) {
0213         const FlashCookie flashCookie = flashCookies.at(i);
0214         QTreeWidgetItem* item;
0215 
0216         QString cookieOrigin = flashCookie.origin;
0217         if (cookieOrigin.startsWith(QLatin1Char('.'))) {
0218             cookieOrigin.remove(0, 1);
0219         }
0220 
0221         QTreeWidgetItem* findParent = hash.value(cookieOrigin);
0222         if (findParent) {
0223             item = new QTreeWidgetItem(findParent);
0224         }
0225         else {
0226             auto* newParent = new QTreeWidgetItem(ui->flashCookieTree);
0227             newParent->setText(0, cookieOrigin);
0228             newParent->setIcon(0, IconProvider::standardIcon(QStyle::SP_DirIcon));
0229             ui->flashCookieTree->addTopLevelItem(newParent);
0230             hash[cookieOrigin] = newParent;
0231 
0232             item = new QTreeWidgetItem(newParent);
0233         }
0234 
0235         QString suffix;
0236         if (flashCookie.path.startsWith(m_manager->flashPlayerDataPath() + QL1S("/macromedia.com/support/flashplayer/sys"))) {
0237             suffix = tr(" (settings)");
0238         }
0239 
0240         if (m_manager->newCookiesList().contains(flashCookie.path + QL1C('/') + flashCookie.name)) {
0241             suffix += tr(" [new]");
0242             QFont font = item->font(0);
0243             font.setBold(true);
0244             item->setFont(0, font);
0245             item->parent()->setExpanded(true);
0246         }
0247 
0248         item->setText(0, flashCookie.name + suffix);
0249         item->setData(0, Qt::UserRole + 10, QVariant::fromValue(flashCookie));
0250         ui->flashCookieTree->addTopLevelItem(item);
0251 
0252         ++counter;
0253         if (counter > 200) {
0254             QApplication::processEvents();
0255             counter = 0;
0256         }
0257 
0258         if (!guard) {
0259             break;
0260         }
0261     }
0262 
0263     QApplication::restoreOverrideCursor();
0264 }
0265 
0266 void FCM_Dialog::refreshFilters()
0267 {
0268     ui->whiteList->clear();
0269     ui->blackList->clear();
0270 
0271     ui->whiteList->addItems(m_manager->readSettings().value(QL1S("flashCookiesWhitelist")).toStringList());
0272     ui->blackList->addItems(m_manager->readSettings().value(QL1S("flashCookiesBlacklist")).toStringList());
0273 }
0274 
0275 void FCM_Dialog::addWhitelist()
0276 {
0277     const QString origin = QInputDialog::getText(this, tr("Add to whitelist"), tr("Origin:"));
0278 
0279     addWhitelist(origin);
0280 }
0281 
0282 void FCM_Dialog::addWhitelist(const QString &origin)
0283 {
0284     if (origin.isEmpty()) {
0285         return;
0286     }
0287 
0288     if (!ui->blackList->findItems(origin, Qt::MatchFixedString).isEmpty()) {
0289         QMessageBox::information(this, tr("Already whitelisted!"), tr("The server \"%1\" is already in blacklist, please remove it first.").arg(origin));
0290         return;
0291     }
0292 
0293     if (ui->whiteList->findItems(origin, Qt::MatchFixedString).isEmpty()) {
0294         ui->whiteList->addItem(origin);
0295     }
0296 }
0297 
0298 void FCM_Dialog::removeWhitelist()
0299 {
0300     delete ui->whiteList->currentItem();
0301 }
0302 
0303 void FCM_Dialog::addBlacklist()
0304 {
0305     const QString origin = QInputDialog::getText(this, tr("Add to blacklist"), tr("Origin:"));
0306 
0307     addBlacklist(origin);
0308 }
0309 
0310 void FCM_Dialog::addBlacklist(const QString &origin)
0311 {
0312     if (origin.isEmpty()) {
0313         return;
0314     }
0315 
0316     if (!ui->whiteList->findItems(origin, Qt::MatchFixedString).isEmpty()) {
0317         QMessageBox::information(this, tr("Already whitelisted!"), tr("The origin \"%1\" is already in whitelist, please remove it first.").arg(origin));
0318         return;
0319     }
0320 
0321     if (ui->blackList->findItems(origin, Qt::MatchFixedString).isEmpty()) {
0322         ui->blackList->addItem(origin);
0323     }
0324 }
0325 
0326 void FCM_Dialog::removeBlacklist()
0327 {
0328     delete ui->blackList->currentItem();
0329 }
0330 
0331 void FCM_Dialog::deletePressed()
0332 {
0333     if (ui->flashCookieTree->hasFocus()) {
0334         removeCookie();
0335     }
0336     else if (ui->whiteList->hasFocus()) {
0337         removeWhitelist();
0338     }
0339     else if (ui->blackList->hasFocus()) {
0340         removeBlacklist();
0341     }
0342 }
0343 
0344 void FCM_Dialog::autoModeChanged(bool state)
0345 {
0346     ui->notification->setEnabled(state);
0347 }
0348 
0349 void FCM_Dialog::filterString(const QString &string)
0350 {
0351     if (string.isEmpty()) {
0352         for (int i = 0; i < ui->flashCookieTree->topLevelItemCount(); ++i) {
0353             ui->flashCookieTree->topLevelItem(i)->setHidden(false);
0354             ui->flashCookieTree->topLevelItem(i)->setExpanded(ui->flashCookieTree->defaultItemShowMode() == TreeWidget::ItemsExpanded);
0355         }
0356     }
0357     else {
0358         for (int i = 0; i < ui->flashCookieTree->topLevelItemCount(); ++i) {
0359             QString text = QL1C('.') + ui->flashCookieTree->topLevelItem(i)->text(0);
0360             ui->flashCookieTree->topLevelItem(i)->setHidden(!text.contains(string, Qt::CaseInsensitive));
0361             ui->flashCookieTree->topLevelItem(i)->setExpanded(true);
0362         }
0363     }
0364 }
0365 
0366 void FCM_Dialog::reloadFromDisk()
0367 {
0368     refreshView(true);
0369 }
0370 
0371 void FCM_Dialog::cookieTreeContextMenuRequested(const QPoint &pos)
0372 {
0373     QMenu menu;
0374     QAction* actAddBlacklist = menu.addAction(tr("Add to blacklist"));
0375     QAction* actAddWhitelist = menu.addAction(tr("Add to whitelist"));
0376 
0377     QTreeWidgetItem* item = ui->flashCookieTree->itemAt(pos);
0378 
0379     if (!item) {
0380         return;
0381     }
0382 
0383     ui->flashCookieTree->setCurrentItem(item);
0384 
0385     QAction* activatedAction = menu.exec(ui->flashCookieTree->viewport()->mapToGlobal(pos));
0386 
0387     const QString origin = item->childCount() > 0 ? item->text(0)
0388                                                   : item->data(0, Qt::UserRole + 10).value<FlashCookie>().origin;
0389 
0390     if (activatedAction == actAddBlacklist) {
0391         addBlacklist(origin);
0392     }
0393     else if (activatedAction == actAddWhitelist) {
0394         addWhitelist(origin);
0395     }
0396 }
0397 
0398 void FCM_Dialog::closeEvent(QCloseEvent* e)
0399 {
0400     m_manager->clearNewOrigins();
0401 
0402     QStringList flashWhitelist;
0403     QStringList flashBlacklist;
0404 
0405     for (int i = 0; i < ui->whiteList->count(); ++i) {
0406         flashWhitelist.append(ui->whiteList->item(i)->text());
0407     }
0408 
0409     for (int i = 0; i < ui->blackList->count(); ++i) {
0410         flashBlacklist.append(ui->blackList->item(i)->text());
0411     }
0412 
0413     QVariantHash settingsHash;
0414     settingsHash.insert(QL1S("autoMode"), QVariant(ui->autoMode->isChecked()));
0415     settingsHash.insert(QL1S("deleteAllOnStartExit"), QVariant(ui->deleteAllOnStartExit->isChecked()));
0416     settingsHash.insert(QL1S("notification"), QVariant(ui->notification->isChecked()));
0417     settingsHash.insert(QL1S("flashCookiesWhitelist"), flashWhitelist);
0418     settingsHash.insert(QL1S("flashCookiesBlacklist"), flashBlacklist);
0419     m_manager->writeSettings(settingsHash);
0420 
0421     e->accept();
0422 }
0423 
0424 void FCM_Dialog::keyPressEvent(QKeyEvent* e)
0425 {
0426     if (e->key() == Qt::Key_Escape) {
0427         close();
0428     }
0429 
0430     QWidget::keyPressEvent(e);
0431 }
0432 
0433 FCM_Dialog::~FCM_Dialog()
0434 {
0435     delete ui;
0436 }