]> gitweb.stoutner.com Git - PrivacyBrowserPC.git/blob - src/widgets/PrivacyWebEngineView.cpp
Move the new tab actions to the top of the action menu. https://redmine.stoutner...
[PrivacyBrowserPC.git] / src / widgets / PrivacyWebEngineView.cpp
1 /*
2  * Copyright 2022-2023 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 "PrivacyWebEngineView.h"
22 #include "Settings.h"
23 #include "databases/CookiesDatabase.h"
24 #include "databases/DomainsDatabase.h"
25 #include "interceptors/UrlRequestInterceptor.h"
26 #include "windows/BrowserWindow.h"
27
28 // Qt toolkit headers.
29 #include <QContextMenuEvent>
30 #include <QMenu>
31
32 // Construct the class.
33 PrivacyWebEngineView::PrivacyWebEngineView() : QWebEngineView(nullptr)
34 {
35     // Create an off-the-record profile (the default when no profile name is specified).
36     webEngineProfilePointer = new QWebEngineProfile(QLatin1String(""));
37
38     // Create a WebEngine page.
39     QWebEnginePage *webEnginePagePointer = new QWebEnginePage(webEngineProfilePointer);
40
41     // Set the WebEngine page.
42     setPage(webEnginePagePointer);
43
44     // Get handles for the various aspects of the WebEngine.
45     webEngineSettingsPointer = webEnginePagePointer->settings();
46
47     // Instantiate the URL request interceptor.
48     UrlRequestInterceptor *urlRequestInterceptorPointer = new UrlRequestInterceptor();
49
50     // Set the URL request interceptor.
51     webEngineProfilePointer->setUrlRequestInterceptor(urlRequestInterceptorPointer);
52
53     // Reapply the domain settings when the host changes.
54     connect(urlRequestInterceptorPointer, SIGNAL(applyDomainSettings(QString)), this, SLOT(applyDomainSettingsWithoutReloading(QString)));
55 }
56
57 void PrivacyWebEngineView::addCookieToList(const QNetworkCookie &cookie) const
58 {
59     //qDebug() << "Add cookie:  " << cookie.toRawForm();
60
61     // Add the new cookie to the list.
62     cookieListPointer->push_front(cookie);
63
64     // Update the cookie if it is durable and has new data.
65     if (CookiesDatabase::isUpdate(cookie))
66         CookiesDatabase::updateCookie(cookie);
67
68     // Update the cookies action.
69     emit updateCookiesAction(cookieListPointer->size());
70 }
71
72 void PrivacyWebEngineView::applyDomainSettingsWithoutReloading(const QString &hostname)
73 {
74     // Apply the domain settings  `false` does not reload the website.
75     applyDomainSettings(hostname, false);
76 }
77
78 void PrivacyWebEngineView::applyDomainSettings(const QString &hostname, const bool reloadWebsite)
79 {
80     // Get the record for the hostname.
81     QSqlQuery domainQuery = DomainsDatabase::getDomainQuery(hostname);
82
83     // Check if the hostname has domain settings.
84     if (domainQuery.isValid())  // The hostname has domain settings.
85     {
86         // Get the domain record.
87         QSqlRecord domainRecord = domainQuery.record();
88
89         // Store the domain settings name.
90         domainSettingsName = domainRecord.field(DomainsDatabase::DOMAIN_NAME).value().toString();
91
92         // Set the JavaScript status.
93         switch (domainRecord.field(DomainsDatabase::JAVASCRIPT).value().toInt())
94         {
95             // Set the default JavaScript status.
96             case (DomainsDatabase::SYSTEM_DEFAULT):
97             {
98                 webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, Settings::javaScriptEnabled());
99
100                 break;
101             }
102
103             // Disable JavaScript.
104             case (DomainsDatabase::DISABLED):
105             {
106                 webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, false);
107
108                 break;
109             }
110
111             // Enable JavaScript.
112             case (DomainsDatabase::ENABLED):
113             {
114                 webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
115
116                 break;
117             }
118         }
119
120         // Set the local storage status.
121         switch (domainRecord.field(DomainsDatabase::LOCAL_STORAGE).value().toInt())
122         {
123             // Set the default local storage status.
124             case (DomainsDatabase::SYSTEM_DEFAULT):
125             {
126                 localStorageEnabled = Settings::localStorageEnabled();
127
128                 break;
129             }
130
131             // Disable local storage.
132             case (DomainsDatabase::DISABLED):
133             {
134                 localStorageEnabled = false;
135
136                 break;
137             }
138
139             // Enable local storage.
140             case (DomainsDatabase::ENABLED):
141             {
142                 localStorageEnabled = true;
143
144                 break;
145             }
146         }
147
148         // Set the DOM storage status.
149         switch (domainRecord.field(DomainsDatabase::DOM_STORAGE).value().toInt())
150         {
151             // Set the default DOM storage status.  QWebEngineSettings confusingly calls this local storage.
152             case (DomainsDatabase::SYSTEM_DEFAULT):
153             {
154                 webEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, Settings::domStorageEnabled());
155
156                 break;
157             }
158
159             // Disable DOM storage.  QWebEngineSettings confusingly calls this local storage.
160             case (DomainsDatabase::DISABLED):
161             {
162                 webEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, false);
163
164                 break;
165             }
166
167             // Enable DOM storage.  QWebEngineSettings confusingly calls this local storage.
168             case (DomainsDatabase::ENABLED):
169             {
170                 webEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
171
172                 break;
173             }
174         }
175
176         // Set the user agent.
177         webEngineProfilePointer->setHttpUserAgent(UserAgentHelper::getResultingDomainSettingsUserAgent(domainRecord.field(DomainsDatabase::USER_AGENT).value().toString()));
178
179         // Check if a custom zoom factor is set.
180         if (domainRecord.field(DomainsDatabase::ZOOM_FACTOR).value().toInt())
181         {
182             // Store the current zoom factor.
183             setZoomFactor(domainRecord.field(DomainsDatabase::CUSTOM_ZOOM_FACTOR).value().toDouble());
184         }
185         else
186         {
187             // Reset the current zoom factor.
188             setZoomFactor(Settings::zoomFactor());
189         }
190     }
191     else  // The hostname does not have domain settings.
192     {
193         // Reset the domain settings name.
194         domainSettingsName = QLatin1String("");
195
196         // Set the JavaScript status.
197         webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, Settings::javaScriptEnabled());
198
199         // Set the local storage status.
200         localStorageEnabled = Settings::localStorageEnabled();
201
202         // Set DOM storage.  In QWebEngineSettings it is called Local Storage.
203         webEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, Settings::domStorageEnabled());
204
205         // Set the user agent.
206         webEngineProfilePointer->setHttpUserAgent(UserAgentHelper::getUserAgentFromDatabaseName(Settings::userAgent()));
207
208         // Set the zoom factor.
209         setZoomFactor(Settings::zoomFactor());
210     }
211
212     // Reload the website if requested.
213     if (reloadWebsite)
214         reload();
215
216     // Update the UI.
217     emit updateUi(this);
218 }
219
220 void PrivacyWebEngineView::contextMenuEvent(QContextMenuEvent *contextMenuEvent) {
221     // Get a handle for the
222     QWebEnginePage *webEnginePagePointer = page();
223
224     // Get a handle for the menu.
225     QMenu *contextMenu = webEnginePagePointer->createStandardContextMenu();
226
227     // Get the list of context menu actions.
228     const QList<QAction *> contextMenuActionsList = contextMenu->actions();
229
230     // Add the open link in new background tab action if the context menu already contains the open link in new window action.
231     if (contextMenuActionsList.contains(webEnginePagePointer->action(QWebEnginePage::OpenLinkInNewWindow)))
232     {
233         // Move the open in new tab action to the top of the list.
234         contextMenu->insertAction(webEnginePagePointer->action(QWebEnginePage::Back), webEnginePagePointer->action(QWebEnginePage::OpenLinkInNewTab));
235
236         // Add the open link in background tab action below the open in new tab action.
237         contextMenu->insertAction(webEnginePagePointer->action(QWebEnginePage::Back), webEnginePagePointer->action(QWebEnginePage::OpenLinkInNewBackgroundTab));
238
239         // Move the open in new window action below the open in background tab action.
240         contextMenu->insertAction(webEnginePagePointer->action(QWebEnginePage::Back), webEnginePagePointer->action(QWebEnginePage::OpenLinkInNewWindow));
241
242         // Add a separator below the open in new window action.
243         contextMenu->insertSeparator(webEnginePagePointer->action(QWebEnginePage::Back));
244     }
245
246     // Display the menu using the location in the context menu event.
247     contextMenu->popup(contextMenuEvent->globalPos());
248 }
249
250 QWebEngineView* PrivacyWebEngineView::createWindow(QWebEnginePage::WebWindowType webWindowType) {
251     // Get a handle for the browser window.
252     BrowserWindow *browserWindowPointer = qobject_cast<BrowserWindow*>(window());
253
254     // Create the requested window type.
255     switch (webWindowType)
256     {
257         case QWebEnginePage::WebBrowserTab:
258         {
259             // Create the new tab and return the privacy WebEngine view pointer.  `true` removes the focus from the blank URL line edit.
260             // The new privacy WebEngine view pointer is returned so it can be populated with the link from the context menu.
261             return browserWindowPointer->tabWidgetPointer->addTab(true);
262         }
263
264         case QWebEnginePage::WebBrowserWindow:
265         {
266             // Create a new browser window.
267             BrowserWindow *newBrowserWindowPointer = new BrowserWindow();
268
269             // Show the new browser window.
270             newBrowserWindowPointer->show();
271
272             // The new privacy WebEngine view pointer is returned so it can be populated with the link from the context menu.
273             return newBrowserWindowPointer->tabWidgetPointer->loadBlankInitialWebsite();
274         }
275
276         case QWebEnginePage::WebBrowserBackgroundTab:
277         {
278             // Create the new tab and return the privacy WebEngine view pointer.  `false` does not clear the URL line edit.  `true` creates a background tab.
279             // The new privacy WebEngine view pointer is returned so it can be populated with the link from the context menu.
280             return browserWindowPointer->tabWidgetPointer->addTab(false, true);
281         }
282
283         default:
284         {
285             // Return a null pointer for opening a web dialog.
286             return nullptr;
287         }
288     }
289 }
290
291 void PrivacyWebEngineView::removeCookieFromList(const QNetworkCookie &cookie) const
292 {
293     //qDebug() << "Remove cookie:  " << cookie.toRawForm();
294
295     // Remove the cookie from the list.
296     cookieListPointer->remove(cookie);
297
298     // Update the cookies action.
299     emit updateCookiesAction(cookieListPointer->size());
300 }