uis/DurableCookiesDialog.ui
uis/EditBookmarkDialog.ui
uis/EditFolderDialog.ui
+ uis/FilterEntryDialog.ui
uis/FilterListsDialog.ui
uis/HttpAuthenticationDialog.ui
uis/RequestDetailDialog.ui
# 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
DurableCookiesDialog.cpp
EditBookmarkDialog.cpp
EditFolderDialog.cpp
+ FilterEntryDialog.cpp
FilterListsDialog.cpp
HttpAuthenticationDialog.cpp
RequestDetailDialog.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 "FilterEntryDialog.h"
+#include "GlobalVariables.h"
+#include "ui_FilterEntryDialog.h"
+
+// KDE Framework headers.
+#include <KColorScheme>
+
+// Qt toolkit headers.
+#include <QShortcut>
+
+// Construct the class.
+FilterEntryDialog::FilterEntryDialog(QWidget *parentWidgetPointer, QTableWidget *tableWidgetPointer, const int initialRow, const QString &filterListTitle, const QString &sublistTitle) :
+ QDialog(parentWidgetPointer), currentRow(initialRow), tableWidgetPointer(tableWidgetPointer)
+{
+ // Set the window modality.
+ setWindowModality(Qt::WindowModality::ApplicationModal);
+
+ // Instantiate the filter entry dialog UI.
+ Ui::FilterEntryDialog filterEntryDialogUi;
+
+ // Setup the UI.
+ filterEntryDialogUi.setupUi(this);
+
+ // Get handles for the views.
+ QLineEdit *filterListLineEditPointer = filterEntryDialogUi.filterListLineEdit;
+ QLineEdit *sublistLineEditPointer = filterEntryDialogUi.sublistListLineEdit;
+ appliedEntryListLineEditPointer = filterEntryDialogUi.appliedEntryListLineEdit;
+ initialMatchLineEditPointer = filterEntryDialogUi.initialMatchLineEdit;
+ finalMatchLineEditPointer = filterEntryDialogUi.finalMatchLineEdit;
+ domainLineEditPointer = filterEntryDialogUi.domainLineEdit;
+ domainListLineEditPointer = filterEntryDialogUi.domainListLineEdit;
+ thirdPartyLineEditPointer = filterEntryDialogUi.thirdPartyLineEdit;
+ hasRequestOptionsCheckBoxPointer = filterEntryDialogUi.hasRequestOptionsCheckBox;
+ fontLineEditPointer = filterEntryDialogUi.fontLineEdit;
+ imageLineEditPointer = filterEntryDialogUi.imageLineEdit;
+ mainFrameLineEditPointer = filterEntryDialogUi.mainFrameLineEdit;
+ mediaLineEditPointer = filterEntryDialogUi.mediaLineEdit;
+ objectLineEditPointer = filterEntryDialogUi.objectLineEdit;
+ otherLineEditPointer = filterEntryDialogUi.otherLineEdit;
+ pingLineEditPointer = filterEntryDialogUi.pingLineEdit;
+ scriptLineEditPointer = filterEntryDialogUi.scriptLineEdit;
+ styleSheetLineEditPointer = filterEntryDialogUi.styleSheetLineEdit;
+ subFrameLineEditPointer = filterEntryDialogUi.subFrameLineEdit;
+ xmlHttpRequestLineEditPointer = filterEntryDialogUi.xmlHttpRequestLineEdit;
+ appliedFilterOptionsLineEditPointer = filterEntryDialogUi.appliedFilterOptionsLineEdit;
+ originalFilterOptionsLineEditPointer = filterEntryDialogUi.originalFilterOptionsLineEdit;
+ originalEntryLineEditPointer = filterEntryDialogUi.originalEntryLineEdit;
+ previousButtonPointer = filterEntryDialogUi.previousButton;
+ nextButtonPointer = filterEntryDialogUi.nextButton;
+ QDialogButtonBox *dialogButtonBoxPointer = filterEntryDialogUi.dialogButtonBox;
+ QPushButton *closeButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::StandardButton::Close);
+
+ // Populate the views.
+ filterListLineEditPointer->setText(filterListTitle);
+ sublistLineEditPointer->setText(sublistTitle);
+
+ // Disable changing the checkbox checked status.
+ hasRequestOptionsCheckBoxPointer->setAttribute(Qt::WA_TransparentForMouseEvents);
+
+ // Make the close button the default.
+ closeButtonPointer->setDefault(true);
+
+ // Get the disposition line edit palettes.
+ normalBackgroundPalette = appliedEntryListLineEditPointer->palette();
+ negativeBackgroundPalette = normalBackgroundPalette;
+ positiveBackgroundPalette = normalBackgroundPalette;
+
+ // Modify the palettes.
+ KColorScheme::adjustBackground(negativeBackgroundPalette, KColorScheme::NegativeBackground);
+ KColorScheme::adjustBackground(positiveBackgroundPalette, KColorScheme::PositiveBackground);
+
+ // Set the sublist background palette. TODO Add logic for allow lists.
+ sublistLineEditPointer->setPalette(negativeBackgroundPalette);
+
+ // Set the applied entry background palette to be the same as the sublist.
+ appliedEntryListLineEditPointer->setPalette(sublistLineEditPointer->palette());
+
+ // 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 FilterEntryDialog::populateDialog(const int row)
+{
+ // Set the window title.
+ setWindowTitle(i18nc("The filter entry dialog window title", "Filter Entry %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);
+
+ // Determine if previous should be enabled.
+ bool previousEnabled = (row > 0);
+
+ // Determine if next should be enabled.
+ bool nextEnabled = (row < (tableWidgetPointer->rowCount() - 1));
+
+ // Populate the line edits.
+ appliedEntryListLineEditPointer->setText(tableWidgetPointer->item(row, 0)->text());
+ initialMatchLineEditPointer->setText(tableWidgetPointer->item(row, 1)->text());
+ finalMatchLineEditPointer->setText(tableWidgetPointer->item(row, 2)->text());
+ domainLineEditPointer->setText(tableWidgetPointer->item(row, 3)->text());
+ domainListLineEditPointer->setText(tableWidgetPointer->item(row, 4)->text());
+ thirdPartyLineEditPointer->setText(tableWidgetPointer->item(row, 5)->text());
+ fontLineEditPointer->setText(tableWidgetPointer->item(row, 7)->text());
+ imageLineEditPointer->setText(tableWidgetPointer->item(row, 8)->text());
+ mainFrameLineEditPointer->setText(tableWidgetPointer->item(row, 9)->text());
+ mediaLineEditPointer->setText(tableWidgetPointer->item(row, 10)->text());
+ objectLineEditPointer->setText(tableWidgetPointer->item(row, 11)->text());
+ otherLineEditPointer->setText(tableWidgetPointer->item(row, 12)->text());
+ pingLineEditPointer->setText(tableWidgetPointer->item(row, 13)->text());
+ scriptLineEditPointer->setText(tableWidgetPointer->item(row, 14)->text());
+ styleSheetLineEditPointer->setText(tableWidgetPointer->item(row, 15)->text());
+ subFrameLineEditPointer->setText(tableWidgetPointer->item(row, 16)->text());
+ xmlHttpRequestLineEditPointer->setText(tableWidgetPointer->item(row, 17)->text());
+ appliedFilterOptionsLineEditPointer->setText(tableWidgetPointer->item(row, 18)->text());
+ originalFilterOptionsLineEditPointer->setText(tableWidgetPointer->item(row, 19)->text());
+ originalEntryLineEditPointer->setText(tableWidgetPointer->item(row, 20)->text());
+
+ // Populate the check boxes.
+ hasRequestOptionsCheckBoxPointer->setChecked(tableWidgetPointer->item(row, 6)->text() == i18n("Yes"));
+
+ // Set the initial and final match background palettes.
+ setInitialAndFinalMatchBackgroundPalette(initialMatchLineEditPointer);
+ setInitialAndFinalMatchBackgroundPalette(finalMatchLineEditPointer);
+
+ // Set the request option background palettes and status.
+ setFilterOptionBackgroundPalette(domainLineEditPointer);
+ setFilterOptionBackgroundPalette(thirdPartyLineEditPointer);
+ setFilterOptionBackgroundPalette(fontLineEditPointer);
+ setFilterOptionBackgroundPalette(imageLineEditPointer);
+ setFilterOptionBackgroundPalette(mainFrameLineEditPointer);
+ setFilterOptionBackgroundPalette(mediaLineEditPointer);
+ setFilterOptionBackgroundPalette(objectLineEditPointer);
+ setFilterOptionBackgroundPalette(otherLineEditPointer);
+ setFilterOptionBackgroundPalette(pingLineEditPointer);
+ setFilterOptionBackgroundPalette(scriptLineEditPointer);
+ setFilterOptionBackgroundPalette(styleSheetLineEditPointer);
+ setFilterOptionBackgroundPalette(subFrameLineEditPointer);
+ setFilterOptionBackgroundPalette(xmlHttpRequestLineEditPointer);
+
+ // Set the request option status.
+ fontLineEditPointer->setEnabled(hasRequestOptionsCheckBoxPointer->isChecked());
+ imageLineEditPointer->setEnabled(hasRequestOptionsCheckBoxPointer->isChecked());
+ mainFrameLineEditPointer->setEnabled(hasRequestOptionsCheckBoxPointer->isChecked());
+ mediaLineEditPointer->setEnabled(hasRequestOptionsCheckBoxPointer->isChecked());
+ objectLineEditPointer->setEnabled(hasRequestOptionsCheckBoxPointer->isChecked());
+ otherLineEditPointer->setEnabled(hasRequestOptionsCheckBoxPointer->isChecked());
+ pingLineEditPointer->setEnabled(hasRequestOptionsCheckBoxPointer->isChecked());
+ scriptLineEditPointer->setEnabled(hasRequestOptionsCheckBoxPointer->isChecked());
+ styleSheetLineEditPointer->setEnabled(hasRequestOptionsCheckBoxPointer->isChecked());
+ subFrameLineEditPointer->setEnabled(hasRequestOptionsCheckBoxPointer->isChecked());
+ xmlHttpRequestLineEditPointer->setEnabled(hasRequestOptionsCheckBoxPointer->isChecked());
+
+ // Set the domain list line edit to have the same palette as the domain line edit.
+ domainListLineEditPointer->setPalette(domainLineEditPointer->palette());
+
+ // Set the button status.
+ previousButtonPointer->setEnabled(previousEnabled);
+ nextButtonPointer->setEnabled(nextEnabled);
+}
+
+void FilterEntryDialog::previous()
+{
+ // Update the current row.
+ --currentRow;
+
+ // Populate the dialog.
+ populateDialog(currentRow);
+}
+
+void FilterEntryDialog::next()
+{
+ // Update the current row.
+ ++currentRow;
+
+ // Populate the dialog.
+ populateDialog(currentRow);
+}
+
+void FilterEntryDialog::setFilterOptionBackgroundPalette(QLineEdit *lineEditPointer)
+{
+ // Set the background palette according to the text.
+ if (lineEditPointer->text() == globalFilterListHelperPointer->getRequestOptionDispositionString(FilterOptionEnum::Disposition::Null)) // Not text is displayed.
+ {
+ // Set the normal background palette.
+ lineEditPointer->setPalette(normalBackgroundPalette);
+ }
+ else if (lineEditPointer->text() == globalFilterListHelperPointer->getRequestOptionDispositionString(FilterOptionEnum::Disposition::Apply)) // `Apply` is displayed.
+ {
+ // Set the negative (red) background palette.
+ lineEditPointer->setPalette(negativeBackgroundPalette);
+ }
+ else // `Override` is displayed.
+ {
+ // Set the positive (green) background palette.
+ lineEditPointer->setPalette(positiveBackgroundPalette);
+ }
+}
+
+void FilterEntryDialog::setInitialAndFinalMatchBackgroundPalette(QLineEdit *lineEditPointer)
+{
+ // Set the background palette according to the text.
+ if (lineEditPointer->text() == i18n("Yes")) // `Yes` is displayed.
+ {
+ // Set the negative (red) background palette.
+ lineEditPointer->setPalette(negativeBackgroundPalette);
+ }
+ else // No text is displayed.
+ {
+ // Set the normal background palette.
+ lineEditPointer->setPalette(normalBackgroundPalette);
+ }
+}
--- /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 FILTERENTRYDIALOG_H
+#define FILTERENTRYDIALOG_H
+
+// Qt toolkit headers.
+#include <QCheckBox>
+#include <QDialog>
+#include <QTableWidget>
+
+class FilterEntryDialog : public QDialog
+{
+ // Include the Q_OBJECT macro.
+ Q_OBJECT
+
+public:
+ // The primary constructor.
+ explicit FilterEntryDialog(QWidget *parentWidgetPointer, QTableWidget *tableWidgetPointer, const int initialRow, const QString &filterListTitle, const QString &sublistTitle);
+
+private Q_SLOTS:
+ // The private slots.
+ void next();
+ void previous();
+
+private:
+ // The private variables.
+ QLineEdit *appliedEntryListLineEditPointer;
+ QLineEdit *appliedFilterOptionsLineEditPointer;
+ int currentRow;
+ QLineEdit *domainLineEditPointer;
+ QLineEdit *domainListLineEditPointer;
+ QLineEdit *finalMatchLineEditPointer;
+ QLineEdit *fontLineEditPointer;
+ QCheckBox *hasRequestOptionsCheckBoxPointer;
+ QLineEdit *imageLineEditPointer;
+ QLineEdit *initialMatchLineEditPointer;
+ QLineEdit *mainFrameLineEditPointer;
+ QLineEdit *mediaLineEditPointer;
+ QPalette negativeBackgroundPalette;
+ QPushButton *nextButtonPointer;
+ QPalette normalBackgroundPalette;
+ QLineEdit *objectLineEditPointer;
+ QLineEdit *originalEntryLineEditPointer;
+ QLineEdit *originalFilterOptionsLineEditPointer;
+ QLineEdit *otherLineEditPointer;
+ QLineEdit *pingLineEditPointer;
+ QPalette positiveBackgroundPalette;
+ QPushButton *previousButtonPointer;
+ QLineEdit *scriptLineEditPointer;
+ QLineEdit *styleSheetLineEditPointer;
+ QLineEdit *subFrameLineEditPointer;
+ QTableWidget *tableWidgetPointer;
+ QLineEdit *thirdPartyLineEditPointer;
+ QLineEdit *xmlHttpRequestLineEditPointer;
+
+ // The private functions.
+ void populateDialog(const int row);
+ void setFilterOptionBackgroundPalette(QLineEdit *lineEditPointer);
+ void setInitialAndFinalMatchBackgroundPalette(QLineEdit *lineEditPointer);
+};
+#endif
#include "FilterListsDialog.h"
#include "GlobalVariables.h"
#include "ui_FilterListsDialog.h"
-#include "delegates/ViewAndCopyDelegate.h"
+#include "dialogs/FilterEntryDialog.h"
// Qt toolkit headers.
+#include <QDebug>
#include <QFile>
#include <QTextStream>
sublistTableWidgetPointer = filterListsDialogUi.sublistTableWidget;
QDialogButtonBox *dialogButtonBoxPointer = filterListsDialogUi.dialogButtonBox;
- // Create a view and copy delegate.
- ViewAndCopyDelegate *viewAndCopyDelegate = new ViewAndCopyDelegate(this);
+ // Select an entire row at a time.
+ sublistTableWidgetPointer->setSelectionBehavior(QAbstractItemView::SelectRows);
- // Set the sublist table widget allow copying but not editing.
- sublistTableWidgetPointer->setItemDelegate(viewAndCopyDelegate);
+ // Open the filter entry dialog when a cell is clicked.
+ connect(sublistTableWidgetPointer, SIGNAL(cellClicked(int, int)), this, SLOT(showFilterEntryDialog(int)));
// Connect the combo boxes.
connect(filterListComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(populateFilterListTextEdit(int)));
connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(close()));
// Populate the filter list combo box.
- populateFilterListComboBox(globalFilterListHelperPointer->ultraListStructPointer);
populateFilterListComboBox(globalFilterListHelperPointer->ultraPrivacyStructPointer);
- populateFilterListComboBox(globalFilterListHelperPointer->easyListStructPointer);
+ populateFilterListComboBox(globalFilterListHelperPointer->ultraListStructPointer);
populateFilterListComboBox(globalFilterListHelperPointer->easyPrivacyStructPointer);
+ populateFilterListComboBox(globalFilterListHelperPointer->easyListStructPointer);
populateFilterListComboBox(globalFilterListHelperPointer->fanboyAnnoyanceStructPointer);
}
-void FilterListsDialog::populateFilterListComboBox(const FilterListStruct *filterListStructPointer) const
+std::forward_list<EntryStruct *>* FilterListsDialog::getFilterListForwardList(FilterListStruct *filterListStructPointer) const
{
- // Populate the filter list combo box.
- filterListComboBoxPointer->addItem(i18nc("Filter list combo box items", "%1 - %2", filterListStructPointer->title, filterListStructPointer->version));
+ // Return the filter list forward list.
+ switch (sublistComboBoxPointer->currentIndex())
+ {
+ case FilterListHelper::MAIN_ALLOWLIST: return filterListStructPointer->mainAllowListPointer; // The main allow list.
+ case FilterListHelper::MAIN_BLOCKLIST: return filterListStructPointer->mainBlockListPointer; // The main block list.
+ case FilterListHelper::INITIAL_DOMAIN_BLOCKLIST: return filterListStructPointer->initialDomainBlockListPointer; // The initial domain block list.
+ case FilterListHelper::REGULAR_EXPRESSION_BLOCKLIST: return filterListStructPointer->regularExpressionBlockListPointer; // The regular expression block list.
+ }
+
+ // This return statement should never be reached.
+ return new std::forward_list<EntryStruct *>;
}
-void FilterListsDialog::populateFilterListTextEdit(int filterListComboBoxInt) const
+FilterListStruct *FilterListsDialog::getFilterListStruct(int filterListComboBoxIndex) const
{
- // Create the filter list struct pointer.
- FilterListStruct *filterListStructPointer;
-
- // Get the indicated filter list map.
- switch (filterListComboBoxInt)
+ // Return the filer list struct.
+ switch (filterListComboBoxIndex)
{
- case 0: // UltraList.
- filterListStructPointer = globalFilterListHelperPointer->ultraListStructPointer;
- break;
-
- case 1: // UltraPrivacy.
- filterListStructPointer = globalFilterListHelperPointer->ultraPrivacyStructPointer;
- break;
+ case 0: return globalFilterListHelperPointer->ultraPrivacyStructPointer; // UltraPrivacy.
+ case 1: return globalFilterListHelperPointer->ultraListStructPointer; // UltraList.
+ case 2: return globalFilterListHelperPointer->easyPrivacyStructPointer; // EasyPrivacy.
+ case 3: return globalFilterListHelperPointer->easyListStructPointer; // EasyList.
+ case 4: return globalFilterListHelperPointer->fanboyAnnoyanceStructPointer; // Fanboy's Annoyance List.
+ }
- case 2: // EasyList.
- filterListStructPointer = globalFilterListHelperPointer->easyListStructPointer;
- break;
+ // This return statement should never be reached.
+ return new FilterListStruct;
+}
- case 3: // EasyPrivacy.
- filterListStructPointer = globalFilterListHelperPointer->easyPrivacyStructPointer;
- break;
+void FilterListsDialog::populateFilterListComboBox(const FilterListStruct *filterListStructPointer) const
+{
+ // Populate the filter list combo box.
+ filterListComboBoxPointer->addItem(i18nc("Filter list combo box items", "%1 - %2", filterListStructPointer->title, filterListStructPointer->version));
+}
- case 4: // Fanboy's Annoyance List.
- filterListStructPointer = globalFilterListHelperPointer->fanboyAnnoyanceStructPointer;
- break;
- }
+void FilterListsDialog::populateFilterListTextEdit(int filterListComboBoxIndex) const
+{
+ // Get the filter list struct.
+ FilterListStruct *filterListStructPointer = getFilterListStruct(filterListComboBoxIndex);
// Get the filter list file.
QFile filterListFile(filterListStructPointer->filePath);
sublistComboBoxPointer->clear();
// 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());
+ int mainAllowListSize = distance(filterListStructPointer->mainAllowListPointer->begin(), filterListStructPointer->mainAllowListPointer->end());
+ int mainBlockListSize = distance(filterListStructPointer->mainBlockListPointer->begin(), filterListStructPointer->mainBlockListPointer->end());
+ int initialDomainBlockListSize = distance(filterListStructPointer->initialDomainBlockListPointer->begin(), filterListStructPointer->initialDomainBlockListPointer->end());
+ int regularExpressionBlockListSize = distance(filterListStructPointer->regularExpressionBlockListPointer->begin(), filterListStructPointer->regularExpressionBlockListPointer->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);
+ QString regularExpressionBlockListName = globalFilterListHelperPointer->getSublistName(FilterListHelper::REGULAR_EXPRESSION_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));
+ sublistComboBoxPointer->addItem(i18nc("the regular expression block list", "%1 - %2", regularExpressionBlockListName, regularExpressionBlockListSize));
}
void FilterListsDialog::populateTableWidget(int sublistComboBoxIndex) const
{
- // Wipe the current table.
- sublistTableWidgetPointer->clear();
- sublistTableWidgetPointer->setColumnCount(0);
- sublistTableWidgetPointer->setRowCount(0);
-
- // Create the filter list struct.
- FilterListStruct *filterListStructPointer;
-
- // Populate the filer list array.
- switch (filterListComboBoxPointer->currentIndex())
- {
- case 0: // UltraList.
- filterListStructPointer = globalFilterListHelperPointer->ultraListStructPointer;
- break;
-
- case 1: // UltraPrivacy.
- filterListStructPointer = globalFilterListHelperPointer->ultraPrivacyStructPointer;
- break;
-
- case 2: // EasyList.
- filterListStructPointer = globalFilterListHelperPointer->easyListStructPointer;
- break;
-
- case 3: // EasyPrivacy.
- filterListStructPointer = globalFilterListHelperPointer->easyPrivacyStructPointer;
- break;
-
- case 4: // Fanboy's Annoyance List.
- filterListStructPointer = globalFilterListHelperPointer->fanboyAnnoyanceStructPointer;
- break;
- }
-
- // Create a filter list forward list.
- std::forward_list<EntryStruct *> filterListForwardList;
-
- // Populate the filter list forward list.
- switch (sublistComboBoxIndex)
+ // Populate the table widget if there is at least one item in teh sublist combo box.
+ if (sublistComboBoxIndex >= 0)
{
- 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;
+ // Wipe the current table.
+ sublistTableWidgetPointer->clear();
+ sublistTableWidgetPointer->setColumnCount(0);
+ sublistTableWidgetPointer->setRowCount(0);
+
+ // Get the filter list struct.
+ FilterListStruct *filterListStructPointer = getFilterListStruct(filterListComboBoxPointer->currentIndex());
+
+ // Create a filter list forward list.
+ std::forward_list<EntryStruct *> *filterListForwardListPointer;
+
+ // Populate the filter list forward list.
+ switch (sublistComboBoxIndex)
+ {
+ case FilterListHelper::MAIN_ALLOWLIST: // The main allow list.
+ filterListForwardListPointer = filterListStructPointer->mainAllowListPointer;
+ break;
+
+ case FilterListHelper::MAIN_BLOCKLIST: // The main block list.
+ filterListForwardListPointer = filterListStructPointer->mainBlockListPointer;
+ break;
+
+ case FilterListHelper::INITIAL_DOMAIN_BLOCKLIST: // The initial domain block list.
+ filterListForwardListPointer = filterListStructPointer->initialDomainBlockListPointer;
+ break;
+
+ case FilterListHelper::REGULAR_EXPRESSION_BLOCKLIST: // the regular expression block list.
+ filterListForwardListPointer = filterListStructPointer->regularExpressionBlockListPointer;
+ break;
+ }
+
+ // Create the columns.
+ sublistTableWidgetPointer->setColumnCount(21);
+
+ // Create the table headers.
+ QTableWidgetItem *appliedEntryListHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist applied entry list header", "Applied Entry List"));
+ QTableWidgetItem *initialMatchHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist initial match header", "Initial Match"));
+ QTableWidgetItem *finalMatchHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist final match header", "Final Match"));
+ QTableWidgetItem *domainHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist domain header", "Domain"));
+ QTableWidgetItem *domainListHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist domain list Header", "Domain List"));
+ QTableWidgetItem *thirdPartyHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist third-party header", "Third Party"));
+ QTableWidgetItem *hasRequestOptionsHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist has request options header", "Has Request Options"));
+ 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("Sublist XML HTTP request header", "XML HTTP Request"));
+ QTableWidgetItem *appliedFilterOptionsHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist applied filter options header", "Applied Filter Options"));
+ QTableWidgetItem *originalFilterOptionsHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist original filter options header", "Original Filter Options"));
+ QTableWidgetItem *originalEntryHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist original entry header", "Original Entry"));
+
+ // Set the horizontal headers.
+ sublistTableWidgetPointer->setHorizontalHeaderItem(0, appliedEntryListHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(1, initialMatchHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(2, finalMatchHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(3, domainHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(4, domainListHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(5, thirdPartyHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(6, hasRequestOptionsHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(7, fontHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(8, imageHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(9, mainFrameHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(10, mediaHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(11, objectHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(12, otherHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(13, pingHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(14, scriptHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(15, styleSheetHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(16, subFrameHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(17, xmlHttpRequestHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(18, appliedFilterOptionsHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(19, originalFilterOptionsHeaderItemPointer);
+ sublistTableWidgetPointer->setHorizontalHeaderItem(20, originalEntryHeaderItemPointer);
+
+ // Initialize the row counter.
+ int rowCounter = 0;
+
+ // Populate the table.
+ for (auto filterListEntry = filterListForwardListPointer->begin(); filterListEntry != filterListForwardListPointer->end(); ++filterListEntry) {
+ // Get the entry struct.
+ EntryStruct *entryStructPointer = *filterListEntry;
+
+ // Add a new row.
+ sublistTableWidgetPointer->insertRow(rowCounter);
+
+ // Create the entry items.
+ QTableWidgetItem *appliedEntryListItemPointer = new QTableWidgetItem(entryStructPointer->appliedEntryList.join(QLatin1String(" * ")));
+ QTableWidgetItem *initialMatchItemPointer = new QTableWidgetItem(entryStructPointer->initialMatch ? i18n("Yes") : QLatin1String());
+ QTableWidgetItem *finalMatchItemPointer = new QTableWidgetItem(entryStructPointer->finalMatch ? i18n("Yes") : QLatin1String());
+ QTableWidgetItem *domainItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->domain));
+ QTableWidgetItem *domainListItemPointer = new QTableWidgetItem(entryStructPointer->domainList.join(QLatin1String(" | ")));
+ QTableWidgetItem *thirdPartyItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->thirdParty));
+ QTableWidgetItem *hasRequestOptionsItemPointer = new QTableWidgetItem(entryStructPointer->hasRequestOptions ? i18n("Yes") : QLatin1String());
+ QTableWidgetItem *fontItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->font));
+ QTableWidgetItem *imageItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->image));
+ QTableWidgetItem *mainFrameItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->mainFrame));
+ QTableWidgetItem *mediaItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->media));
+ QTableWidgetItem *objectItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->object));
+ QTableWidgetItem *otherItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->other));
+ QTableWidgetItem *pingItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->ping));
+ QTableWidgetItem *scriptItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->script));
+ QTableWidgetItem *styleSheetItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->styleSheet));
+ QTableWidgetItem *subFrameItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->subFrame));
+ QTableWidgetItem *xmlHttpRequestItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->xmlHttpRequest));
+ QTableWidgetItem *appliedFilterOptionsItemPointer = new QTableWidgetItem(entryStructPointer->appliedFilterOptionsList.join(QLatin1String(" , ")));
+ QTableWidgetItem *originalFilterOptionsItemPointer = new QTableWidgetItem(entryStructPointer->originalFilterOptions);
+ QTableWidgetItem *originalEntryItemPointer = new QTableWidgetItem(entryStructPointer->originalEntry);
+
+ // Add the entries to the table.
+ sublistTableWidgetPointer->setItem(rowCounter, 0, appliedEntryListItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 1, initialMatchItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 2, finalMatchItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 3, domainItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 4, domainListItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 5, thirdPartyItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 6, hasRequestOptionsItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 7, fontItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 8, imageItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 9, mainFrameItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 10, mediaItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 11, objectItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 12, otherItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 13, pingItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 14, scriptItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 15, styleSheetItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 16, subFrameItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 17, xmlHttpRequestItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 18, appliedFilterOptionsItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 19, originalFilterOptionsItemPointer);
+ sublistTableWidgetPointer->setItem(rowCounter, 20, originalEntryItemPointer);
+
+ // Increment the row counter.
+ ++rowCounter;
+ }
+
+ // Get the table header view.
+ QHeaderView *headerViewPointer = sublistTableWidgetPointer->horizontalHeader();
+
+ // Resize the header to fit the contents.
+ headerViewPointer->resizeSections(QHeaderView::ResizeToContents);
+
+ // Connect changes in the sort order.
+ connect(headerViewPointer, SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SLOT(sortTable(int, Qt::SortOrder)));
}
+}
- // Create the columns.
- 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, 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;
-
- // Populate the table.
- for (auto filterListEntry = filterListForwardList.begin(); filterListEntry != filterListForwardList.end(); ++filterListEntry) {
- // Get the entry struct.
- EntryStruct *entryStructPointer = *filterListEntry;
-
- // Add a new row.
- sublistTableWidgetPointer->insertRow(rowCounter);
-
- // 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, 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;
- }
+void FilterListsDialog::showFilterEntryDialog(int row)
+{
+ // Get the filter list struct.
+ FilterListStruct *filterListStructPointer = getFilterListStruct(filterListComboBoxPointer->currentIndex());
- // Get the table header view.
- QHeaderView *headerViewPointer = sublistTableWidgetPointer->horizontalHeader();
+ // Create a sublist title.
+ QString sublistTitle = globalFilterListHelperPointer->getSublistName(sublistComboBoxPointer->currentIndex());
- // Resize the header to fit the contents.
- headerViewPointer->resizeSections(QHeaderView::ResizeToContents);
+ // Instantiate the filter entry dialog.
+ FilterEntryDialog *filterEntryDialogPointer = new FilterEntryDialog(this, sublistTableWidgetPointer, row, filterListStructPointer->title, sublistTitle);
- // Connect changes in the sort order.
- connect(headerViewPointer, SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SLOT(sortTable(int, Qt::SortOrder)));
+ // Show the dialog.
+ filterEntryDialogPointer->show();
}
void FilterListsDialog::sortTable(int column, Qt::SortOrder sortOrder) const
private Q_SLOTS:
void populateFilterListTextEdit(int filterListComboBoxIndex) const;
void populateTableWidget(int sublistComboBoxIndex) const;
+ void showFilterEntryDialog(int row);
void sortTable(int column, Qt::SortOrder sortOrder) const;
private:
QTableWidget *sublistTableWidgetPointer;
// The private functions.
+ std::forward_list<EntryStruct *>* getFilterListForwardList(FilterListStruct *filterListStructPointer) const;
+ FilterListStruct* getFilterListStruct(int filterListComboBoxIndex) const;
void populateFilterListComboBox(const FilterListStruct *filterListStructPointer) const;
};
#endif
filterListLineEditPointer = requestDetailDialogUi.filterListLineEdit;
sublistLabelPointer = requestDetailDialogUi.sublistLabel;
sublistLineEditPointer = requestDetailDialogUi.sublistListLineEdit;
- appliedEntryLabelPointer = requestDetailDialogUi.appliedEntryLabel;
- appliedEntryLineEditPointer = requestDetailDialogUi.appliedEntryLineEdit;
+ appliedEntryListLabelPointer = requestDetailDialogUi.appliedEntryListLabel;
+ appliedEntryListLineEditPointer = requestDetailDialogUi.appliedEntryListLineEdit;
originalEntryLabelPointer = requestDetailDialogUi.originalEntryLabel;
originalEntryLineEditPointer = requestDetailDialogUi.originalEntryLineEdit;
previousButtonPointer = requestDetailDialogUi.previousButton;
// Populate the new request struct.
requestStructDataStreamReader >> requestStructPointer->dispositionInt;
- requestStructDataStreamReader >> requestStructPointer->entryStruct.appliedEntry;
+ requestStructDataStreamReader >> requestStructPointer->entryStruct.appliedEntryList;
requestStructDataStreamReader >> requestStructPointer->entryStruct.originalEntry;
requestStructDataStreamReader >> requestStructPointer->filterListTitle;
requestStructDataStreamReader >> requestStructPointer->navigationTypeInt;
resourceTypeLineEditPointer->setText(globalFilterListHelperPointer->getResourceTypeString(requestStructPointer->resourceTypeInt));
filterListLineEditPointer->setText(requestStructPointer->filterListTitle);
sublistLineEditPointer->setText(globalFilterListHelperPointer->getSublistName(requestStructPointer->sublistInt));
- appliedEntryLineEditPointer->setText(requestStructPointer->entryStruct.appliedEntry);
+ appliedEntryListLineEditPointer->setText(requestStructPointer->entryStruct.appliedEntryList.join(QLatin1String(" * ")));
originalEntryLineEditPointer->setText(requestStructPointer->entryStruct.originalEntry);
// Set the button status.
filterListLineEditPointer->hide();
sublistLabelPointer->hide();
sublistLineEditPointer->hide();
- appliedEntryLabelPointer->hide();
- appliedEntryLineEditPointer->hide();
+ appliedEntryListLabelPointer->hide();
+ appliedEntryListLineEditPointer->hide();
originalEntryLabelPointer->hide();
originalEntryLineEditPointer->hide();
filterListLineEditPointer->show();
sublistLabelPointer->show();
sublistLineEditPointer->show();
- appliedEntryLabelPointer->show();
- appliedEntryLineEditPointer->show();
+ appliedEntryListLabelPointer->show();
+ appliedEntryListLineEditPointer->show();
originalEntryLabelPointer->show();
originalEntryLineEditPointer->show();
filterListLineEditPointer->show();
sublistLabelPointer->show();
sublistLineEditPointer->show();
- appliedEntryLabelPointer->show();
- appliedEntryLineEditPointer->show();
+ appliedEntryListLabelPointer->show();
+ appliedEntryListLineEditPointer->show();
originalEntryLabelPointer->show();
originalEntryLineEditPointer->show();
private:
// The private variables.
- QLabel *appliedEntryLabelPointer;
- QLineEdit *appliedEntryLineEditPointer;
+ QLabel *appliedEntryListLabelPointer;
+ QLineEdit *appliedEntryListLineEditPointer;
int currentRow;
QLineEdit *dispositionLineEditPointer;
QLabel *filterListLabelPointer;
// Populate the request struct data stream.
requestStructDataStream << requestStructPointer->dispositionInt;
- requestStructDataStream << requestStructPointer->entryStruct.appliedEntry;
+ requestStructDataStream << requestStructPointer->entryStruct.appliedEntryList;
requestStructDataStream << requestStructPointer->entryStruct.originalEntry;
requestStructDataStream << requestStructPointer->filterListTitle;
requestStructDataStream << requestStructPointer->navigationTypeInt;
#include "FilterListHelper.h"
#include "structs/OverrideStruct.h"
+// KDE Framework headers.
+#include <KLocalizedString>
+
// Qt toolkit headers.
#include <QDebug>
#include <QFile>
+#include <QRegularExpression>
#include <QTextStream>
-// KDE Framework headers.
-#include <KLocalizedString>
-
// Construct the class.
FilterListHelper::FilterListHelper()
{
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");
+ REGULAR_EXPRESSION_BLOCKLIST_STRING = i18nc("Regular expression blocklist string", "Regular Expression Block List");
// Populate the filter lists.
- ultraListStructPointer = populateFilterList(QLatin1String(":/filterlists/ultralist.txt"));
ultraPrivacyStructPointer = populateFilterList(QLatin1String(":/filterlists/ultraprivacy.txt"));
- easyListStructPointer = populateFilterList(QLatin1String(":/filterlists/easylist.txt"));
+ ultraListStructPointer = populateFilterList(QLatin1String(":/filterlists/ultralist.txt"));
easyPrivacyStructPointer = populateFilterList(QLatin1String(":/filterlists/easyprivacy.txt"));
+ easyListStructPointer = populateFilterList(QLatin1String(":/filterlists/easylist.txt"));
fanboyAnnoyanceStructPointer = populateFilterList(QLatin1String(":/filterlists/fanboy-annoyance.txt"));
}
bool FilterListHelper::checkFilterLists(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer) const
{
- // Initiate a continue checking tracker. If the tracker changes to false, all process of the request will be stopped.
+ // Initiate a continue checking tracker. If the tracker changes to false, all processing of the request will be stopped.
bool continueChecking = true;
// Create a URL struct.
// Get the hosts.
QString firstPartyHost = firstPartyUrl.host();
- QString requestHost = requestUrl.host();
+ urlStruct.fqdn = requestUrl.host();
// Determine if this is a third-party request.
- urlStruct.isThirdPartyRequest = (firstPartyHost != requestHost);
+ urlStruct.isThirdPartyRequest = (firstPartyHost != urlStruct.fqdn);
// Get the request URL string.
urlStruct.urlString = requestUrl.toString();
urlStruct.urlStringWithSeparators.replace(QLatin1Char('='), QLatin1Char('^'));
urlStruct.urlStringWithSeparators.replace(QLatin1Char('&'), QLatin1Char('^'));
- // Add a `^` to the end of the string.
- urlStruct.urlStringWithSeparators.append(QLatin1Char('^'));
+ // Add a `^` to the end of the string it it doesn't already contain one.
+ if (!urlStruct.urlStringWithSeparators.endsWith(QLatin1Char('^')))
+ urlStruct.urlStringWithSeparators.append(QLatin1Char('^'));
// Create truncated URL strings and initially populate it with the original URL strings.
urlStruct.truncatedUrlString = urlStruct.urlString;
urlStruct.truncatedUrlStringWithSeparators.remove(0, fqdnIndex);
// Check UltraList.
- continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, ultraListStructPointer);
+ continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, ultraPrivacyStructPointer);
// Check UltraPrivacy.
if (continueChecking)
- continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, ultraPrivacyStructPointer);
-
- // Check EasyList.
- if (continueChecking)
- continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, easyListStructPointer);
+ continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, ultraListStructPointer);
// Check EasyPrivacy.
if (continueChecking)
continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, easyPrivacyStructPointer);
+ // Check EasyList.
+ if (continueChecking)
+ continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, easyListStructPointer);
+
+ // Check Fanboy's Annoyance list.
if (continueChecking)
continueChecking = checkIndividualList(urlRequestInfo, urlStruct, requestStructPointer, fanboyAnnoyanceStructPointer);
return continueChecking;
}
-bool FilterListHelper::blockRequest(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt,
- EntryStruct *entryStructPointer) const
-{
- // Block the request.
- urlRequestInfo.block(true);
-
- // 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
{
+ // Initiate a continue checking tracker. If the tracker changes to false, all process of the request will be stopped.
+ bool continueChecking = true;
+
// Check the main allow list.
- for (auto filterListEntry = filterListStructPointer->mainAllowList.begin(); filterListEntry != filterListStructPointer->mainAllowList.end(); ++filterListEntry)
+ for (auto filterListEntry = filterListStructPointer->mainAllowListPointer->begin(); filterListEntry != filterListStructPointer->mainAllowListPointer->end(); ++filterListEntry)
{
// Get the entry struct.
EntryStruct *entryStructPointer = *filterListEntry;
// TODO. Temporarily ignore empty applied entries.
- if (!entryStructPointer->appliedEntry.isEmpty())
+ if (!entryStructPointer->appliedEntryList[0].isEmpty())
{
- // Check if the URL string contains the applied entry.
- if (urlStruct.urlString.contains(entryStructPointer->appliedEntry) || urlStruct.urlStringWithSeparators.contains(entryStructPointer->appliedEntry))
+ // Check if the URL string contains the applied entry. TODO.
+ if (urlStruct.urlString.contains(entryStructPointer->appliedEntryList[0]) || urlStruct.urlStringWithSeparators.contains(entryStructPointer->appliedEntryList[0]))
{
// Allow the request.
urlRequestInfo.block(false);
}
}
+ // Get the main block list end.
+ auto mainBlockListEnd = filterListStructPointer->mainBlockListPointer->end();
+
// Check the main block list.
- for (auto filterListEntry = filterListStructPointer->mainBlockList.begin(); filterListEntry != filterListStructPointer->mainBlockList.end(); ++filterListEntry)
+ for (auto mainBlockListEntry = filterListStructPointer->mainBlockListPointer->begin(); mainBlockListEntry != mainBlockListEnd; ++mainBlockListEntry)
{
+ // Exit the loop if continue checking is false.
+ if (!continueChecking)
+ break;
+
// Get the entry struct.
- EntryStruct *entryStructPointer = *filterListEntry;
+ EntryStruct *entryStructPointer = *mainBlockListEntry;
- // TODO. Temporarily ignore empty applied entries.
- if (!entryStructPointer->appliedEntry.isEmpty())
+ // Check the applied entries.
+ continueChecking = checkAppliedEntry(urlRequestInfo, urlStruct, requestStructPointer, filterListStructPointer->title, MAIN_BLOCKLIST, entryStructPointer, urlStruct.urlString,
+ urlStruct.urlStringWithSeparators);
+ }
+
+ // Get the initial domain block list end.
+ auto initialDomainBlockListEnd = filterListStructPointer->initialDomainBlockListPointer->end();
+
+ // Check the initial domain block list.
+ for (auto initialDomainBlockListEntry = filterListStructPointer->initialDomainBlockListPointer->begin(); initialDomainBlockListEntry != initialDomainBlockListEnd;
+ ++initialDomainBlockListEntry)
+ {
+ // Exit the loop if continue checking is false.
+ if (!continueChecking)
+ break;
+
+ // Get the entry struct.
+ EntryStruct *entryStructPointer = *initialDomainBlockListEntry;
+
+ // Check the applied entries.
+ continueChecking = checkAppliedEntry(urlRequestInfo, urlStruct, requestStructPointer, filterListStructPointer->title, INITIAL_DOMAIN_BLOCKLIST, entryStructPointer,
+ urlStruct.truncatedUrlString, urlStruct.truncatedUrlStringWithSeparators);
+ }
+
+ // Get the regular expression block list end.
+ auto regularExpressionBlockListEnd = filterListStructPointer->regularExpressionBlockListPointer->end();
+
+ // Check the regular expression block list.
+ for (auto regularExpressionBlockListEntry = filterListStructPointer->regularExpressionBlockListPointer->begin(); regularExpressionBlockListEntry != regularExpressionBlockListEnd;
+ ++regularExpressionBlockListEntry)
+ {
+ // Exit the loop if continue checking is false.
+ if (!continueChecking)
+ break;
+
+ // Get the entry struct.
+ EntryStruct *entryStructPointer = *regularExpressionBlockListEntry;
+
+ // Check the applied entries.
+ continueChecking = checkRegularExpression(urlRequestInfo, urlStruct, requestStructPointer, filterListStructPointer->title, REGULAR_EXPRESSION_BLOCKLIST, entryStructPointer);
+ }
+
+ // Return the continue checking status.
+ return continueChecking;
+}
+
+bool FilterListHelper::checkAppliedEntry(QWebEngineUrlRequestInfo &urlRequestInfo, UrlStruct &urlStruct, RequestStruct *requestStructPointer, const QString &filterListTitle,
+ const int sublistInt, EntryStruct *entryStructPointer, QString &urlString, QString &urlStringWithSeparators) const
+{
+ // Check the entries according to the number.
+ if (entryStructPointer->singleAppliedEntry)
+ {
+ // Process initial and final matches.
+ if (entryStructPointer->initialMatch && entryStructPointer->finalMatch) // This is both an initial and final match.
+ {
+ // Check the URL against the applied entry.
+ if ((urlString == entryStructPointer->appliedEntryList[0]) || (urlStringWithSeparators == entryStructPointer->appliedEntryList[0]))
+ {
+ // Check the domain status.
+ return checkDomain(urlRequestInfo, urlStruct, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ }
+ else if (entryStructPointer->initialMatch) // This is an initial match.
+ {
+ // Check the URL against the applied entry.
+ if (urlString.startsWith(entryStructPointer->appliedEntryList[0]) || urlStringWithSeparators.startsWith(entryStructPointer->appliedEntryList[0]))
+ {
+ // Check the domain status.
+ return checkDomain(urlRequestInfo, urlStruct, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ }
+ else if (entryStructPointer->finalMatch) // This is a final match.
+ {
+ // Check the URL against the applied entry.
+ if (urlString.endsWith(entryStructPointer->appliedEntryList[0]) || urlStringWithSeparators.endsWith(entryStructPointer->appliedEntryList[0]))
+ {
+ // Check the domain status.
+ return checkDomain(urlRequestInfo, urlStruct, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ }
+ else // There is no initial or final matching.
{
// Check if the URL string contains the applied entry.
- if (urlStruct.urlString.contains(entryStructPointer->appliedEntry) || urlStruct.urlStringWithSeparators.contains(entryStructPointer->appliedEntry))
+ if (urlString.contains(entryStructPointer->appliedEntryList[0]) || urlStringWithSeparators.contains(entryStructPointer->appliedEntryList[0]))
{
- // Check the third-party status.
- bool continueChecking = checkThirdParty(urlRequestInfo, requestStructPointer, urlStruct.isThirdPartyRequest, filterListStructPointer->title, MAIN_BLOCKLIST, entryStructPointer);
+ // Check the domain status.
+ return checkDomain(urlRequestInfo, urlStruct, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
+ }
+ }
+ else // There are multiple entries.
+ {
+ // Create a URL matches flag.
+ bool urlMatches = true;
+
+ // Process initial and final matches.
+ if (entryStructPointer->initialMatch && entryStructPointer->finalMatch) // This is both an initial and final match.
+ {
+ // Check the first entry.
+ if (urlString.startsWith(entryStructPointer->appliedEntryList[0]) ||
+ urlStringWithSeparators.startsWith(entryStructPointer->appliedEntryList[0])) // The URL string starts with the first applied entry.
+ {
+ // Get the number of characters to remove from the front of the URL strings.
+ int charactersToRemove = entryStructPointer->appliedEntryList[0].size();
+
+ // Remove the entry from the front of the URL string copies.
+ urlString.remove(0, charactersToRemove);
+ urlStringWithSeparators.remove(0, charactersToRemove);
+ }
+ else // The URL string does not end with the last applied entry.
+ {
+ // Mark the URL matches flag as false.
+ urlMatches = false;
+ }
+
+ // Check the other entries if the URL still matches.
+ if (urlMatches)
+ {
+ // Calculate the penultimate entry.
+ int penultimateEntryNumber = (entryStructPointer->sizeOfAppliedEntryList - 1);
+ int ultimateEntryIndex = penultimateEntryNumber;
+
+ // Check all the middle entries.
+ for (int i = 1; i < penultimateEntryNumber; ++i)
+ {
+ // Get the index of the applied entry, which will be `-1` if it doesn't exist.
+ int stringIndex = urlString.indexOf(entryStructPointer->appliedEntryList[i]);
+ int stringWithSeparatorsIndex = urlStringWithSeparators.indexOf(entryStructPointer->appliedEntryList[i]);
+
+ // Get the larger of the two indexes.
+ int index = std::max(stringIndex, stringWithSeparatorsIndex);
+
+ // Check if the entry was found.
+ if (index >= 0) // The entry is contained in the URL string.
+ {
+ // Get the number of characters to remove from the front of the URL strings.
+ int charactersToRemove = index + entryStructPointer->appliedEntryList[i].size();
+
+ // Remove the entry from the front of the URL string copies.
+ urlString.remove(0, charactersToRemove);
+ urlStringWithSeparators.remove(0, charactersToRemove);
+ }
+ else // The entry is not contained in the URL string.
+ {
+ // Mark the URL matches flag as false.
+ urlMatches = false;
+ }
+ }
+
+ // Check the final entry if the URL still matches.
+ if (urlMatches)
+ {
+ if (urlString.endsWith(entryStructPointer->appliedEntryList[ultimateEntryIndex]) ||
+ urlStringWithSeparators.endsWith(entryStructPointer->appliedEntryList[ultimateEntryIndex])) // The URL string ends with the last applied entry.
+ {
+ // There is no need to modify the URL string copies as no further checks will be performed.
+ }
+ else // The URL string does not end with the last applied entry.
+ {
+ // Mark the URL matches flag as false.
+ urlMatches = false;
+ }
+ }
+ }
+ }
+ else if (entryStructPointer->initialMatch) // This is an initial match.
+ {
+ // Check the first entry.
+ if (urlString.startsWith(entryStructPointer->appliedEntryList[0]) ||
+ urlStringWithSeparators.startsWith(entryStructPointer->appliedEntryList[0])) // The URL string starts with the first applied entry.
+ {
+ // Get the number of characters to remove from the front of the URL strings.
+ int charactersToRemove = entryStructPointer->appliedEntryList[0].size();
+
+ // Remove the entry from the front of the URL string copies.
+ urlString.remove(0, charactersToRemove);
+ urlStringWithSeparators.remove(0, charactersToRemove);
+ }
+ else // The URL string does not end with the last applied entry.
+ {
+ // Mark the URL matches flag as false.
+ urlMatches = false;
+ }
+
+ // Check the other entries if the URL still matches.
+ if (urlMatches)
+ {
+ for (int i = 1; i < entryStructPointer->sizeOfAppliedEntryList; ++i)
+ {
+ // Get the index of the applied entry, which will be `-1` if it doesn't exist.
+ int stringIndex = urlString.indexOf(entryStructPointer->appliedEntryList[i]);
+ int stringWithSeparatorsIndex = urlStringWithSeparators.indexOf(entryStructPointer->appliedEntryList[i]);
+
+ // Get the larger of the two indexes.
+ int index = std::max(stringIndex, stringWithSeparatorsIndex);
+
+ // Check if the entry was found.
+ if (index >= 0) // The entry is contained in the URL string.
+ {
+ // Get the number of characters to remove from the front of the URL strings.
+ int charactersToRemove = index + entryStructPointer->appliedEntryList[i].size();
+
+ // Remove the entry from the front of the URL string copies.
+ urlString.remove(0, charactersToRemove);
+ urlStringWithSeparators.remove(0, charactersToRemove);
+ }
+ else // The entry is not contained in the URL string.
+ {
+ // Mark the URL matches flag as false.
+ urlMatches = false;
+ }
+ }
+ }
+ }
+ else if (entryStructPointer->finalMatch) // This is a final match.
+ {
+ // Calculate the penultimate entry.
+ int penultimateEntryNumber = (entryStructPointer->sizeOfAppliedEntryList - 1);
+ int ultimateEntryIndex = penultimateEntryNumber;
+
+ // Check all the entries except the last one.
+ for (int i = 0; i < penultimateEntryNumber; ++i)
+ {
+ // Get the index of the applied entry, which will be `-1` if it doesn't exist.
+ int stringIndex = urlString.indexOf(entryStructPointer->appliedEntryList[i]);
+ int stringWithSeparatorsIndex = urlStringWithSeparators.indexOf(entryStructPointer->appliedEntryList[i]);
+
+ // Get the larger of the two indexes.
+ int index = std::max(stringIndex, stringWithSeparatorsIndex);
+
+ // Check if the entry was found.
+ if (index >= 0) // The entry is contained in the URL string.
+ {
+ // Get the number of characters to remove from the front of the URL strings.
+ int charactersToRemove = index + entryStructPointer->appliedEntryList[i].size();
+
+ // Remove the entry from the front of the URL string copies.
+ urlString.remove(0, charactersToRemove);
+ urlStringWithSeparators.remove(0, charactersToRemove);
+ }
+ else // The entry is not contained in the URL string.
+ {
+ // Mark the URL matches flag as false.
+ urlMatches = false;
+ }
+ }
- // 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 final entry if the URL still matches.
+ if (urlMatches)
+ {
+ if (urlString.endsWith(entryStructPointer->appliedEntryList[ultimateEntryIndex]) ||
+ urlStringWithSeparators.endsWith(entryStructPointer->appliedEntryList[ultimateEntryIndex])) // The URL string ends with the last applied entry.
+ {
+ // There is no need to modify the URL string copies as no further checks will be performed.
+ }
+ else // The URL string does not end with the last applied entry.
+ {
+ // Mark the URL matches flag as false.
+ urlMatches = false;
+ }
}
}
+ else // There is no initial or final matching.
+ {
+ for (int i = 0; i < entryStructPointer->sizeOfAppliedEntryList; ++i)
+ {
+ // Get the index of the applied entry, which will be `-1` if it doesn't exist.
+ int stringIndex = urlString.indexOf(entryStructPointer->appliedEntryList[i]);
+ int stringWithSeparatorsIndex = urlStringWithSeparators.indexOf(entryStructPointer->appliedEntryList[i]);
+
+ // Get the larger of the two indexes.
+ int index = std::max(stringIndex, stringWithSeparatorsIndex);
+
+ // Check if the entry was found.
+ if (index >= 0) // The entry is contained in the URL string.
+ {
+
+ // Get the number of characters to remove from the front of the URL strings.
+ int charactersToRemove = index + entryStructPointer->appliedEntryList[i].size();
+
+ // Remove the entry from the front of the URL string copies.
+ urlString.remove(0, charactersToRemove);
+ urlStringWithSeparators.remove(0, charactersToRemove);
+ }
+ else // The entry is not contained in the URL string.
+ {
+ // Mark the URL matches flag as false.
+ urlMatches = false;
+ }
+ }
+ }
+
+ // Check the domain status if the URL matches.
+ if (urlMatches)
+ return checkDomain(urlRequestInfo, urlStruct, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
}
- // Check the initial domain block list.
- for (auto filterListEntry = filterListStructPointer->initialDomainBlockList.begin(); filterListEntry != filterListStructPointer->initialDomainBlockList.end(); ++filterListEntry)
+ // If the applied entry doesn't match, return `true` to continue processing the URL request.
+ return true;
+}
+
+bool FilterListHelper::checkRegularExpression(QWebEngineUrlRequestInfo &urlRequestInfo, UrlStruct &urlStruct, RequestStruct *requestStructPointer, const QString &filterListTitle,
+ const int sublistInt, EntryStruct *entryStructPointer) const
+{
+ // Create an applied entry regular expression.
+ QRegularExpression appliedEntryRegularExpression(entryStructPointer->appliedEntryList[0]);
+
+ // Check if the regular expression matches the applied entry.
+ if (urlStruct.urlString.contains(appliedEntryRegularExpression))
{
- // Get the entry struct.
- EntryStruct *entryStructPointer = *filterListEntry;
+ // Check the domain status.
+ return checkDomain(urlRequestInfo, urlStruct, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ }
- // Check if the truncated URL string begins with the applied entry.
- if (urlStruct.truncatedUrlString.startsWith(entryStructPointer->appliedEntry) || urlStruct.truncatedUrlStringWithSeparators.startsWith(entryStructPointer->appliedEntry))
+ // If the regular expression doesn't match, return `true` to continue processing the URL request.
+ return true;
+}
+
+bool FilterListHelper::checkDomain(QWebEngineUrlRequestInfo &urlRequestInfo, UrlStruct &urlStruct, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt,
+ EntryStruct *entryStructPointer) const
+{
+ // Check domain status.
+ if (entryStructPointer->domain == FilterOptionEnum::Disposition::Null) // Ignore domain status.
+ {
+ // Check the third-party status.
+ return checkThirdParty(urlRequestInfo, requestStructPointer, urlStruct.isThirdPartyRequest, filterListTitle, sublistInt, entryStructPointer);
+ }
+ else if (entryStructPointer->domain == FilterOptionEnum::Disposition::Apply) // Block requests from listed domains.
+ {
+ // Check each domain.
+ foreach (QString blockedDomain, entryStructPointer->domainList)
{
- // Check the third-party status.
- bool continueChecking = checkThirdParty(urlRequestInfo, requestStructPointer, urlStruct.isThirdPartyRequest, filterListStructPointer->title, INITIAL_DOMAIN_BLOCKLIST, entryStructPointer);
+ // Check if the request came from a blocked domain.
+ if (urlStruct.fqdn.endsWith(blockedDomain))
+ {
+ // Check the third-party status.
+ return checkThirdParty(urlRequestInfo, requestStructPointer, urlStruct.isThirdPartyRequest, filterListTitle, sublistInt, entryStructPointer);
+ }
+ }
+ }
+ else if (entryStructPointer->domain == FilterOptionEnum::Disposition::Override) // Block domains that are not overridden.
+ {
+ // Create a block domain flag.
+ bool blockDomain = true;
- // Stop processing the filter lists if continue checking is `false`. Returning false halts all processing at upper levels.
- if (continueChecking == false)
- return false;
+ // Check each overridden domain.
+ foreach (QString overriddenDomain, entryStructPointer->domainList)
+ {
+ // Check if the request came from an overridden domain.
+ if (urlStruct.fqdn.endsWith(overriddenDomain))
+ {
+ // Don't block the domain.
+ blockDomain = false;
+ }
+ }
+
+ // Continue checking if the domain is blocked.
+ if (blockDomain)
+ {
+ // Check the third-party status.
+ return checkThirdParty(urlRequestInfo, requestStructPointer, urlStruct.isThirdPartyRequest, filterListTitle, sublistInt, entryStructPointer);
}
}
- // Return `true` to continue processing the URL request.
+ // There is a domain specified that doesn't match this request. Return `true` to continue processing the URL request.
return true;
}
// 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.
+ // Check if request options are applied.
+ if (entryStructPointer->hasRequestOptions) // Request options are applied.
{
- // Process the filter options.
- return processFilterOptions(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ // Check the request options.
+ return checkRequestOptions(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
}
- else // Filter options are not applied.
+ else // Request 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.
+ // Check if request options are applied.
+ if (entryStructPointer->hasRequestOptions) // Request options are applied.
{
- // Process the filter options.
- return processFilterOptions(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ // Check the request options.
+ return checkRequestOptions(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
}
- else // Filter options are not applied.
+ else // Request 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.
+ // Check if request options are applied.
+ if (entryStructPointer->hasRequestOptions) // Request options are applied.
{
- // Process the filter options.
- return processFilterOptions(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ // Check the request options.
+ return checkRequestOptions(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
}
- else // Filter options are not applied.
+ else // Request 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.
+ // The third-party option specified doesn't match this request. Return `true` to continue processing the URL request.
+ return true;
+}
+
+bool FilterListHelper::checkRequestOptions(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);
+ }
+
+ // The request options specified don't match this request. Return `true` to continue processing the URL request.
return true;
}
+bool FilterListHelper::blockRequest(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt,
+ EntryStruct *entryStructPointer) const
+{
+ // Block the request.
+ urlRequestInfo.block(true);
+
+ // 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;
+}
+
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.
}
}
+QString FilterListHelper::getRequestOptionDispositionString(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::getResourceTypeString(int resourceTypeInt) const
{
// Return the translated resource type string.
case MAIN_ALLOWLIST: return MAIN_ALLOWLIST_STRING;
case MAIN_BLOCKLIST: return MAIN_BLOCKLIST_STRING;
case INITIAL_DOMAIN_BLOCKLIST: return INITIAL_DOMAIN_BLOCKLIST_STRING;
+ case REGULAR_EXPRESSION_BLOCKLIST: return REGULAR_EXPRESSION_BLOCKLIST_STRING;
default: return QString(); // The default return should never be reached.
}
}
}
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;
+ // Get the index of the last dollar sign.
+ int indexOfLastDollarSign = filterListString.lastIndexOf(QLatin1Char('$'));
// Process the filter options if they exist.
- if (splitEntryStringList.size() > 1)
+ if (indexOfLastDollarSign > -1)
{
- // Store the filter options.
- entryStructPointer->filterOptions = splitEntryStringList[1];
+ // Get the filter options.
+ entryStructPointer->originalFilterOptions = filterListString.section(QLatin1Char('$'), -1);
+
+ // Store the entry without the filter options as the filter list string.
+ filterListString.truncate(indexOfLastDollarSign);
// Split the filter options.
- QStringList filterOptionsList = splitEntryStringList[1].split(QLatin1Char(','));
+ QStringList originalFilterOptionsList = entryStructPointer->originalFilterOptions.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.
+ // Create an applied filter options list.
+ QStringList appliedFilterOptionsList;
+
+ // Populate the applied filter options list.
+ foreach (QString filterOption, originalFilterOptionsList)
{
- // Set the popup only filter option flag.
- popupOnlyFilterOption = true;
+ // Only add filter options that are handled by Privacy Browser.
+ if (!(filterOption.startsWith(QLatin1String("csp=")) ||
+ filterOption.startsWith(QLatin1String("method=")) ||
+ filterOption.startsWith(QLatin1String("redirect=")) ||
+ filterOption.startsWith(QLatin1String("rewrite="))))
+ appliedFilterOptionsList.append(filterOption);
}
- 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;
+ // Store the applied filter options list.
+ entryStructPointer->appliedFilterOptionsList = appliedFilterOptionsList;
- // Set the filter options flag.
- entryStructPointer->hasFilterOptions = true;
- }
+ // Initialize an override struct.
+ OverrideStruct overrideStruct;
- if (filterOption == QLatin1String("media"))
- {
- // Populate the media option.
- entryStructPointer->media = FilterOptionEnum::Disposition::Apply;
+ // Populate the filter options entries.
+ foreach (QString filterOption, appliedFilterOptionsList)
+ {
+ // Parse the filter options.
+ if (filterOption.startsWith(QLatin1String("domain="))) // Domain.
+ {
+ // Remove `domain=` from the filter option.
+ filterOption.remove(0, 7);
- // Set the filter options flag.
- entryStructPointer->hasFilterOptions = true;
- }
+ // Store the domain list.
+ entryStructPointer->domainList = filterOption.split(QLatin1Char('|'));
- if (filterOption == QLatin1String("object"))
+ // Set the disposition.
+ if (entryStructPointer->domainList[0].startsWith(QLatin1Char('~'))) // Override domains.
{
- // Populate the object option.
- entryStructPointer->object = FilterOptionEnum::Disposition::Apply;
+ // Populate the domain filter disposition.
+ entryStructPointer->domain = FilterOptionEnum::Disposition::Override;
- // Set the filter options flag.
- entryStructPointer->hasFilterOptions = true;
+ // Remove the initial `~` from each domain.
+ entryStructPointer->domainList.replaceInStrings(QLatin1String("~"), QLatin1String(""));
}
-
- if (filterOption == QLatin1String("other"))
+ else // Standard domains.
{
- // Populate the other option.
- entryStructPointer->other = FilterOptionEnum::Disposition::Apply;
-
- // Set the filter options flag.
- entryStructPointer->hasFilterOptions = true;
+ // Populate the domain filter disposition.
+ entryStructPointer->domain = FilterOptionEnum::Disposition::Apply;
}
+ }
+ else if (filterOption == QLatin1String("third-party")) // Third-party.
+ {
+ // Populate the third-party filter disposition.
+ entryStructPointer->thirdParty = FilterOptionEnum::Disposition::Apply;
+ }
+ else if (filterOption == QLatin1String("~third-party")) // Third-party override.
+ {
+ // Populate the third-party filter disposition.
+ entryStructPointer->thirdParty = FilterOptionEnum::Disposition::Override;
+ }
+ else if ((filterOption == QLatin1String("document")) || (filterOption == QLatin1String("popup"))) // Document (and popup).
+ {
+ // Populate the main frame disposition.
+ entryStructPointer->mainFrame = FilterOptionEnum::Disposition::Apply;
- if (filterOption == QLatin1String("ping"))
- {
- // Populate the ping option.
- entryStructPointer->ping = FilterOptionEnum::Disposition::Apply;
+ // Set the has request options flag.
+ entryStructPointer->hasRequestOptions = true;
+ }
+ else if (filterOption == QLatin1String("font")) // Font.
+ {
+ // Populate the font disposition.
+ entryStructPointer->font = FilterOptionEnum::Disposition::Apply;
- // Set the filter options flag.
- entryStructPointer->hasFilterOptions = true;
- }
+ // Set the has request options flag.
+ entryStructPointer->hasRequestOptions = true;
+ }
+ else if (filterOption == QLatin1String("image")) // Image.
+ {
+ // Populate the image disposition.
+ entryStructPointer->image = FilterOptionEnum::Disposition::Apply;
- if (filterOption == QLatin1String("script"))
- {
- // Populate the script option.
- entryStructPointer->script = FilterOptionEnum::Disposition::Apply;
+ // Set the has request options flag.
+ entryStructPointer->hasRequestOptions = true;
+ }
+ else if (filterOption == QLatin1String("media")) // Media.
+ {
+ // Populate the media disposition.
+ entryStructPointer->media = FilterOptionEnum::Disposition::Apply;
- // Set the filter options flag.
- entryStructPointer->hasFilterOptions = true;
- }
+ // Set the has request options flag.
+ entryStructPointer->hasRequestOptions = true;
+ }
+ else if (filterOption == QLatin1String("object")) // Object.
+ {
+ // Populate the object disposition.
+ entryStructPointer->object = FilterOptionEnum::Disposition::Apply;
- if (filterOption == QLatin1String("stylesheet"))
- {
- // Populate the script option.
- entryStructPointer->styleSheet = FilterOptionEnum::Disposition::Apply;
+ // Set the has request options flag.
+ entryStructPointer->hasRequestOptions = true;
+ }
+ else if ((filterOption == QLatin1String("other")) || (filterOption == QLatin1String("webrtc")) || (filterOption == QLatin1String("websocket"))) // Other.
+ { // `websocket` will get its own section in Qt6.
+ // Populate the other disposition.
+ entryStructPointer->other = FilterOptionEnum::Disposition::Apply;
- // Set the filter options flag.
- entryStructPointer->hasFilterOptions = true;
- }
+ // Set the has request options flag.
+ entryStructPointer->hasRequestOptions = true;
+ }
+ else if (filterOption == QLatin1String("ping")) // Ping.
+ {
+ // Populate the ping disposition.
+ entryStructPointer->ping = FilterOptionEnum::Disposition::Apply;
- if (filterOption == QLatin1String("subdocument"))
- {
- // Populate the sub resource option.
- entryStructPointer->subFrame = FilterOptionEnum::Disposition::Apply;
+ // Set the has request options flag.
+ entryStructPointer->hasRequestOptions = true;
+ }
+ else if (filterOption == QLatin1String("script")) // Script.
+ {
+ // Populate the script disposition.
+ entryStructPointer->script = FilterOptionEnum::Disposition::Apply;
- // Set the filter options flag.
- entryStructPointer->hasFilterOptions = true;
- }
+ // Set the has request options flag.
+ entryStructPointer->hasRequestOptions = true;
+ }
+ else if (filterOption == QLatin1String("stylesheet")) // Style sheet.
+ {
+ // Populate the script disposition.
+ entryStructPointer->styleSheet = FilterOptionEnum::Disposition::Apply;
- if (filterOption == QLatin1String("xmlhttprequest"))
- {
- //Populate the XML HTTP request option.
- entryStructPointer->xmlHttpRequest = FilterOptionEnum::Disposition::Apply;
+ // Set the has request options flag.
+ entryStructPointer->hasRequestOptions = true;
+ }
+ else if (filterOption == QLatin1String("subdocument")) // Sub document.
+ {
+ // Populate the sub resource disposition.
+ entryStructPointer->subFrame = FilterOptionEnum::Disposition::Apply;
- // Set the filter options flag.
- entryStructPointer->hasFilterOptions = true;
- }
+ // Set the has request options flag.
+ entryStructPointer->hasRequestOptions = true;
+ }
+ else if (filterOption == QLatin1String("xmlhttprequest")) // XML HTTP request.
+ {
+ //Populate the XML HTTP request disposition.
+ entryStructPointer->xmlHttpRequest = FilterOptionEnum::Disposition::Apply;
+ // Set the has request options flag.
+ entryStructPointer->hasRequestOptions = true;
+ }
+ else if (filterOption == QLatin1String("~document")) // Document override.
+ {
// 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;
- }
+ overrideStruct.hasOverride = true;
+ overrideStruct.mainFrame = true;
}
-
- // Apply the overrides.
- if (overrideStruct.hasOverride)
+ else if (filterOption == QLatin1String("~font")) // Font override.
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.font = true;
+ }
+ else if (filterOption == QLatin1String("~image")) // Image override.
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.image = true;
+ }
+ else if (filterOption == QLatin1String("~media")) // Media override.
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.media = true;
+ }
+ else if (filterOption == QLatin1String("~object")) // Object override.
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.object = true;
+ }
+ else if ((filterOption == QLatin1String("~other")) || (filterOption == QLatin1String("~webrtc")) || (filterOption == QLatin1String("~websocket"))) // Other override.
+ { // `websocket` will get its own section in Qt6.
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.other = true;
+ }
+ else if (filterOption == QLatin1String("~ping")) // Ping override.
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.ping = true;
+ }
+ else if (filterOption == QLatin1String("~script")) // Script override.
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.script = true;
+ }
+ else if (filterOption == QLatin1String("~stylesheet")) // Style sheet override.
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.styleSheet = true;
+ }
+ else if (filterOption == QLatin1String("~subdocument")) // Sub document override.
+ {
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.subFrame = true;
+ }
+ else if (filterOption == QLatin1String("~xmlhttprequest")) // XML HTTP request override.
{
- // 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;
+ // Populate the override struct.
+ overrideStruct.hasOverride = true;
+ overrideStruct.xmlHttpRequest = true;
}
}
- }
- // 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.
+ // Apply the overrides.
+ if (overrideStruct.hasOverride)
+ {
+ // Set the has request options flag.
+ entryStructPointer->hasRequestOptions = true;
+
+ // 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;
+ }
+ } // Finish processing filter options.
+
+
+ if (filterListString.isEmpty() && !entryStructPointer->hasRequestOptions) // There are no applied entries and no request options.
{
- // Do nothing.
+ // Ignore these entries as they will block all requests generally or for a specified domain. Typically these are left over after removing `csp=` filter options.
- // Log the dropping of the line.
- //qDebug().noquote().nospace() << entryStructPointer->originalEntry << " NOT added from " << filterListFileName << " (single popup filter option).";
+ // Log the dropping of the entry.
+ //qDebug().noquote().nospace() << entryStructPointer->originalEntry << " NOT added from " << filterListFileName << ".";
}
else if (filterListString.startsWith(QLatin1String("@@"))) // Process an allow list entry.
{
// Remove the initial `@@`.
filterListString.remove(0, 2);
- // Remove any initial and trailing asterisks.
- removeInitialAndTrailingAsterisks(filterListString);
+ // Prepare the filter list string. TODO. Initial allow lists must be processed first.
+ prepareFilterListString(filterListString, entryStructPointer);
- // 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);
+ // Add the entry struct to the main allow list.
+ filterListStructPointer->mainAllowListPointer->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.
+ else if (filterListString.startsWith(QLatin1String("||"))) // Process an initial domain block list entry.
{
// Remove the initial `||`.
filterListString.remove(0, 2);
- // Add the applied entry to the struct.
- entryStructPointer->appliedEntry = filterListString;
+ // Set the initial match flag.
+ entryStructPointer->initialMatch = true;
+
+ // Prepare the filter list string.
+ prepareFilterListString(filterListString, entryStructPointer);
- // Add the filter list entry struct to the initial domain block list.
- filterListStructPointer->initialDomainBlockList.push_front(entryStructPointer);
+ // Add the entry struct to the initial domain block list.
+ filterListStructPointer->initialDomainBlockListPointer->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.
+ else if (filterListString.contains(QLatin1String("\\"))) // Process a regular expression block list entry.
{
- // Remove any initial and trailing asterisks.
- removeInitialAndTrailingAsterisks(filterListString);
+ // Add the regular expression to the applied entry list.
+ entryStructPointer->appliedEntryList.append(filterListString);
- // Add the applied entry to the struct.
- entryStructPointer->appliedEntry = filterListString;
+ // Add the entry struct to the regular expression block list.
+ filterListStructPointer->regularExpressionBlockListPointer->push_front(entryStructPointer);
+ }
+ else // Process a main block list entry.
+ {
+ // Prepare the filter list string.
+ prepareFilterListString(filterListString, entryStructPointer);
- // Add the filter list entry struct to the main block list.
- filterListStructPointer->mainBlockList.push_front(entryStructPointer);
+ // Add the entry struct to the main block list.
+ filterListStructPointer->mainBlockListPointer->push_front(entryStructPointer);
// Log the addition to the filter list.
//qDebug().noquote().nospace() << entryStructPointer->originalEntry << " added to Main Block List from " << filterListFileName << ".";
requestStructPointer->dispositionInt = disposition;
requestStructPointer->filterListTitle = filterListTitle;
requestStructPointer->sublistInt = sublistInt;
- requestStructPointer->entryStruct.appliedEntry = entryStructPointer->appliedEntry;
+ requestStructPointer->entryStruct.appliedEntryList = entryStructPointer->appliedEntryList;
requestStructPointer->entryStruct.originalEntry = entryStructPointer->originalEntry;
}
-bool FilterListHelper::processFilterOptions(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt,
- EntryStruct *entryStructPointer) const
+void FilterListHelper::prepareFilterListString(QString &filterListString, 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)))
+ // Check if this is an initial match.
+ if (filterListString.startsWith(QLatin1Char('|')))
{
- // Block the request.
- return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
- }
+ // Strip the initial `|`.
+ filterListString.remove(0, 1);
- // Block ping requests
- if ((entryStructPointer->ping == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypePing))
- {
- // Block the request.
- return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ // Set the initial match flag.
+ entryStructPointer->initialMatch = true;
}
- // Block script requests.
- if ((entryStructPointer->script == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeScript))
+ // Check if this is a final match.
+ if (filterListString.endsWith(QLatin1Char('|')))
{
- // Block the request.
- return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
- }
+ // Strip the final `|`.
+ filterListString.chop(1);
- // Block style sheet requests.
- if ((entryStructPointer->styleSheet == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeStylesheet))
- {
- // Block the request.
- return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
+ // Set the final match flag.
+ entryStructPointer->finalMatch = true;
}
- // 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);
- }
+ // Remove the initial asterisk if it exists.
+ if (filterListString.startsWith(QLatin1Char('*')))
+ filterListString.remove(0, 1);
- // Block XML HTTP requests.
- if ((entryStructPointer->xmlHttpRequest == FilterOptionEnum::Disposition::Apply) && (requestStructPointer->resourceTypeInt == QWebEngineUrlRequestInfo::ResourceTypeXhr))
- {
- // Block the request.
- return blockRequest(urlRequestInfo, requestStructPointer, filterListTitle, sublistInt, entryStructPointer);
- }
+ // Remove the final asterisk if it exists.
+ if (filterListString.endsWith(QLatin1Char('*')))
+ filterListString.chop(1);
- // Returning true continues processing the filter list.
- return true;
-}
+ // Split the filter list string and set it as the applied entry list.
+ entryStructPointer->appliedEntryList = filterListString.split(QLatin1Char('*'));
-void FilterListHelper::removeInitialAndTrailingAsterisks(QString &filterListEntry) const
-{
- // Remove the initial asterisk if it exists.
- if (filterListEntry.startsWith(QLatin1Char('*')))
- filterListEntry.remove(0, 1);
+ // Store the size of the applied entry list.
+ entryStructPointer->sizeOfAppliedEntryList = entryStructPointer->appliedEntryList.size();
- // Remove the final asterisk if it exists.
- if (filterListEntry.endsWith(QLatin1Char('*')))
- filterListEntry.chop(1);
+ // Determine if this is a single applied entry (including an empty entry).
+ entryStructPointer->singleAppliedEntry = (entryStructPointer->sizeOfAppliedEntryList == 1);
}
static const int MAIN_ALLOWLIST = 0;
static const int MAIN_BLOCKLIST = 1;
static const int INITIAL_DOMAIN_BLOCKLIST = 2;
+ static const int REGULAR_EXPRESSION_BLOCKLIST = 3;
// 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 getRequestOptionDispositionString(const FilterOptionEnum::Disposition filterOptionDisposition) const;
QString getResourceTypeString(int resourceTypeInt) const;
QString getSublistName(int sublistInt) const;
QString MAIN_ALLOWLIST_STRING;
QString MAIN_BLOCKLIST_STRING;
QString INITIAL_DOMAIN_BLOCKLIST_STRING;
+ QString REGULAR_EXPRESSION_BLOCKLIST_STRING;
// The private functions.
bool blockRequest(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt, EntryStruct *entryStructPointer) const;
+ bool checkAppliedEntry(QWebEngineUrlRequestInfo &urlRequestInfo, UrlStruct &urlStruct, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt,
+ EntryStruct *entryStructPointer, QString &urlString, QString &urlStringWithSeparators) const;
+ bool checkDomain(QWebEngineUrlRequestInfo &urlRequestInfo, UrlStruct &urlStruct, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt,
+ EntryStruct *entryStructPointer) const;
bool checkIndividualList(QWebEngineUrlRequestInfo &urlRequestInfo, UrlStruct &urlStruct, RequestStruct *requestStructPointer, FilterListStruct *filterListStructPointer) const;
+ bool checkRegularExpression(QWebEngineUrlRequestInfo &urlRequestInfo, UrlStruct &urlStruct, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt,
+ EntryStruct *entryStructPointer) const;
+ bool checkRequestOptions(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt,
+ EntryStruct *entryStructPointer) 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, EntryStruct *entryStructPointer) const;
- bool processFilterOptions(QWebEngineUrlRequestInfo &urlRequestInfo, RequestStruct *requestStructPointer, const QString &filterListTitle, const int sublistInt,
- EntryStruct *entryStructPointer) const;
- void removeInitialAndTrailingAsterisks(QString &filterListEntry) const;
+ void prepareFilterListString(QString &filterListString, EntryStruct *entryStructPointer) const;
};
#endif
requestStructPointer->urlString = urlRequestInfo.requestUrl().toString();
// Check the filter lists.
- bool requestNotHandled = globalFilterListHelperPointer->checkFilterLists(urlRequestInfo, requestStructPointer);
+ bool continueProcessing = globalFilterListHelperPointer->checkFilterLists(urlRequestInfo, requestStructPointer);
// Further process the request if it hasn't already been handled.
- if (requestNotHandled) {
+ if (continueProcessing) {
// Handle the request according to the resource type.
switch (urlRequestInfo.resourceType())
{
// Mark the request struct as blocked.
requestStructPointer->dispositionInt = FilterListHelper::BLOCKED;
+ // Mark the ping as blocked by the default behavior.
+ requestStructPointer->filterListTitle = i18nc("Default HTTP ping blocking", "Default blocking of all HTTP ping requests.");
+
// Display the HTTP Ping blocked dialog.
emit displayHttpPingDialog(urlRequestInfo.requestUrl().toString());
#include "enums/FilterOptionEnum.h"
// Qt toolkit headers.
-#include <QString>
+#include <QStringList>
struct EntryStruct
{
// The strings.
- QString appliedEntry;
- QString filterOptions;
QString originalEntry;
+ QString originalFilterOptions;
- // The filter options flag.
- bool hasFilterOptions = false;
+ // The string lists.
+ QStringList appliedEntryList;
+ QStringList appliedFilterOptionsList;
+ QStringList domainList;
+
+ // The booleans.
+ bool finalMatch = false;
+ bool hasRequestOptions = false;
+ bool initialMatch = false;
+ bool singleAppliedEntry = false;
+
+ // The ints.
+ int sizeOfAppliedEntryList;
// The filter options.
+ FilterOptionEnum::Disposition domain = FilterOptionEnum::Disposition::Null;
FilterOptionEnum::Disposition font = FilterOptionEnum::Disposition::Null;
FilterOptionEnum::Disposition image = FilterOptionEnum::Disposition::Null;
FilterOptionEnum::Disposition mainFrame = FilterOptionEnum::Disposition::Null;
struct FilterListStruct
{
+ // The strings.
QString title;
QString version;
QString filePath;
- std::forward_list<EntryStruct *> mainAllowList;
- std::forward_list<EntryStruct *> mainBlockList;
- std::forward_list<EntryStruct *> initialDomainBlockList;
+
+ // The filter lists.
+ std::forward_list<EntryStruct *> *mainAllowListPointer = new std::forward_list<EntryStruct *>;
+ std::forward_list<EntryStruct *> *mainBlockListPointer = new std::forward_list<EntryStruct *>;
+ std::forward_list<EntryStruct *> *initialDomainBlockListPointer = new std::forward_list<EntryStruct *>;
+ std::forward_list<EntryStruct *> *regularExpressionBlockListPointer = new std::forward_list<EntryStruct *>;
};
#endif
QString urlStringWithSeparators;
QString truncatedUrlString;
QString truncatedUrlStringWithSeparators;
+ QString fqdn;
bool isThirdPartyRequest;
};
#endif
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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/>. -->
+
+<ui version="4.0">
+ <class>FilterEntryDialog</class>
+
+ <widget class="QWidget">
+ <layout class="QVBoxLayout">
+ <item>
+ <layout class="QHBoxLayout">
+ <!-- Filter List. -->
+ <item>
+ <widget class="QLabel" name="filterListLabel">
+ <property name="text">
+ <string>Filter List</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="filterListLineEdit">
+ <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>
+
+ <!-- Sublist. -->
+ <item>
+ <widget class="QLabel" name="sublistLabel">
+ <property name="text">
+ <string>Sublist</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="sublistListLineEdit">
+ <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>
+ </item>
+
+ <!-- Applied Entry. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="appliedEntryListLabel">
+ <property name="text">
+ <string>Applied Entry List</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="appliedEntryListLineEdit">
+ <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>
+ </item>
+
+ <item>
+ <layout class="QHBoxLayout">
+ <!-- Domain. -->
+ <item>
+ <widget class="QLabel" name="domainLabel">
+ <property name="text">
+ <string>Domain</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="domainLineEdit">
+ <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>
+
+ <!-- Third Party. -->
+ <item>
+ <widget class="QLabel" name="thirdPartyLabel">
+ <property name="text">
+ <string>Third Party</string>
+ </property>
+
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="thirdPartyLineEdit">
+ <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>
+
+ <!-- Initial Match. -->
+ <item>
+ <widget class="QLabel" name="initialMatchLabel">
+ <property name="text">
+ <string>Initial Match</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="initialMatchLineEdit">
+ <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>
+
+ <!-- Final Match. -->
+ <item>
+ <widget class="QLabel" name="finalMatchLabel">
+ <property name="text">
+ <string>Final Match</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="finalMatchLineEdit">
+ <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>
+ </item>
+
+ <item>
+ <layout class="QHBoxLayout">
+ <!-- Domain List. -->
+ <item>
+ <widget class="QLabel" name="domainListLabel">
+ <property name="text">
+ <string>Domain List</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="domainListLineEdit">
+ <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>
+ </item>
+
+ <item>
+ <!-- Request Options. -->
+ <widget class="QGroupBox">
+ <!-- Has Request Options. -->
+ <layout class="QVBoxLayout">
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </spacer>
+ </item>
+
+ <item>
+ <widget class="QCheckBox" name="hasRequestOptionsCheckBox">
+ <property name="text">
+ <string>Has Request Options</string>
+ </property>
+
+ <!-- Disabling focus allows the arrow keys to activate the buttons. -->
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+
+ <item>
+ <layout class="QGridLayout">
+ <!-- Font. -->
+ <item row="0" column="0">
+ <widget class="QLabel" name="fontLabel">
+ <property name="text">
+ <string>Font</string>
+ </property>
+
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="fontLineEdit">
+ <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>
+
+ <!-- Image. -->
+ <item row="0" column="2">
+ <widget class="QLabel" name="imageLabel">
+ <property name="text">
+ <string>Image</string>
+ </property>
+
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+
+ <item row="0" column="3">
+ <widget class="QLineEdit" name="imageLineEdit">
+ <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>
+
+ <!-- Main Frame. -->
+ <item row="0" column="4">
+ <widget class="QLabel" name="mainFrameLabel">
+ <property name="text">
+ <string>Main Frame</string>
+ </property>
+
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+
+ <item row="0" column="5">
+ <widget class="QLineEdit" name="mainFrameLineEdit">
+ <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>
+
+ <!-- Media. -->
+ <item row="0" column="6">
+ <widget class="QLabel" name="mediaLabel">
+ <property name="text">
+ <string>Media</string>
+ </property>
+
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+
+ <item row="0" column="7">
+ <widget class="QLineEdit" name="mediaLineEdit">
+ <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>
+
+ <!-- Object. -->
+ <item row="1" column="0">
+ <widget class="QLabel" name="objectLabel">
+ <property name="text">
+ <string>Object</string>
+ </property>
+
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="objectLineEdit">
+ <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>
+
+ <!-- Other. -->
+ <item row="1" column="2">
+ <widget class="QLabel" name="otherLabel">
+ <property name="text">
+ <string>Other</string>
+ </property>
+
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+
+ <item row="1" column="3">
+ <widget class="QLineEdit" name="otherLineEdit">
+ <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>
+
+ <!-- Ping. -->
+ <item row="1" column="4">
+ <widget class="QLabel" name="pingLabel">
+ <property name="text">
+ <string>Ping</string>
+ </property>
+
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+
+ <item row="1" column="5">
+ <widget class="QLineEdit" name="pingLineEdit">
+ <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>
+
+ <!-- Script. -->
+ <item row="1" column="6">
+ <widget class="QLabel" name="scriptLabel">
+ <property name="text">
+ <string>Script</string>
+ </property>
+
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+
+ <item row="1" column="7">
+ <widget class="QLineEdit" name="scriptLineEdit">
+ <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>
+
+ <!-- Style Sheet. -->
+ <item row="2" column="0">
+ <widget class="QLabel" name="styleSheetLabel">
+ <property name="text">
+ <string>Style Sheet</string>
+ </property>
+
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="styleSheetLineEdit">
+ <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>
+
+ <!-- Sub Frame. -->
+ <item row="2" column="2">
+ <widget class="QLabel" name="subFrameLabel">
+ <property name="text">
+ <string>Sub Frame</string>
+ </property>
+
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+
+ <item row="2" column="3">
+ <widget class="QLineEdit" name="subFrameLineEdit">
+ <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>
+
+ <!-- XML HTTP Request. -->
+ <item row="2" column="4">
+ <widget class="QLabel" name="xmlHttpRequestLabel">
+ <property name="text">
+ <string>XML HTTP Request</string>
+ </property>
+
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+
+ <item row="2" column="5">
+ <widget class="QLineEdit" name="xmlHttpRequestLineEdit">
+ <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>
+ </item>
+ </layout>
+ </widget>
+ </item>
+
+ <!-- Applied Filter Options. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="appliedFilterOptionsLabel">
+ <property name="text">
+ <string>Applied Filter Options</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="appliedFilterOptionsLineEdit">
+ <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>
+ </item>
+
+ <!-- Original Filter Options. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="originalFilterOptionsLabel">
+ <property name="text">
+ <string>Original Filter Options</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="originalFilterOptionsLineEdit">
+ <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>
+ </item>
+
+ <!-- Original Entry. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="originalEntryLabel">
+ <property name="text">
+ <string>Original Entry</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="originalEntryLineEdit">
+ <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>
+ </item>
+
+ <!-- Spacer. -->
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </spacer>
+ </item>
+
+ <item>
+ <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>
+</ui>
<item>
<layout class="QHBoxLayout">
<item>
- <widget class="QLabel" name="appliedEntryLabel">
+ <widget class="QLabel" name="appliedEntryListLabel">
<property name="text">
- <string>Applied Entry</string>
+ <string>Applied Entry List</string>
</property>
</widget>
</item>
<item>
- <widget class="QLineEdit" name="appliedEntryLineEdit">
+ <widget class="QLineEdit" name="appliedEntryListLineEdit">
<property name="readOnly">
<bool>true</bool>
</property>