From 7c6edb3608791950c6146ac242e2b6f493ca8e8c Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Sat, 12 Aug 2023 19:46:20 -0700 Subject: [PATCH] Partial bookmark implementation. https://redmine.stoutner.com/issues/968 --- src/CMakeLists.txt | 2 + src/databases/BookmarksDatabase.cpp | 242 +++++++++++++++++++++++++ src/databases/BookmarksDatabase.h | 58 ++++++ src/databases/CMakeLists.txt | 1 + src/databases/CookiesDatabase.cpp | 4 +- src/dialogs/AddBookmarkDialog.cpp | 91 ++++++++++ src/dialogs/AddBookmarkDialog.h | 49 +++++ src/dialogs/AddOrEditCookieDialog.cpp | 12 +- src/dialogs/AddOrEditCookieDialog.h | 2 +- src/dialogs/BookmarksDialog.cpp | 131 ++++++++++++++ src/dialogs/BookmarksDialog.h | 47 +++++ src/dialogs/CMakeLists.txt | 2 + src/dialogs/CookiesDialog.cpp | 14 +- src/dialogs/CookiesDialog.h | 2 +- src/main.cpp | 4 +- src/structs/BookmarkStruct.h | 34 ++++ src/ui.rcs/browserwindowui.rc | 10 ++ src/uis/AddBookmarkDialog.ui | 152 ++++++++++++++++ src/uis/AddOrEditCookieDialog.ui | 2 +- src/uis/BookmarksDialog.ui | 55 ++++++ src/uis/CookiesDialog.ui | 3 +- src/widgets/TabWidget.cpp | 18 ++ src/widgets/TabWidget.h | 3 + src/windows/BrowserWindow.cpp | 247 +++++++++++++++++++------- src/windows/BrowserWindow.h | 13 ++ 25 files changed, 1120 insertions(+), 78 deletions(-) create mode 100644 src/databases/BookmarksDatabase.cpp create mode 100644 src/databases/BookmarksDatabase.h create mode 100644 src/dialogs/AddBookmarkDialog.cpp create mode 100644 src/dialogs/AddBookmarkDialog.h create mode 100644 src/dialogs/BookmarksDialog.cpp create mode 100644 src/dialogs/BookmarksDialog.h create mode 100644 src/structs/BookmarkStruct.h create mode 100644 src/uis/AddBookmarkDialog.ui create mode 100644 src/uis/BookmarksDialog.ui diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index af21d5a..f96399a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,8 +35,10 @@ kconfig_add_kcfg_files(privacybrowser settings/Settings.kcfgc) # Use KDE Frameworks to handle internationalization of the following UI files. ki18n_wrap_ui(privacybrowser + uis/AddBookmarkDialog.ui uis/AddOrEditCookieDialog.ui uis/AddTabWidget.ui + uis/BookmarksDialog.ui uis/CookiesDialog.ui uis/DomainSettingsDialog.ui uis/DurableCookiesDialog.ui diff --git a/src/databases/BookmarksDatabase.cpp b/src/databases/BookmarksDatabase.cpp new file mode 100644 index 0000000..c290682 --- /dev/null +++ b/src/databases/BookmarksDatabase.cpp @@ -0,0 +1,242 @@ +/* + * Copyright 2023 Soren Stoutner . + * + * This file is part of 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 . + */ + +// Application headers. +#include "BookmarksDatabase.h" + +// Define the private static schema constants. +const int BookmarksDatabase::SCHEMA_VERSION = 0; + +// Define the public static constants. +const QString BookmarksDatabase::CONNECTION_NAME = "bookmarks_database"; +const QString BookmarksDatabase::BOOKMARK_NAME = "bookmark_name"; +const QString BookmarksDatabase::BOOKMARKS_TABLE = "bookmarks"; +const QString BookmarksDatabase::BOOKMARK_URL = "bookmark_url"; +const QString BookmarksDatabase::DISPLAY_ORDER = "display_order"; +const QString BookmarksDatabase::FAVORITE_ICON = "favorite_icon"; +const QString BookmarksDatabase::FOLDER_ID = "folder_id"; +const QString BookmarksDatabase::ID = "_id"; +const QString BookmarksDatabase::IS_FOLDER = "is_folder"; +const QString BookmarksDatabase::PARENT_FOLDER_ID = "parent_folder_id"; + +// Construct the class. +BookmarksDatabase::BookmarksDatabase() {} + +void BookmarksDatabase::addDatabase() +{ + // Add the bookmarks database. + QSqlDatabase bookmarksDatabase = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), CONNECTION_NAME); + + // Set the database name. + bookmarksDatabase.setDatabaseName(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/bookmarks.db"); + + // Open the database. + if (bookmarksDatabase.open()) // Opening the database succeeded. + { + // Check to see if the bookmarks table already exists. + if (bookmarksDatabase.tables().contains(BOOKMARKS_TABLE)) // The bookmarks table already exists. + { + // Query the database schema version. + QSqlQuery schemaVersionQuery = bookmarksDatabase.exec(QStringLiteral("PRAGMA user_version")); + + // Move to the first record. + schemaVersionQuery.first(); + + // Get the current schema version. + int currentSchemaVersion = schemaVersionQuery.value(0).toInt(); + + // Check to see if the schema has been updated. + if (currentSchemaVersion < SCHEMA_VERSION) + { + // Run the schema update code. + + // Update the schema version. + bookmarksDatabase.exec("PRAGMA user_version = " + QString::number(SCHEMA_VERSION)); + } + } + else // The bookmarks table does not exist. + { + // Instantiate a create table query. + QSqlQuery createTableQuery(bookmarksDatabase); + + // Populate the create table query. + createTableQuery.prepare("CREATE TABLE " + BOOKMARKS_TABLE + "(" + + ID + " INTEGER PRIMARY KEY, " + + BOOKMARK_NAME + " TEXT, " + + BOOKMARK_URL + " TEXT, " + + PARENT_FOLDER_ID + " INTEGER DEFAULT 0, " + + DISPLAY_ORDER + " INTEGER DEFAULT 0, " + + IS_FOLDER + " BOOLEAN DEFAULT FALSE, " + + FOLDER_ID + " INTEGER DEFAULT 0, " + + FAVORITE_ICON + " BLOB)"); + + // Execute the query. + if (!createTableQuery.exec()) + { + // Log any errors. + qDebug().noquote().nospace() << "Error creating table: " << bookmarksDatabase.lastError(); + } + + // Set the schema version. + bookmarksDatabase.exec("PRAGMA user_version = " + QString::number(SCHEMA_VERSION)); + } + } + else // Opening the database failed. + { + // Write the last database error message to the debug output. + qDebug().noquote().nospace() << "Error opening database: " << bookmarksDatabase.lastError(); + } +}; + +void BookmarksDatabase::addBookmark(const QString &bookmarkName, const QString &bookmarkUrl, const QIcon &favoriteIcon) +{ + // Get a handle for the bookmarks database. + QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME); + + // Get a favorite icon pixmap. + QPixmap favoriteIconPixmap = favoriteIcon.pixmap(32, 32); + + // Create a favorite icon byte array. + QByteArray favoriteIconByteArray; + + // Create a favorite icon buffer. + QBuffer favoriteIconBuffer(&favoriteIconByteArray); + + // Open the buffer. + favoriteIconBuffer.open(QIODevice::WriteOnly); + + // Convert the favorite icon pixmap into a byte array in PNG format. + favoriteIconPixmap.save(&favoriteIconBuffer, "PNG"); + + // Close the buffer. + favoriteIconBuffer.close(); + + // Convert the favorite icon byte array to a base 64 string. + QString favoriteIconBase64String = favoriteIconByteArray.toBase64(); + + // Instantiate an add bookmark query. + QSqlQuery addBookmarkQuery(bookmarksDatabase); + + // Prepare the add bookmark query. + addBookmarkQuery.prepare("INSERT INTO " + BOOKMARKS_TABLE + " (" + + BOOKMARK_NAME + ", " + + BOOKMARK_URL + ", " + + FAVORITE_ICON + ") " + "VALUES (:bookmark_name, :bookmark_url, :favorite_icon)" + ); + + // Bind the values. + addBookmarkQuery.bindValue(":bookmark_name", bookmarkName); + addBookmarkQuery.bindValue(":bookmark_url", bookmarkUrl); + addBookmarkQuery.bindValue(":favorite_icon", favoriteIconBase64String); + + // Execute the query. + addBookmarkQuery.exec(); +} + +std::list* BookmarksDatabase::getBookmarks() +{ + // Get a handle for the bookmarks database. + QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME); + + // Instantiate a bookmarks query. + QSqlQuery bookmarksQuery(bookmarksDatabase); + + // Set the query to be forward only, which is more performant. + bookmarksQuery.setForwardOnly(true); + + // Prepare the bookmarks query. + bookmarksQuery.prepare("SELECT * FROM " + BOOKMARKS_TABLE); + + // Execute the query. + bookmarksQuery.exec(); + + // Create a bookmark list. + std::list *bookmarkListPointer = new std::list; + + // Populate the bookmark list. + while (bookmarksQuery.next()) + { + // Create a bookmark struct. + struct BookmarkStruct bookmarkStruct; + + // Get the favorite icon base 64 bute array. + QByteArray favoriteIconByteArray = QByteArray::fromBase64(bookmarksQuery.value(FAVORITE_ICON).toByteArray()); + + // Create a favorite icon pixmap. + QPixmap favoriteIconPixmap; + + // Load the pixmap from byte array. + favoriteIconPixmap.loadFromData(favoriteIconByteArray); + + // Populate the bookmark struct. + bookmarkStruct.id = bookmarksQuery.value(ID).toInt(); + bookmarkStruct.bookmarkName = bookmarksQuery.value(BOOKMARK_NAME).toString(); + bookmarkStruct.bookmarkUrl = bookmarksQuery.value(BOOKMARK_URL).toString(); + bookmarkStruct.favoriteIcon = QIcon(favoriteIconPixmap); + + // Add the bookmark to the list. + bookmarkListPointer->push_back(bookmarkStruct); + } + + // Return the bookmark list. + return bookmarkListPointer; +} + +void BookmarksDatabase::updateBookmarkName(const int bookmarkId, const QString &bookmarkName) +{ + // Get a handle for the bookmarks database. + QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME); + + // Instantiate an update bookmark name query. + QSqlQuery updateBookmarkNameQuery(bookmarksDatabase); + + // Prepare the update bookmark name query. + updateBookmarkNameQuery.prepare("UPDATE " + BOOKMARKS_TABLE + + " SET " + BOOKMARK_NAME + " = :bookmark_name " + + "WHERE " + ID + " = :id"); + + // Bind the values. + updateBookmarkNameQuery.bindValue(":bookmark_name", bookmarkName); + updateBookmarkNameQuery.bindValue(":id", bookmarkId); + + // Execute the query. + updateBookmarkNameQuery.exec(); +} + +void BookmarksDatabase::updateBookmarkUrl(const int bookmarkId, const QString &bookmarkUrl) +{ + // Get a handle for the bookmarks database. + QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME); + + // Instantiate an update bookmark URL query. + QSqlQuery updateBookmarkUrlQuery(bookmarksDatabase); + + // Prepare the update bookmark URL query. + updateBookmarkUrlQuery.prepare("UPDATE " + BOOKMARKS_TABLE + + " SET " + BOOKMARK_URL + " = :bookmark_url " + + "WHERE " + ID + " = :id"); + + // Bind the values. + updateBookmarkUrlQuery.bindValue(":bookmark_url", bookmarkUrl); + updateBookmarkUrlQuery.bindValue(":id", bookmarkId); + + // Execute the query. + updateBookmarkUrlQuery.exec(); +} diff --git a/src/databases/BookmarksDatabase.h b/src/databases/BookmarksDatabase.h new file mode 100644 index 0000000..d0f743a --- /dev/null +++ b/src/databases/BookmarksDatabase.h @@ -0,0 +1,58 @@ +/* + * Copyright 2023 Soren Stoutner . + * + * This file is part of 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 . + */ + +#ifndef BOOKMARKSDATABASE_H +#define BOOKMARKSDATABASE_H + +// Application headers. +#include "structs/BookmarkStruct.h" + +// Qt framework headers. +#include + +class BookmarksDatabase +{ +public: + // The default constructor. + BookmarksDatabase(); + + // The public functions. + static void addBookmark(const QString &bookmarkName, const QString &bookmarkUrl, const QIcon &favoriteIcon); + static void addDatabase(); + static std::list* getBookmarks(); + static void updateBookmarkName(const int bookmarkId, const QString &bookmarkName); + static void updateBookmarkUrl(const int bookmarkId, const QString &bookmarkUrl); + + // The public constants. + static const QString CONNECTION_NAME; + static const QString BOOKMARK_NAME; + static const QString BOOKMARKS_TABLE; + static const QString BOOKMARK_URL; + static const QString DISPLAY_ORDER; + static const QString FAVORITE_ICON; + static const QString FOLDER_ID; + static const QString ID; + static const QString IS_FOLDER; + static const QString PARENT_FOLDER_ID; + + private: + // The private static constants. + static const int SCHEMA_VERSION; +}; +#endif diff --git a/src/databases/CMakeLists.txt b/src/databases/CMakeLists.txt index e38dbd2..5f40f99 100644 --- a/src/databases/CMakeLists.txt +++ b/src/databases/CMakeLists.txt @@ -18,6 +18,7 @@ # List the sources to include in the executable. target_sources(privacybrowser PRIVATE + BookmarksDatabase.cpp CookiesDatabase.cpp DomainsDatabase.cpp ) diff --git a/src/databases/CookiesDatabase.cpp b/src/databases/CookiesDatabase.cpp index dcb6f0b..e8a870b 100644 --- a/src/databases/CookiesDatabase.cpp +++ b/src/databases/CookiesDatabase.cpp @@ -230,7 +230,7 @@ QList* CookiesDatabase::getCookies() // Instantiate a cookies query. QSqlQuery cookiesQuery(cookiesDatabase); - // Set the query to be forward only. + // Set the query to be forward only, which is more performant. cookiesQuery.setForwardOnly(true); // Prepare the cookies query. @@ -402,7 +402,7 @@ void CookiesDatabase::updateCookie(const QNetworkCookie &cookie) // Create the update cookie query. QSqlQuery updateCookieQuery(cookiesDatabase); - // Prepare the edit cookie query. + // Prepare the update cookie query. updateCookieQuery.prepare("UPDATE " + COOKIES_TABLE + " SET " + EXPIRATION_DATE + " = :expiration_date , " + HTTP_ONLY + " = :http_only , " + diff --git a/src/dialogs/AddBookmarkDialog.cpp b/src/dialogs/AddBookmarkDialog.cpp new file mode 100644 index 0000000..cc0d132 --- /dev/null +++ b/src/dialogs/AddBookmarkDialog.cpp @@ -0,0 +1,91 @@ +/* + * Copyright 2023 Soren Stoutner . + * + * This file is part of 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 . + */ + +// Application headers. +#include "AddBookmarkDialog.h" +#include "ui_AddBookmarkDialog.h" +#include "databases/BookmarksDatabase.h" + +// KDE Framework headers. +#include + +// Qt toolkit headers. +#include + +// Construct the class. +AddBookmarkDialog::AddBookmarkDialog(const QString &bookmarkName, const QString &bookmarkUrl, const QIcon &favoriteIcon) : QDialog(nullptr), icon(favoriteIcon) +{ + // Set the window title. + setWindowTitle(i18nc("The add bookmark dialog window title.", "Add Bookmark")); + + // Set the window modality. + setWindowModality(Qt::WindowModality::ApplicationModal); + + // Instantiate the bookmarks dialog UI. + Ui::AddBookmarkDialog addBookmarkDialogUi; + + // Setup the UI. + addBookmarkDialogUi.setupUi(this); + + // Get handles for the widgets. + QGraphicsView *favoriteIconGraphicsViewPointer = addBookmarkDialogUi.favoriteIconGraphicsView; + bookmarkNamePointer = addBookmarkDialogUi.bookmarkNameLineEdit; + bookmarkUrlPointer = addBookmarkDialogUi.bookmarkUrlLineEdit; + QDialogButtonBox *dialogButtonBoxPointer = addBookmarkDialogUi.dialogButtonBox; + + // Create a graphics scene. + QGraphicsScene *favoriteIconGraphicsScenePointer = new QGraphicsScene(this); + + // Set the graphics scene. + favoriteIconGraphicsViewPointer->setScene(favoriteIconGraphicsScenePointer); + + // Set the background of the graphics view to be the same as the window + favoriteIconGraphicsViewPointer->setBackgroundRole(QPalette::Window); + + // Add the MIME type icon to the scene. + favoriteIconGraphicsScenePointer->addPixmap(favoriteIcon.pixmap(32, 32)); + + // Populate the line edits. + bookmarkNamePointer->setText(bookmarkName); + bookmarkUrlPointer->setText(bookmarkUrl); + + // Scroll the the beginning of the line edits. + bookmarkNamePointer->setCursorPosition(0); + bookmarkUrlPointer->setCursorPosition(0); + + // Add buttons to the dialog button box. + QPushButton *addBookmarkButtonPointer = dialogButtonBoxPointer->addButton(i18nc("The add bookmark button", "Add"), QDialogButtonBox::AcceptRole); + + // Set the button icons. + addBookmarkButtonPointer->setIcon(QIcon::fromTheme("list-add")); + + // Connect the buttons. + connect(dialogButtonBoxPointer, SIGNAL(accepted()), this, SLOT(addBookmark())); + connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject())); +} + +void AddBookmarkDialog::addBookmark() +{ + // Add the bookmark. + BookmarksDatabase::addBookmark(bookmarkNamePointer->text(), bookmarkUrlPointer->text(), icon); + + // Close the dialog. + close(); +} + diff --git a/src/dialogs/AddBookmarkDialog.h b/src/dialogs/AddBookmarkDialog.h new file mode 100644 index 0000000..2cee8b9 --- /dev/null +++ b/src/dialogs/AddBookmarkDialog.h @@ -0,0 +1,49 @@ +/* + * Copyright 2023 Soren Stoutner . + * + * This file is part of 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 . + */ + +#ifndef ADDBOOKMARKDIALOG_H +#define ADDBOOKMARKDIALOG_H + +// Qt toolkit headers. +#include +#include +#include + +class AddBookmarkDialog : public QDialog +{ + // Include the Q_OBJECT macro. + Q_OBJECT + +public: + // The primary constructor. + explicit AddBookmarkDialog(const QString &bookmarkName, const QString &bookmarkUrl, const QIcon &favoriteIcon); + +private Q_SLOTS: + // The private slots. + void addBookmark(); + +private: + // The private widgets. + QLineEdit *bookmarkNamePointer; + QLineEdit *bookmarkUrlPointer; + + // The private variables. + const QIcon icon; +}; +#endif diff --git a/src/dialogs/AddOrEditCookieDialog.cpp b/src/dialogs/AddOrEditCookieDialog.cpp index e39303e..eba44b8 100644 --- a/src/dialogs/AddOrEditCookieDialog.cpp +++ b/src/dialogs/AddOrEditCookieDialog.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2022 Soren Stoutner . + * Copyright 2022-2023 Soren Stoutner . * * This file is part of Privacy Browser PC . * @@ -49,7 +49,7 @@ AddOrEditCookieDialog::AddOrEditCookieDialog(const int &dialogType, const QNetwo // Set the window modality. setWindowModality(Qt::WindowModality::ApplicationModal); - // Instantiate the cookie settings dialog UI. + // Instantiate the cookie dialog UI. Ui::AddOrEditCookieDialog addOrEditCookieDialogUi; // Setup the UI. @@ -83,6 +83,12 @@ AddOrEditCookieDialog::AddOrEditCookieDialog(const int &dialogType, const QNetwo secureCheckBoxPointer->setChecked(originalCookie.isSecure()); valueLineEditPointer->setText(originalCookie.value()); + // Scroll to the beginning of the line edits. + domainLineEditPointer->setCursorPosition(0); + nameLineEditPointer->setCursorPosition(0); + pathLineEditPointer->setCursorPosition(0); + valueLineEditPointer->setCursorPosition(0); + // Populate the expiration date if it exists. if (!originalCookie.isSessionCookie()) { @@ -167,7 +173,7 @@ void AddOrEditCookieDialog::saveCookie() emit addCookie(cookie, isDurable); // Close the dialog. - reject(); + close(); } void AddOrEditCookieDialog::updateExpirationDateTimeState(const int &newState) const diff --git a/src/dialogs/AddOrEditCookieDialog.h b/src/dialogs/AddOrEditCookieDialog.h index d00e3f7..895b14a 100644 --- a/src/dialogs/AddOrEditCookieDialog.h +++ b/src/dialogs/AddOrEditCookieDialog.h @@ -1,5 +1,5 @@ /* - * Copyright © 2022 Soren Stoutner . + * Copyright 2022 Soren Stoutner . * * This file is part of Privacy Browser PC . * diff --git a/src/dialogs/BookmarksDialog.cpp b/src/dialogs/BookmarksDialog.cpp new file mode 100644 index 0000000..509fade --- /dev/null +++ b/src/dialogs/BookmarksDialog.cpp @@ -0,0 +1,131 @@ +/* + * Copyright 2023 Soren Stoutner . + * + * This file is part of 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 . + */ + +// Application headers. +#include "BookmarksDialog.h" +#include "ui_BookmarksDialog.h" +#include "databases/BookmarksDatabase.h" + +// KDE Frameworks headers. +#include + +// Qt toolkit headers. +#include +#include +#include + +// Construct the class. +BookmarksDialog::BookmarksDialog() : QDialog(nullptr) +{ + // Set the dialog window title. + setWindowTitle(i18nc("The bookmarks dialog window title", "Bookmarks")); + + // Set the window modality. + setWindowModality(Qt::WindowModality::ApplicationModal); + + // Instantiate the bookmarks settings dialog UI. + Ui::BookmarksDialog bookmarksDialogUi; + + // Setup the UI. + bookmarksDialogUi.setupUi(this); + + // Get the list of bookmarks. + std::list *bookmarksListPointer = BookmarksDatabase::getBookmarks(); + + // Get a handle for the tree view. + QTreeView *treeViewPointer = bookmarksDialogUi.treeView; + + // Initialize the tree model. + QStandardItemModel *treeModelPointer = new QStandardItemModel(); + + // Set the column count. + treeModelPointer->setColumnCount(3); + + // Set the tree header data. The first column is the database ID, which is not displayed. + treeModelPointer->setHeaderData(1, Qt::Horizontal, i18nc("The bookmark Name header.", "Name")); + treeModelPointer->setHeaderData(2, Qt::Horizontal, i18nc("The bookmark URL header.", "URL")); + + // Populate the bookmarks tree view. + for (BookmarkStruct bookmarkStruct : *bookmarksListPointer) + { + // Create a list for the bookmark items. + QList bookmarkItemList; + + // Create the bookmark items. + QStandardItem *idItemPointer = new QStandardItem(QString::number(bookmarkStruct.id)); + QStandardItem *nameItemPointer = new QStandardItem(bookmarkStruct.favoriteIcon, bookmarkStruct.bookmarkName); + QStandardItem *urlItemPointer = new QStandardItem(bookmarkStruct.bookmarkUrl); + + // Populate the cookie standard item list. + bookmarkItemList.append(idItemPointer); + bookmarkItemList.append(nameItemPointer); + bookmarkItemList.append(urlItemPointer); + + // Add the cookie to the tree. + treeModelPointer->appendRow(bookmarkItemList); + } + + // Auto resize the headers. + treeViewPointer->header()->setSectionResizeMode(QHeaderView::ResizeToContents); + + // Indicate that all the rows are the same height, which improves performance. + treeViewPointer->setUniformRowHeights(true); + + // Set the tree model. + treeViewPointer->setModel(treeModelPointer); + + // Hide the database ID column. + treeViewPointer->setColumnHidden(0, true); + + // Get handles for the buttons. + QDialogButtonBox *dialogButtonBoxPointer = bookmarksDialogUi.dialogButtonBox; + + // Connect the buttons. + connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject())); + + // Monitor editing of data in the tree model. + connect(treeModelPointer, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(updateBookmarkFromTree(QStandardItem*))); +} + +void BookmarksDialog::updateBookmarkFromTree(QStandardItem *modifiedStandardItem) +{ + // Get the model index of the modified item. + QModelIndex modifiedItemModelIndex = modifiedStandardItem->index(); + + // Get the model index of the database ID. + QModelIndex databaseIdModelIndex = modifiedItemModelIndex.siblingAtColumn(0); + + // Get the database ID. + int databaseId = databaseIdModelIndex.data().toInt(); + + // Check to see if the bookmark name or the URL was edited. + if (modifiedStandardItem->column() == 1) // The bookmark name was edited. + { + // Update the bookmark name. + BookmarksDatabase::updateBookmarkName(databaseId, modifiedStandardItem->text()); + } + else // The bookmark URL was edited. + { + // Update the bookmark URL. + BookmarksDatabase::updateBookmarkUrl(databaseId, modifiedStandardItem->text()); + } + + // Emit the bookmark updated signal. + emit bookmarkUpdated(); +} diff --git a/src/dialogs/BookmarksDialog.h b/src/dialogs/BookmarksDialog.h new file mode 100644 index 0000000..3e2713e --- /dev/null +++ b/src/dialogs/BookmarksDialog.h @@ -0,0 +1,47 @@ +/* + * Copyright 2023 Soren Stoutner . + * + * This file is part of 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 . + */ + +#ifndef BOOKMARKSDIALOG_H +#define BOOKMARKSDIALOG_H + +// Application headers. +#include "structs/BookmarkStruct.h" + +// Qt toolkit headers. +#include +#include + +class BookmarksDialog : public QDialog +{ + // Include the Q_OBJECT macro. + Q_OBJECT + +public: + // The primary constructor. + explicit BookmarksDialog(); + +signals: + // The signals. + void bookmarkUpdated() const; + +private Q_SLOTS: + // The private slots. + void updateBookmarkFromTree(QStandardItem *modifiedStandardItem); +}; +#endif diff --git a/src/dialogs/CMakeLists.txt b/src/dialogs/CMakeLists.txt index d30f067..b5d7cfd 100644 --- a/src/dialogs/CMakeLists.txt +++ b/src/dialogs/CMakeLists.txt @@ -18,7 +18,9 @@ # List the sources to include in the executable. target_sources(privacybrowser PRIVATE + AddBookmarkDialog.cpp AddOrEditCookieDialog.cpp + BookmarksDialog.cpp CookiesDialog.cpp DomainSettingsDialog.cpp DurableCookiesDialog.cpp diff --git a/src/dialogs/CookiesDialog.cpp b/src/dialogs/CookiesDialog.cpp index 693eb3c..3dc357f 100644 --- a/src/dialogs/CookiesDialog.cpp +++ b/src/dialogs/CookiesDialog.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2022-2023 Soren Stoutner . + * Copyright 2022-2023 Soren Stoutner . * * This file is part of Privacy Browser PC . * @@ -202,11 +202,11 @@ CookiesDialog::CookiesDialog(std::list *originalCookieListPointe // Create the cookie items. QStandardItem *nameItemPointer = new QStandardItem(QString(cookie.name())); - QStandardItem *durableItemPointer = new QStandardItem(QString(isDurable ? i18n("yes") : i18n("no"))); - QStandardItem *pathItemPointer = new QStandardItem(QString(cookie.path())); - QStandardItem *expirationDateItemPointer = new QStandardItem(QString(cookie.expirationDate().toString())); - QStandardItem *isHttpOnlyItemPointer = new QStandardItem(QString(cookie.isHttpOnly() ? i18n("yes") : i18n("no"))); - QStandardItem *isSecureItemPointer = new QStandardItem(QString(cookie.isSecure() ? i18n("yes") : i18n("no"))); + QStandardItem *durableItemPointer = new QStandardItem(isDurable ? i18n("yes") : i18n("no")); + QStandardItem *pathItemPointer = new QStandardItem(cookie.path()); + QStandardItem *expirationDateItemPointer = new QStandardItem(cookie.expirationDate().toString()); + QStandardItem *isHttpOnlyItemPointer = new QStandardItem(cookie.isHttpOnly() ? i18n("yes") : i18n("no")); + QStandardItem *isSecureItemPointer = new QStandardItem(cookie.isSecure() ? i18n("yes") : i18n("no")); QStandardItem *valueItemPointer = new QStandardItem(QString(cookie.value())); // Populate the cookie standard item list. @@ -231,7 +231,7 @@ CookiesDialog::CookiesDialog(std::list *originalCookieListPointe // Don't elide the Value field (or any other field). treeViewPointer->setTextElideMode(Qt::ElideNone); - // Indicate that all the rows are the same height, wich improves performance. + // Indicate that all the rows are the same height, which improves performance. treeViewPointer->setUniformRowHeights(true); // Disable editing in the tree view. diff --git a/src/dialogs/CookiesDialog.h b/src/dialogs/CookiesDialog.h index 36a7d72..be4acda 100644 --- a/src/dialogs/CookiesDialog.h +++ b/src/dialogs/CookiesDialog.h @@ -1,5 +1,5 @@ /* - * Copyright © 2022 Soren Stoutner . + * Copyright 2022-2023 Soren Stoutner . * * This file is part of Privacy Browser PC . * diff --git a/src/main.cpp b/src/main.cpp index d90258c..c39eb88 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,6 +18,7 @@ */ // Application headers. +#include "databases/BookmarksDatabase.h" #include "databases/CookiesDatabase.h" #include "databases/DomainsDatabase.h" #include "windows/BrowserWindow.h" @@ -87,8 +88,9 @@ int main(int argc, char *argv[]) QDir().mkdir(QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).first()); // Add the databases. - DomainsDatabase::addDatabase(); + BookmarksDatabase::addDatabase(); CookiesDatabase::addDatabase(); + DomainsDatabase::addDatabase(); // Create the main window. BrowserWindow *browserWindowPointer = new BrowserWindow(); diff --git a/src/structs/BookmarkStruct.h b/src/structs/BookmarkStruct.h new file mode 100644 index 0000000..2819174 --- /dev/null +++ b/src/structs/BookmarkStruct.h @@ -0,0 +1,34 @@ +/* + * Copyright 2023 Soren Stoutner . + * + * This file is part of 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 . + */ + +#ifndef BOOKMARKSTRUCT_H +#define BOOKMARKSTRUCT_H + +// Qt framework headers. +#include +#include + +struct BookmarkStruct +{ + int id; + QString bookmarkName; + QString bookmarkUrl; + QIcon favoriteIcon; +}; +#endif diff --git a/src/ui.rcs/browserwindowui.rc b/src/ui.rcs/browserwindowui.rc index 1a79d69..c0e5a19 100644 --- a/src/ui.rcs/browserwindowui.rc +++ b/src/ui.rcs/browserwindowui.rc @@ -81,6 +81,13 @@ + + + + + + + @@ -109,4 +116,7 @@ + + + diff --git a/src/uis/AddBookmarkDialog.ui b/src/uis/AddBookmarkDialog.ui new file mode 100644 index 0000000..b6dc2cf --- /dev/null +++ b/src/uis/AddBookmarkDialog.ui @@ -0,0 +1,152 @@ + + + + + + AddBookmarkDialog + + + + + + + + + Qt::AlignLeft + + + + + + + + 0 + 0 + + + + + + 32 + 32 + + + + + QFrame::NoFrame + + + + Qt::AlignCenter + + + + + + + + + Qt::RichText + + + + &nbsp; + + + + + + + + + The name of the bookmark. + + + + Bookmark name + + + + + + + + + + + + + + + Qt::AlignLeft + + + + + + + The URL of the bookmark. + + + + Bookmark URL + + + + + + + + + 0 + 0 + + + + + + 700 + 0 + + + + + + + + + + + + Qt::Vertical + + + + + + + + + QDialogButtonBox::Cancel + + + + + + diff --git a/src/uis/AddOrEditCookieDialog.ui b/src/uis/AddOrEditCookieDialog.ui index 658cb8d..779b8fb 100644 --- a/src/uis/AddOrEditCookieDialog.ui +++ b/src/uis/AddOrEditCookieDialog.ui @@ -1,7 +1,7 @@ + + + BookmarksDialog + + + + + 0 + 0 + 1000 + 1500 + + + + + + + + + + + + + + + + + QDialogButtonBox::Close + + + + + + + + diff --git a/src/uis/CookiesDialog.ui b/src/uis/CookiesDialog.ui index 7849245..32529cb 100644 --- a/src/uis/CookiesDialog.ui +++ b/src/uis/CookiesDialog.ui @@ -1,7 +1,7 @@