]> gitweb.stoutner.com Git - PrivacyBrowserPC.git/blob - src/MainView.cpp
9ddf1fb4524177e07627da213c047bb9d7b6354e
[PrivacyBrowserPC.git] / src / MainView.cpp
1 /*
2  * Copyright © 2022 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 "BrowserWindow.h"
22 #include "MainView.h"
23 #include "MouseEventFilter.h"
24 #include "Settings.h"
25 #include "ui_MainView.h"
26 #include "helpers/SearchEngineHelper.h"
27 #include "helpers/UserAgentHelper.h"
28
29 // Qt framework headers.
30 #include <QWebEngineProfile>
31
32 MainView::MainView(QWidget *parent) : QWidget(parent)
33 {
34     // Instantiate the mainview UI.
35     Ui::MainView mainViewUi;
36
37     // Setup the UI.
38     mainViewUi.setupUi(this);
39
40     // Get handles for the views.
41     backButtonPointer = mainViewUi.backButton;
42     forwardButtonPointer = mainViewUi.forwardButton;
43     QPushButton *refreshButtonPointer = mainViewUi.refreshButton;
44     QPushButton *homeButtonPointer = mainViewUi.homeButton;
45     urlLineEditPointer = mainViewUi.urlLineEdit;
46     javaScriptButtonPointer = mainViewUi.javaScript;
47     webEngineViewPointer = mainViewUi.webEngineView;
48
49     // Get handles for the aspects of the WebEngine.
50     QWebEnginePage *webEnginePagePointer = webEngineViewPointer->page();
51     webEngineHistoryPointer = webEnginePagePointer->history();
52     webEngineProfilePointer = webEnginePagePointer->profile();
53     webEngineSettingsPointer = webEngineViewPointer->settings();
54
55     // Update the webengine view from the URL line edit.
56     connect(urlLineEditPointer, SIGNAL(returnKeyPressed(const QString)), this, SLOT(loadUrlFromTextBox(const QString)));
57
58     // Update the URL line edit form the webengine view.
59     connect(webEngineViewPointer, SIGNAL(loadStarted()), this, SLOT(updateInterface()));
60     connect(webEngineViewPointer, SIGNAL(loadProgress(const int)), this, SLOT(updateInterface()));
61     connect(webEngineViewPointer, SIGNAL(loadFinished(const bool)), this, SLOT(updateInterface()));
62
63     // Setup the URL bar buttons.
64     connect(backButtonPointer, SIGNAL(clicked()), webEngineViewPointer, SLOT(back()));
65     connect(forwardButtonPointer, SIGNAL(clicked()), webEngineViewPointer, SLOT(forward()));
66     connect(refreshButtonPointer, SIGNAL(clicked()), webEngineViewPointer, SLOT(reload()));
67     connect(homeButtonPointer, SIGNAL(clicked()), this, SLOT(goHome()));
68     connect(javaScriptButtonPointer, SIGNAL(clicked()), this, SLOT(toggleJavaScript()));
69
70     // Instantiate the mouse event pointer.
71     MouseEventFilter *mouseEventFilterPointer = new MouseEventFilter(webEngineViewPointer);
72
73     // Install the mouse event filter.
74     qApp->installEventFilter(mouseEventFilterPointer);
75
76     // Listen for hovered link URLs.
77     connect(webEnginePagePointer, SIGNAL(linkHovered(const QString)), this, SLOT(pageLinkHovered(const QString)));
78
79     // Disable the cache.
80     webEngineProfilePointer->setHttpCacheType(QWebEngineProfile::NoCache);
81
82     // Don't allow JavaScript to open windows.
83     webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, false);
84
85     // Set the zoom factor.
86     webEngineViewPointer->setZoomFactor(Settings::zoomFactor());
87
88     // Apply the application settings.
89     applyApplicationSettings();
90
91     // Apply the domain settings.  `false` does not reload the website.
92     applyDomainSettings(false);
93
94     // Set the focus on the WebEngine view.
95     webEngineViewPointer->setFocus();
96
97     // Get the arguments.
98     QStringList argumentsStringList = qApp->arguments();
99
100     // Check to see if the arguments lists contains a URL.
101     if (argumentsStringList.size() > 1)
102     {
103         // Load the URL from the arguments list.
104         webEngineViewPointer->setUrl(QUrl::fromUserInput(argumentsStringList.at(1)));
105     }
106     else
107     {
108         // Load the homepage.
109         goHome();
110     }
111 }
112
113 void MainView::applyApplicationSettings() const
114 {
115     // TODO.
116 }
117
118 // This exists as a separate function from `applyDomainSettings()` so it can be listed as a slot and function without the need for a boolean argument.
119 void MainView::applyDomainSettingsAndReload() const
120 {
121     // Apply the domain setings.  `true` reloads the website.
122     applyDomainSettings(true);
123 }
124
125 void MainView::applyDomainSettings(bool reloadWebsite) const
126 {
127     // Set the JavaScript status.
128     webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, Settings::javaScript());
129
130     // Update the JavaScript button.
131     if (Settings::javaScript())
132     {
133         javaScriptButtonPointer->setIcon(QIcon(":/icons/javascript-warning"));
134     }
135     else
136     {
137         javaScriptButtonPointer->setIcon(QIcon(":/icons/privacy-mode"));
138     }
139
140     // Apply the user agent.
141     webEngineProfilePointer->setHttpUserAgent(UserAgentHelper::getUserAgent(Settings::userAgent()));
142
143     // Reload the website if requested.
144     if (reloadWebsite)
145     {
146         webEngineViewPointer->reload();
147     }
148 }
149
150 void MainView::goHome() const
151 {
152     // Load the homepage.
153     webEngineViewPointer->setUrl(QUrl::fromUserInput(Settings::homepage()));
154 }
155
156 void MainView::loadUrlFromTextBox(QString urlFromUser) const
157 {
158     // Remove the focus from the URL line edit.
159     urlLineEditPointer->clearFocus();
160
161     // Decide if the text is more likely to be a URL or a search.
162     if (urlFromUser.contains("."))  // The text is likely a URL.
163     {
164         // Check if the URL does not start with a valid protocol.
165         if (!urlFromUser.startsWith("http") && !urlFromUser.startsWith("file://"))
166         {
167             // Add `https://` to the beginning of the URL.
168             urlFromUser = "https://" + urlFromUser;
169         }
170
171         // Load the URL.
172         webEngineViewPointer->setUrl(QUrl::fromUserInput(urlFromUser));
173     }
174     else  // The text is likely a search.
175     {
176         // Load the search.
177         webEngineViewPointer->setUrl(QUrl::fromUserInput(SearchEngineHelper::getSearchUrl(Settings::searchEngine()) + urlFromUser));
178     }
179 }
180
181 void MainView::pageLinkHovered(const QString &linkUrl) const
182 {
183     // Emit a signal so that the browser window can update the status bar.
184     emit linkHovered(linkUrl);
185 }
186
187 void MainView::toggleJavaScript() const
188 {
189     // Toggle JavaScript.
190     webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, !webEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled));
191
192     // Update the JavaScript button.
193     if (webEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled))
194     {
195         javaScriptButtonPointer->setIcon(QIcon(":/icons/javascript-warning"));
196     }
197     else
198     {
199         javaScriptButtonPointer->setIcon(QIcon(":/icons/privacy-mode"));
200     }
201
202     // Reload the website.
203     webEngineViewPointer->reload();
204 }
205
206 void MainView::updateInterface() const
207 {
208     // Update the URL line edit if it does not have focus.
209     if (!urlLineEditPointer->hasFocus())
210     {
211         // Update the URL line edit.
212         urlLineEditPointer->setText(webEngineViewPointer->url().toString());
213     }
214
215     // Update the status of the forward and back buttons.
216     backButtonPointer->setEnabled(webEngineHistoryPointer->canGoBack());
217     forwardButtonPointer->setEnabled(webEngineHistoryPointer->canGoForward());
218
219     // Reapply the zoom factor.  This is a bug in QWebEngineView that resets the zoom with every load.  Hopefully it will be fixed in Qt6.  <https://bugreports.qt.io/browse/QTBUG-51992>
220     webEngineViewPointer->setZoomFactor(Settings::zoomFactor());
221 }