-# Copyright 2022-2023 Soren Stoutner <soren@stoutner.com>.
+# Copyright 2022-2024 Soren Stoutner <soren@stoutner.com>.
#
-# This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+# This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
#
# Privacy Browser PC is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# List the sources to include in the executable.
target_sources(privacybrowser PRIVATE
+ ViewAndCopyDelegate.cpp
ViewOnlyDelegate.cpp
)
--- /dev/null
+ /*
+ * Copyright 2024 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
+ *
+ * Privacy Browser PC 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.
+ *
+ * Privacy Browser PC 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 Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// Application headers.
+#include "ViewAndCopyDelegate.h"
+
+// Qt toolkit headers.
+#include <QLineEdit>
+
+ViewAndCopyDelegate::ViewAndCopyDelegate(QObject *parentObjectPointer) : QStyledItemDelegate(parentObjectPointer) {}
+
+QWidget* ViewAndCopyDelegate::createEditor(QWidget *parentWidgetPointer, const QStyleOptionViewItem &styleOptionViewItem, const QModelIndex &modelIndex) const
+{
+ // Instruct the compiler to ignore the unused variables.
+ (void) styleOptionViewItem;
+
+ // Get the data string from the model index.
+ QString dataString = modelIndex.data().toString();
+
+ // Create a line edit.
+ QLineEdit *lineEditPointer = new QLineEdit(dataString, parentWidgetPointer);
+
+ // Set the line edit to be read only.
+ lineEditPointer->setReadOnly(true);
+
+ // Return the line edit.
+ return lineEditPointer;
+}
--- /dev/null
+/*
+ * Copyright 2024 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
+ *
+ * Privacy Browser PC 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.
+ *
+ * Privacy Browser PC 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 Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef VIEWANDCOPYDELEGATE_H
+#define VIEWANDCOPYDELEGATE_H
+
+// Qt toolkit headers.
+#include <QStyledItemDelegate>
+
+class ViewAndCopyDelegate : public QStyledItemDelegate
+{
+ // Include the Q_OBJECT macro.
+ Q_OBJECT
+
+public:
+ // The default constructor.
+ explicit ViewAndCopyDelegate(QObject *parenObjectPointer = nullptr);
+
+ // The public functions.
+ QWidget* createEditor(QWidget *parentWidgetPointer, const QStyleOptionViewItem &styleOptionViewItem, const QModelIndex &modelIndex) const override;
+};
+#endif
/*
- * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2022, 2024 Soren Stoutner <soren@stoutner.com>.
*
- * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
*
* Privacy Browser PC is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
// Application headers.
#include "ViewOnlyDelegate.h"
-ViewOnlyDelegate::ViewOnlyDelegate(QObject *parentPointer) : QStyledItemDelegate(parentPointer) {}
+ViewOnlyDelegate::ViewOnlyDelegate(QObject *parentObjectPointer) : QStyledItemDelegate(parentObjectPointer) {}
QWidget* ViewOnlyDelegate::createEditor(QWidget *parentWidgetPointer, const QStyleOptionViewItem &styleOptionsViewItem, const QModelIndex &modelIndex) const
{
/*
- * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2022, 2024 Soren Stoutner <soren@stoutner.com>.
*
- * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
*
* Privacy Browser PC is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
public:
// The default constructor.
- explicit ViewOnlyDelegate(QObject *parentPointer = nullptr);
+ explicit ViewOnlyDelegate(QObject *parentObjectPointer = nullptr);
// The public functions.
QWidget* createEditor(QWidget *parentWidgetPointer, const QStyleOptionViewItem &styleOptionsViewItem, const QModelIndex &modelIndex) const override;
#include "FilterListsDialog.h"
#include "GlobalVariables.h"
#include "ui_FilterListsDialog.h"
+#include "delegates/ViewAndCopyDelegate.h"
// Qt toolkit headers.
#include <QFile>
sublistTableWidgetPointer = filterListsDialogUi.sublistTableWidget;
QDialogButtonBox *dialogButtonBoxPointer = filterListsDialogUi.dialogButtonBox;
+ // Create a view and copy delegate.
+ ViewAndCopyDelegate *viewAndCopyDelegate = new ViewAndCopyDelegate(this);
+
+ // Set the sublist table widget allow copying but not editing.
+ sublistTableWidgetPointer->setItemDelegate(viewAndCopyDelegate);
+
// Connect the combo boxes.
connect(filterListComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(populateFilterListTextEdit(int)));
connect(sublistComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(populateTableWidget(int)));
// Clear the sublist combo box.
sublistComboBoxPointer->clear();
- // Calculate the size of the main filter list.
+ // Calculate the size of the filter lists.
+ int mainAllowListSize = distance(filterListStructPointer->mainAllowList.begin(), filterListStructPointer->mainAllowList.end());
int mainBlockListSize = distance(filterListStructPointer->mainBlockList.begin(), filterListStructPointer->mainBlockList.end());
+ int initialDomainBlockListSize = distance(filterListStructPointer->initialDomainBlockList.begin(), filterListStructPointer->initialDomainBlockList.end());
// Get the translated filter list names.
+ QString mainAllowListName = globalFilterListHelperPointer->getSublistName(FilterListHelper::MAIN_ALLOWLIST);
QString mainBlockListName = globalFilterListHelperPointer->getSublistName(FilterListHelper::MAIN_BLOCKLIST);
+ QString initialDomainBlockListName = globalFilterListHelperPointer->getSublistName(FilterListHelper::INITIAL_DOMAIN_BLOCKLIST);
// Populate the sublist combo box.
+ sublistComboBoxPointer->addItem(i18nc("The main allow list", "%1 - %2", mainAllowListName, mainAllowListSize));
sublistComboBoxPointer->addItem(i18nc("The main block list", "%1 - %2", mainBlockListName, mainBlockListSize));
+ sublistComboBoxPointer->addItem(i18nc("The initial domain block list", "%1 - %2", initialDomainBlockListName, initialDomainBlockListSize));
}
void FilterListsDialog::populateTableWidget(int sublistComboBoxIndex) const
// Populate the filter list forward list.
switch (sublistComboBoxIndex)
{
- case 0: // Main block list.
+ case FilterListHelper::MAIN_ALLOWLIST: // The main allow list.
+ filterListForwardList = filterListStructPointer->mainAllowList;
+ break;
+
+ case FilterListHelper::MAIN_BLOCKLIST: // The main block list.
filterListForwardList = filterListStructPointer->mainBlockList;
break;
+
+ case FilterListHelper::INITIAL_DOMAIN_BLOCKLIST: // The initial domain block list.
+ filterListForwardList = filterListStructPointer->initialDomainBlockList;
+ break;
}
// Create the columns.
- sublistTableWidgetPointer->setColumnCount(2);
+ sublistTableWidgetPointer->setColumnCount(15);
// Create the table headers.
QTableWidgetItem *appliedEntryHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist applied entry header", "Applied Entry"));
+ QTableWidgetItem *thirdPartyHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist third-party header", "Third-Party"));
+ QTableWidgetItem *fontHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist font header", "Font"));
+ QTableWidgetItem *imageHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist image header", "Image"));
+ QTableWidgetItem *mainFrameHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist main frame header", "Main Frame"));
+ QTableWidgetItem *mediaHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist media header", "Media"));
+ QTableWidgetItem *objectHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist object header", "Object"));
+ QTableWidgetItem *otherHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist object header", "Other"));
+ QTableWidgetItem *pingHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist ping header", "Ping"));
+ QTableWidgetItem *scriptHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist script header", "Script"));
+ QTableWidgetItem *styleSheetHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist style sheet header", "Style Sheet"));
+ QTableWidgetItem *subFrameHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist sub frame header", "Sub Frame"));
+ QTableWidgetItem *xmlHttpRequestHeaderItemPointer = new QTableWidgetItem(i18nc("XML HTTP request header", "XML HTTP Request"));
+ QTableWidgetItem *filterOptionsHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist filter options header", "Filter Options"));
QTableWidgetItem *originalEntryHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist original entry header", "Original Entry"));
// Set the horizontal headers.
sublistTableWidgetPointer->setHorizontalHeaderItem(0, appliedEntryHeaderItemPointer);
- sublistTableWidgetPointer->setHorizontalHeaderItem(1, originalEntryHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(1, thirdPartyHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(2, fontHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(3, imageHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(4, mainFrameHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(5, mediaHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(6, objectHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(7, otherHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(8, pingHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(9, scriptHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(10, styleSheetHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(11, subFrameHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(12, xmlHttpRequestHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(13, filterOptionsHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(14, originalEntryHeaderItemPointer);
// Initialize the row counter.
int rowCounter = 0;
// Create the entry items.
QTableWidgetItem *appliedEntryItemPointer = new QTableWidgetItem(entryStructPointer->appliedEntry);
+ QTableWidgetItem *thirdPartyItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getFilterOptionDispositionString(entryStructPointer->thirdParty));
+ QTableWidgetItem *fontItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getFilterOptionDispositionString(entryStructPointer->font));
+ QTableWidgetItem *imageItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getFilterOptionDispositionString(entryStructPointer->image));
+ QTableWidgetItem *mainFrameItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getFilterOptionDispositionString(entryStructPointer->mainFrame));
+ QTableWidgetItem *mediaItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getFilterOptionDispositionString(entryStructPointer->media));
+ QTableWidgetItem *objectItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getFilterOptionDispositionString(entryStructPointer->object));
+ QTableWidgetItem *otherItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getFilterOptionDispositionString(entryStructPointer->other));
+ QTableWidgetItem *pingItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getFilterOptionDispositionString(entryStructPointer->ping));
+ QTableWidgetItem *scriptItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getFilterOptionDispositionString(entryStructPointer->script));
+ QTableWidgetItem *styleSheetItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getFilterOptionDispositionString(entryStructPointer->styleSheet));
+ QTableWidgetItem *subFrameItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getFilterOptionDispositionString(entryStructPointer->subFrame));
+ QTableWidgetItem *xmlHttpRequestItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getFilterOptionDispositionString(entryStructPointer->xmlHttpRequest));
+ QTableWidgetItem *filterOptionsItemPointer = new QTableWidgetItem(entryStructPointer->filterOptions);
QTableWidgetItem *originalEntryItemPointer = new QTableWidgetItem(entryStructPointer->originalEntry);
// Add the entries to the table.
sublistTableWidgetPointer->setItem(rowCounter, 0, appliedEntryItemPointer);
- sublistTableWidgetPointer->setItem(rowCounter, 1, originalEntryItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 1, thirdPartyItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 2, fontItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 3, imageItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 4, mainFrameItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 5, mediaItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 6, objectItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 7, otherItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 8, pingItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 9, scriptItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 10, styleSheetItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 11, subFrameItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 12, xmlHttpRequestItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 13, filterOptionsItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 14, originalEntryItemPointer);
// Increment the row counter.
++rowCounter;
#include "ui_RequestDetailDialog.h"
#include "structs/RequestStruct.h"
-// Qt toolkit headers.
-#include <QDebug>
-
// KDE Frameworks headers.
#include <KActionCollection>
#include <KColorScheme>
+// Qt toolkit headers.
+#include <QShortcut>
+
// Construct the class.
-RequestDetailDialog::RequestDetailDialog(QWidget *parentWidgetPointer, QByteArray &requestStructByteArray) : QDialog(parentWidgetPointer)
+RequestDetailDialog::RequestDetailDialog(QWidget *parentWidgetPointer, QTableWidget *tableWidgetPointer, const int initialRow) :
+ QDialog(parentWidgetPointer), currentRow(initialRow), tableWidgetPointer(tableWidgetPointer)
+{
+ // Set the window modality.
+ setWindowModality(Qt::WindowModality::ApplicationModal);
+
+ // Instantiate the request detail dialog UI.
+ Ui::RequestDetailDialog requestDetailDialogUi;
+
+ // Setup the UI.
+ requestDetailDialogUi.setupUi(this);
+
+ // Get handles for the views.
+ dispositionLineEditPointer = requestDetailDialogUi.dispositionLineEdit;
+ urlLineEditPointer = requestDetailDialogUi.urlLineEdit;
+ requestMethodLineEditPointer = requestDetailDialogUi.requestMethodLineEdit;
+ navigationTypeLineEditPointer = requestDetailDialogUi.navigationTypeLineEdit;
+ resourceTypeLineEditPointer = requestDetailDialogUi.resourceTypeLineEdit;
+ horizontalLinePointer = requestDetailDialogUi.horizontalLine;
+ filterListLabelPointer = requestDetailDialogUi.filterListLabel;
+ filterListLineEditPointer = requestDetailDialogUi.filterListLineEdit;
+ sublistLabelPointer = requestDetailDialogUi.sublistLabel;
+ sublistLineEditPointer = requestDetailDialogUi.sublistListLineEdit;
+ appliedEntryLabelPointer = requestDetailDialogUi.appliedEntryLabel;
+ appliedEntryLineEditPointer = requestDetailDialogUi.appliedEntryLineEdit;
+ originalEntryLabelPointer = requestDetailDialogUi.originalEntryLabel;
+ originalEntryLineEditPointer = requestDetailDialogUi.originalEntryLineEdit;
+ previousButtonPointer = requestDetailDialogUi.previousButton;
+ nextButtonPointer = requestDetailDialogUi.nextButton;
+ QDialogButtonBox *dialogButtonBoxPointer = requestDetailDialogUi.dialogButtonBox;
+ QPushButton *closeButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::StandardButton::Close);
+
+ // Make the close button the default.
+ closeButtonPointer->setDefault(true);
+
+ // Get the disposition line edit palettes.
+ normalBackgroundPalette = dispositionLineEditPointer->palette();
+ negativeBackgroundPalette = normalBackgroundPalette;
+ positiveBackgroundPalette = normalBackgroundPalette;
+
+ // Modify the palettes.
+ KColorScheme::adjustBackground(negativeBackgroundPalette, KColorScheme::NegativeBackground);
+ KColorScheme::adjustBackground(positiveBackgroundPalette, KColorScheme::PositiveBackground);
+
+ // Connect the buttons.
+ connect(previousButtonPointer, SIGNAL(clicked()), this, SLOT(previous()));
+ connect(nextButtonPointer, SIGNAL(clicked()), this, SLOT(next()));
+ connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(close()));
+
+ // Create the keyboard shortcuts.
+ QShortcut *previousShortcutPointer = new QShortcut(Qt::Key_Left, this);
+ QShortcut *nextShortcutPointer = new QShortcut(Qt::Key_Right, this);
+
+ // Connect the keyboard shortcuts to the buttons.
+ connect(previousShortcutPointer, SIGNAL(activated()), previousButtonPointer, SLOT(click()));
+ connect(nextShortcutPointer, SIGNAL(activated()), nextButtonPointer, SLOT(click()));
+
+ // Populate the dialog.
+ populateDialog(currentRow);
+}
+
+void RequestDetailDialog::populateDialog(const int row)
{
+ // Set the window title.
+ setWindowTitle(i18nc("The request detail dialog window title", "Request %1 Detail", row + 1));
+
+ // Select the row in the table widget (this displays the correct row highlighted in the background of the dialog).
+ tableWidgetPointer->selectRow(row);
+
+ // Get the first table widget item in the row.
+ QTableWidgetItem *rowFirstTableWidgetItemPointer = tableWidgetPointer->item(row, 0);
+
+ // Get the data variant.
+ QVariant dataVariant = rowFirstTableWidgetItemPointer->data(Qt::UserRole);
+
+ // Get the request struct byte array from the data variant.
+ QByteArray requestStructByteArray = dataVariant.toByteArray();
+
+ // Determine if previous should be enabled.
+ bool previousEnabled = (row > 0);
+
+ // Determine if next should be enabled.
+ bool nextEnabled = (row < (tableWidgetPointer->rowCount() - 1));
+
// Create a request struct data stream reader.
QDataStream requestStructDataStreamReader(requestStructByteArray);
requestStructDataStreamReader >> requestStructPointer->sublistInt;
requestStructDataStreamReader >> requestStructPointer->urlString;
- qDebug().noquote().nospace() << "Disposition: " << requestStructPointer->dispositionInt;
- qDebug().noquote().nospace() << "Applied Entry: " << requestStructPointer->entryStruct.appliedEntry;
- qDebug().noquote().nospace() << "Original Entry: " << requestStructPointer->entryStruct.originalEntry;
- qDebug().noquote().nospace() << "Filter List: " << requestStructPointer->filterListTitle;
- qDebug().noquote().nospace() << "Request Method: " << requestStructPointer->requestMethodString;
- qDebug().noquote().nospace() << "Navigation Type: " << requestStructPointer->navigationTypeInt;
- qDebug().noquote().nospace() << "Resource Type: " << requestStructPointer->resourceTypeInt;
- qDebug().noquote().nospace() << "Sublist: " << requestStructPointer->sublistInt;
- qDebug().noquote().nospace() << "URL: " << requestStructPointer->urlString;
-
- // Set the window title.
- setWindowTitle(i18nc("The request detail dialog window title", "Request Detail"));
-
- // Set the window modality.
- setWindowModality(Qt::WindowModality::ApplicationModal);
-
- // Instantiate the request detail dialog UI.
- Ui::RequestDetailDialog requestDetailDialogUi;
-
- // Setup the UI.
- requestDetailDialogUi.setupUi(this);
-
- // Get handles for the views.
- QLineEdit *dispositionLineEditPointer = requestDetailDialogUi.dispositionLineEdit;
- QLineEdit *urlLineEditPointer = requestDetailDialogUi.urlLineEdit;
- QLineEdit *requestMethodLineEditPointer = requestDetailDialogUi.requestMethodLineEdit;
- QLineEdit *navigationTypeLineEditPointer = requestDetailDialogUi.navigationTypeLineEdit;
- QLineEdit *resourceTypeLineEditPointer = requestDetailDialogUi.resourceTypeLineEdit;
- QFrame *horizontalLinePointer = requestDetailDialogUi.horizontalLine;
- QLabel *filterListLabelPointer = requestDetailDialogUi.filterListLabel;
- QLineEdit *filterListLineEditPointer = requestDetailDialogUi.filterListLineEdit;
- QLabel *sublistLabelPointer = requestDetailDialogUi.sublistLabel;
- QLineEdit *sublistLineEditPointer = requestDetailDialogUi.sublistListLineEdit;
- QLabel *appliedEntryLabelPointer = requestDetailDialogUi.appliedEntryLabel;
- QLineEdit *appliedEntryLineEditPointer = requestDetailDialogUi.appliedEntryLineEdit;
- QLabel *originalEntryLabelPointer = requestDetailDialogUi.originalEntryLabel;
- QLineEdit *originalEntryLineEditPointer = requestDetailDialogUi.originalEntryLineEdit;
- QDialogButtonBox *dialogButtonBoxPointer = requestDetailDialogUi.dialogButtonBox;
-
// Populate the views.
dispositionLineEditPointer->setText(globalFilterListHelperPointer->getDispositionString(requestStructPointer->dispositionInt));
urlLineEditPointer->setText(requestStructPointer->urlString);
appliedEntryLineEditPointer->setText(requestStructPointer->entryStruct.appliedEntry);
originalEntryLineEditPointer->setText(requestStructPointer->entryStruct.originalEntry);
- // Get the disposition line edit palettes.
- QPalette normalBackgroundPalette = dispositionLineEditPointer->palette();
- QPalette negativeBackgroundPalette = normalBackgroundPalette;
- QPalette positiveBackgroundPalette = normalBackgroundPalette;
-
- // Modify the palettes.
- KColorScheme::adjustBackground(negativeBackgroundPalette, KColorScheme::NegativeBackground);
- KColorScheme::adjustBackground(positiveBackgroundPalette, KColorScheme::PositiveBackground);
+ // Set the button status.
+ previousButtonPointer->setEnabled(previousEnabled);
+ nextButtonPointer->setEnabled(nextEnabled);
// Modify the interface based on the disposition.
switch (requestStructPointer->dispositionInt)
{
case FilterListHelper::DEFAULT:
{
- // Hide the filter list views.
+ // Reset the disposition line edit background.
+ dispositionLineEditPointer->setPalette(normalBackgroundPalette);
+
+ // Hide the views.
horizontalLinePointer->hide();
filterListLabelPointer->hide();
filterListLineEditPointer->hide();
// Colorize the disposition line edit background.
dispositionLineEditPointer->setPalette(positiveBackgroundPalette);
+ // Show the views.
+ horizontalLinePointer->show();
+ filterListLabelPointer->show();
+ filterListLineEditPointer->show();
+ sublistLabelPointer->show();
+ sublistLineEditPointer->show();
+ appliedEntryLabelPointer->show();
+ appliedEntryLineEditPointer->show();
+ originalEntryLabelPointer->show();
+ originalEntryLineEditPointer->show();
+
break;
}
// Colorize the disposition line edit background.
dispositionLineEditPointer->setPalette(negativeBackgroundPalette);
+ // Show the views.
+ horizontalLinePointer->show();
+ filterListLabelPointer->show();
+ filterListLineEditPointer->show();
+ sublistLabelPointer->show();
+ sublistLineEditPointer->show();
+ appliedEntryLabelPointer->show();
+ appliedEntryLineEditPointer->show();
+ originalEntryLabelPointer->show();
+ originalEntryLineEditPointer->show();
+
break;
}
}
+}
- // Connect the buttons.
- connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(close()));
+void RequestDetailDialog::previous()
+{
+ // Update the current row.
+ --currentRow;
+
+ // Populate the dialog.
+ populateDialog(currentRow);
+}
+
+void RequestDetailDialog::next()
+{
+ // Update the current row.
+ ++currentRow;
+
+ // Populate the dialog.
+ populateDialog(currentRow);
}
// Qt toolkit headers.
#include <QDialog>
+#include <QLabel>
+#include <QTableWidget>
class RequestDetailDialog : public QDialog
{
public:
// The primary constructor.
- explicit RequestDetailDialog(QWidget *parentWidgetPointer, QByteArray &requestStructByteArray);
+ explicit RequestDetailDialog(QWidget *parentWidgetPointer, QTableWidget *tableWidgetPointer, const int initialRow);
+
+private Q_SLOTS:
+ // The private slots.
+ void next();
+ void previous();
+
+private:
+ // The private variables.
+ QLabel *appliedEntryLabelPointer;
+ QLineEdit *appliedEntryLineEditPointer;
+ int currentRow;
+ QLineEdit *dispositionLineEditPointer;
+ QLabel *filterListLabelPointer;
+ QLineEdit *filterListLineEditPointer;
+ QFrame *horizontalLinePointer;
+ QLineEdit *navigationTypeLineEditPointer;
+ QPalette negativeBackgroundPalette;
+ QPushButton *nextButtonPointer;
+ QPalette normalBackgroundPalette;
+ QLabel *originalEntryLabelPointer;
+ QLineEdit *originalEntryLineEditPointer;
+ QPushButton *previousButtonPointer;
+ QPalette positiveBackgroundPalette;
+ QLineEdit *requestMethodLineEditPointer;
+ QLineEdit *resourceTypeLineEditPointer;
+ QLabel *sublistLabelPointer;
+ QLineEdit *sublistLineEditPointer;
+ QTableWidget *tableWidgetPointer;
+ QLineEdit *urlLineEditPointer;
+
+ // The private functions.
+ void populateDialog(const int row);
};
#endif
// Connect the buttons.
connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(close()));
- // Open the request detail dialog when
+ // Open the request detail dialog when a cell is clicked.
connect(tableWidgetPointer, SIGNAL(cellClicked(int, int)), this, SLOT(showRequestDetailDialog(int)));
}
void RequestsDialog::showRequestDetailDialog(int row)
{
- // Get the first table widget item in the row.
- QTableWidgetItem *rowFirstTableWidgetItemPointer = tableWidgetPointer->item(row, 0);
-
- // Get the data variant.
- QVariant dataVariant = rowFirstTableWidgetItemPointer->data(Qt::UserRole);
-
- // Get the request struct byte array from the data variant.
- QByteArray requestStructByteArray = dataVariant.toByteArray();
-
// Instantiate the request details dialog.
- RequestDetailDialog *requestDetailDialogPointer = new RequestDetailDialog(this, requestStructByteArray);
+ RequestDetailDialog *requestDetailDialogPointer = new RequestDetailDialog(this, tableWidgetPointer, row);
// Show the dialog.
requestDetailDialogPointer->show();
--- /dev/null
+/*
+ * Copyright 2024 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
+ *
+ * Privacy Browser PC 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.
+ *
+ * Privacy Browser PC 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 Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FILTEROPTIONENUM_H
+#define FILTEROPTIONENUM_H
+
+struct FilterOptionEnum
+{
+ enum Disposition
+ {
+ Null = 0,
+ Apply = 1,
+ Override = 2,
+ };
+};
+#endif
// Application headers.
#include "FilterListHelper.h"
+#include "structs/OverrideStruct.h"
// Qt toolkit headers.
#include <QDebug>
ALLOWED_STRING = i18nc("Allowed disposition", "Allowed");
BLOCKED_STRING = i18nc("Blocked disposition", "Blocked");
+ // Populate the translated filter option disposition strings. Translated entries cannot be public static const.
+ FILTER_OPTION_NULL = QString();
+ FILTER_OPTION_APPLY = i18nc("Apply filter option", "Apply");
+ FILTER_OPTION_OVERRIDE = i18nc("Override filter option", "Override");
+
// Populate the translated navigation type strings. Translated entries cannot be public static const.
NAVIGATION_TYPE_LINK = i18nc("Navigation type link", "Link");
NAVIGATION_TYPE_TYPED = i18nc("Navigation type typed", "Typed");
RESOURCE_TYPE_UNKNOWN = i18nc("Resource type unknown", "Unknown");
// Populate the translated sublist strings. Translated entries cannot be public static const.
+ MAIN_ALLOWLIST_STRING = i18nc("Main allowlist sublist", "Main Allow List");
MAIN_BLOCKLIST_STRING = i18nc("Main blocklist sublist", "Main Block List");
+ INITIAL_DOMAIN_BLOCKLIST_STRING = i18nc("Initial domain blocklist string", "Initial Domain Block List");
// Populate the filter lists.
ultraListStructPointer = populateFilterList(QLatin1String(":/filterlists/ultralist.txt"));
bool FilterListHelper::checkFilterLists(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer) const
{
- // Initiate a status tracker. If the tracker changes to false, all process of the request will be stopped.
- bool status = true;
+ // Initiate a continue checking tracker. If the tracker changes to false, all process of the request will be stopped.
+ bool continueChecking = true;
+
+ // Create a URL struct.
+ UrlStruct urlStruct;
+
+ // Get the URLs.
+ QUrl firstPartyUrl = urlRequestInfo.firstPartyUrl();
+ QUrl requestUrl = urlRequestInfo.requestUrl();
+
+ // Get the hosts.
+ QString firstPartyHost = firstPartyUrl.host();
+ QString requestHost = requestUrl.host();
+
+ // Determine if this is a third-party request.
+ urlStruct.isThirdPartyRequest = (firstPartyHost != requestHost);
+
+ // Get the request URL string.
+ urlStruct.urlString = requestUrl.toString();
+
+ // Create a URL string with separators.
+ urlStruct.urlStringWithSeparators = urlStruct.urlString;
+
+ // Replace the separators characters with `^`.
+ urlStruct.urlStringWithSeparators.replace(QLatin1Char(':'), QLatin1Char('^'));
+ urlStruct.urlStringWithSeparators.replace(QLatin1Char('/'), QLatin1Char('^'));
+ urlStruct.urlStringWithSeparators.replace(QLatin1Char('?'), QLatin1Char('^'));
+ urlStruct.urlStringWithSeparators.replace(QLatin1Char('='), QLatin1Char('^'));
+ urlStruct.urlStringWithSeparators.replace(QLatin1Char('&'), QLatin1Char('^'));
+
+ // Add a `^` to the end of the string.
+ urlStruct.urlStringWithSeparators.append(QLatin1Char('^'));
+
+ // Create truncated URL strings and initially populate it with the original URL strings.
+ urlStruct.truncatedUrlString = urlStruct.urlString;
+ urlStruct.truncatedUrlStringWithSeparators = urlStruct.urlStringWithSeparators;
+
+ // Get the index of the beginning of the fully qualified domain name.
+ int fqdnIndex = urlStruct.truncatedUrlString.indexOf(QLatin1String("://")) + 3;
+
+ // Truncate the URL to the beginning of the fully qualified domain name.
+ urlStruct.truncatedUrlString.remove(0, fqdnIndex);
+ urlStruct.truncatedUrlStringWithSeparators.remove(0, fqdnIndex);
// Check UltraList.
- status = checkIndividualList(urlRequestInfo, requestStructPointer, ultraListStructPointer);
+ continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, ultraListStructPointer);
- // check UltraPrivacy if the status is still true.
- if (status) {
- status = checkIndividualList(urlRequestInfo, requestStructPointer, ultraPrivacyStructPointer);
- }
+ // Check UltraPrivacy.
+ if (continueChecking)
+ continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, ultraPrivacyStructPointer);
- // Return the status.
- return status;
+ // Check EasyList.
+ if (continueChecking)
+ continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, easyListStructPointer);
+
+ // Check EasyPrivacy.
+ if (continueChecking)
+ continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, easyPrivacyStructPointer);
+
+ if (continueChecking)
+ continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, fanboyAnnoyanceStructPointer);
+
+ // Return the continue checking status.
+ return continueChecking;
}
-bool FilterListHelper::checkIndividualList(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, FilterListStruct *filterListStruct) const
+bool FilterListHelper::blockRequest(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt,
+ EntryStruct *entryStructPointer) const
{
- // Get the request URL.
- QUrl url = urlRequestInfo.requestUrl();
+ // Block the request.
+ urlRequestInfo.block(true);
- // Get the request URL string.
- QString urlString = url.toString();
+ // Populate the request struct.
+ populateRequestStruct(requestStructPointer, BLOCKED, filterListTitle, sublistInt, entryStructPointer);
+
+ // Log the block.
+ //qDebug().noquote().nospace() << "Blocked request: " << urlRequestInfo.firstPartyUrl() << ", Filter list entry: " << entryStructPointer->appliedEntry;
+
+ // Returning `false` stops all processing of the request.
+ return false;
+}
+
+bool FilterListHelper::checkIndividualList(QWebEngineUrlRequestInfo &urlRequestInfo, UrlStruct &urlStruct, RequestStruct *requestStructPointer, FilterListStruct *filterListStructPointer) const
+{
+ // Check the main allow list.
+ for (auto filterListEntry = filterListStructPointer->mainAllowList.begin(); filterListEntry != filterListStructPointer->mainAllowList.end(); ++filterListEntry)
+ {
+ // Get the entry struct.
+ EntryStruct *entryStructPointer = *filterListEntry;
+
+ // TODO. Temporarily ignore empty applied entries.
+ if (!entryStructPointer->appliedEntry.isEmpty())
+ {
+ // Check if the URL string contains the applied entry.
+ if (urlStruct.urlString.contains(entryStructPointer->appliedEntry) || urlStruct.urlStringWithSeparators.contains(entryStructPointer->appliedEntry))
+ {
+ // Allow the request.
+ urlRequestInfo.block(false);
+
+ // Populate the request struct.
+ populateRequestStruct(requestStructPointer, ALLOWED, filterListStructPointer->title, MAIN_ALLOWLIST, entryStructPointer);
+
+ // Log the allow.
+ //qDebug().noquote().nospace() << "Allowed request: " << urlStruct.urlString << ", Filter list entry: " << entryStructPointer->appliedEntry;
+
+ // Returning `false` stops all processing of the request.
+ return false;
+ }
+ }
+ }
// Check the main block list.
- for (auto filterListEntry = filterListStruct->mainBlockList.begin(); filterListEntry != filterListStruct->mainBlockList.end(); ++filterListEntry) {
+ for (auto filterListEntry = filterListStructPointer->mainBlockList.begin(); filterListEntry != filterListStructPointer->mainBlockList.end(); ++filterListEntry)
+ {
// Get the entry struct.
EntryStruct *entryStructPointer = *filterListEntry;
- // Check if the URL string contains the applied entry
- if (urlString.contains(entryStructPointer->appliedEntry)) {
- // Block the request.
- urlRequestInfo.block(true);
+ // TODO. Temporarily ignore empty applied entries.
+ if (!entryStructPointer->appliedEntry.isEmpty())
+ {
+ // Check if the URL string contains the applied entry.
+ if (urlStruct.urlString.contains(entryStructPointer->appliedEntry) || urlStruct.urlStringWithSeparators.contains(entryStructPointer->appliedEntry))
+ {
+ // Check the third-party status.
+ bool continueChecking = checkThirdParty(urlRequestInfo, requestStructPointer, urlStruct.isThirdPartyRequest, filterListStructPointer->title, MAIN_BLOCKLIST, entryStructPointer);
- // Populate the request struct.
- populateRequestStruct(requestStructPointer, BLOCKED, filterListStruct->title, MAIN_BLOCKLIST, entryStructPointer->appliedEntry, entryStructPointer->originalEntry);
+ // Stop processing the filter lists if continue checking is `false`. Returning false halts all processing at upper levels.
+ if (continueChecking == false)
+ return false;
+ }
+ }
+ }
+
+ // Check the initial domain block list.
+ for (auto filterListEntry = filterListStructPointer->initialDomainBlockList.begin(); filterListEntry != filterListStructPointer->initialDomainBlockList.end(); ++filterListEntry)
+ {
+ // Get the entry struct.
+ EntryStruct *entryStructPointer = *filterListEntry;
- // Log the block.
- //qDebug().noquote().nospace() << "Blocked request: " << urlString << ", Filter list entry: " << entryStructPointer->appliedEntry;
+ // Check if the truncated URL string begins with the applied entry.
+ if (urlStruct.truncatedUrlString.startsWith(entryStructPointer->appliedEntry) || urlStruct.truncatedUrlStringWithSeparators.startsWith(entryStructPointer->appliedEntry))
+ {
+ // Check the third-party status.
+ bool continueChecking = checkThirdParty(urlRequestInfo, requestStructPointer, urlStruct.isThirdPartyRequest, filterListStructPointer->title, INITIAL_DOMAIN_BLOCKLIST, entryStructPointer);
- // Returning `false` stops all processing of the request.
- return false;
+ // Stop processing the filter lists if continue checking is `false`. Returning false halts all processing at upper levels.
+ if (continueChecking == false)
+ return false;
}
}
return true;
}
+bool FilterListHelper::checkThirdParty(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const bool isThirdPartyRequest, const QString &filterListTitle,
+ const int sublistInt, EntryStruct *entryStructPointer) const
+{
+ // Check third-party status.
+ if (entryStructPointer->thirdParty == FilterOptionEnum::Disposition::Null) // Ignore third-party status.
+ {
+ // Check if filter options are applied.
+ if (entryStructPointer->hasFilterOptions) // Filter options are applied.
+ {
+ // Process the filter options.
+ return processFilterOptions(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ else // Filter options are not applied.
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ }
+ else if ((entryStructPointer->thirdParty == FilterOptionEnum::Disposition::Apply) && isThirdPartyRequest) // Block third-party request.
+ {
+ // Check if filter options are applied.
+ if (entryStructPointer->hasFilterOptions) // Filter options are applied.
+ {
+ // Process the filter options.
+ return processFilterOptions(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ else // Filter options are not applied.
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ }
+ else if ((entryStructPointer->thirdParty == FilterOptionEnum::Disposition::Override) && !isThirdPartyRequest) // Block first-party requests.
+ {
+ // Check if filter options are applied.
+ if (entryStructPointer->hasFilterOptions) // Filter options are applied.
+ {
+ // Process the filter options.
+ return processFilterOptions(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ else // Filter options are not applied.
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ }
+
+ // Returning `true` continues to process the filter lists. Returning `false` halts all processing of the filter lists.
+ return true;
+}
+
QString FilterListHelper::getDispositionString(int dispositionInt) const
{
// Return the translated disposition string.
}
}
+QString FilterListHelper::getFilterOptionDispositionString(const FilterOptionEnum::Disposition filterOptionDisposition) const
+{
+ // Return the translated filter option disposition string.
+ switch (filterOptionDisposition)
+ {
+ case FilterOptionEnum::Disposition::Apply: return FILTER_OPTION_APPLY;
+ case FilterOptionEnum::Disposition::Override: return FILTER_OPTION_OVERRIDE;
+ default: return FILTER_OPTION_NULL;
+ }
+}
+
QString FilterListHelper::getNavigationTypeString(int navigationTypeInt) const
{
// Return the translated navigation type string.
// Return the name of the requested sublist.
switch (sublistInt)
{
+ case MAIN_ALLOWLIST: return MAIN_ALLOWLIST_STRING;
case MAIN_BLOCKLIST: return MAIN_BLOCKLIST_STRING;
+ case INITIAL_DOMAIN_BLOCKLIST: return INITIAL_DOMAIN_BLOCKLIST_STRING;
default: return QString(); // The default return should never be reached.
}
}
entryStructPointer->originalEntry = filterListString;
// Process the entry.
- if (filterListString.startsWith(QLatin1Char('['))) { // The line starts with `[`, which is the file format.
+ if (filterListString.isEmpty()) // Ignore empty lines.
+ {
+ // Do nothing.
+
+ // Log the dropping of the line.
+ //qDebug().noquote().nospace() << filterListString << " NOT added from " << filterListFileName << " (empty line).";
+ }
+ else if (filterListString.startsWith(QLatin1Char('['))) // The line starts with `[`, which is the file format.
+ {
// Do nothing.
// Log the dropping of the line.
- //qDebug().noquote().nospace() << filterListString << " NOT added from " << filterListFileName;
- } else if (filterListString.startsWith(QLatin1Char('!'))) { // The line starts with `!`, which are comments.
+ //qDebug().noquote().nospace() << filterListString << " NOT added from " << filterListFileName << " (file format).";
+ }
+ else if (filterListString.contains(QLatin1String("##")) ||
+ filterListString.contains(QLatin1String("#?#")) ||
+ filterListString.contains(QLatin1String("#@#")) ||
+ filterListString.contains(QLatin1String("#$#"))) // The line contains unimplemented content filtering.
+ {
+ // Do nothing.
+
+ // Log the dropping of the line.
+ //qDebug().noquote().nospace() << filterListString << " NOT added from " << filterListFileName << " (content filtering).";
+ }
+ else if (filterListString.startsWith(QLatin1Char('!'))) // The line starts with `!`, which are comments.
+ {
if (filterListString.startsWith(QLatin1String("! Title: "))) // The line contains the title.
{
// Add the title to the filter list struct.
// Log the dropping of the line.
//qDebug().noquote().nospace() << originalFilterListString << " NOT added from " << filterListFileName;
- } else { // Process the entry.
- // Add the applied entry to the struct.
- entryStructPointer->appliedEntry = filterListString;
+ }
+ else // Process the filter options.
+ {
+ // Split any filter options from the end of the string.
+ QStringList splitEntryStringList = filterListString.split(QLatin1Char('$'));
+
+ // Store the entry without the filter options as the filter list string.
+ filterListString = splitEntryStringList[0];
+
+ // Create a popup only filter option tracker.
+ bool popupOnlyFilterOption = false;
+
+ // Process the filter options if they exist.
+ if (splitEntryStringList.size() > 1)
+ {
+ // Store the filter options.
+ entryStructPointer->filterOptions = splitEntryStringList[1];
+
+ // Split the filter options.
+ QStringList filterOptionsList = splitEntryStringList[1].split(QLatin1Char(','));
+
+ // Check if the entry has a single popup filter option as Qt WebEngine doesn't know how to process them.
+ if ((filterOptionsList.size() == 1) && (filterOptionsList[0] == QLatin1String("popup"))) // This entry has a single popup filter option.
+ {
+ // Set the popup only filter option flag.
+ popupOnlyFilterOption = true;
+ }
+ else // This entry has filter options besides popup.
+ {
+ // Initialize an override struct.
+ OverrideStruct overrideStruct;
+
+ // Populate the filter options entries.
+ foreach (QString filterOption, filterOptionsList)
+ {
+ // Populate the third-party options.
+ if (filterOption == QLatin1String("third-party")) entryStructPointer->thirdParty = FilterOptionEnum::Disposition::Apply;
+ if (filterOption == QLatin1String("~third-party")) entryStructPointer->thirdParty = FilterOptionEnum::Disposition::Override;
+
+ // Populate the filter options.
+ if (filterOption == QLatin1String("document"))
+ {
+ // Populate the main frame option.
+ entryStructPointer->mainFrame = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("font"))
+ {
+ // Populate the font option.
+ entryStructPointer->font = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("image"))
+ {
+ // Populate the image option.
+ entryStructPointer->image = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("media"))
+ {
+ // Populate the media option.
+ entryStructPointer->media = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("object"))
+ {
+ // Populate the object option.
+ entryStructPointer->object = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("other"))
+ {
+ // Populate the other option.
+ entryStructPointer->other = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("ping"))
+ {
+ // Populate the ping option.
+ entryStructPointer->ping = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("script"))
+ {
+ // Populate the script option.
+ entryStructPointer->script = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("stylesheet"))
+ {
+ // Populate the script option.
+ entryStructPointer->styleSheet = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("subdocument"))
+ {
+ // Populate the sub resource option.
+ entryStructPointer->subFrame = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ if (filterOption == QLatin1String("xmlhttprequest"))
+ {
+ //Populate the XML HTTP request option.
+ entryStructPointer->xmlHttpRequest = FilterOptionEnum::Disposition::Apply;
+
+ // Set the filter options flag.
+ entryStructPointer->hasFilterOptions = true;
+ }
+
+ // Populate the override struct.
+ if (filterOption == QLatin1String("~document"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.mainFrame = true;
+ }
+
+ if (filterOption == QLatin1String("~font"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.font = true;
+ }
+
+ if (filterOption == QLatin1String("~image"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.image = true;
+ }
+
+ if (filterOption == QLatin1String("~media"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.media = true;
+ }
+
+ if (filterOption == QLatin1String("~object"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.object = true;
+ }
+
+ if (filterOption == QLatin1String("~other"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.other = true;
+ }
+
+ if (filterOption == QLatin1String("~ping"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.ping = true;
+ }
+
+ if (filterOption == QLatin1String("~script"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.script = true;
+ }
+
+ if (filterOption == QLatin1String("~stylesheet"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.styleSheet = true;
+ }
+
+ if (filterOption == QLatin1String("~subdocument"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.subFrame = true;
+ }
+
+ if (filterOption == QLatin1String("~xmlhttprequest"))
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.xmlHttpRequest = true;
+ }
+ }
+
+ // Apply the overrides.
+ if (overrideStruct.hasOverride)
+ {
+ // Font.
+ if (overrideStruct.font)
+ entryStructPointer->font = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->font = FilterOptionEnum::Disposition::Apply;
+
+ // Image.
+ if (overrideStruct.image)
+ entryStructPointer->image = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->image = FilterOptionEnum::Disposition::Apply;
+
+ // Main Frame (document).
+ if (overrideStruct.mainFrame)
+ entryStructPointer->mainFrame = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->mainFrame = FilterOptionEnum::Disposition::Apply;
+
+ // Media.
+ if (overrideStruct.media)
+ entryStructPointer->media = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->media = FilterOptionEnum::Disposition::Apply;
+
+ // Object.
+ if (overrideStruct.object)
+ entryStructPointer->object = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->object = FilterOptionEnum::Disposition::Apply;
+
+ // Other.
+ if (overrideStruct.other)
+ entryStructPointer->other = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->other = FilterOptionEnum::Disposition::Apply;
+
+ // Ping.
+ if (overrideStruct.ping)
+ entryStructPointer->ping = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->ping = FilterOptionEnum::Disposition::Apply;
+
+ // Script.
+ if (overrideStruct.script)
+ entryStructPointer->script = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->script = FilterOptionEnum::Disposition::Apply;
+
+ // Style Sheet.
+ if (overrideStruct.styleSheet)
+ entryStructPointer->styleSheet = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->styleSheet = FilterOptionEnum::Disposition::Apply;
+
+ // Sub Resource.
+ if (overrideStruct.subFrame)
+ entryStructPointer->subFrame = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->subFrame = FilterOptionEnum::Disposition::Apply;
+
+ // XML HTTP Request.
+ if (overrideStruct.xmlHttpRequest)
+ entryStructPointer->xmlHttpRequest = FilterOptionEnum::Disposition::Override;
+ else
+ entryStructPointer->xmlHttpRequest = FilterOptionEnum::Disposition::Apply;
+ }
+ }
+ }
+
+ // Drop entries that only have a single popup filter option as Qt WebEngine doesn't know how to process them.
+ if (popupOnlyFilterOption) // This entry has a single popup filter option.
+ {
+ // Do nothing.
+
+ // Log the dropping of the line.
+ //qDebug().noquote().nospace() << entryStructPointer->originalEntry << " NOT added from " << filterListFileName << " (single popup filter option).";
+ }
+ else if (filterListString.startsWith(QLatin1String("@@"))) // Process an allow list entry.
+ {
+ // Remove the initial `@@`.
+ filterListString.remove(0, 2);
- // Add the filter list entry struct to the main block list.
- filterListStructPointer->mainBlockList.push_front(entryStructPointer);
+ // Remove any initial and trailing asterisks.
+ removeInitialAndTrailingAsterisks(filterListString);
- // Log the addition to the filter list.
- //qDebug().noquote().nospace() << originalFilterListString << " added from " << filterListFileName;
+ // Add the applied entry to the struct.
+ entryStructPointer->appliedEntry = filterListString;
+
+ // Add the filter list entry struct to the main allow list.
+ filterListStructPointer->mainAllowList.push_front(entryStructPointer);
+
+ // Log the addition to the filter list.
+ //qDebug().noquote().nospace() << entryStructPointer->originalEntry << " added to Main Allow List from " << filterListFileName << ".";
+ }
+ else if (filterListString.startsWith(QLatin1String("||"))) // Process an initial domain allow list entry.
+ {
+ // Remove the initial `||`.
+ filterListString.remove(0, 2);
+
+ // Add the applied entry to the struct.
+ entryStructPointer->appliedEntry = filterListString;
+
+ // Add the filter list entry struct to the initial domain block list.
+ filterListStructPointer->initialDomainBlockList.push_front(entryStructPointer);
+
+ // Log the addition to the filter list.
+ //qDebug().noquote().nospace() << entryStructPointer->originalEntry << " added to Initial Domain Block List from " << filterListFileName << ".";
+ }
+ else // Process a block list entry.
+ {
+ // Remove any initial and trailing asterisks.
+ removeInitialAndTrailingAsterisks(filterListString);
+
+ // Add the applied entry to the struct.
+ entryStructPointer->appliedEntry = filterListString;
+
+ // Add the filter list entry struct to the main block list.
+ filterListStructPointer->mainBlockList.push_front(entryStructPointer);
+
+ // Log the addition to the filter list.
+ //qDebug().noquote().nospace() << entryStructPointer->originalEntry << " added to Main Block List from " << filterListFileName << ".";
+ }
}
}
return filterListStructPointer;
}
-void FilterListHelper::populateRequestStruct(RequestStruct *requestStructPointer, const int disposition, const QString &filterListTitle, const int sublistInt, const QString &appliedEntry,
- const QString &originalEntry) const
+void FilterListHelper::populateRequestStruct(RequestStruct *requestStructPointer, const int disposition, const QString &filterListTitle, const int sublistInt, EntryStruct *entryStructPointer) const
{
// Populate the request struct.
requestStructPointer->dispositionInt = disposition;
requestStructPointer->filterListTitle = filterListTitle;
requestStructPointer->sublistInt = sublistInt;
- requestStructPointer->entryStruct.appliedEntry = appliedEntry;
- requestStructPointer->entryStruct.originalEntry = originalEntry;
+ requestStructPointer->entryStruct.appliedEntry = entryStructPointer->appliedEntry;
+ requestStructPointer->entryStruct.originalEntry = entryStructPointer->originalEntry;
+}
+
+bool FilterListHelper::processFilterOptions(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt,
+ EntryStruct *entryStructPointer) const
+{
+ // Block font requests.
+ if ((entryStructPointer->font == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeFontResource))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block image requests.
+ if ((entryStructPointer->image == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeImage))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block main frame requests.
+ if ((entryStructPointer->mainFrame == FilterOptionEnum::Disposition::Apply) && ((requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeMainFrame) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeNavigationPreloadMainFrame)))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block media requests.
+ if ((entryStructPointer->media == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeMedia))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block object requests.
+ if ((entryStructPointer->object == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeObject))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block other requests.
+ if ((entryStructPointer->other == FilterOptionEnum::Disposition::Apply) && ((requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeSubResource) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeWorker) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeSharedWorker) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypePrefetch) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeFavicon) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeServiceWorker) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeCspReport) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypePluginResource) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeUnknown)))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block ping requests
+ if ((entryStructPointer->ping == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypePing))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block script requests.
+ if ((entryStructPointer->script == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeScript))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block style sheet requests.
+ if ((entryStructPointer->styleSheet == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeStylesheet))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block sub resource requests.
+ if ((entryStructPointer->subFrame == FilterOptionEnum::Disposition::Apply) && ((requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeSubFrame) ||
+ (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeNavigationPreloadSubFrame)))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Block XML HTTP requests.
+ if ((entryStructPointer->xmlHttpRequest == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeXhr))
+ {
+ // Block the request.
+ return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+
+ // Returning true continues processing the filter list.
+ return true;
+}
+
+void FilterListHelper::removeInitialAndTrailingAsterisks(QString &filterListEntry) const
+{
+ // Remove the initial asterisk if it exists.
+ if (filterListEntry.startsWith(QLatin1Char('*')))
+ filterListEntry.remove(0, 1);
+
+ // Remove the final asterisk if it exists.
+ if (filterListEntry.endsWith(QLatin1Char('*')))
+ filterListEntry.chop(1);
}
// Application headers.
#include "structs/FilterListStruct.h"
#include "structs/RequestStruct.h"
+#include "structs/UrlStruct.h"
// Qt framework headers.
#include <QString>
static const int BLOCKED = 2;
// The public static sublist constant integers.
- static const int MAIN_BLOCKLIST = 0;
+ static const int MAIN_ALLOWLIST = 0;
+ static const int MAIN_BLOCKLIST = 1;
+ static const int INITIAL_DOMAIN_BLOCKLIST = 2;
// The public variables.
FilterListStruct *easyListStructPointer;
// The public functions.
bool checkFilterLists(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer) const;
QString getDispositionString(int dispositionInt) const;
+ QString getFilterOptionDispositionString(const FilterOptionEnum::Disposition filterOptionDisposition) const;
QString getNavigationTypeString(int navigationTypeInt) const;
QString getResourceTypeString(int resourceTypeInt) const;
QString getSublistName(int sublistInt) const;
QString ALLOWED_STRING;
QString BLOCKED_STRING;
+ // The private translated filter option dispositions.
+ QString FILTER_OPTION_NULL;
+ QString FILTER_OPTION_APPLY;
+ QString FILTER_OPTION_OVERRIDE;
+
// The private translated navigation type strings.
QString NAVIGATION_TYPE_LINK;
QString NAVIGATION_TYPE_TYPED;
QString RESOURCE_TYPE_UNKNOWN;
// The private translated sublist strings.
+ QString MAIN_ALLOWLIST_STRING;
QString MAIN_BLOCKLIST_STRING;
+ QString INITIAL_DOMAIN_BLOCKLIST_STRING;
// The private functions.
- bool checkIndividualList(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, FilterListStruct *filterListStruct) const;
+ bool blockRequest(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt, EntryStruct *entryStructPointer) const;
+ bool checkIndividualList(QWebEngineUrlRequestInfo &urlRequestInfo, UrlStruct &urlStruct, RequestStruct *requestStructPointer, FilterListStruct *filterListStructPointer) const;
+ bool checkThirdParty(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const bool isThirdPartyRequest, const QString &filterListTitle, const int sublistInt,
+ EntryStruct *entryStructPointer) const;
FilterListStruct* populateFilterList(const QString &filterListFileName) const;
- void populateRequestStruct(RequestStruct *requestStructPointer, const int disposition, const QString &filterListTitle, const int sublistInt, const QString &appliedEntry,
- const QString &originalEntry) const;
+ void populateRequestStruct(RequestStruct *requestStructPointer, const int disposition, const QString &filterListTitle, const int sublistInt, EntryStruct *entryStructPointer) const;
+ bool processFilterOptions(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt,
+ EntryStruct *entryStructPointer) const;
+ void removeInitialAndTrailingAsterisks(QString &filterListEntry) const;
};
#endif
// Define the public user agent constants.
const QString UserAgentHelper::PRIVACY_BROWSER_USER_AGENT = QLatin1String("PrivacyBrowser/1.0");
const QString UserAgentHelper::FIREFOX_LINUX_USER_AGENT = QLatin1String("Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0");
-const QString UserAgentHelper::CHROMIUM_LINUX_USER_AGENT = QLatin1String("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36");
-const QString UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT = QLatin1String("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:122.0) Gecko/20100101 Firefox/122.0");
-const QString UserAgentHelper::CHROME_WINDOWS_USER_AGENT = QLatin1String("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36");
-const QString UserAgentHelper::EDGE_WINDOWS_USER_AGENT = QLatin1String("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0");
-const QString UserAgentHelper::SAFARI_MACOS_USER_AGENT = QLatin1String("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15");
+const QString UserAgentHelper::CHROMIUM_LINUX_USER_AGENT = QLatin1String("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36");
+const QString UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT = QLatin1String("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0");
+const QString UserAgentHelper::CHROME_WINDOWS_USER_AGENT = QLatin1String("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36");
+const QString UserAgentHelper::EDGE_WINDOWS_USER_AGENT = QLatin1String("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0");
+const QString UserAgentHelper::SAFARI_MACOS_USER_AGENT = QLatin1String("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_Z) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15");
// Construct the class.
UserAgentHelper::UserAgentHelper() {
- /*
+/*
* Copyright 2024 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
#ifndef ENTRYSTRUCT_H
#define ENTRYSTRUCT_H
+// Application headers.
+#include "enums/FilterOptionEnum.h"
+
// Qt toolkit headers.
#include <QString>
struct EntryStruct
{
+ // The strings.
QString appliedEntry;
+ QString filterOptions;
QString originalEntry;
+
+ // The filter options flag.
+ bool hasFilterOptions = false;
+
+ // The filter options.
+ FilterOptionEnum::Disposition font = FilterOptionEnum::Disposition::Null;
+ FilterOptionEnum::Disposition image = FilterOptionEnum::Disposition::Null;
+ FilterOptionEnum::Disposition mainFrame = FilterOptionEnum::Disposition::Null;
+ FilterOptionEnum::Disposition media = FilterOptionEnum::Disposition::Null;
+ FilterOptionEnum::Disposition object = FilterOptionEnum::Disposition::Null;
+ FilterOptionEnum::Disposition other = FilterOptionEnum::Disposition::Null;
+ FilterOptionEnum::Disposition ping = FilterOptionEnum::Disposition::Null;
+ FilterOptionEnum::Disposition script = FilterOptionEnum::Disposition::Null;
+ FilterOptionEnum::Disposition styleSheet = FilterOptionEnum::Disposition::Null;
+ FilterOptionEnum::Disposition subFrame = FilterOptionEnum::Disposition::Null;
+ FilterOptionEnum::Disposition thirdParty = FilterOptionEnum::Disposition::Null;
+ FilterOptionEnum::Disposition xmlHttpRequest = FilterOptionEnum::Disposition::Null;
};
#endif
QString title;
QString version;
QString filePath;
- std::forward_list<EntryStruct*> mainBlockList;
+ std::forward_list<EntryStruct *> mainAllowList;
+ std::forward_list<EntryStruct *> mainBlockList;
+ std::forward_list<EntryStruct *> initialDomainBlockList;
};
#endif
--- /dev/null
+/*
+ * Copyright 2024 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
+ *
+ * Privacy Browser PC 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.
+ *
+ * Privacy Browser PC 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 Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef OVERRIDESTRUCT_H
+#define OVERRIDESTRUCT_H
+
+struct OverrideStruct
+{
+ bool hasOverride = false;
+ bool font = false;
+ bool image = false;
+ bool mainFrame = false;
+ bool media = false;
+ bool object = false;
+ bool other = false;
+ bool ping = false;
+ bool script = false;
+ bool styleSheet = false;
+ bool subFrame = false;
+ bool xmlHttpRequest = false;
+};
+#endif
--- /dev/null
+/*
+ * Copyright 2024 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
+ *
+ * Privacy Browser PC 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.
+ *
+ * Privacy Browser PC 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 Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef URLSTRUCT_H
+#define URLSTRUCT_H
+
+// Qt toolkit headers.
+#include <QString>
+
+struct UrlStruct
+{
+ QString urlString;
+ QString urlStringWithSeparators;
+ QString truncatedUrlString;
+ QString truncatedUrlStringWithSeparators;
+ bool isThirdPartyRequest;
+};
+#endif
<!--
Copyright 2022 Soren Stoutner <soren@stoutner.com>.
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
<layout class="QVBoxLayout">
<!-- Main content. -->
<item>
- <layout class="QHBoxLayout">
+ <widget class="QSplitter">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+
+ <property name="handleWidth">
+ <number>5</number>
+ </property>
+
<!-- Left column. -->
- <item>
+ <widget class="QWidget">
<layout class="QVBoxLayout">
<!-- Filter list combo box. -->
<item>
<property name="readOnly">
<bool>true</bool>
</property>
+
+ <property name="lineWrapMode">
+ <enum>QTextEdit::NoWrap</enum>
+ </property>
</widget>
</item>
</layout>
- </item>
+ </widget>
<!-- Right column. -->
- <item>
+ <widget class="QWidget">
<layout class="QVBoxLayout">
<!-- Sublist combo box. -->
<item>
<!-- Sublist table. -->
<item>
<widget class="QTableWidget" name="sublistTableWidget">
- <property name="editTriggers">
- <set>QAbstractItemView::NoEditTriggers</set>
- </property>
-
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
</item>
</layout>
- </item>
- </layout>
+ </widget>
+ </widget>
</item>
<!-- Buttons. -->
<property name="readOnly">
<bool>true</bool>
</property>
+
+ <!-- Disabling focus allows the arrow keys to activate the buttons. -->
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
</widget>
</item>
</layout>
<property name="readOnly">
<bool>true</bool>
</property>
+
+ <!-- Disabling focus allows the arrow keys to activate the buttons. -->
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
</widget>
</item>
</layout>
<property name="readOnly">
<bool>true</bool>
</property>
+
+ <!-- Disabling focus allows the arrow keys to activate the buttons. -->
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
</widget>
</item>
<property name="readOnly">
<bool>true</bool>
</property>
+
+ <!-- Disabling focus allows the arrow keys to activate the buttons. -->
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
</widget>
</item>
<property name="readOnly">
<bool>true</bool>
</property>
+
+ <!-- Disabling focus allows the arrow keys to activate the buttons. -->
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
</widget>
</item>
</layout>
<property name="readOnly">
<bool>true</bool>
</property>
+
+ <!-- Disabling focus allows the arrow keys to activate the buttons. -->
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
</widget>
</item>
</layout>
<property name="readOnly">
<bool>true</bool>
</property>
+
+ <!-- Disabling focus allows the arrow keys to activate the buttons. -->
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
</widget>
</item>
</layout>
<property name="readOnly">
<bool>true</bool>
</property>
+
+ <!-- Disabling focus allows the arrow keys to activate the buttons. -->
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
</widget>
</item>
</layout>
<property name="readOnly">
<bool>true</bool>
</property>
+
+ <!-- Disabling focus allows the arrow keys to activate the buttons. -->
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
</widget>
</item>
</layout>
</spacer>
</item>
- <!-- Close button - dialog button box. -->
<item>
- <widget class="QDialogButtonBox" name="dialogButtonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Close</set>
- </property>
- </widget>
+ <layout class="QHBoxLayout">
+ <!-- Previous button. -->
+ <item>
+ <widget class="QPushButton" name="previousButton">
+ <property name="text">
+ <string>Previous</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="go-previous" />
+ </property>
+ </widget>
+ </item>
+
+ <!-- Next button. -->
+ <item>
+ <widget class="QPushButton" name="nextButton">
+ <property name="text">
+ <string>Next</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="go-next" />
+ </property>
+ </widget>
+ </item>
+
+ <!-- Close button - dialog button box. -->
+ <item>
+ <widget class="QDialogButtonBox" name="dialogButtonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
</layout>
</widget>
<!-- Requests table. -->
<item>
<widget class="QTableWidget" name="tableWidget">
- <property name="editTriggers">
- <set>QAbstractItemView::NoEditTriggers</set>
- </property>
-
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2022 Soren Stoutner <soren@stoutner.com>.
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "TabWidget.h"
#include "Settings.h"
#include "ui_AddTabWidget.h"
-#include "ui_Tab.h"
#include "ui_TabWidget.h"
#include "databases/CookiesDatabase.h"
#include "dialogs/SaveDialog.h"
#include <QPrintDialog>
#include <QPrintPreviewDialog>
#include <QPrinter>
+#include <QSplitter>
// Initialize the public static variables.
QString TabWidget::webEngineDefaultUserAgent = QLatin1String("");