Enable setting as the default browser.
[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
27 MainView::MainView(QWidget *parent) : QWidget(parent)
28 {
29     // Instantiate the mainview UI.
30     Ui::MainView mainViewUi;
31
32     // Setup the UI.
33     mainViewUi.setupUi(this);
34
35     // Get handles for the views.
36     backButtonPointer = mainViewUi.backButton;
37     forwardButtonPointer = mainViewUi.forwardButton;
38     QPushButton *homeButtonPointer = mainViewUi.homeButton;
39     urlLineEditPointer = mainViewUi.urlLineEdit;
40     javaScriptButtonPointer = mainViewUi.javaScript;
41     webEngineViewPointer = mainViewUi.webEngineView;
42
43     // Get handles for the aspects of the WebEngine.
44     QWebEnginePage *webEnginePagePointer = webEngineViewPointer->page();
45     webEngineHistoryPointer = webEnginePagePointer->history();
46     webEngineSettingsPointer = webEngineViewPointer->settings();
47
48     // Update the webengine view from the URL line edit.
49     connect(urlLineEditPointer, SIGNAL(returnKeyPressed(const QString)), this, SLOT(loadUrl(const QString)));
50
51     // Update the URL line edit form the webengine view.
52     connect(webEngineViewPointer, SIGNAL(loadStarted()), this, SLOT(updateInterface()));
53     connect(webEngineViewPointer, SIGNAL(loadProgress(int)), this, SLOT(updateInterface()));
54     connect(webEngineViewPointer, SIGNAL(loadFinished(bool)), this, SLOT(updateInterface()));
55
56     // Setup the URL bar buttons.
57     connect(backButtonPointer, SIGNAL(clicked()), webEngineViewPointer, SLOT(back()));
58     connect(forwardButtonPointer, SIGNAL(clicked()), webEngineViewPointer, SLOT(forward()));
59     connect(homeButtonPointer, SIGNAL(clicked()), this, SLOT(goHome()));
60     connect(javaScriptButtonPointer, SIGNAL(clicked()), this, SLOT(toggleJavaScript()));
61
62     // Instantiate the mouse event pointer.
63     MouseEventFilter *mouseEventFilterPointer = new MouseEventFilter(webEngineViewPointer);
64
65     // Install the mouse event filter.
66     qApp->installEventFilter(mouseEventFilterPointer);
67
68     // Listen for hovered link URLs.
69     connect(webEnginePagePointer, SIGNAL(linkHovered(QString)), this, SLOT(pageLinkHovered(QString)));
70
71     // Don't allow JavaScript to open windows.
72     webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, false);
73
74     // Set the zoom factor.
75     webEngineViewPointer->setZoomFactor(Settings::zoomFactor());
76
77     // Apply the application settings.
78     applyApplicationSettings();
79
80     // Apply the domain settings.
81     applyDomainSettings();
82
83     // Set the focus on the WebEngine view.
84     webEngineViewPointer->setFocus();
85
86     // Get the arguments.
87     QStringList argumentsStringList = qApp->arguments();
88
89     // Check to see if the arguments lists contains a URL.
90     if (argumentsStringList.size() > 1)
91     {
92         // Load the URL from the arguments list.
93         webEngineViewPointer->setUrl(QUrl::fromUserInput(argumentsStringList.at(1)));
94     }
95     else
96     {
97         // Load the homepage.
98         goHome();
99     }
100 }
101
102 void MainView::applyApplicationSettings()
103 {
104     // TODO.
105 }
106
107 void MainView::applyDomainSettings()
108 {
109     // Set the JavaScript status.
110     webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, Settings::javaScript());
111
112     // Update the JavaScript button.
113     if (Settings::javaScript())
114     {
115         javaScriptButtonPointer->setIcon(QIcon(":/icons/javascript-warning"));
116     }
117     else
118     {
119         javaScriptButtonPointer->setIcon(QIcon(":/icons/privacy-mode"));
120     }
121
122     // Reload the website.
123     webEngineViewPointer->reload();
124 }
125
126 void MainView::goHome()
127 {
128     // Load the homepage.  TODO.  Consider sanitizing the homepage input and adding things like protocols if they are missing.
129     webEngineViewPointer->setUrl(Settings::homepage());
130 }
131
132 void MainView::loadUrl(const QString &urlFromUser)
133 {
134     // Remove the focus from the URL line edit.
135     urlLineEditPointer->clearFocus();
136
137     // Load the URL, adding standard protocol sections if needed.  TODO.  Replace this with logic that prefers HTTPS.
138     webEngineViewPointer->setUrl(QUrl::fromUserInput(urlFromUser));
139 }
140
141 void MainView::pageLinkHovered(const QString &linkUrl)
142 {
143     // Emit a signal so that the browser window can update the status bar.
144     emit linkHovered(linkUrl);
145 }
146
147 void MainView::toggleJavaScript()
148 {
149     // Toggle JavaScript.
150     webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, !webEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled));
151
152     // Update the JavaScript button.
153     if (webEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled))
154     {
155         javaScriptButtonPointer->setIcon(QIcon(":/icons/javascript-warning"));
156     }
157     else
158     {
159         javaScriptButtonPointer->setIcon(QIcon(":/icons/privacy-mode"));
160     }
161
162     // Reload the website.
163     webEngineViewPointer->reload();
164 }
165
166 void MainView::updateInterface()
167 {
168     // Update the URL line edit if it does not have focus.
169     if (!urlLineEditPointer->hasFocus())
170     {
171         // Update the URL line edit.
172         urlLineEditPointer->setText(webEngineViewPointer->url().toString());
173     }
174
175     // Update the status of the forward and back buttons.
176     backButtonPointer->setEnabled(webEngineHistoryPointer->canGoBack());
177     forwardButtonPointer->setEnabled(webEngineHistoryPointer->canGoForward());
178
179     // 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>
180     webEngineViewPointer->setZoomFactor(Settings::zoomFactor());
181 }