2 * Copyright 2024 Soren Stoutner <soren@stoutner.com>.
4 * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
6 * Privacy Browser PC is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * Privacy Browser PC is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
20 // Application headers.
21 #include "FilterListsDialog.h"
22 #include "GlobalVariables.h"
23 #include "ui_FilterListsDialog.h"
24 #include "dialogs/FilterEntryDialog.h"
26 // Qt toolkit headers.
29 #include <QTextStream>
31 // Construct the class.
32 FilterListsDialog::FilterListsDialog(QWidget *parentWidgetPointer) : QDialog(parentWidgetPointer)
34 // Set the window title.
35 setWindowTitle(i18nc("The filter lists dialog window title", "Filter Lists"));
37 // Set the window modality.
38 setWindowModality(Qt::WindowModality::ApplicationModal);
40 // Instantiate the filter lists dialog UI.
41 Ui::FilterListsDialog filterListsDialogUi;
44 filterListsDialogUi.setupUi(this);
46 // Get handles for the views.
47 filterListComboBoxPointer = filterListsDialogUi.filterListComboBox;
48 filterListTextEditPointer = filterListsDialogUi.filterListTextEdit;
49 sublistComboBoxPointer = filterListsDialogUi.sublistComboBox;
50 sublistTableWidgetPointer = filterListsDialogUi.sublistTableWidget;
51 QDialogButtonBox *dialogButtonBoxPointer = filterListsDialogUi.dialogButtonBox;
53 // Select an entire row at a time.
54 sublistTableWidgetPointer->setSelectionBehavior(QAbstractItemView::SelectRows);
56 // Open the filter entry dialog when a cell is clicked.
57 connect(sublistTableWidgetPointer, SIGNAL(cellClicked(int, int)), this, SLOT(showFilterEntryDialog(int)));
59 // Connect the combo boxes.
60 connect(filterListComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(populateFilterListTextEdit(int)));
61 connect(sublistComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(populateTableWidget(int)));
63 // Connect the buttons.
64 connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(close()));
66 // Populate the filter list combo box.
67 populateFilterListComboBox(globalFilterListHelperPointer->ultraPrivacyStructPointer);
68 populateFilterListComboBox(globalFilterListHelperPointer->ultraListStructPointer);
69 populateFilterListComboBox(globalFilterListHelperPointer->easyPrivacyStructPointer);
70 populateFilterListComboBox(globalFilterListHelperPointer->easyListStructPointer);
71 populateFilterListComboBox(globalFilterListHelperPointer->fanboyAnnoyanceStructPointer);
74 std::forward_list<EntryStruct *>* FilterListsDialog::getFilterListForwardList(FilterListStruct *filterListStructPointer) const
76 // Return the filter list forward list.
77 switch (sublistComboBoxPointer->currentIndex())
79 case FilterListHelper::MAIN_ALLOWLIST: return filterListStructPointer->mainAllowListPointer; // The main allow list.
80 case FilterListHelper::MAIN_BLOCKLIST: return filterListStructPointer->mainBlockListPointer; // The main block list.
81 case FilterListHelper::INITIAL_DOMAIN_BLOCKLIST: return filterListStructPointer->initialDomainBlockListPointer; // The initial domain block list.
82 case FilterListHelper::REGULAR_EXPRESSION_BLOCKLIST: return filterListStructPointer->regularExpressionBlockListPointer; // The regular expression block list.
85 // This return statement should never be reached.
86 return new std::forward_list<EntryStruct *>;
89 FilterListStruct *FilterListsDialog::getFilterListStruct(int filterListComboBoxIndex) const
91 // Return the filer list struct.
92 switch (filterListComboBoxIndex)
94 case 0: return globalFilterListHelperPointer->ultraPrivacyStructPointer; // UltraPrivacy.
95 case 1: return globalFilterListHelperPointer->ultraListStructPointer; // UltraList.
96 case 2: return globalFilterListHelperPointer->easyPrivacyStructPointer; // EasyPrivacy.
97 case 3: return globalFilterListHelperPointer->easyListStructPointer; // EasyList.
98 case 4: return globalFilterListHelperPointer->fanboyAnnoyanceStructPointer; // Fanboy's Annoyance List.
101 // This return statement should never be reached.
102 return new FilterListStruct;
105 void FilterListsDialog::populateFilterListComboBox(const FilterListStruct *filterListStructPointer) const
107 // Populate the filter list combo box.
108 filterListComboBoxPointer->addItem(i18nc("Filter list combo box items", "%1 - %2", filterListStructPointer->title, filterListStructPointer->version));
111 void FilterListsDialog::populateFilterListTextEdit(int filterListComboBoxIndex) const
113 // Get the filter list struct.
114 FilterListStruct *filterListStructPointer = getFilterListStruct(filterListComboBoxIndex);
116 // Get the filter list file.
117 QFile filterListFile(filterListStructPointer->filePath);
119 // Open the filter list file.
120 filterListFile.open(QIODevice::ReadOnly);
122 // Create a filter list text stream.
123 QTextStream filterListTextStream(&filterListFile);
125 // Populate the text edit.
126 filterListTextEditPointer->setText(filterListTextStream.readAll());
128 // Clear the sublist combo box.
129 sublistComboBoxPointer->clear();
131 // Calculate the size of the filter lists.
132 int mainAllowListSize = distance(filterListStructPointer->mainAllowListPointer->begin(), filterListStructPointer->mainAllowListPointer->end());
133 int mainBlockListSize = distance(filterListStructPointer->mainBlockListPointer->begin(), filterListStructPointer->mainBlockListPointer->end());
134 int initialDomainBlockListSize = distance(filterListStructPointer->initialDomainBlockListPointer->begin(), filterListStructPointer->initialDomainBlockListPointer->end());
135 int regularExpressionBlockListSize = distance(filterListStructPointer->regularExpressionBlockListPointer->begin(), filterListStructPointer->regularExpressionBlockListPointer->end());
137 // Get the translated filter list names.
138 QString mainAllowListName = globalFilterListHelperPointer->getSublistName(FilterListHelper::MAIN_ALLOWLIST);
139 QString mainBlockListName = globalFilterListHelperPointer->getSublistName(FilterListHelper::MAIN_BLOCKLIST);
140 QString initialDomainBlockListName = globalFilterListHelperPointer->getSublistName(FilterListHelper::INITIAL_DOMAIN_BLOCKLIST);
141 QString regularExpressionBlockListName = globalFilterListHelperPointer->getSublistName(FilterListHelper::REGULAR_EXPRESSION_BLOCKLIST);
143 // Populate the sublist combo box.
144 sublistComboBoxPointer->addItem(i18nc("The main allow list", "%1 - %2", mainAllowListName, mainAllowListSize));
145 sublistComboBoxPointer->addItem(i18nc("The main block list", "%1 - %2", mainBlockListName, mainBlockListSize));
146 sublistComboBoxPointer->addItem(i18nc("The initial domain block list", "%1 - %2", initialDomainBlockListName, initialDomainBlockListSize));
147 sublistComboBoxPointer->addItem(i18nc("the regular expression block list", "%1 - %2", regularExpressionBlockListName, regularExpressionBlockListSize));
150 void FilterListsDialog::populateTableWidget(int sublistComboBoxIndex) const
152 // Populate the table widget if there is at least one item in teh sublist combo box.
153 if (sublistComboBoxIndex >= 0)
155 // Wipe the current table.
156 sublistTableWidgetPointer->clear();
157 sublistTableWidgetPointer->setColumnCount(0);
158 sublistTableWidgetPointer->setRowCount(0);
160 // Get the filter list struct.
161 FilterListStruct *filterListStructPointer = getFilterListStruct(filterListComboBoxPointer->currentIndex());
163 // Create a filter list forward list.
164 std::forward_list<EntryStruct *> *filterListForwardListPointer;
166 // Populate the filter list forward list.
167 switch (sublistComboBoxIndex)
169 case FilterListHelper::MAIN_ALLOWLIST: // The main allow list.
170 filterListForwardListPointer = filterListStructPointer->mainAllowListPointer;
173 case FilterListHelper::MAIN_BLOCKLIST: // The main block list.
174 filterListForwardListPointer = filterListStructPointer->mainBlockListPointer;
177 case FilterListHelper::INITIAL_DOMAIN_BLOCKLIST: // The initial domain block list.
178 filterListForwardListPointer = filterListStructPointer->initialDomainBlockListPointer;
181 case FilterListHelper::REGULAR_EXPRESSION_BLOCKLIST: // the regular expression block list.
182 filterListForwardListPointer = filterListStructPointer->regularExpressionBlockListPointer;
186 // Create the columns.
187 sublistTableWidgetPointer->setColumnCount(21);
189 // Create the table headers.
190 QTableWidgetItem *appliedEntryListHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist applied entry list header", "Applied Entry List"));
191 QTableWidgetItem *initialMatchHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist initial match header", "Initial Match"));
192 QTableWidgetItem *finalMatchHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist final match header", "Final Match"));
193 QTableWidgetItem *domainHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist domain header", "Domain"));
194 QTableWidgetItem *domainListHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist domain list Header", "Domain List"));
195 QTableWidgetItem *thirdPartyHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist third-party header", "Third Party"));
196 QTableWidgetItem *hasRequestOptionsHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist has request options header", "Has Request Options"));
197 QTableWidgetItem *fontHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist font header", "Font"));
198 QTableWidgetItem *imageHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist image header", "Image"));
199 QTableWidgetItem *mainFrameHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist main frame header", "Main Frame"));
200 QTableWidgetItem *mediaHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist media header", "Media"));
201 QTableWidgetItem *objectHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist object header", "Object"));
202 QTableWidgetItem *otherHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist object header", "Other"));
203 QTableWidgetItem *pingHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist ping header", "Ping"));
204 QTableWidgetItem *scriptHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist script header", "Script"));
205 QTableWidgetItem *styleSheetHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist style sheet header", "Style Sheet"));
206 QTableWidgetItem *subFrameHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist sub frame header", "Sub Frame"));
207 QTableWidgetItem *xmlHttpRequestHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist XML HTTP request header", "XML HTTP Request"));
208 QTableWidgetItem *appliedFilterOptionsHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist applied filter options header", "Applied Filter Options"));
209 QTableWidgetItem *originalFilterOptionsHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist original filter options header", "Original Filter Options"));
210 QTableWidgetItem *originalEntryHeaderItemPointer = new QTableWidgetItem(i18nc("Sublist original entry header", "Original Entry"));
212 // Set the horizontal headers.
213 sublistTableWidgetPointer->setHorizontalHeaderItem(0, appliedEntryListHeaderItemPointer);
214 sublistTableWidgetPointer->setHorizontalHeaderItem(1, initialMatchHeaderItemPointer);
215 sublistTableWidgetPointer->setHorizontalHeaderItem(2, finalMatchHeaderItemPointer);
216 sublistTableWidgetPointer->setHorizontalHeaderItem(3, domainHeaderItemPointer);
217 sublistTableWidgetPointer->setHorizontalHeaderItem(4, domainListHeaderItemPointer);
218 sublistTableWidgetPointer->setHorizontalHeaderItem(5, thirdPartyHeaderItemPointer);
219 sublistTableWidgetPointer->setHorizontalHeaderItem(6, hasRequestOptionsHeaderItemPointer);
220 sublistTableWidgetPointer->setHorizontalHeaderItem(7, fontHeaderItemPointer);
221 sublistTableWidgetPointer->setHorizontalHeaderItem(8, imageHeaderItemPointer);
222 sublistTableWidgetPointer->setHorizontalHeaderItem(9, mainFrameHeaderItemPointer);
223 sublistTableWidgetPointer->setHorizontalHeaderItem(10, mediaHeaderItemPointer);
224 sublistTableWidgetPointer->setHorizontalHeaderItem(11, objectHeaderItemPointer);
225 sublistTableWidgetPointer->setHorizontalHeaderItem(12, otherHeaderItemPointer);
226 sublistTableWidgetPointer->setHorizontalHeaderItem(13, pingHeaderItemPointer);
227 sublistTableWidgetPointer->setHorizontalHeaderItem(14, scriptHeaderItemPointer);
228 sublistTableWidgetPointer->setHorizontalHeaderItem(15, styleSheetHeaderItemPointer);
229 sublistTableWidgetPointer->setHorizontalHeaderItem(16, subFrameHeaderItemPointer);
230 sublistTableWidgetPointer->setHorizontalHeaderItem(17, xmlHttpRequestHeaderItemPointer);
231 sublistTableWidgetPointer->setHorizontalHeaderItem(18, appliedFilterOptionsHeaderItemPointer);
232 sublistTableWidgetPointer->setHorizontalHeaderItem(19, originalFilterOptionsHeaderItemPointer);
233 sublistTableWidgetPointer->setHorizontalHeaderItem(20, originalEntryHeaderItemPointer);
235 // Initialize the row counter.
238 // Populate the table.
239 for (auto filterListEntry = filterListForwardListPointer->begin(); filterListEntry != filterListForwardListPointer->end(); ++filterListEntry) {
240 // Get the entry struct.
241 EntryStruct *entryStructPointer = *filterListEntry;
244 sublistTableWidgetPointer->insertRow(rowCounter);
246 // Create the entry items.
247 QTableWidgetItem *appliedEntryListItemPointer = new QTableWidgetItem(entryStructPointer->appliedEntryList.join(QLatin1String(" * ")));
248 QTableWidgetItem *initialMatchItemPointer = new QTableWidgetItem(entryStructPointer->initialMatch ? i18n("Yes") : QLatin1String());
249 QTableWidgetItem *finalMatchItemPointer = new QTableWidgetItem(entryStructPointer->finalMatch ? i18n("Yes") : QLatin1String());
250 QTableWidgetItem *domainItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->domain));
251 QTableWidgetItem *domainListItemPointer = new QTableWidgetItem(entryStructPointer->domainList.join(QLatin1String(" | ")));
252 QTableWidgetItem *thirdPartyItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->thirdParty));
253 QTableWidgetItem *hasRequestOptionsItemPointer = new QTableWidgetItem(entryStructPointer->hasRequestOptions ? i18n("Yes") : QLatin1String());
254 QTableWidgetItem *fontItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->font));
255 QTableWidgetItem *imageItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->image));
256 QTableWidgetItem *mainFrameItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->mainFrame));
257 QTableWidgetItem *mediaItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->media));
258 QTableWidgetItem *objectItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->object));
259 QTableWidgetItem *otherItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->other));
260 QTableWidgetItem *pingItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->ping));
261 QTableWidgetItem *scriptItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->script));
262 QTableWidgetItem *styleSheetItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->styleSheet));
263 QTableWidgetItem *subFrameItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->subFrame));
264 QTableWidgetItem *xmlHttpRequestItemPointer = new QTableWidgetItem(globalFilterListHelperPointer->getRequestOptionDispositionString(entryStructPointer->xmlHttpRequest));
265 QTableWidgetItem *appliedFilterOptionsItemPointer = new QTableWidgetItem(entryStructPointer->appliedFilterOptionsList.join(QLatin1String(" , ")));
266 QTableWidgetItem *originalFilterOptionsItemPointer = new QTableWidgetItem(entryStructPointer->originalFilterOptions);
267 QTableWidgetItem *originalEntryItemPointer = new QTableWidgetItem(entryStructPointer->originalEntry);
269 // Add the entries to the table.
270 sublistTableWidgetPointer->setItem(rowCounter, 0, appliedEntryListItemPointer);
271 sublistTableWidgetPointer->setItem(rowCounter, 1, initialMatchItemPointer);
272 sublistTableWidgetPointer->setItem(rowCounter, 2, finalMatchItemPointer);
273 sublistTableWidgetPointer->setItem(rowCounter, 3, domainItemPointer);
274 sublistTableWidgetPointer->setItem(rowCounter, 4, domainListItemPointer);
275 sublistTableWidgetPointer->setItem(rowCounter, 5, thirdPartyItemPointer);
276 sublistTableWidgetPointer->setItem(rowCounter, 6, hasRequestOptionsItemPointer);
277 sublistTableWidgetPointer->setItem(rowCounter, 7, fontItemPointer);
278 sublistTableWidgetPointer->setItem(rowCounter, 8, imageItemPointer);
279 sublistTableWidgetPointer->setItem(rowCounter, 9, mainFrameItemPointer);
280 sublistTableWidgetPointer->setItem(rowCounter, 10, mediaItemPointer);
281 sublistTableWidgetPointer->setItem(rowCounter, 11, objectItemPointer);
282 sublistTableWidgetPointer->setItem(rowCounter, 12, otherItemPointer);
283 sublistTableWidgetPointer->setItem(rowCounter, 13, pingItemPointer);
284 sublistTableWidgetPointer->setItem(rowCounter, 14, scriptItemPointer);
285 sublistTableWidgetPointer->setItem(rowCounter, 15, styleSheetItemPointer);
286 sublistTableWidgetPointer->setItem(rowCounter, 16, subFrameItemPointer);
287 sublistTableWidgetPointer->setItem(rowCounter, 17, xmlHttpRequestItemPointer);
288 sublistTableWidgetPointer->setItem(rowCounter, 18, appliedFilterOptionsItemPointer);
289 sublistTableWidgetPointer->setItem(rowCounter, 19, originalFilterOptionsItemPointer);
290 sublistTableWidgetPointer->setItem(rowCounter, 20, originalEntryItemPointer);
292 // Increment the row counter.
296 // Get the table header view.
297 QHeaderView *headerViewPointer = sublistTableWidgetPointer->horizontalHeader();
299 // Resize the header to fit the contents.
300 headerViewPointer->resizeSections(QHeaderView::ResizeToContents);
302 // Connect changes in the sort order.
303 connect(headerViewPointer, SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SLOT(sortTable(int, Qt::SortOrder)));
307 void FilterListsDialog::showFilterEntryDialog(int row)
309 // Get the filter list struct.
310 FilterListStruct *filterListStructPointer = getFilterListStruct(filterListComboBoxPointer->currentIndex());
312 // Create a sublist title.
313 QString sublistTitle = globalFilterListHelperPointer->getSublistName(sublistComboBoxPointer->currentIndex());
315 // Instantiate the filter entry dialog.
316 FilterEntryDialog *filterEntryDialogPointer = new FilterEntryDialog(this, sublistTableWidgetPointer, row, filterListStructPointer->title, sublistTitle);
319 filterEntryDialogPointer->show();
322 void FilterListsDialog::sortTable(int column, Qt::SortOrder sortOrder) const
325 sublistTableWidgetPointer->sortItems(column, sortOrder);