uis/CookiesDialog.ui
uis/DomainSettingsDialog.ui
uis/DurableCookiesDialog.ui
+ uis/EditBookmarkDialog.ui
uis/SaveDialog.ui
uis/SettingsGeneral.ui
uis/SettingsPrivacy.ui
}
};
-void BookmarksDatabase::addBookmark(const QString &bookmarkName, const QString &bookmarkUrl, const QIcon &favoriteIcon)
+void BookmarksDatabase::addBookmark(const BookmarkStruct *bookmarkStructPointer)
{
// Get a handle for the bookmarks database.
QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
- // Get a favorite icon pixmap.
- QPixmap favoriteIconPixmap = favoriteIcon.pixmap(32, 32);
+ // Instantiate a count bookmarks query. TODO: This needs to be updated to only count the bookmarks in the current folder.
+ QSqlQuery countBookmarksQuery(bookmarksDatabase);
- // Create a favorite icon byte array.
- QByteArray favoriteIconByteArray;
+ // Set the query to be forward only, which is more performant.
+ countBookmarksQuery.setForwardOnly(true);
- // Create a favorite icon buffer.
- QBuffer favoriteIconBuffer(&favoriteIconByteArray);
+ // Prepare the count bookmarks query.
+ countBookmarksQuery.prepare("SELECT " + DISPLAY_ORDER + " FROM " + BOOKMARKS_TABLE);
- // Open the buffer.
- favoriteIconBuffer.open(QIODevice::WriteOnly);
+ // Execute the count bookmarks query.
+ countBookmarksQuery.exec();
- // Convert the favorite icon pixmap into a byte array in PNG format.
- favoriteIconPixmap.save(&favoriteIconBuffer, "PNG");
+ // Move to the last row.
+ countBookmarksQuery.last();
- // Close the buffer.
- favoriteIconBuffer.close();
+ // Initialize a bookmarks count variable.
+ int bookmarksCount = 0;
- // Convert the favorite icon byte array to a base 64 string.
- QString favoriteIconBase64String = favoriteIconByteArray.toBase64();
+ // Check to see if the query is valid (there is at least one bookmark).
+ if (countBookmarksQuery.isValid())
+ {
+ // Get the number of rows (which is zero based) and add one to calculate the number of bookmarks.
+ bookmarksCount = countBookmarksQuery.at() + 1;
+ }
// Instantiate an add bookmark query.
QSqlQuery addBookmarkQuery(bookmarksDatabase);
addBookmarkQuery.prepare("INSERT INTO " + BOOKMARKS_TABLE + " (" +
BOOKMARK_NAME + ", " +
BOOKMARK_URL + ", " +
- FAVORITE_ICON + ") "
- "VALUES (:bookmark_name, :bookmark_url, :favorite_icon)"
+ FAVORITE_ICON + ", " +
+ DISPLAY_ORDER + ") " +
+ "VALUES (:bookmark_name, :bookmark_url, :favorite_icon, :display_order)"
);
- // Bind the values.
- addBookmarkQuery.bindValue(":bookmark_name", bookmarkName);
- addBookmarkQuery.bindValue(":bookmark_url", bookmarkUrl);
- addBookmarkQuery.bindValue(":favorite_icon", favoriteIconBase64String);
+ // Bind the query values.
+ addBookmarkQuery.bindValue(":bookmark_name", bookmarkStructPointer->bookmarkName);
+ addBookmarkQuery.bindValue(":bookmark_url", bookmarkStructPointer->bookmarkUrl);
+ addBookmarkQuery.bindValue(":favorite_icon", getFavoriteIconBase64String(bookmarkStructPointer->favoriteIcon));
+ addBookmarkQuery.bindValue(":display_order", bookmarksCount);
- // Execute the query.
+ // Execute the add bookmark query.
addBookmarkQuery.exec();
}
+void BookmarksDatabase::deleteBookmark(const int bookmarkId)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate a delete bookmark query.
+ QSqlQuery deleteBookmarkQuery(bookmarksDatabase);
+
+ // Prepare the delete bookmark query.
+ deleteBookmarkQuery.prepare("DELETE FROM " + BOOKMARKS_TABLE + " WHERE " + ID + " = :id");
+
+ // Bind the query values.
+ deleteBookmarkQuery.bindValue(":id", bookmarkId);
+
+ // Execute the query.
+ deleteBookmarkQuery.exec();
+
+ // Reset the display order for the other items in the folder. TODO: make this folder aware.
+ // TODO: Perhaps, for performance reasons, this shouldn't run each time a bookmarks is deleted, but batched at the end.
+
+ // 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 " + ID + ", " + DISPLAY_ORDER + " FROM " + BOOKMARKS_TABLE + " ORDER BY " + DISPLAY_ORDER + " ASC");
+
+ // Execute the query.
+ bookmarksQuery.exec();
+
+ // Create a new display order int.
+ int newDisplayOrder = 0;
+
+ // Update the display order for each bookmark.
+ while (bookmarksQuery.next())
+ {
+ // Check if the new display order is different than the current display order.
+ if (bookmarksQuery.value(DISPLAY_ORDER).toInt() != newDisplayOrder)
+ {
+ // Instantiate an update display order query.
+ QSqlQuery updateDisplayOrderQuery(bookmarksDatabase);
+
+ // Prepare the update display order query.
+ updateDisplayOrderQuery.prepare("UPDATE " + BOOKMARKS_TABLE + " SET " + DISPLAY_ORDER + " = :display_order WHERE " + ID + " = :id");
+
+ // Bind the query values.
+ updateDisplayOrderQuery.bindValue(":display_order", newDisplayOrder);
+ updateDisplayOrderQuery.bindValue(":id", bookmarksQuery.value(ID).toInt());
+
+ // Execute the query.
+ updateDisplayOrderQuery.exec();
+ }
+
+ // Increment the new display order.
+ ++newDisplayOrder;
+ }
+}
+
+BookmarkStruct *BookmarksDatabase::getBookmark(int bookmarkId)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate a bookmark query.
+ QSqlQuery bookmarkQuery(bookmarksDatabase);
+
+ // Set the query to be forward only, which is more performant.
+ bookmarkQuery.setForwardOnly(true);
+
+ // Prepare the bookmark query.
+ bookmarkQuery.prepare("SELECT * FROM " + BOOKMARKS_TABLE + " WHERE " + ID + " = :id");
+
+ // Bind the query values.
+ bookmarkQuery.bindValue(":id", bookmarkId);
+
+ // Execute the query.
+ bookmarkQuery.exec();
+
+ // Move to the first entry.
+ bookmarkQuery.first();
+
+ // Create a bookmark struct.
+ struct BookmarkStruct *bookmarkStructPointer = new BookmarkStruct();
+
+ // Get the favorite icon base 64 byte array.
+ QByteArray favoriteIconByteArray = QByteArray::fromBase64(bookmarkQuery.value(FAVORITE_ICON).toByteArray());
+
+ // Create a favorite icon pixmap.
+ QPixmap favoriteIconPixmap;
+
+ // Load the pixmap from byte array.
+ favoriteIconPixmap.loadFromData(favoriteIconByteArray);
+
+ // Populate the bookmark struct.
+ bookmarkStructPointer->id = bookmarkQuery.value(ID).toInt();
+ bookmarkStructPointer->bookmarkName = bookmarkQuery.value(BOOKMARK_NAME).toString();
+ bookmarkStructPointer->bookmarkUrl = bookmarkQuery.value(BOOKMARK_URL).toString();
+ bookmarkStructPointer->displayOrder = bookmarkQuery.value(DISPLAY_ORDER).toInt();
+ bookmarkStructPointer->favoriteIcon = QIcon(favoriteIconPixmap);
+
+ // Return the bookmark struct pointer.
+ return bookmarkStructPointer;
+}
+
std::list<BookmarkStruct>* BookmarksDatabase::getBookmarks()
{
// Get a handle for the bookmarks database.
bookmarksQuery.setForwardOnly(true);
// Prepare the bookmarks query.
- bookmarksQuery.prepare("SELECT * FROM " + BOOKMARKS_TABLE);
+ bookmarksQuery.prepare("SELECT * FROM " + BOOKMARKS_TABLE + " ORDER BY " + DISPLAY_ORDER + " ASC");
// Execute the query.
bookmarksQuery.exec();
// Create a bookmark struct.
struct BookmarkStruct bookmarkStruct;
- // Get the favorite icon base 64 bute array.
+ // Get the favorite icon base 64 byte array.
QByteArray favoriteIconByteArray = QByteArray::fromBase64(bookmarksQuery.value(FAVORITE_ICON).toByteArray());
// Create a favorite icon pixmap.
bookmarkStruct.id = bookmarksQuery.value(ID).toInt();
bookmarkStruct.bookmarkName = bookmarksQuery.value(BOOKMARK_NAME).toString();
bookmarkStruct.bookmarkUrl = bookmarksQuery.value(BOOKMARK_URL).toString();
+ bookmarkStruct.displayOrder = bookmarksQuery.value(DISPLAY_ORDER).toInt();
bookmarkStruct.favoriteIcon = QIcon(favoriteIconPixmap);
// Add the bookmark to the list.
return bookmarkListPointer;
}
+QList<BookmarkStruct>* BookmarksDatabase::getBookmarksExcept(QList<int> *exceptDatabaseIdsListPointer)
+{
+ // 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);
+
+ // Create an IDs not to get string.
+ QString idsNotToGetString;
+
+ for (const int databaseId : *exceptDatabaseIdsListPointer)
+ {
+ // Check to see if there the string already has at least one number.
+ if (!idsNotToGetString.isEmpty())
+ {
+ // This is not the first number, so add a `,`.
+ idsNotToGetString.append(QLatin1Char(','));
+ }
+
+ // Append the database ID.
+ idsNotToGetString.append(QString::number(databaseId));
+ }
+
+ // Prepare the bookmarks query.
+ bookmarksQuery.prepare("SELECT * FROM " + BOOKMARKS_TABLE + " WHERE " + ID + " NOT IN (" + idsNotToGetString + ") ORDER BY " + DISPLAY_ORDER + " ASC");
+
+ // Execute the query.
+ bookmarksQuery.exec();
+
+ // Create a bookmark list.
+ QList<BookmarkStruct> *bookmarkListPointer = new QList<BookmarkStruct>;
+
+ // Populate the bookmark list.
+ while (bookmarksQuery.next())
+ {
+ // Create a bookmark struct.
+ struct BookmarkStruct bookmarkStruct;
+
+ // Get the favorite icon base 64 byte 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.displayOrder = bookmarksQuery.value(DISPLAY_ORDER).toInt();
+ bookmarkStruct.favoriteIcon = QIcon(favoriteIconPixmap);
+
+ // Add the bookmark to the list.
+ bookmarkListPointer->push_back(bookmarkStruct);
+ }
+
+ // Return the bookmark list.
+ return bookmarkListPointer;
+}
+
+QString BookmarksDatabase::getFavoriteIconBase64String(const QIcon &favoriteIcon)
+{
+ // 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();
+
+ // Return the favorite icon base 64 string.
+ return favoriteIconBase64String;
+}
+
+void BookmarksDatabase::updateBookmark(const BookmarkStruct *bookmarkStructPointer)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate an update bookmark name.
+ QSqlQuery updateBookmarkQuery(bookmarksDatabase);
+
+ // Prepare the update bookmark query.
+ updateBookmarkQuery.prepare("UPDATE " + BOOKMARKS_TABLE + " SET " +
+ BOOKMARK_NAME + " = :bookmark_name, " +
+ BOOKMARK_URL + " = :bookmark_url, " +
+ DISPLAY_ORDER + " = :display_order, " +
+ FAVORITE_ICON + "= :favorite_icon " +
+ "WHERE " + ID + " = :id");
+
+ // Bind the query values.
+ updateBookmarkQuery.bindValue(":bookmark_name", bookmarkStructPointer->bookmarkName);
+ updateBookmarkQuery.bindValue(":bookmark_url", bookmarkStructPointer->bookmarkUrl);
+ updateBookmarkQuery.bindValue(":display_order", bookmarkStructPointer->displayOrder);
+ updateBookmarkQuery.bindValue(":favorite_icon", getFavoriteIconBase64String(bookmarkStructPointer->favoriteIcon));
+ updateBookmarkQuery.bindValue(":id", bookmarkStructPointer->id);
+
+ // Execute the query.
+ updateBookmarkQuery.exec();
+}
+
+void BookmarksDatabase::updateDisplayOrder(const int bookmarkId, const int displayOrder)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate an update bookmark display order query.
+ QSqlQuery updateBookmarkDisplayOrderQuery(bookmarksDatabase);
+
+ // Prepare the update bookmark display order query.
+ updateBookmarkDisplayOrderQuery.prepare("UPDATE " + BOOKMARKS_TABLE +
+ " SET " + DISPLAY_ORDER + " = :display_order " +
+ "WHERE " + ID + " = :id");
+
+ // Bind the query values.
+ updateBookmarkDisplayOrderQuery.bindValue(":display_order", displayOrder);
+ updateBookmarkDisplayOrderQuery.bindValue(":id", bookmarkId);
+
+ // Execute the query.
+ updateBookmarkDisplayOrderQuery.exec();
+}
+
void BookmarksDatabase::updateBookmarkName(const int bookmarkId, const QString &bookmarkName)
{
// Get a handle for the bookmarks database.
" SET " + BOOKMARK_NAME + " = :bookmark_name " +
"WHERE " + ID + " = :id");
- // Bind the values.
+ // Bind the query values.
updateBookmarkNameQuery.bindValue(":bookmark_name", bookmarkName);
updateBookmarkNameQuery.bindValue(":id", bookmarkId);
" SET " + BOOKMARK_URL + " = :bookmark_url " +
"WHERE " + ID + " = :id");
- // Bind the values.
+ // Bind the query values.
updateBookmarkUrlQuery.bindValue(":bookmark_url", bookmarkUrl);
updateBookmarkUrlQuery.bindValue(":id", bookmarkId);
BookmarksDatabase();
// The public functions.
- static void addBookmark(const QString &bookmarkName, const QString &bookmarkUrl, const QIcon &favoriteIcon);
+ static void addBookmark(const BookmarkStruct *bookmarkStructPointer);
static void addDatabase();
+ static void deleteBookmark(const int bookmarkId);
+ static BookmarkStruct* getBookmark(int bookmarkId);
static std::list<BookmarkStruct>* getBookmarks();
+ static QList<BookmarkStruct>* getBookmarksExcept(QList<int> *exceptDatabaseIdsListPointer);
+ static void updateBookmark(const BookmarkStruct *bookmarkStructPointer);
+ static void updateDisplayOrder(const int bookmarkId, const int displayOrder);
static void updateBookmarkName(const int bookmarkId, const QString &bookmarkName);
static void updateBookmarkUrl(const int bookmarkId, const QString &bookmarkUrl);
static const QString IS_FOLDER;
static const QString PARENT_FOLDER_ID;
- private:
+private:
// The private static constants.
static const int SCHEMA_VERSION;
+
+ // The private functions.
+ static QString getFavoriteIconBase64String(const QIcon &favoriteIcon);
};
#endif
#include <KLocalizedString>
// Qt toolkit headers.
+#include <QFileDialog>
#include <QPushButton>
// Construct the class.
-AddBookmarkDialog::AddBookmarkDialog(const QString &bookmarkName, const QString &bookmarkUrl, const QIcon &favoriteIcon) : QDialog(nullptr), icon(favoriteIcon)
+AddBookmarkDialog::AddBookmarkDialog(const QString &bookmarkName, const QString &bookmarkUrl, const QIcon &favoriteIcon) : QDialog(nullptr)
{
// Set the window title.
setWindowTitle(i18nc("The add bookmark dialog window title.", "Add Bookmark"));
addBookmarkDialogUi.setupUi(this);
// Get handles for the widgets.
- QGraphicsView *favoriteIconGraphicsViewPointer = addBookmarkDialogUi.favoriteIconGraphicsView;
+ defaultFavoriteIconRadioButtonPointer = addBookmarkDialogUi.defaultFavoriteIconRadioButton;
+ customFavoriteIconRadioButtonPointer = addBookmarkDialogUi.customFavoriteIconRadioButton;
bookmarkNamePointer = addBookmarkDialogUi.bookmarkNameLineEdit;
bookmarkUrlPointer = addBookmarkDialogUi.bookmarkUrlLineEdit;
+ QPushButton *browseButtonPointer = addBookmarkDialogUi.browseButton;
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));
+ // Set the default favorite icon.
+ defaultFavoriteIconRadioButtonPointer->setIcon(favoriteIcon);
// Populate the line edits.
bookmarkNamePointer->setText(bookmarkName);
bookmarkUrlPointer->setText(bookmarkUrl);
- // Scroll the the beginning of the line edits.
+ // Scroll to the beginning of the line edits.
bookmarkNamePointer->setCursorPosition(0);
bookmarkUrlPointer->setCursorPosition(0);
addBookmarkButtonPointer->setIcon(QIcon::fromTheme("list-add"));
// Connect the buttons.
+ connect(browseButtonPointer, SIGNAL(clicked()), this, SLOT(browse()));
connect(dialogButtonBoxPointer, SIGNAL(accepted()), this, SLOT(addBookmark()));
connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
}
void AddBookmarkDialog::addBookmark()
{
+ // Get the favorite icon.
+ QIcon favoriteIcon = defaultFavoriteIconRadioButtonPointer->isChecked() ? defaultFavoriteIconRadioButtonPointer->icon() : customFavoriteIconRadioButtonPointer->icon();
+
+ // Create a bookmark struct.
+ BookmarkStruct *bookmarkStructPointer = new BookmarkStruct;
+
+ // Populate the bookmark struct.
+ bookmarkStructPointer->bookmarkName = bookmarkNamePointer->text();
+ bookmarkStructPointer->bookmarkUrl = bookmarkUrlPointer->text();
+ bookmarkStructPointer->favoriteIcon = favoriteIcon;
+
// Add the bookmark.
- BookmarksDatabase::addBookmark(bookmarkNamePointer->text(), bookmarkUrlPointer->text(), icon);
+ BookmarksDatabase::addBookmark(bookmarkStructPointer);
+
+ // Update the list of bookmarks in the menu and toolbar.
+ emit bookmarkAdded();
// Close the dialog.
close();
}
+void AddBookmarkDialog::browse()
+{
+ // Get an image file string from the user.
+ QString imageFileString = QFileDialog::getOpenFileName(this, tr("Favorite Icon Image"), QDir::homePath(),
+ tr("Image Files — *.bmp, *.gif, *.jpg, *.jpeg, *.png, *.svg (*.bmp *.gif *.jpg *.jpeg *.png *.svg);;All Files (*)"));
+
+ // Check to see if an image file string was returned. This will be empty if the user selected cancel.
+ if (!imageFileString.isEmpty())
+ {
+ // Set the custom favorite icon.
+ customFavoriteIconRadioButtonPointer->setIcon(QIcon(imageFileString));
+
+ // Check the custom favorite icon radio button.
+ customFavoriteIconRadioButtonPointer->setChecked(true);
+ }
+}
// Qt toolkit headers.
#include <QDialog>
-#include <QIcon>
#include <QLineEdit>
+#include <QRadioButton>
class AddBookmarkDialog : public QDialog
{
// The primary constructor.
explicit AddBookmarkDialog(const QString &bookmarkName, const QString &bookmarkUrl, const QIcon &favoriteIcon);
+signals:
+ // The signals.
+ void bookmarkAdded() const;
+
private Q_SLOTS:
// The private slots.
void addBookmark();
+ void browse();
private:
// The private widgets.
QLineEdit *bookmarkNamePointer;
QLineEdit *bookmarkUrlPointer;
-
- // The private variables.
- const QIcon icon;
+ QRadioButton *customFavoriteIconRadioButtonPointer;
+ QRadioButton *defaultFavoriteIconRadioButtonPointer;
};
#endif
#include "BookmarksDialog.h"
#include "ui_BookmarksDialog.h"
#include "databases/BookmarksDatabase.h"
+#include "dialogs/AddBookmarkDialog.h"
+#include "dialogs/EditBookmarkDialog.h"
// KDE Frameworks headers.
#include <KLocalizedString>
// Qt toolkit headers.
#include <QDebug>
#include <QStandardItemModel>
-#include <QTreeView>
// Construct the class.
-BookmarksDialog::BookmarksDialog() : QDialog(nullptr)
+BookmarksDialog::BookmarksDialog(QIcon currentWebsiteFavorieIcon) : QDialog(nullptr), websiteFavoriteIcon(currentWebsiteFavorieIcon)
{
// Set the dialog window title.
setWindowTitle(i18nc("The bookmarks dialog window title", "Bookmarks"));
// Setup the UI.
bookmarksDialogUi.setupUi(this);
- // Get the list of bookmarks.
- std::list<BookmarkStruct> *bookmarksListPointer = BookmarksDatabase::getBookmarks();
-
- // Get a handle for the tree view.
- QTreeView *treeViewPointer = bookmarksDialogUi.treeView;
+ // Get a handle for the draggable tree view.
+ draggableTreeViewPointer = bookmarksDialogUi.draggableTreeView;
// Initialize the tree model.
- QStandardItemModel *treeModelPointer = new QStandardItemModel();
+ treeModelPointer = new QStandardItemModel();
+
+ // Auto resize the headers.
+ draggableTreeViewPointer->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+
+ // Indicate that all the rows are the same height, which improves performance.
+ draggableTreeViewPointer->setUniformRowHeights(true);
+
+ // Set the selection mode to allow multiple rows to be selected at once.
+ draggableTreeViewPointer->setSelectionMode(QAbstractItemView::ExtendedSelection);
+
+ // Allow dragging of bookmarks to reorder.
+ draggableTreeViewPointer->setDragDropMode(QAbstractItemView::InternalMove);
+
+ // Set the tree model.
+ draggableTreeViewPointer->setModel(treeModelPointer);
+
+ // Get a handle for the tree selection model.
+ treeSelectionModelPointer = draggableTreeViewPointer->selectionModel();
+
+ // Listen for selection changes.
+ connect(treeSelectionModelPointer, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(updateUi()));
+
+ // Repopulate the bookmarks when they are moved.
+ connect(draggableTreeViewPointer, SIGNAL(bookmarksMoved()), this, SLOT(refreshBookmarks()));
+
+ // Get handles for the buttons.
+ QPushButton *addBookmarkButtonPointer = bookmarksDialogUi.addBookmarkButton;
+ editButtonPointer = bookmarksDialogUi.editButton;
+ deleteItemsButtonPointer = bookmarksDialogUi.deleteItemsButton;
+ QDialogButtonBox *dialogButtonBoxPointer = bookmarksDialogUi.dialogButtonBox;
+ QPushButton *closeButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Close);
+
+ // Connect the buttons.
+ connect(addBookmarkButtonPointer, SIGNAL(clicked()), this, SLOT(showAddBookmarkDialog()));
+ connect(editButtonPointer, SIGNAL(clicked()), this, SLOT(showEditDialog()));
+ connect(deleteItemsButtonPointer, SIGNAL(clicked()), this, SLOT(deleteItems()));
+ connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
+
+ // Set the close button to be the default.
+ closeButtonPointer->setDefault(true);
+
+ // Monitor editing of data in the tree model.
+ connect(treeModelPointer, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(updateBookmarkFromTree(QStandardItem*)));
+
+ // Populate the bookmarks.
+ populateBookmarks();
+}
+
+void BookmarksDialog::deleteItems() const
+{
+ // Get the list of selected model indexes.
+ QList<QModelIndex> selectedModelIndexList = treeSelectionModelPointer->selectedRows(DATABASE_ID_COLUMN);
+
+ // Delete each of the bookmarks.
+ for (const QModelIndex &modelIndex : selectedModelIndexList)
+ {
+ // Delete the bookmark.
+ BookmarksDatabase::deleteBookmark(modelIndex.data().toInt());
+ }
+
+ // Repopulate the bookmarks in this dialog
+ populateBookmarks();
+
+ // Emit the bookmark updated signal to redraw the bookmarks in the menu and toolbar.
+ emit bookmarkUpdated();
+}
+
+void BookmarksDialog::populateBookmarks() const
+{
+ // Clear the current contents of the tree model.
+ treeModelPointer->clear();
// Set the column count.
- treeModelPointer->setColumnCount(3);
+ treeModelPointer->setColumnCount(4);
- // 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"));
+ // Set the tree header data. The last column is the database ID, which is not displayed.
+ treeModelPointer->setHeaderData(BOOKMARK_NAME_COLUMN, Qt::Horizontal, i18nc("The bookmark Name header.", "Name"));
+ treeModelPointer->setHeaderData(BOOKMARK_URL_COLUMN, Qt::Horizontal, i18nc("The bookmark URL header.", "URL"));
+
+ // Hide the backend columns.
+ draggableTreeViewPointer->setColumnHidden(DATABASE_ID_COLUMN, true);
+ draggableTreeViewPointer->setColumnHidden(DISPLAY_ORDER, true);
+
+ // Get the list of bookmarks.
+ std::list<BookmarkStruct> *bookmarksListPointer = BookmarksDatabase::getBookmarks();
// Populate the bookmarks tree view.
- for (BookmarkStruct bookmarkStruct : *bookmarksListPointer)
+ for (const BookmarkStruct &bookmarkStruct : *bookmarksListPointer)
{
// Create a list for the bookmark items.
QList<QStandardItem*> 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);
+ QStandardItem *idItemPointer = new QStandardItem(QString::number(bookmarkStruct.id));
+ QStandardItem *displayOrderPointer = new QStandardItem(QString::number(bookmarkStruct.displayOrder));
- // Populate the cookie standard item list.
- bookmarkItemList.append(idItemPointer);
+ nameItemPointer->setDragEnabled(true);
+ nameItemPointer->setDropEnabled(true);
+
+ // Disable dragging the URL.
+ urlItemPointer->setDragEnabled(false);
+
+ // Disable dropping on the URL. For some reason this doesn't work.
+ urlItemPointer->setDropEnabled(false);
+
+ // Disable selecting the URL.
+ urlItemPointer->setSelectable(false);
+
+ // Populate the bookmark item list.
bookmarkItemList.append(nameItemPointer);
bookmarkItemList.append(urlItemPointer);
+ bookmarkItemList.append(idItemPointer);
+ bookmarkItemList.append(displayOrderPointer);
- // Add the cookie to the tree.
+ // Add the bookmark to the tree.
treeModelPointer->appendRow(bookmarkItemList);
}
- // Auto resize the headers.
- treeViewPointer->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+ // Update the UI.
+ updateUi();
+}
- // Indicate that all the rows are the same height, which improves performance.
- treeViewPointer->setUniformRowHeights(true);
+void BookmarksDialog::refreshBookmarks() const
+{
+ // Repopulate the bookmarks in this dialog
+ populateBookmarks();
- // Set the tree model.
- treeViewPointer->setModel(treeModelPointer);
+ // Emit the bookmark updated signal to redraw the bookmarks in the menu and toolbar.
+ emit bookmarkUpdated();
+}
- // Hide the database ID column.
- treeViewPointer->setColumnHidden(0, true);
+void BookmarksDialog::showAddBookmarkDialog() const
+{
+ // Instantiate an add bookmark dialog.
+ AddBookmarkDialog *addBookmarkDialogPointer = new AddBookmarkDialog(QLatin1String(""), QLatin1String(""), websiteFavoriteIcon);
- // Get handles for the buttons.
- QDialogButtonBox *dialogButtonBoxPointer = bookmarksDialogUi.dialogButtonBox;
+ // Update the displayed bookmarks when a new one is added.
+ connect(addBookmarkDialogPointer, SIGNAL(bookmarkAdded()), this, SLOT(refreshBookmarks()));
- // Connect the buttons.
- connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
+ // Show the dialog.
+ addBookmarkDialogPointer->show();
+}
- // Monitor editing of data in the tree model.
- connect(treeModelPointer, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(updateBookmarkFromTree(QStandardItem*)));
+void BookmarksDialog::showEditDialog()
+{
+ // Get the current model index.
+ QModelIndex currentIndex = treeSelectionModelPointer->currentIndex();
+
+ // Instantiate an edit bookmark dialog.
+ QDialog *editBookmarkDialogPointer = new EditBookmarkDialog(currentIndex.siblingAtColumn(DATABASE_ID_COLUMN).data().toInt(), websiteFavoriteIcon);
+
+ // Show the dialog.
+ editBookmarkDialogPointer->show();
+
+ // Process bookmark events.
+ connect(editBookmarkDialogPointer, SIGNAL(bookmarkSaved()), this, SLOT(refreshBookmarks()));
}
void BookmarksDialog::updateBookmarkFromTree(QStandardItem *modifiedStandardItem)
QModelIndex modifiedItemModelIndex = modifiedStandardItem->index();
// Get the model index of the database ID.
- QModelIndex databaseIdModelIndex = modifiedItemModelIndex.siblingAtColumn(0);
+ QModelIndex databaseIdModelIndex = modifiedItemModelIndex.siblingAtColumn(DATABASE_ID_COLUMN);
// 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.
+ if (modifiedStandardItem->column() == BOOKMARK_NAME_COLUMN) // The bookmark name was edited.
{
// Update the bookmark name.
BookmarksDatabase::updateBookmarkName(databaseId, modifiedStandardItem->text());
// Emit the bookmark updated signal.
emit bookmarkUpdated();
}
+
+void BookmarksDialog::updateUi() const
+{
+ // Set the status of the buttons.
+ if (treeSelectionModelPointer->hasSelection()) // A bookmark or folder is selected.
+ {
+ // Enabled the buttons.
+ editButtonPointer->setEnabled(true);
+ deleteItemsButtonPointer->setEnabled(true);
+
+ // Update the delete items button text.
+ deleteItemsButtonPointer->setText(i18ncp("Delete items button populated text.", "Delete %1 item", "Delete %1 items", treeSelectionModelPointer->selectedRows().count()));
+ }
+ else // Nothing is selected.
+ {
+ // Disable the buttons.
+ editButtonPointer->setEnabled(false);
+ deleteItemsButtonPointer->setEnabled(false);
+
+ // Update the delete items button text.
+ deleteItemsButtonPointer->setText(i18nc("Delete items button default text", "Delete items"));
+ }
+}
// Application headers.
#include "structs/BookmarkStruct.h"
+#include "widgets/DraggableTreeView.h"
// Qt toolkit headers.
#include <QDialog>
+#include <QItemSelectionModel>
#include <QStandardItem>
class BookmarksDialog : public QDialog
public:
// The primary constructor.
- explicit BookmarksDialog();
+ explicit BookmarksDialog(QIcon currentWebsiteFavoriteIcon);
+
+ // The public constants.
+ static const int BOOKMARK_NAME_COLUMN = 0;
+ static const int BOOKMARK_URL_COLUMN = 1;
+ static const int DATABASE_ID_COLUMN = 2;
+ static const int DISPLAY_ORDER = 3;
signals:
// The signals.
private Q_SLOTS:
// The private slots.
+ void deleteItems() const;
+ void refreshBookmarks() const;
+ void showAddBookmarkDialog() const;
+ void showEditDialog();
void updateBookmarkFromTree(QStandardItem *modifiedStandardItem);
+ void updateUi() const;
+
+private:
+ // The private functions.
+ void populateBookmarks() const;
+
+ // The private variables.
+ QPushButton *deleteItemsButtonPointer;
+ QPushButton *editButtonPointer;
+ QStandardItemModel *treeModelPointer;
+ QItemSelectionModel *treeSelectionModelPointer;
+ DraggableTreeView *draggableTreeViewPointer;
+ QIcon websiteFavoriteIcon;
};
#endif
CookiesDialog.cpp
DomainSettingsDialog.cpp
DurableCookiesDialog.cpp
+ EditBookmarkDialog.cpp
SaveDialog.cpp
)
--- /dev/null
+/*
+ * Copyright 2023 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 "EditBookmarkDialog.h"
+#include "ui_EditBookmarkDialog.h"
+#include "databases/BookmarksDatabase.h"
+
+// Qt toolkit headers.
+#include <QFileDialog>
+
+// Construct the class.
+EditBookmarkDialog::EditBookmarkDialog(const int bookmarkId, QIcon ¤tWebsiteFavoriteIcon) : QDialog(nullptr), bookmarkDatabaseId(bookmarkId)
+{
+ // Set the window title.
+ setWindowTitle(i18nc("The edit bookmark dialog window title.", "Edit Bookmark"));
+
+ // Set the window modality.
+ setWindowModality(Qt::WindowModality::ApplicationModal);
+
+ // Instantiate the bookmarks dialog UI.
+ Ui::EditBookmarkDialog editBookmarkDialogUi;
+
+ // Setup the UI.
+ editBookmarkDialogUi.setupUi(this);
+
+ // Get handles for the widgets.
+ currentFavoriteIconRadioButtonPointer = editBookmarkDialogUi.currentFavoriteIconRadioButton;
+ currentWebsiteFavoritIconRadioButtonPointer = editBookmarkDialogUi.currentWebsiteFavoriteIconRadioButton;
+ customFavoriteIconRadioButtonPointer = editBookmarkDialogUi.customFavoriteIconRadioButton;
+ bookmarkNamePointer = editBookmarkDialogUi.bookmarkNameLineEdit;
+ bookmarkUrlPointer = editBookmarkDialogUi.bookmarkUrlLineEdit;
+ QPushButton *browseButtonPointer = editBookmarkDialogUi.browseButton;
+ QDialogButtonBox *dialogButtonBoxPointer = editBookmarkDialogUi.dialogButtonBox;
+
+ // Get the bookmark struct.
+ bookmarkStructPointer = BookmarksDatabase::getBookmark(bookmarkId);
+
+ // Set the favorite icons.
+ currentFavoriteIconRadioButtonPointer->setIcon(bookmarkStructPointer->favoriteIcon);
+ currentWebsiteFavoritIconRadioButtonPointer->setIcon(currentWebsiteFavoriteIcon);
+
+ // Populate the line edits.
+ bookmarkNamePointer->setText(bookmarkStructPointer->bookmarkName);
+ bookmarkUrlPointer->setText(bookmarkStructPointer->bookmarkUrl);
+
+ // Scroll to the beginning of the line edits.
+ bookmarkNamePointer->setCursorPosition(0);
+ bookmarkUrlPointer->setCursorPosition(0);
+
+ // Connect the buttons.
+ connect(browseButtonPointer, SIGNAL(clicked()), this, SLOT(browse()));
+ connect(dialogButtonBoxPointer, SIGNAL(accepted()), this, SLOT(save()));
+ connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
+}
+
+void EditBookmarkDialog::browse()
+{
+ // Get an image file string from the user.
+ QString imageFileString = QFileDialog::getOpenFileName(this, tr("Favorite Icon Image"), QDir::homePath(),
+ tr("Image Files — *.bmp, *.gif, *.jpg, *.jpeg, *.png, *.svg (*.bmp *.gif *.jpg *.jpeg *.png *.svg);;All Files (*)"));
+
+ // Check to see if an image file string was returned. This will be empty if the user selected cancel.
+ if (!imageFileString.isEmpty())
+ {
+ // Set the custom favorite icon.
+ customFavoriteIconRadioButtonPointer->setIcon(QIcon(imageFileString));
+
+ // Check the custom favorite icon radio button.
+ customFavoriteIconRadioButtonPointer->setChecked(true);
+ }
+}
+
+void EditBookmarkDialog::save()
+{
+ // Create a favorite icon.
+ QIcon favoriteIcon;
+
+ // Get the favorite icon.
+ if (currentFavoriteIconRadioButtonPointer->isChecked()) // The current favorite icon is checked.
+ favoriteIcon = currentFavoriteIconRadioButtonPointer->icon();
+ else if (currentWebsiteFavoritIconRadioButtonPointer->isChecked()) // The current website favorite icon is checked.
+ favoriteIcon = currentWebsiteFavoritIconRadioButtonPointer->icon();
+ else // The custom favorite icon is checked.
+ favoriteIcon = customFavoriteIconRadioButtonPointer->icon();
+
+ qDebug() << "Favorite icon: " << favoriteIcon;
+
+ // Create a bookmark struct.
+ BookmarkStruct *bookmarkStructPointer = new BookmarkStruct;
+
+ // Populate the bookmark struct.
+ bookmarkStructPointer->id = bookmarkDatabaseId;
+ bookmarkStructPointer->bookmarkName = bookmarkNamePointer->text();
+ bookmarkStructPointer->bookmarkUrl = bookmarkUrlPointer->text();
+ bookmarkStructPointer->displayOrder = bookmarkStructPointer->displayOrder;
+ bookmarkStructPointer->favoriteIcon = favoriteIcon;
+
+ // Update the bookmark.
+ BookmarksDatabase::updateBookmark(bookmarkStructPointer);
+
+ // Emit the bookmark saved signal.
+ emit bookmarkSaved();
+
+ // Close the dialog.
+ close();
+}
--- /dev/null
+/*
+ * Copyright 2023 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 EDITBOOKMARKDIALOG_H
+#define EDITBOOKMARKDIALOG_H
+
+// Application headers.
+#include "structs/BookmarkStruct.h"
+
+// Qt toolkit headers.
+#include <QDialog>
+#include <QLineEdit>
+#include <QRadioButton>
+
+class EditBookmarkDialog : public QDialog
+{
+ // Include the Q_OBJECT macro.
+ Q_OBJECT
+
+public:
+ // The primary constructor.
+ explicit EditBookmarkDialog(const int bookmarkId, QIcon ¤tWebsiteFavoriteIcon);
+
+signals:
+ // The signals.
+ void bookmarkSaved() const;
+
+private Q_SLOTS:
+ // The private slots.
+ void browse();
+ void save();
+
+private:
+ // The private widgets.
+ int bookmarkDatabaseId;
+ QLineEdit *bookmarkNamePointer;
+ BookmarkStruct *bookmarkStructPointer;
+ QLineEdit *bookmarkUrlPointer;
+ QRadioButton *currentFavoriteIconRadioButtonPointer;
+ QRadioButton *currentWebsiteFavoritIconRadioButtonPointer;
+ QRadioButton *customFavoriteIconRadioButtonPointer;
+};
+#endif
int id;
QString bookmarkName;
QString bookmarkUrl;
+ int displayOrder;
QIcon favoriteIcon;
};
#endif
along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>. -->
<ui version="4.0">
- <class>AddBookmarkDialog</class>
-
- <widget class="QWidget">
- <layout class="QVBoxLayout">
-
- <!-- First row. -->
- <item>
- <layout class="QHBoxLayout">
- <property name="alignment">
- <enum>Qt::AlignLeft</enum>
- </property>
-
- <!-- Icon. -->
- <item>
- <widget class="QGraphicsView" name="favoriteIconGraphicsView">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
-
- <property name="maximumSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
-
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
-
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
-
- <!-- Spacer label. -->
- <item>
- <widget class="QLabel">
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
-
- <property name="text">
- <string>&nbsp;</string>
- </property>
- </widget>
- </item>
-
- <!-- Bookmark name. -->
- <item>
- <widget class="QLabel">
- <property name="toolTip">
- <string>The name of the bookmark.</string>
- </property>
-
- <property name="text">
- <string>Bookmark name</string>
- </property>
- </widget>
- </item>
-
- <item>
- <widget class="QLineEdit" name="bookmarkNameLineEdit" />
- </item>
+ <class>AddBookmarkDialog</class>
+
+ <widget class="QWidget">
+ <layout class="QVBoxLayout">
+ <!-- Dialog body. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <!-- Favorite icon column. -->
+ <item>
+ <layout class="QVBoxLayout">
+ <property name="rightMargin">
+ <number>10</number>
+ </property>
+
+ <!-- First row, default favorite icon. -->
+ <item>
+ <widget class="QRadioButton" name="defaultFavoriteIconRadioButton">
+ <property name="text">
+ <string>Default favorite icon</string>
+ </property>
+
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+
+ <property name="iconSize">
+ <size>
+ <height>32</height>
+ <width>32</width>
+ </size>
+ </property>
+ </widget>
+ </item>
+
+ <!-- Second row, custom favorite icon. -->
+ <item>
+ <widget class="QRadioButton" name="customFavoriteIconRadioButton">
+ <property name="text">
+ <string>Custom favorite icon</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="globe"/>
+ </property>
+
+ <property name="iconSize">
+ <size>
+ <height>32</height>
+ <width>32</width>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+
+ <!-- Name and URL column. -->
+ <item>
+ <layout class="QVBoxLayout">
+ <!-- First row. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="alignment">
+ <enum>Qt::AlignLeft</enum>
+ </property>
+ <!-- Bookmark name. -->
+ <item>
+ <widget class="QLabel">
+ <property name="toolTip">
+ <string>The name of the bookmark.</string>
+ </property>
+
+ <property name="text">
+ <string>Bookmark name</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="bookmarkNameLineEdit" />
+ </item>
+ </layout>
+ </item>
+
+ <!-- Second row. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="alignment">
+ <enum>Qt::AlignLeft</enum>
+ </property>
+ <!-- Bookmark URL. -->
+ <item>
+ <widget class="QLabel">
+ <property name="toolTip">
+ <string>The URL of the bookmark.</string>
+ </property>
+
+ <property name="text">
+ <string>Bookmark URL</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="bookmarkUrlLineEdit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+
+ <property name="minimumSize">
+ <size>
+ <width>700</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+
+ <!-- Spacer. -->
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </spacer>
+ </item>
+
+ <!-- Buttons. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <!-- Browse button. -->
+ <item>
+ <widget class="QPushButton" name="browseButton">
+ <property name="text">
+ <string>Browse</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="insert-image" />
+ </property>
+ </widget>
+ </item>
+
+ <!-- Cancel button - dialog button box. -->
+ <item>
+ <widget class="QDialogButtonBox" name="dialogButtonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
</layout>
- </item>
-
- <!-- Second row. -->
- <item>
- <layout class="QHBoxLayout">
- <property name="alignment">
- <enum>Qt::AlignLeft</enum>
- </property>
-
- <!-- Bookmark URL. -->
- <item>
- <widget class="QLabel">
- <property name="toolTip">
- <string>The URL of the bookmark.</string>
- </property>
-
- <property name="text">
- <string>Bookmark URL</string>
- </property>
- </widget>
- </item>
-
- <item>
- <widget class="QLineEdit" name="bookmarkUrlLineEdit">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
-
- <property name="minimumSize">
- <size>
- <width>700</width>
- <height>0</height>
- </size>
- </property>
- </widget>
- </item>
- </layout>
- </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::Cancel</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
+ </widget>
</ui>
<ui version="4.0">
<class>BookmarksDialog</class>
+ <customwidgets>
+ <customwidget>
+ <class>DraggableTreeView</class>
+ <extends>QTreeView</extends>
+ <header>widgets/DraggableTreeView.h</header>
+ </customwidget>
+ </customwidgets>
+
<widget class="QWidget">
<property name="geometry">
<rect>
<layout class="QVBoxLayout">
<!-- Tree view. -->
<item>
- <widget class="QTreeView" name="treeView" />
+ <widget class="DraggableTreeView" name="draggableTreeView" />
</item>
<!-- Buttons. -->
<item>
<layout class="QHBoxLayout">
+ <!-- Add bookmark button. -->
+ <item>
+ <widget class="QPushButton" name="addBookmarkButton">
+ <property name="text">
+ <string>Add bookmark</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="list-add" />
+ </property>
+ </widget>
+ </item>
+
+ <!-- Edit button. -->
+ <item>
+ <widget class="QPushButton" name="editButton">
+ <property name="text">
+ <string>Edit</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="edit-entry" />
+ </property>
+ </widget>
+ </item>
+
+ <!-- Delete button. -->
+ <item>
+ <widget class="QPushButton" name="deleteItemsButton">
+ <property name="text">
+ <string>Delete items</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="list-remove" />
+ </property>
+ </widget>
+ </item>
+
<!-- Close button - dialog button box. -->
<item>
<widget class="QDialogButtonBox" name="dialogButtonBox">
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright 2023 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/>. -->
+
+<ui version="4.0">
+ <class>EditBookmarkDialog</class>
+
+ <widget class="QWidget">
+ <layout class="QVBoxLayout">
+ <!-- Dialog body. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <!-- Favorite icon column. -->
+ <item>
+ <layout class="QVBoxLayout">
+ <property name="rightMargin">
+ <number>10</number>
+ </property>
+
+ <!-- First row, current favorite icon. -->
+ <item>
+ <widget class="QRadioButton" name="currentFavoriteIconRadioButton">
+ <property name="text">
+ <string>Current favorite icon</string>
+ </property>
+
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+
+ <property name="iconSize">
+ <size>
+ <height>32</height>
+ <width>32</width>
+ </size>
+ </property>
+ </widget>
+ </item>
+
+ <!-- Second row, current website favorite icon. -->
+ <item>
+ <widget class="QRadioButton" name="currentWebsiteFavoriteIconRadioButton">
+ <property name="text">
+ <string>Current website favorite icon</string>
+ </property>
+
+ <property name="iconSize">
+ <size>
+ <height>32</height>
+ <width>32</width>
+ </size>
+ </property>
+ </widget>
+ </item>
+
+ <!-- Third row, custom favorite icon. -->
+ <item>
+ <widget class="QRadioButton" name="customFavoriteIconRadioButton">
+ <property name="text">
+ <string>Custom favorite icon</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="globe"/>
+ </property>
+
+ <property name="iconSize">
+ <size>
+ <height>32</height>
+ <width>32</width>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+
+ <!-- Name and URL column. -->
+ <item>
+ <layout class="QVBoxLayout">
+ <!-- First row. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="alignment">
+ <enum>Qt::AlignLeft</enum>
+ </property>
+ <!-- Bookmark name. -->
+ <item>
+ <widget class="QLabel">
+ <property name="toolTip">
+ <string>The name of the bookmark.</string>
+ </property>
+
+ <property name="text">
+ <string>Bookmark name</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="bookmarkNameLineEdit" />
+ </item>
+ </layout>
+ </item>
+
+ <!-- Second row. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="alignment">
+ <enum>Qt::AlignLeft</enum>
+ </property>
+ <!-- Bookmark URL. -->
+ <item>
+ <widget class="QLabel">
+ <property name="toolTip">
+ <string>The URL of the bookmark.</string>
+ </property>
+
+ <property name="text">
+ <string>Bookmark URL</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="bookmarkUrlLineEdit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+
+ <property name="minimumSize">
+ <size>
+ <width>700</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+
+ <!-- Spacer. -->
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </spacer>
+ </item>
+
+ <!-- Buttons. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <!-- Browse button. -->
+ <item>
+ <widget class="QPushButton" name="browseButton">
+ <property name="text">
+ <string>Browse</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="insert-image" />
+ </property>
+ </widget>
+ </item>
+
+ <!-- Cancel button - dialog button box. -->
+ <item>
+ <widget class="QDialogButtonBox" name="dialogButtonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Save | QDialogButtonBox::Cancel</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+</ui>
-# Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+# Copyright 2022-2023 Soren Stoutner <soren@stoutner.com>.
#
# This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
#
# List the sources to include in the executable.
target_sources(privacybrowser PRIVATE
- TabWidget.cpp
+ DraggableTreeView.cpp
PrivacyWebEngineView.cpp
+ TabWidget.cpp
)
--- /dev/null
+/*
+ * Copyright 2023 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 "DraggableTreeView.h"
+#include "databases/BookmarksDatabase.h"
+#include "dialogs/BookmarksDialog.h"
+
+// Qt toolkit headers.
+#include <QDebug>
+#include <QDropEvent>
+#include <QList>
+
+// Construct the class.
+DraggableTreeView::DraggableTreeView(QWidget *parentWidget) : QTreeView(parentWidget) {}
+
+// Handle drop events.
+void DraggableTreeView::dropEvent(QDropEvent *dropEvent)
+{
+ // Get the list of currently selected items that are moving.
+ QList<QModelIndex> indexesMovingList = selectedIndexes();
+
+ // Create a list of database IDs that are moving.
+ QList<int> *databaseIdsMovingListPointer = new QList<int>;
+
+ // Populate the list of moving database IDs.
+ for (const QModelIndex &modelIndex : indexesMovingList)
+ {
+ // Only process model indexes from the bookmark name column (by default, there will be model indexes from all the visible columns in the list).
+ if (modelIndex.column() == BookmarksDialog::BOOKMARK_NAME_COLUMN)
+ databaseIdsMovingListPointer->append(modelIndex.siblingAtColumn(BookmarksDialog::DATABASE_ID_COLUMN).data().toInt());
+ }
+
+ // Get the drop position.
+ int dropPosition = dropIndicatorPosition();
+
+ // Get the drop model index.
+ QModelIndex dropModelIndex = indexAt(dropEvent->pos());
+
+ // Get the drop display order.
+ int dropDisplayOrder = dropModelIndex.siblingAtColumn(BookmarksDialog::DISPLAY_ORDER).data().toInt();
+
+ // Process the move according to the drop position.
+ switch (dropPosition)
+ {
+ case QAbstractItemView::OnItem:
+ // TODO Implement for moving into a folder.
+ break;
+
+ case QAbstractItemView::AboveItem:
+ {
+ // Get a list of all the bookmarks except those selected.
+ QList<BookmarkStruct> *bookmarksExceptSelectedListPointer = BookmarksDatabase::getBookmarksExcept(databaseIdsMovingListPointer);
+
+ // Initialize a new display order tracker.
+ int newDisplayOrder = 0;
+
+ // Move the bookmarks.
+ for (const BookmarkStruct &bookmarkStruct : *bookmarksExceptSelectedListPointer)
+ {
+ // Check to see if this is the drop display order.
+ if (bookmarkStruct.displayOrder == dropDisplayOrder)
+ {
+ // Add all of the bookmarks being moved to this point.
+ for (const int databaseId : *databaseIdsMovingListPointer)
+ {
+ // Update the display order for each bookmark.
+ BookmarksDatabase::updateDisplayOrder(databaseId, newDisplayOrder);
+
+ // Increment the new display order.
+ ++newDisplayOrder;
+ }
+ }
+
+ // Set the bookmark's display order if it has changed.
+ if (bookmarkStruct.displayOrder != newDisplayOrder)
+ BookmarksDatabase::updateDisplayOrder(bookmarkStruct.id, newDisplayOrder);
+
+ // Increment the new display order.
+ ++newDisplayOrder;
+ }
+
+ break;
+ }
+
+ case QAbstractItemView::BelowItem:
+ {
+ // Get a list of all the bookmarks except those selected.
+ QList<BookmarkStruct> *bookmarksExceptSelectedListPointer = BookmarksDatabase::getBookmarksExcept(databaseIdsMovingListPointer);
+
+ // Initialize a new display order tracker.
+ int newDisplayOrder = 0;
+
+ // Move the bookmarks.
+ for (const BookmarkStruct &bookmarkStruct : *bookmarksExceptSelectedListPointer)
+ {
+ // Set the bookmark's display order if it has changed.
+ if (bookmarkStruct.displayOrder != newDisplayOrder)
+ BookmarksDatabase::updateDisplayOrder(bookmarkStruct.id, newDisplayOrder);
+
+ // Increment the new display order.
+ ++newDisplayOrder;
+
+ // Check to see if this is the drop display order.
+ if (bookmarkStruct.displayOrder == dropDisplayOrder)
+ {
+ // Add all of the bookmarks being moved to this point.
+ for (const int databaseId : *databaseIdsMovingListPointer)
+ {
+ // Update the display order for each bookmark.
+ BookmarksDatabase::updateDisplayOrder(databaseId, newDisplayOrder);
+
+ // Increment the new display order.
+ ++newDisplayOrder;
+ }
+ }
+ }
+
+ break;
+ }
+
+ case QAbstractItemView::OnViewport:
+
+ // Get a list of all the bookmarks except those selected.
+ QList<BookmarkStruct> *bookmarksExceptSelectedListPointer = BookmarksDatabase::getBookmarksExcept(databaseIdsMovingListPointer);
+
+ // Initialize a new display order tracker.
+ int newDisplayOrder = 0;
+
+ // Move the bookmarks.
+ for (const BookmarkStruct &bookmarkStruct : *bookmarksExceptSelectedListPointer)
+ {
+ // Set the bookmark's display order if it has changed.
+ if (bookmarkStruct.displayOrder != newDisplayOrder)
+ BookmarksDatabase::updateDisplayOrder(bookmarkStruct.id, newDisplayOrder);
+
+ // Increment the new display order.
+ ++newDisplayOrder;
+ }
+
+ // Add all of the bookmarks being moved to the end of the list.
+ for (const int databaseId : *databaseIdsMovingListPointer)
+ {
+ // Update the display order for each bookmark.
+ BookmarksDatabase::updateDisplayOrder(databaseId, newDisplayOrder);
+
+ // Increment the new display order.
+ ++newDisplayOrder;
+ }
+ break;
+ }
+
+ // Emit the bookmarks moved signal.
+ emit bookmarksMoved();
+}
--- /dev/null
+/*
+ * Copyright 2023 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 DRAGGABLETREEVIEW_H
+#define DRAGGABLETREEVIEW_H
+
+// Qt toolkit headers.
+#include <QTreeView>
+
+class DraggableTreeView : public QTreeView
+{
+ // Include the Q_OBJECT macro.
+ Q_OBJECT
+
+public:
+ // The default contructor.
+ explicit DraggableTreeView(QWidget *parentWidget = nullptr);
+
+signals:
+ // The signals.
+ void bookmarksMoved() const;
+
+protected:
+ void dropEvent(QDropEvent *event) override;
+};
+#endif
QAction *backActionPointer = KStandardAction::back(this, SLOT(back()), actionCollectionPointer);
QAction *forwardActionPointer = KStandardAction::forward(this, SLOT(forward()), actionCollectionPointer);
KStandardAction::home(this, SLOT(home()), actionCollectionPointer);
- KStandardAction::addBookmark(this, SLOT(addBookmark()), actionCollectionPointer);
+ KStandardAction::addBookmark(this, SLOT(showAddBookmarkDialog()), actionCollectionPointer);
QAction *editBookmarksActionPointer = KStandardAction::editBookmarks(this, SLOT(editBookmarks()), actionCollectionPointer);
KStandardAction::preferences(this, SLOT(showSettingsDialog()), actionCollectionPointer);
KStandardAction::find(this, SLOT(showFindTextActions()), actionCollectionPointer);
bookmarksMenuCurrentActionList = QList<QAction*>();
bookmarksToolBarCurrentActionList = QList<QAction*>();
+ // Set the bookmarks toolbar context menu policy.
+ bookmarksToolBarPointer->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ // Show the custom bookmark context menu when requested.
+ connect(bookmarksToolBarPointer, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showBookmarkContextMenu(const QPoint&)));
+
// Populate the bookmarks.
populateBookmarks();
tabWidgetPointer->loadInitialWebsite();
}
-void BrowserWindow::addBookmark() const
-{
- // Instantiate an add bookmark dialog.
- AddBookmarkDialog *addBookmarkDialogPointer = new AddBookmarkDialog(tabWidgetPointer->getCurrentTabTitle(), tabWidgetPointer->getCurrentTabUrl(), tabWidgetPointer->getCurrentTabFavoritIcon());
-
- // Show the dialog.
- addBookmarkDialogPointer->show();
-}
-
void BrowserWindow::addOrEditDomainSettings() const
{
// Remove the focus from the URL line edit.
void BrowserWindow::editBookmarks() const
{
// Instantiate an edit bookmarks dialog.
- BookmarksDialog *bookmarksDialogPointer = new BookmarksDialog();
+ BookmarksDialog *bookmarksDialogPointer = new BookmarksDialog(tabWidgetPointer->getCurrentTabFavoritIcon());
// Update the displayed bookmarks when edited.
connect(bookmarksDialogPointer, SIGNAL(bookmarkUpdated()), this, SLOT(populateBookmarks()));
tabWidgetPointer->refresh();
}
+void BrowserWindow::showAddBookmarkDialog() const
+{
+ // Instantiate an add bookmark dialog.
+ AddBookmarkDialog *addBookmarkDialogPointer = new AddBookmarkDialog(tabWidgetPointer->getCurrentTabTitle(), tabWidgetPointer->getCurrentTabUrl(), tabWidgetPointer->getCurrentTabFavoritIcon());
+
+ // Update the displayed bookmarks when a new one is added.
+ connect(addBookmarkDialogPointer, SIGNAL(bookmarkAdded()), this, SLOT(populateBookmarks()));
+
+ // Show the dialog.
+ addBookmarkDialogPointer->show();
+}
+
+void BrowserWindow::showBookmarkContextMenu(const QPoint&) const
+{
+ qDebug() << "Show the bookmark context menu.";
+}
+
void BrowserWindow::showCookiesDialog()
{
// Remove the focus from the URL line edit.
private Q_SLOTS:
// The private slots.
- void addBookmark() const;
void addOrEditDomainSettings() const;
void back() const;
void clearUrlLineEditFocus() const;
void populateBookmarks();
void refresh() const;
void reloadAndBypassCache() const;
+ void showAddBookmarkDialog() const;
+ void showBookmarkContextMenu(const QPoint&) const;
void showCookiesDialog();
void showDownloadLocationBrowseDialog() const;
void showDomainSettingsDialog() const;