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