]> gitweb.stoutner.com Git - PrivacyBrowserPC.git/blob - src/dialogs/FilterListsDialog.cpp
Finish block list implementation.
[PrivacyBrowserPC.git] / src / dialogs / FilterListsDialog.cpp
1 /*
2  * Copyright 2024 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 // Application headers.
21 #include "FilterListsDialog.h"
22 #include "GlobalVariables.h"
23 #include "ui_FilterListsDialog.h"
24 #include "dialogs/FilterEntryDialog.h"
25
26 // Qt toolkit headers.
27 #include <QDebug>
28 #include <QFile>
29 #include <QTextStream>
30
31 // Construct the class.
32 FilterListsDialog::FilterListsDialog(QWidget *parentWidgetPointer) : QDialog(parentWidgetPointer)
33 {
34     // Set the window title.
35     setWindowTitle(i18nc("The filter lists dialog window title", "Filter Lists"));
36
37     // Set the window modality.
38     setWindowModality(Qt::WindowModality::ApplicationModal);
39
40     // Instantiate the filter lists dialog UI.
41     Ui::FilterListsDialog filterListsDialogUi;
42
43     // Setup the UI.
44     filterListsDialogUi.setupUi(this);
45
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;
52
53     // Select an entire row at a time.
54     sublistTableWidgetPointer->setSelectionBehavior(QAbstractItemView::SelectRows);
55
56     // Open the filter entry dialog when a cell is clicked.
57     connect(sublistTableWidgetPointer, SIGNAL(cellClicked(int, int)), this, SLOT(showFilterEntryDialog(int)));
58
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)));
62
63     // Connect the buttons.
64     connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(close()));
65
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);
72 }
73
74 std::forward_list<EntryStruct *>* FilterListsDialog::getFilterListForwardList(FilterListStruct *filterListStructPointer) const
75 {
76     // Return the filter list forward list.
77     switch (sublistComboBoxPointer->currentIndex())
78     {
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.
83     }
84
85     // This return statement should never be reached.
86     return new std::forward_list<EntryStruct *>;
87 }
88
89 FilterListStruct *FilterListsDialog::getFilterListStruct(int filterListComboBoxIndex) const
90 {
91     // Return the filer list struct.
92     switch (filterListComboBoxIndex)
93     {
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.
99     }
100
101     // This return statement should never be reached.
102     return new FilterListStruct;
103 }
104
105 void FilterListsDialog::populateFilterListComboBox(const FilterListStruct *filterListStructPointer) const
106 {
107     // Populate the filter list combo box.
108     filterListComboBoxPointer->addItem(i18nc("Filter list combo box items", "%1 - %2", filterListStructPointer->title, filterListStructPointer->version));
109 }
110
111 void FilterListsDialog::populateFilterListTextEdit(int filterListComboBoxIndex) const
112 {
113     // Get the filter list struct.
114     FilterListStruct *filterListStructPointer = getFilterListStruct(filterListComboBoxIndex);
115
116     // Get the filter list file.
117     QFile filterListFile(filterListStructPointer->filePath);
118
119     // Open the filter list file.
120     filterListFile.open(QIODevice::ReadOnly);
121
122     // Create a filter list text stream.
123     QTextStream filterListTextStream(&filterListFile);
124
125     // Populate the text edit.
126     filterListTextEditPointer->setText(filterListTextStream.readAll());
127
128     // Clear the sublist combo box.
129     sublistComboBoxPointer->clear();
130
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());
136
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);
142
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));
148 }
149
150 void FilterListsDialog::populateTableWidget(int sublistComboBoxIndex) const
151 {
152     // Populate the table widget if there is at least one item in teh sublist combo box.
153     if (sublistComboBoxIndex >= 0)
154     {
155         // Wipe the current table.
156         sublistTableWidgetPointer->clear();
157         sublistTableWidgetPointer->setColumnCount(0);
158         sublistTableWidgetPointer->setRowCount(0);
159
160         // Get the filter list struct.
161         FilterListStruct *filterListStructPointer = getFilterListStruct(filterListComboBoxPointer->currentIndex());
162
163         // Create a filter list forward list.
164         std::forward_list<EntryStruct *> *filterListForwardListPointer;
165
166         // Populate the filter list forward list.
167         switch (sublistComboBoxIndex)
168         {
169             case FilterListHelper::MAIN_ALLOWLIST:  // The main allow list.
170                 filterListForwardListPointer = filterListStructPointer->mainAllowListPointer;
171                 break;
172
173             case FilterListHelper::MAIN_BLOCKLIST:  // The main block list.
174                 filterListForwardListPointer = filterListStructPointer->mainBlockListPointer;
175                 break;
176
177             case FilterListHelper::INITIAL_DOMAIN_BLOCKLIST:  // The initial domain block list.
178                 filterListForwardListPointer = filterListStructPointer->initialDomainBlockListPointer;
179                 break;
180
181             case FilterListHelper::REGULAR_EXPRESSION_BLOCKLIST:  // the regular expression block list.
182                 filterListForwardListPointer = filterListStructPointer->regularExpressionBlockListPointer;
183                 break;
184         }
185
186         // Create the columns.
187         sublistTableWidgetPointer->setColumnCount(21);
188
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"));
211
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);
234
235         // Initialize the row counter.
236         int rowCounter = 0;
237
238         // Populate the table.
239         for (auto filterListEntry = filterListForwardListPointer->begin(); filterListEntry != filterListForwardListPointer->end(); ++filterListEntry) {
240             // Get the entry struct.
241             EntryStruct *entryStructPointer = *filterListEntry;
242
243             // Add a new row.
244             sublistTableWidgetPointer->insertRow(rowCounter);
245
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);
268
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);
291
292             // Increment the row counter.
293             ++rowCounter;
294         }
295
296         // Get the table header view.
297         QHeaderView *headerViewPointer = sublistTableWidgetPointer->horizontalHeader();
298
299         // Resize the header to fit the contents.
300         headerViewPointer->resizeSections(QHeaderView::ResizeToContents);
301
302         // Connect changes in the sort order.
303         connect(headerViewPointer, SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SLOT(sortTable(int, Qt::SortOrder)));
304     }
305 }
306
307 void FilterListsDialog::showFilterEntryDialog(int row)
308 {
309     // Get the filter list struct.
310     FilterListStruct *filterListStructPointer = getFilterListStruct(filterListComboBoxPointer->currentIndex());
311
312     // Create a sublist title.
313     QString sublistTitle = globalFilterListHelperPointer->getSublistName(sublistComboBoxPointer->currentIndex());
314
315     // Instantiate the filter entry dialog.
316     FilterEntryDialog *filterEntryDialogPointer = new FilterEntryDialog(this, sublistTableWidgetPointer, row, filterListStructPointer->title, sublistTitle);
317
318     // Show the dialog.
319     filterEntryDialogPointer->show();
320 }
321
322 void FilterListsDialog::sortTable(int column, Qt::SortOrder sortOrder) const
323 {
324     // Sort the table.
325     sublistTableWidgetPointer->sortItems(column, sortOrder);
326 }