# Use KDE Frameworks to handle internationalization of the following UI files.
ki18n_wrap_ui(privacy-browser
BrowserView.ui
- DomainSettingsView.ui
+ DomainSettingsDialog.ui
SettingsPrivacy.ui
SettingsGeneral.ui
)
)
# Add the subdirectories.
+add_subdirectory(dialogs)
add_subdirectory(helpers)
add_subdirectory(views)
add_subdirectory(windows)
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+
+ Privacy Browser PC is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Privacy Browser PC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>. -->
+
+<ui version="4.0">
+ <class>DomainSettingsDialog</class>
+
+ <widget class="QWidget" name="DomainSettingsDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>700</width>
+ <height>500</height>
+ </rect>
+ </property>
+
+ <!-- Main layout. -->
+ <layout class="QHBoxLayout">
+ <item>
+ <layout class="QVBoxLayout">
+ <!-- Domains list view. -->
+ <item>
+ <widget class="QListView" name="domainsListView"/>
+ </item>
+
+ <!-- Domain buttons. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <!-- Add domain button. -->
+ <item>
+ <widget class="QPushButton" name="addDomainButton">
+ <property name="text">
+ <string>Add Domain</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="list-add"/>
+ </property>
+ </widget>
+ </item>
+
+ <!-- Delete domain button. -->
+ <item>
+ <widget class="QPushButton" name="deleteDomainButton">
+ <property name="text">
+ <string>Delete domain</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="list-remove"/>
+ </property>
+ </widget>
+ </item>
+
+ <!-- Spacer. -->
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+
+ <item>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QWidget" name="domainSettingsWidget">
+ <!-- Domain settings form layout. -->
+ <layout class="QFormLayout">
+ <!-- Domain name. -->
+ <item row="0" column="0">
+ <widget class="QLabel" name="domainNameLabel">
+ <property name="text">
+ <string>Domain name</string>
+ </property>
+ </widget>
+ </item>
+
+ <item row="0" column="1">
+ <widget class="KLineEdit" name="domainNameLineEdit">
+ <property name="toolTip">
+ <string>*. may be prepended to a domain to include all subdomains (eg. *.stoutner.com).</string>
+ </property>
+ </widget>
+ </item>
+
+ <!-- JavaScript. -->
+ <item row="1" column="0">
+ <widget class="QLabel">
+ <property name="text">
+ <string>JavaScript</string>
+ </property>
+ </widget>
+ </item>
+
+ <item row="1" column="1">
+ <widget class="QComboBox" name="javaScriptComboBox">
+ <property name="toolTip">
+ <string>JavaScript allows websites to run programs (scripts) on the device.</string>
+ </property>
+
+ <item>
+ <property name="text">
+ <string>System default</string>
+ </property>
+ </item>
+
+ <item>
+ <property name="text">
+ <string>JavaScript disabled</string>
+ </property>
+ </item>
+
+ <item>
+ <property name="text">
+ <string>JavaScript enabled</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+
+ <!-- Spacer. -->
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </spacer>
+ </item>
+
+ <!-- Dialog buttons. -->
+ <item>
+ <widget class="QDialogButtonBox" name="dialogButtonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Reset | QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+</ui>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
-
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
-
- Privacy Browser PC is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Privacy Browser PC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>. -->
-
-<ui version="4.0">
- <class>DomainSettingsView</class>
-
- <widget class="QWidget" name="DomainSettingsView">
- <!-- TODO. Make this maximized by default. -->
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>700</width>
- <height>500</height>
- </rect>
- </property>
-
- <!-- Main widget. -->
- <layout class="QHBoxLayout">
- <!-- Set the spacing between items to 0. -->
- <property name="spacing">
- <number>0</number>
- </property>
-
- <!-- Set the margins to 0. -->
- <property name="topMargin">
- <number>0</number>
- </property>
-
- <property name="bottomMargin">
- <number>0</number>
- </property>
-
- <property name="leftMargin">
- <number>0</number>
- </property>
-
- <property name="rightMargin">
- <number>0</number>
- </property>
-
- <!-- Domains list view. -->
- <item>
- <widget class="QListView" name="domainsListView"/>
- </item>
-
- <!-- Domain settings form layout. -->
- <item>
- <layout class="QFormLayout">
- <!-- Domain name. -->
- <item row="0" column="0">
- <widget class="QLabel" name="domainNameLabel">
- <property name="text">
- <string>Domain name</string>
- </property>
- </widget>
- </item>
-
- <item row="0" column="1">
- <widget class="KLineEdit" name="domainNameLineEdit">
- <property name="toolTip">
- <string>*. may be prepended to a domain to include all subdomains (eg. *.stoutner.com).</string>
- </property>
- </widget>
- </item>
-
- <!-- JavaScript. -->
- <item row="1" column="0">
- <widget class="QLabel">
- <property name="text">
- <string>JavaScript</string>
- </property>
- </widget>
- </item>
-
- <item row="1" column="1">
- <widget class="QComboBox" name="javaScriptComboBox">
- <property name="toolTip">
- <string>JavaScript allows websites to run programs (scripts) on the device.</string>
- </property>
-
- <item>
- <property name="text">
- <string>System default</string>
- </property>
- </item>
-
- <item>
- <property name="text">
- <string>JavaScript disabled</string>
- </property>
- </item>
-
- <item>
- <property name="text">
- <string>JavaScript enabled</string>
- </property>
- </item>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
-</ui>
// Reapply the domain settings if the host is changing.
if (requestingHost != requestedHost)
{
- emit applyDomainSettings();
+ emit applyDomainSettings(requestedHost);
}
}
signals:
// The signals.
- void applyDomainSettings() const;
+ void applyDomainSettings(const QString hostname) const;
};
#endif
--- /dev/null
+# Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+#
+# This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+#
+# Privacy Browser PC is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Privacy Browser PC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
+
+
+# List the sources to include in the executable.
+target_sources(privacy-browser PRIVATE
+ DomainSettingsDialog.cpp
+)
--- /dev/null
+/*
+ * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+ *
+ * Privacy Browser PC is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Privacy Browser PC is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// Application headers.
+#include "DomainSettingsDialog.h"
+#include "ui_DomainSettingsDialog.h"
+#include "helpers/DomainsDatabaseHelper.h"
+
+// Qt toolkit headers.
+#include <QInputDialog>
+#include <QMessageBox>
+#include <QPushButton>
+
+DomainSettingsDialog::DomainSettingsDialog(QWidget *parent) : QDialog(parent)
+{
+ // Instantiate the domain settings view UI.
+ Ui::DomainSettingsDialog domainSettingsDialogUi;
+
+ // Setup the UI.
+ domainSettingsDialogUi.setupUi(this);
+
+ // Get handles for the views.
+ domainsListViewPointer = domainSettingsDialogUi.domainsListView;
+ domainSettingsWidgetPointer = domainSettingsDialogUi.domainSettingsWidget;
+ domainNameLineEditPointer = domainSettingsDialogUi.domainNameLineEdit;
+ javaScriptComboBoxPointer = domainSettingsDialogUi.javaScriptComboBox;
+ QPushButton *addDomainButtonPointer = domainSettingsDialogUi.addDomainButton;
+ deleteDomainButtonPointer = domainSettingsDialogUi.deleteDomainButton;
+ QDialogButtonBox *dialogButtonBoxPointer = domainSettingsDialogUi.dialogButtonBox;
+ applyButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::StandardButton::Apply);
+ resetButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::StandardButton::Reset);
+
+ // Create a table model.
+ domainsTableModelPointer = new QSqlTableModel(nullptr, QSqlDatabase::database(DomainsDatabaseHelper::CONNECTION_NAME));
+
+ // Set the table for the model.
+ domainsTableModelPointer->setTable(DomainsDatabaseHelper::DOMAINS_TABLE);
+
+ // Set the edit strategy to be manual.
+ domainsTableModelPointer->setEditStrategy(QSqlTableModel::EditStrategy::OnManualSubmit);
+
+ // Sort the output alphabetically.
+ domainsTableModelPointer->setSort(1, Qt::SortOrder::AscendingOrder);
+
+ // Set the model for the list view.
+ domainsListViewPointer->setModel(domainsTableModelPointer);
+
+ // Set the visible column to be the domain name.
+ domainsListViewPointer->setModelColumn(1);
+
+ // Disable editing of the list view.
+ domainsListViewPointer->setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+ // Read the data from the database and apply it to the table model.
+ domainsTableModelPointer->select();
+
+ // Select the first entry in the list view.
+ domainsListViewPointer->setCurrentIndex(domainsTableModelPointer->index(0, domainsTableModelPointer->fieldIndex(DomainsDatabaseHelper::DOMAIN_NAME)));
+
+ // Populate the domain settings.
+ domainSelected(domainsListViewPointer->selectionModel()->currentIndex());
+
+ // Handle clicks on the domains.
+ connect(domainsListViewPointer, SIGNAL(activated(QModelIndex)), this, SLOT(domainSelected(QModelIndex)));
+
+ // Connect the domain settings.
+ connect(domainNameLineEditPointer, SIGNAL(textEdited(QString)), this, SLOT(domainNameChanged(QString)));
+ connect(javaScriptComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(javaScriptChanged(int)));
+
+ // Connect the buttons.
+ connect(addDomainButtonPointer, SIGNAL(released()), this, SLOT(showAddMessageBox()));
+ connect(deleteDomainButtonPointer, SIGNAL(released()), this, SLOT(showDeleteMessageBox()));
+ connect(resetButtonPointer, SIGNAL(released()), this, SLOT(reset()));
+ connect(dialogButtonBoxPointer, SIGNAL(accepted()), this, SLOT(ok()));
+ connect(applyButtonPointer, SIGNAL(released()), this, SLOT(apply()));
+ connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(cancel()));
+
+ // Update the UI.
+ updateUi();
+}
+
+void DomainSettingsDialog::apply() const
+{
+ // Get the current index.
+ QModelIndex currentIndex = domainsListViewPointer->currentIndex();
+
+ // Get the ID of the current index row.
+ QVariant currentId = currentIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabaseHelper::_ID)).data();
+
+ // Submit all pending changes.
+ domainsTableModelPointer->submitAll();
+
+ // Find the new index for the selected id. The `1` keeps searching after the first match.
+ QModelIndexList newIndexList = domainsTableModelPointer->match(currentIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabaseHelper::_ID)), Qt::DisplayRole, currentId,
+ 1, Qt::MatchWrap);
+
+ // Select the new index.
+ domainsListViewPointer->setCurrentIndex(newIndexList[0].siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabaseHelper::DOMAIN_NAME)));
+
+ // Update the UI.
+ updateUi();
+}
+
+void DomainSettingsDialog::cancel()
+{
+ // Revert all pending changes.
+ domainsTableModelPointer->revertAll();
+
+ // Close the dialog.
+ reject();
+}
+
+void DomainSettingsDialog::domainNameChanged(QString updatedDomainName) const
+{
+ // Update the domains table model.
+ domainsTableModelPointer->setData(domainsListViewPointer->selectionModel()->currentIndex(), updatedDomainName);
+
+ // Update the UI.
+ updateUi();
+}
+
+
+void DomainSettingsDialog::domainSelected(QModelIndex modelIndex) const
+{
+ // Populate the domain name line edit pointer.
+ domainNameLineEditPointer->setText(modelIndex.data().toString());
+
+ // Populate the JavaScript combo box.
+ javaScriptComboBoxPointer->setCurrentIndex(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabaseHelper::JAVASCRIPT)).data().toInt());
+
+ // Update the UI.
+ updateUi();
+}
+
+void DomainSettingsDialog::javaScriptChanged(int newIndex) const
+{
+ // Update the domains table model.
+ domainsTableModelPointer->setData(domainsListViewPointer->selectionModel()->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabaseHelper::JAVASCRIPT)),
+ newIndex);
+
+ // Update the UI.
+ updateUi();
+}
+
+
+void DomainSettingsDialog::ok()
+{
+ // Submit all pending changes.
+ domainsTableModelPointer->submitAll();
+
+ // Close the dialog.
+ accept();
+}
+
+void DomainSettingsDialog::reset() const
+{
+ // Cancel all pending changes.
+ domainsTableModelPointer->revertAll();
+
+ // Repopulate the domain name line edit.
+ domainNameLineEditPointer->setText(domainsListViewPointer->currentIndex().data().toString());
+
+ // Update the UI.
+ updateUi();
+}
+
+void DomainSettingsDialog::showAddMessageBox()
+{
+ // Create an OK flag.
+ bool okClicked;
+
+ // Display a dialog to request the new domain name from the user.
+ QString newDomainName = QInputDialog::getText(this, i18nc("Add domain dialog title", "Add Domain"),
+ i18nc("Add domain message. The \n\n are newline codes that should be retained",
+ "Add a new domain. Doing so will also save any pending changes that have been made to other domains.\n\n"
+ "*. may be prepended to a domain to include all subdomains (eg. *.stoutner.com)."),
+ QLineEdit::Normal, QString(), &okClicked);
+
+ // Add the new domain if the user clicked OK.
+ if (okClicked)
+ {
+ // Create a new domain record.
+ QSqlRecord newDomainRecord = QSqlDatabase::database(DomainsDatabaseHelper::CONNECTION_NAME).record(DomainsDatabaseHelper::DOMAINS_TABLE);
+
+ // Add the new domain name.
+ newDomainRecord.setValue(domainsTableModelPointer->fieldIndex(DomainsDatabaseHelper::DOMAIN_NAME), newDomainName);
+
+ // Set the default value of `0` for the other columns.
+ newDomainRecord.setValue(domainsTableModelPointer->fieldIndex(DomainsDatabaseHelper::JAVASCRIPT), 0);
+
+ // Insert the new domain. `-1` appends it to the end.
+ domainsTableModelPointer->insertRecord(-1, newDomainRecord);
+
+ // Submit all pending changes.
+ domainsTableModelPointer->submitAll();
+
+ // Find the index for the new domain. `-1` allows for multiple entries to be returned.
+ QModelIndexList newDomainIndex = domainsTableModelPointer->match(domainsTableModelPointer->index(0, domainsTableModelPointer->fieldIndex(DomainsDatabaseHelper::DOMAIN_NAME)),
+ Qt::DisplayRole, newDomainName, -1, Qt::MatchWrap);
+
+ // Move to the new domain. If there are multiple domains with the same name, the new one should be the last in the list.
+ domainsListViewPointer->setCurrentIndex(newDomainIndex[newDomainIndex.size() - 1]);
+
+ // Populate the domain settings.
+ domainSelected(domainsListViewPointer->selectionModel()->currentIndex());
+
+ // Update the UI.
+ updateUi();
+ }
+}
+
+void DomainSettingsDialog::showDeleteMessageBox() const
+{
+ // Instantiate a delete dialog message box.
+ QMessageBox deleteDialogMessageBox;
+
+ // Set the icon.
+ deleteDialogMessageBox.setIcon(QMessageBox::Warning);
+
+ // Set the window title.
+ deleteDialogMessageBox.setWindowTitle(i18nc("Delete domain dialog title", "Delete Domain"));
+
+ // Set the text.
+ deleteDialogMessageBox.setText(i18nc("Delete domain main message", "Delete the current domain?"));
+
+ // Set the informative text.
+ deleteDialogMessageBox.setInformativeText(i18nc("Delete domain secondary message", "Doing so will also save any pending changes that have been made to other domains."));
+
+ // Set the standard buttons.
+ deleteDialogMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+
+ // Set the default button.
+ deleteDialogMessageBox.setDefaultButton(QMessageBox::No);
+
+ // Display the dialog and capture the return value.
+ int returnValue = deleteDialogMessageBox.exec();
+
+ if (returnValue == QMessageBox::Yes)
+ {
+ // Get the current index.
+ QModelIndex currentIndex = domainsListViewPointer->currentIndex();
+
+ // Delete the current row.
+ domainsTableModelPointer->removeRow(domainsListViewPointer->selectionModel()->currentIndex().row());
+
+ // Submit all pending changes.
+ domainsTableModelPointer->submitAll();
+
+ // Select the row next to the deleted item if one exists.
+ if (domainsTableModelPointer->rowCount() > 0)
+ {
+ // Check the row of the deleted item.
+ if (currentIndex.row() == 0) // The first row was deleted.
+ {
+ // Reselect the current index.
+ domainsListViewPointer->setCurrentIndex(currentIndex);
+ }
+ else // A subsequent row was deleted.
+ {
+ // Select the crow above the deleted itemm.
+ domainsListViewPointer->setCurrentIndex(currentIndex.siblingAtRow(currentIndex.row() - 1));
+ }
+
+ // Populate the domain settings.
+ domainSelected(domainsListViewPointer->currentIndex());
+ }
+
+ // Update the Ui.
+ updateUi();
+ }
+}
+
+void DomainSettingsDialog::updateUi() const
+{
+ // Update the delete button status.
+ deleteDomainButtonPointer->setEnabled(domainsListViewPointer->selectionModel()->hasSelection());
+
+ // Update the apply button status.
+ applyButtonPointer->setEnabled(domainsTableModelPointer->isDirty());
+
+ // Update the reset button status.
+ resetButtonPointer->setEnabled(domainsTableModelPointer->isDirty());
+
+ // Display the domain settings if there is at least one domain.
+ domainSettingsWidgetPointer->setVisible(domainsTableModelPointer->rowCount() > 0);
+}
+
--- /dev/null
+/*
+ * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+ *
+ * Privacy Browser PC is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Privacy Browser PC is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DOMAINSETTINGSDIALOG_H
+#define DOMAINSETTINGSDIALOG_H
+
+// KDE Frameworks headers.
+#include <KLineEdit>
+
+// Qt toolkit headers.
+#include <QDialog>
+#include <QtSql>
+
+class DomainSettingsDialog : public QDialog
+{
+ // Include the Q_OBJECT macro.
+ Q_OBJECT
+
+public:
+ // The primary constructor.
+ explicit DomainSettingsDialog(QWidget *parent = nullptr);
+
+private Q_SLOTS:
+ // The private slots.
+ void apply() const;
+ void cancel();
+ void domainNameChanged(QString updatedDomainName) const;
+ void domainSelected(QModelIndex modelIndex) const;
+ void javaScriptChanged(int newIndex) const;
+ void ok();
+ void reset() const;
+ void showAddMessageBox();
+ void showDeleteMessageBox() const;
+
+private:
+ // The private functions.
+ void updateUi() const;
+
+ // The private variables.
+ QPushButton *applyButtonPointer;
+ QPushButton *deleteDomainButtonPointer;
+ QListView *domainsListViewPointer;
+ KLineEdit *domainNameLineEditPointer;
+ QWidget *domainSettingsWidgetPointer;
+ QSqlTableModel *domainsTableModelPointer;
+ QComboBox *javaScriptComboBoxPointer;
+ QPushButton *resetButtonPointer;
+};
+#endif
// Application headers.
#include "DomainsDatabaseHelper.h"
-// Qt framework headers.
-#include <QtSql>
-
-// Define the static constants.
+// Define the public static domain constants.
const QString DomainsDatabaseHelper::CONNECTION_NAME = "domains_database";
const QString DomainsDatabaseHelper::DOMAINS_TABLE = "domains";
+// Define the private static schema constants.
+const int DomainsDatabaseHelper::SCHEMA_VERSION = 1;
+
+// Define the public static database field names.
+const QString DomainsDatabaseHelper::_ID = "_id";
+const QString DomainsDatabaseHelper::DOMAIN_NAME = "domain_name";
+const QString DomainsDatabaseHelper::JAVASCRIPT = "javascript";
+
// The default constructor.
DomainsDatabaseHelper::DomainsDatabaseHelper() {}
// Check to see if the domains table already exists.
if (domainsDatabase.tables().contains(DOMAINS_TABLE))
{
- // Run schema update code.
+ // Query the database schema version.
+ QSqlQuery getSchemaVersionQuery = domainsDatabase.exec("PRAGMA user_version");
+
+ // Move to the first record.
+ getSchemaVersionQuery.first();
+
+ // Get the current schema version.
+ int currentSchemaVersion = getSchemaVersionQuery.value(0).toInt();
+
+ // Check to see if the schama has been updated.
+ if (SCHEMA_VERSION > currentSchemaVersion)
+ {
+ // Run schema update code.
+ switch (currentSchemaVersion)
+ {
+ // Upgrade from schema version 0.
+ case 0:
+ {
+ // Add the JavaScript column.
+ domainsDatabase.exec("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + JAVASCRIPT + " INTEGER DEFAULT 0");
+
+ // Set the default value.
+ domainsDatabase.exec("UPDATE " + DOMAINS_TABLE + " SET " + JAVASCRIPT + " = 0" );
+ }
+ }
+
+ // Update the schema version.
+ domainsDatabase.exec("PRAGMA user_version = " + QString::number(SCHEMA_VERSION));
+ }
}
else
{
QSqlQuery createTableQuery(domainsDatabase);
// Prepare the create table query.
- createTableQuery.prepare("CREATE TABLE " + DOMAINS_TABLE + "("
- "_id INTEGER PRIMARY KEY, "
- "domain_name TEXT)"
+ createTableQuery.prepare("CREATE TABLE " + DOMAINS_TABLE + "(" +
+ _ID + " INTEGER PRIMARY KEY, " +
+ DOMAIN_NAME + " TEXT, " +
+ JAVASCRIPT + " INTEGER DEFAULT 0)"
);
// Execute the query.
// Log any errors.
qDebug().noquote().nospace() << "Error creating table: " << domainsDatabase.lastError();
}
+
+ // Set the schema version.
+ domainsDatabase.exec("PRAGMA user_version = " + QString::number(SCHEMA_VERSION));
}
}
else // Opening the database failed.
qDebug().noquote().nospace() << "Error opening database: " << domainsDatabase.lastError();
}
};
+
+QSqlQuery DomainsDatabaseHelper::getDomainQuery(const QString &hostname)
+{
+ // Get a handle for the domains database.
+ QSqlDatabase domainsDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate a domain lookup query.
+ QSqlQuery domainLookupQuery(domainsDatabase);
+
+ // Create a hostname field.
+ QSqlField hostnameField(DOMAIN_NAME, QVariant::String);
+
+ // Set the hostname field value.
+ hostnameField.setValue(hostname);
+
+ // SQL escape the hostname field.
+ QString sqlEscapedHostname = domainsDatabase.driver()->formatValue(hostnameField);
+
+ // Prepare the domain lookup query.
+ domainLookupQuery.prepare("SELECT * FROM " + DOMAINS_TABLE + " WHERE " + DOMAIN_NAME + " = " + sqlEscapedHostname);
+
+ // Execute the query.
+ domainLookupQuery.exec();
+
+ // Move to the first entry.
+ domainLookupQuery.first();
+
+ // Return the query.
+ return domainLookupQuery;
+}
+
// The public functions.
static void addDatabase();
+ static QSqlQuery getDomainQuery(const QString &hostname);
+
+ // The public int constants.
+ static const int SYSTEM_DEFAULT = 0;
+ static const int DISABLED = 1;
+ static const int ENABLED = 2;
// The public constants.
+ static const QString _ID;
static const QString CONNECTION_NAME;
+ static const QString DOMAIN_NAME;
static const QString DOMAINS_TABLE;
+ static const QString JAVASCRIPT;
+
+private:
+ // The private static constants.
+ static const int SCHEMA_VERSION;
};
#endif
# Install Privacy Browser's RC (Runtime Configuration) files.
install(FILES
browser_ui.rc
- domain_settings_ui.rc
DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/privacybrowser)
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
-
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
-
- Privacy Browser PC is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Privacy Browser PC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>. -->
-
-<!-- Documentation at <https://techbase.kde.org/Development/Architecture/KDE4/XMLGUI_Technology>. -->
-<gui
- name="domain_settings"
- version="1"
- xmlns="http://www.kde.org/standards/kxmlgui/1.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0 http://www.kde.org/standards/kxmlgui/1.0/kxmlgui.xsd" >
-
- <ToolBar name="mainToolBar" noMerge="1">
- <text>Main Toolbar</text>
-
- <Action name="add_domain" />
- <Action name="delete_domain" />
- </ToolBar>
-
- <ToolBar name="applyToolBar">
- <text>Apply Toolbar</text>
-
- <action name="ok" />
- <action name="apply" />
- <action name="cancel" />
- </ToolBar>
-</gui>
#include "Settings.h"
#include "ui_BrowserView.h"
#include "UrlRequestInterceptor.h"
+#include "dialogs/DomainSettingsDialog.h"
+#include "helpers/DomainsDatabaseHelper.h"
#include "helpers/SearchEngineHelper.h"
#include "helpers/UserAgentHelper.h"
#include "windows/BrowserWindow.h"
-#include "windows/DomainSettingsWindow.h"
// Qt framework headers.
#include <QAction>
connect(javaScriptButtonPointer, SIGNAL(clicked()), this, SLOT(toggleJavaScript()));
connect(domainSettingsButtonPointer, SIGNAL(clicked()), this, SLOT(openDomainSettings()));
+ // Get the URL line edit palettes.
+ noDomainSettingsPalette = urlLineEditPointer->palette();
+ domainSettingsPalette = urlLineEditPointer->palette();
+
+ // Modify the domain settings palette.
+ domainSettingsPalette.setColor(QPalette::Base, Qt::green);
+
// Instantiate the mouse event pointer.
MouseEventFilter *mouseEventFilterPointer = new MouseEventFilter(webEngineViewPointer);
webEngineProfilePointer->setUrlRequestInterceptor(urlRequestInterceptorPointer);
// Reapply the domain settings when the host changes.
- connect(urlRequestInterceptorPointer, SIGNAL(applyDomainSettings()), this, SLOT(applyDomainSettingsWithoutReloading()));
+ connect(urlRequestInterceptorPointer, SIGNAL(applyDomainSettings(QString)), this, SLOT(applyDomainSettingsWithoutReloading(QString)));
// Disable the cache.
webEngineProfilePointer->setHttpCacheType(QWebEngineProfile::NoCache);
void BrowserView::applyDomainSettingsAndReload() const
{
// Apply the domain settings. `true` reloads the website.
- applyDomainSettings(true);
+ applyDomainSettings(webEngineViewPointer->url().host(), true);
}
// 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.
-void BrowserView::applyDomainSettingsWithoutReloading() const
+void BrowserView::applyDomainSettingsWithoutReloading(const QString &hostname) const
{
// Apply the domain settings `false` does not reload the website.
- applyDomainSettings(false);
+ applyDomainSettings(hostname, false);
}
-void BrowserView::applyDomainSettings(bool reloadWebsite) const
+void BrowserView::applyDomainSettings(const QString &hostname, const bool reloadWebsite) const
{
- // Set the JavaScript status.
- webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, Settings::javaScript());
+ // Get the record for the hostname.
+ QSqlQuery domainQuery = DomainsDatabaseHelper::getDomainQuery(hostname);
+
+ // Check if the hostname has domain settings.
+ if (domainQuery.isValid()) // The hostname has domain settings.
+ {
+
+
+ // Get the domain record.
+ QSqlRecord domainRecord = domainQuery.record();
+
+ // Set the JavaScript status.
+ switch (domainRecord.field(DomainsDatabaseHelper::JAVASCRIPT).value().toInt())
+ {
+ case (DomainsDatabaseHelper::SYSTEM_DEFAULT):
+ {
+ // Set the default JavaScript status.
+ webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, Settings::javaScript());
+
+ break;
+ }
+
+ case (DomainsDatabaseHelper::DISABLED):
+ {
+ // Disable JavaScript.
+ webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, false);
+
+ break;
+ }
+
+ case (DomainsDatabaseHelper::ENABLED):
+ {
+ // Enable JavaScript.
+ webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
+
+ break;
+ }
+ }
+
+ // Apply the user agent.
+ webEngineProfilePointer->setHttpUserAgent(UserAgentHelper::getUserAgent(Settings::userAgent()));
+
+ // Set the zoom factor.
+ webEngineViewPointer->setZoomFactor(Settings::zoomFactor());
+
+ // Apply the domain settings palette to the URL line edit.
+ urlLineEditPointer->setPalette(domainSettingsPalette);
+ }
+ else // The hostname does not have domain settings.
+ {
+ // Set the JavaScript status.
+ webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, Settings::javaScript());
+
+ // Apply the user agent.
+ webEngineProfilePointer->setHttpUserAgent(UserAgentHelper::getUserAgent(Settings::userAgent()));
+
+ // Set the zoom factor.
+ webEngineViewPointer->setZoomFactor(Settings::zoomFactor());
+
+ // Apply the no domain settings palette to the URL line edit.
+ urlLineEditPointer->setPalette(noDomainSettingsPalette);
+ }
// Update the JavaScript button.
- if (Settings::javaScript())
+ if (webEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled))
{
javaScriptButtonPointer->setIcon(QIcon(":/icons/javascript-warning"));
}
javaScriptButtonPointer->setIcon(QIcon(":/icons/privacy-mode"));
}
- // Apply the user agent.
- webEngineProfilePointer->setHttpUserAgent(UserAgentHelper::getUserAgent(Settings::userAgent()));
-
- // Set the zoom factor.
- webEngineViewPointer->setZoomFactor(Settings::zoomFactor());
-
// Emit the on-the-fly menu update signals.
emit userAgentUpdated(Settings::userAgent());
emit zoomFactorUpdated(Settings::zoomFactor());
void BrowserView::openDomainSettings() const
{
- // Get a list of the top level widgets.
- const QWidgetList topLevelWidgets = QApplication::topLevelWidgets();
+ // Instantiate the domain settings window.
+ DomainSettingsDialog *domainSettingsDialogPointer = new DomainSettingsDialog();
- // Initialize a domain settings window exists boolean.
- bool domainSettingsWindowExists = false;
+ // Set the dialog window title.
+ domainSettingsDialogPointer->setWindowTitle(i18nc("The domain settings dialog title", "Domain Settings"));
- // Iterate through the top level widgets.
- for (QWidget *widgetPointer : topLevelWidgets)
- {
- // Check for an existing domain settings window.
- if (widgetPointer->objectName() == QStringLiteral("domain_settings"))
- {
- // Show the existing domain settings window if it is hidden.
- widgetPointer->show();
-
- // Raise the existing domain settings window if it is below other windows.
- widgetPointer->raise();
-
- // Restore the existing domain settings window if it has been minimized.
- if (widgetPointer->isMinimized()) {
- widgetPointer->showNormal();
- }
-
- // Activate the existing domain settings window, which brings its virtual desktop into focus.
- widgetPointer->activateWindow();
+ // Resize the dialog window.
+ domainSettingsDialogPointer->resize(1500, 1000);
- // Update the domain settings window exists boolean.
- domainSettingsWindowExists = true;
- }
- }
+ // Set the modality.
+ domainSettingsDialogPointer->setWindowModality(Qt::WindowModality::WindowModal);;
- if (!domainSettingsWindowExists)
- {
- // Instantiate the domain settings window.
- DomainSettingsWindow *domainSettingsWindowPointer = new DomainSettingsWindow();
-
- // Show the window.
- domainSettingsWindowPointer->show();
- }
+ // Show the dialog.
+ domainSettingsDialogPointer->show();
}
void BrowserView::pageLinkHovered(const QString &linkUrl) const
// The public slots.
void applyApplicationSettings();
void applyDomainSettingsAndReload() const;
- void applyDomainSettingsWithoutReloading() const;
+ void applyDomainSettingsWithoutReloading(const QString &hostname) const;
void applyOnTheFlySearchEngine(QAction *searchEngineActionPointer);
void applyOnTheFlyUserAgent(QAction *userAgentActionPointer) const;
private:
// The private variables.
QPushButton *backButtonPointer;
+ QPalette domainSettingsPalette;
QPushButton *forwardButtonPointer;
QPushButton *javaScriptButtonPointer;
+ QPalette noDomainSettingsPalette;
QString searchEngineUrl;
KLineEdit *urlLineEditPointer;
QWebEngineHistory *webEngineHistoryPointer;
QWebEngineView *webEngineViewPointer;
// The private functions.
- void applyDomainSettings(bool reloadWebsite) const;
+ void applyDomainSettings(const QString &hostname, const bool reloadWebsite) const;
};
#endif
# List the sources to include in the executable.
target_sources(privacy-browser PRIVATE
BrowserView.cpp
- DomainSettingsView.cpp
)
+++ /dev/null
-/*
- * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
- *
- * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
- *
- * Privacy Browser PC is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Privacy Browser PC is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
- */
-
-// Application headers.
-#include "DomainSettingsView.h"
-#include "ui_DomainSettingsView.h"
-#include "helpers/DomainsDatabaseHelper.h"
-
-DomainSettingsView::DomainSettingsView(QWidget *parent) : QWidget(parent)
-{
- // Instantiate the domain settings view UI.
- Ui::DomainSettingsView domainSettingsViewUi;
-
- // Setup the UI.
- domainSettingsViewUi.setupUi(this);
-
- // Get handles for the views.
- domainsListViewPointer = domainSettingsViewUi.domainsListView;
- domainNameLineEditPointer = domainSettingsViewUi.domainNameLineEdit;
-
- // Create a table model.
- domainsTableModelPointer = new QSqlTableModel(0, QSqlDatabase::database(DomainsDatabaseHelper::CONNECTION_NAME));
-
- // Set the table for the model.
- domainsTableModelPointer->setTable(DomainsDatabaseHelper::DOMAINS_TABLE);
-
- // Set the model for the list view.
- domainsListViewPointer->setModel(domainsTableModelPointer);
-
- // Set the visible column to be the domain name.
- domainsListViewPointer->setModelColumn(1);
-
- // Disable editing of the list view.
- domainsListViewPointer->setEditTriggers(QAbstractItemView::NoEditTriggers);
-
- // Handle clicks on the domains.
- connect(domainsListViewPointer, SIGNAL(activated(QModelIndex)), this, SLOT(domainSelected(QModelIndex)));
-
- // Read the data from the database and apply it to the table model.
- domainsTableModelPointer->select();
-
- // Select the first entry in the list view.
- domainsListViewPointer->setCurrentIndex(domainsTableModelPointer->index(0, 1));
-
- // Populate the domain settings.
- domainSelected(domainsListViewPointer->selectionModel()->currentIndex());
-}
-
-void DomainSettingsView::addDomain()
-{
- // Insert a row.
- domainsTableModelPointer->insertRows(domainsTableModelPointer->rowCount(), 1);
-}
-
-void DomainSettingsView::deleteDomain()
-{
- // Delete the current row.
- domainsTableModelPointer->removeRow(domainsListViewPointer->selectionModel()->currentIndex().row());
-}
-
-
-void DomainSettingsView::domainSelected(QModelIndex modelIndex)
-{
- // Populate the domain name line edit pointer.
- domainNameLineEditPointer->setText(modelIndex.data().toString());
-}
+++ /dev/null
-/*
- * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
- *
- * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
- *
- * Privacy Browser PC is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Privacy Browser PC is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DOMAINSETTINGSVIEW_H
-#define DOMAINSETTINGSVIEW_H
-
-// Qt framework headers.
-#include <QtSql>
-#include <QWidget>
-
-// KDE Framework headers.
-#include <KLineEdit>
-
-class DomainSettingsView : public QWidget
-{
- // Include the Q_OBJECT macro.
- Q_OBJECT
-
-public:
- // The primary constructor.
- explicit DomainSettingsView(QWidget *parent);
-
-public Q_SLOTS:
- // The public slots.
- void addDomain();
- void deleteDomain();
-
-private Q_SLOTS:
- // The private slots.
- void domainSelected(QModelIndex modelIndex);
-
-private:
- // The private variables.
- QListView *domainsListViewPointer;
- KLineEdit *domainNameLineEditPointer;
- QSqlTableModel *domainsTableModelPointer;
-};
-#endif
bool okClicked;
// Display a dialog to get the new zoom factor from the user. Format the double to display two decimals and have a 0.25 step.
- double newZoomFactor = QInputDialog::getDouble(this, i18nc("The tile of the on-the-fly zoom factor dialog", "On-The-Fly Zoom Factor"),
+ double newZoomFactor = QInputDialog::getDouble(this, i18nc("The on-the-fly zoom factor dialog title", "On-The-Fly Zoom Factor"),
i18nc("The instruction text of the on-the-fly zoom factor dialog", "Enter a zoom factor between 0.25 and 5.00"),
currentZoomFactor, .025, 5.00, 2, &okClicked, Qt::WindowFlags(), 0.25);
+ // Update the zoom factor if the user clicked OK.
if (okClicked)
{
// Update the current zoom factor.
# List the sources to include in the executable.
target_sources(privacy-browser PRIVATE
BrowserWindow.cpp
- DomainSettingsWindow.cpp
)
+++ /dev/null
-/*
- * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
- *
- * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
- *
- * Privacy Browser PC is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Privacy Browser PC is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
- */
-
-// Application headers.
-#include "DomainSettingsWindow.h"
-#include "views/DomainSettingsView.h"
-
-// KDE Frameworks headers.
-#include <KActionCollection>
-#include <KLocalizedString>
-
-DomainSettingsWindow::DomainSettingsWindow() : KXmlGuiWindow()
-{
- // Instantiate the domain settings view pointer.
- DomainSettingsView *domainSettingsViewPointer = new DomainSettingsView(this);
-
- // Set the domain settings view as the central widget.
- setCentralWidget(domainSettingsViewPointer);
-
- // Set the object name.
- this->setObjectName(QStringLiteral("domain_settings"));
-
- // Set the window title.
- setCaption(i18nc("The Domain Settings window title", "Domain Settings"));
-
- // Get a handle for the action collection.
- KActionCollection *actionCollectionPointer = this->actionCollection();
-
- // Add the custom actions.
- QAction *addDomainActionPointer = actionCollectionPointer->addAction(QStringLiteral("add_domain"));
- QAction *deleteDomainActionPointer = actionCollectionPointer->addAction(QStringLiteral("delete_domain"));
- QAction *okActionPointer = actionCollectionPointer->addAction(QStringLiteral("ok"));
- QAction *applyActionPointer = actionCollectionPointer->addAction(QStringLiteral("apply"));
- QAction *cancelActionPointer = actionCollectionPointer->addAction(QStringLiteral("cancel"));
-
- // Set the action text.
- addDomainActionPointer->setText(i18nc("Add domain toolbar button", "Add Domain"));
- deleteDomainActionPointer->setText(i18nc("Delete domain toolbar button", "Delete Domain"));
- okActionPointer->setText(i18nc("OK toolbar button", "OK"));
- applyActionPointer->setText(i18nc("Apply toolbar button", "Apply"));
- cancelActionPointer->setText(i18nc("Cancel toolbar button", "Cancel"));
-
- // Set the action icons.
- addDomainActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
- deleteDomainActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("delete")));
- okActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("dialog-ok")));
- applyActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("dialog-ok-apply")));
- cancelActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("dialog-cancel")));
-
- // Connect the button signals.
- connect(addDomainActionPointer, SIGNAL(triggered()), domainSettingsViewPointer, SLOT(addDomain()));
- connect(deleteDomainActionPointer, SIGNAL(triggered()), domainSettingsViewPointer, SLOT(deleteDomain()));
-
- // Setup the GUI without a status bar based on the domain_settings_ui.rc file.
- setupGUI(StandardWindowOption::ToolBar | StandardWindowOption::Keys | StandardWindowOption::Save | StandardWindowOption::Create, ("domain_settings_ui.rc"));
-}
+++ /dev/null
-/*
- * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
- *
- * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
- *
- * Privacy Browser PC is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Privacy Browser PC is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DOMAINSETTINGSWINDOW_H
-#define DOMAINSETTINGSWINDOW_H
-
-// KDE Frameworks headers.
-#include <KXmlGuiWindow>
-
-// Qt toolkit headers.
-#include <QWidget>
-
-class DomainSettingsWindow : public KXmlGuiWindow
-{
- // Include the Q_OBJECT macro.
- Q_OBJECT
-
-public:
- // The default constructor.
- DomainSettingsWindow();
-};
-#endif