# Use KDE Frameworks to handle internationalization of the following UI files.
ki18n_wrap_ui(privacybrowser
uis/AddBookmarkDialog.ui
+ uis/AddFolderDialog.ui
uis/AddOrEditCookieDialog.ui
uis/AddTabWidget.ui
uis/BookmarksDialog.ui
uis/DomainSettingsDialog.ui
uis/DurableCookiesDialog.ui
uis/EditBookmarkDialog.ui
+ uis/EditFolderDialog.ui
uis/SaveDialog.ui
uis/SettingsGeneral.ui
uis/SettingsPrivacy.ui
// Get a handle for the bookmarks database.
QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
- // Instantiate a count bookmarks query. TODO: This needs to be updated to only count the bookmarks in the current folder.
- QSqlQuery countBookmarksQuery(bookmarksDatabase);
-
- // Set the query to be forward only, which is more performant.
- countBookmarksQuery.setForwardOnly(true);
-
- // Prepare the count bookmarks query.
- countBookmarksQuery.prepare("SELECT " + DISPLAY_ORDER + " FROM " + BOOKMARKS_TABLE);
-
- // Execute the count bookmarks query.
- countBookmarksQuery.exec();
-
- // Move to the last row.
- countBookmarksQuery.last();
-
- // Initialize a bookmarks count variable.
- int bookmarksCount = 0;
-
- // 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;
- }
+ // Get the folder item count.
+ int folderItemCount = getFolderItemCount(bookmarkStructPointer->parentFolderId);
// Instantiate an add bookmark query.
QSqlQuery addBookmarkQuery(bookmarksDatabase);
addBookmarkQuery.prepare("INSERT INTO " + BOOKMARKS_TABLE + " (" +
BOOKMARK_NAME + ", " +
BOOKMARK_URL + ", " +
- FAVORITE_ICON + ", " +
- DISPLAY_ORDER + ") " +
- "VALUES (:bookmark_name, :bookmark_url, :favorite_icon, :display_order)"
+ PARENT_FOLDER_ID + ", " +
+ DISPLAY_ORDER + ", " +
+ FAVORITE_ICON + ") " +
+ "VALUES (:bookmark_name, :bookmark_url, :parent_folder_id, :display_order, :favorite_icon)"
);
// Bind the query values.
- addBookmarkQuery.bindValue(":bookmark_name", bookmarkStructPointer->bookmarkName);
- addBookmarkQuery.bindValue(":bookmark_url", bookmarkStructPointer->bookmarkUrl);
+ addBookmarkQuery.bindValue(":bookmark_name", bookmarkStructPointer->name);
+ addBookmarkQuery.bindValue(":bookmark_url", bookmarkStructPointer->url);
+ addBookmarkQuery.bindValue(":parent_folder_id", bookmarkStructPointer->parentFolderId);
+ addBookmarkQuery.bindValue(":display_order", folderItemCount);
addBookmarkQuery.bindValue(":favorite_icon", getFavoriteIconBase64String(bookmarkStructPointer->favoriteIcon));
- addBookmarkQuery.bindValue(":display_order", bookmarksCount);
// Execute the add bookmark query.
addBookmarkQuery.exec();
}
-void BookmarksDatabase::deleteBookmark(const int bookmarkId)
+void BookmarksDatabase::addFolder(const BookmarkStruct *bookmarkStructPointer)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Get the folder item count.
+ int folderItemCount = getFolderItemCount(bookmarkStructPointer->parentFolderId);
+
+ // Instantiate an add folder query.
+ QSqlQuery addFolderQuery(bookmarksDatabase);
+
+ // Prepare the add folder query.
+ addFolderQuery.prepare("INSERT INTO " + BOOKMARKS_TABLE + " (" +
+ BOOKMARK_NAME + ", " +
+ PARENT_FOLDER_ID + ", " +
+ DISPLAY_ORDER + ", " +
+ IS_FOLDER + ", " +
+ FOLDER_ID + ", " +
+ FAVORITE_ICON + ") " +
+ "VALUES (:bookmark_name, :parent_folder_id, :display_order, :is_folder, :folder_id, :favorite_icon)"
+ );
+
+ // Bind the query values.
+ addFolderQuery.bindValue(":bookmark_name", bookmarkStructPointer->name);
+ addFolderQuery.bindValue(":parent_folder_id", bookmarkStructPointer->parentFolderId);
+ addFolderQuery.bindValue(":display_order", folderItemCount);
+ addFolderQuery.bindValue(":is_folder", 1);
+ addFolderQuery.bindValue(":folder_id", generateFolderId());
+ addFolderQuery.bindValue(":favorite_icon", getFavoriteIconBase64String(bookmarkStructPointer->favoriteIcon));
+
+ // Execute the add folder query.
+ addFolderQuery.exec();
+}
+
+void BookmarksDatabase::deleteBookmark(const int databaseId)
{
// Get a handle for the bookmarks database.
QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
deleteBookmarkQuery.prepare("DELETE FROM " + BOOKMARKS_TABLE + " WHERE " + ID + " = :id");
// Bind the query values.
- deleteBookmarkQuery.bindValue(":id", bookmarkId);
+ deleteBookmarkQuery.bindValue(":id", databaseId);
// 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.
+double BookmarksDatabase::generateFolderId()
+{
+ // Get the current time in epoch format (milliseconds).
+ double possibleFolderId = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
- // Instantiate a bookmarks query.
- QSqlQuery bookmarksQuery(bookmarksDatabase);
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
- // Set the query to be forward only, which is more performant.
- bookmarksQuery.setForwardOnly(true);
+ // Instantiate a existing folder query.
+ QSqlQuery existingFolderQuery(bookmarksDatabase);
- // Prepare the bookmarks query.
- bookmarksQuery.prepare("SELECT " + ID + ", " + DISPLAY_ORDER + " FROM " + BOOKMARKS_TABLE + " ORDER BY " + DISPLAY_ORDER + " ASC");
+ // Prepare the existing folder query.
+ existingFolderQuery.prepare("SELECT " + ID + " FROM " + BOOKMARKS_TABLE + " WHERE " + FOLDER_ID + " = :possible_folder_id");
+
+ // Bind the query values.
+ existingFolderQuery.bindValue(":possible_folder_id", possibleFolderId);
// Execute the query.
- bookmarksQuery.exec();
+ existingFolderQuery.exec();
- // Create a new display order int.
- int newDisplayOrder = 0;
+ // Generate a new folder ID if this one is not unique. The existing folder query will only be valid if there is at least one item.
+ if (existingFolderQuery.isValid())
+ possibleFolderId = generateFolderId();
- // 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);
+ return possibleFolderId;
+}
- // Prepare the update display order query.
- updateDisplayOrderQuery.prepare("UPDATE " + BOOKMARKS_TABLE + " SET " + DISPLAY_ORDER + " = :display_order WHERE " + ID + " = :id");
+QList<QString>* BookmarksDatabase::getAllFolderUrls(const double folderId)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
- // Bind the query values.
- updateDisplayOrderQuery.bindValue(":display_order", newDisplayOrder);
- updateDisplayOrderQuery.bindValue(":id", bookmarksQuery.value(ID).toInt());
+ // Instantiate a folder URLs query.
+ QSqlQuery folderUrlsQuery(bookmarksDatabase);
- // Execute the query.
- updateDisplayOrderQuery.exec();
- }
+ // Set the query to be forward only, which is more performant.
+ folderUrlsQuery.setForwardOnly(true);
- // Increment the new display order.
- ++newDisplayOrder;
+ // Prepare the folder URLs query.
+ folderUrlsQuery.prepare("SELECT " + BOOKMARK_URL + ", " + IS_FOLDER + ", " + FOLDER_ID + " FROM " + BOOKMARKS_TABLE + " WHERE " + PARENT_FOLDER_ID + " = :parent_folder_id");
+
+ // Bind the query values.
+ folderUrlsQuery.bindValue(":parent_folder_id", folderId);
+
+ // Execute the query.
+ folderUrlsQuery.exec();
+
+ // Create a folder URLs list.
+ QList<QString> *folderUrlsListPointer = new QList<QString>;
+
+ // Populate the folder URLs list.
+ while (folderUrlsQuery.next())
+ {
+ // Process the entry according to the type.
+ if (folderUrlsQuery.value(IS_FOLDER).toBool()) // This is a folder.
+ {
+ // Get the subfolder URLs to the list.
+ folderUrlsListPointer->append(*getAllFolderUrls(folderUrlsQuery.value(FOLDER_ID).toDouble()));
+ }
+ else // This is a bookmark.
+ {
+ // Add the URL to the list.
+ folderUrlsListPointer->append(folderUrlsQuery.value(BOOKMARK_URL).toString());
+ }
}
+
+ // Return the folder URLs list.
+ return folderUrlsListPointer;
}
-BookmarkStruct *BookmarksDatabase::getBookmark(int bookmarkId)
+BookmarkStruct* BookmarksDatabase::getBookmark(const int databaseId)
{
// Get a handle for the bookmarks database.
QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
bookmarkQuery.prepare("SELECT * FROM " + BOOKMARKS_TABLE + " WHERE " + ID + " = :id");
// Bind the query values.
- bookmarkQuery.bindValue(":id", bookmarkId);
+ bookmarkQuery.bindValue(":id", databaseId);
// Execute the query.
bookmarkQuery.exec();
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->databaseId = bookmarkQuery.value(ID).toInt();
+ bookmarkStructPointer->name = bookmarkQuery.value(BOOKMARK_NAME).toString();
+ bookmarkStructPointer->url = bookmarkQuery.value(BOOKMARK_URL).toString();
+ bookmarkStructPointer->parentFolderId = bookmarkQuery.value(PARENT_FOLDER_ID).toDouble();
bookmarkStructPointer->displayOrder = bookmarkQuery.value(DISPLAY_ORDER).toInt();
+ bookmarkStructPointer->isFolder = bookmarkQuery.value(IS_FOLDER).toBool();
+ bookmarkStructPointer->folderId = bookmarkQuery.value(FOLDER_ID).toDouble();
bookmarkStructPointer->favoriteIcon = QIcon(favoriteIconPixmap);
// Return the bookmark struct pointer.
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.databaseId = bookmarksQuery.value(ID).toInt();
+ bookmarkStruct.name = bookmarksQuery.value(BOOKMARK_NAME).toString();
+ bookmarkStruct.url = bookmarksQuery.value(BOOKMARK_URL).toString();
+ bookmarkStruct.parentFolderId = bookmarksQuery.value(PARENT_FOLDER_ID).toDouble();
bookmarkStruct.displayOrder = bookmarksQuery.value(DISPLAY_ORDER).toInt();
+ bookmarkStruct.isFolder = bookmarksQuery.value(IS_FOLDER).toBool();
+ bookmarkStruct.folderId = bookmarksQuery.value(FOLDER_ID).toDouble();
bookmarkStruct.favoriteIcon = QIcon(favoriteIconPixmap);
// Add the bookmark to the list.
return bookmarkListPointer;
}
-QList<BookmarkStruct>* BookmarksDatabase::getBookmarksExcept(QList<int> *exceptDatabaseIdsListPointer)
+QList<BookmarkStruct>* BookmarksDatabase::getBookmarksInFolderExcept(const double folderId, QList<int> *exceptDatabaseIdsListPointer)
{
// Get a handle for the bookmarks database.
QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
}
// Prepare the bookmarks query.
- bookmarksQuery.prepare("SELECT * FROM " + BOOKMARKS_TABLE + " WHERE " + ID + " NOT IN (" + idsNotToGetString + ") ORDER BY " + DISPLAY_ORDER + " ASC");
+ bookmarksQuery.prepare("SELECT * FROM " + BOOKMARKS_TABLE + " WHERE " + PARENT_FOLDER_ID + " = :parent_folder_id AND " + ID + " NOT IN (" + idsNotToGetString + ") ORDER BY " + DISPLAY_ORDER + " ASC");
+
+ // Bind the query values.
+ bookmarksQuery.bindValue(":parent_folder_id", folderId);
// Execute the query.
bookmarksQuery.exec();
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.databaseId = bookmarksQuery.value(ID).toInt();
+ bookmarkStruct.name = bookmarksQuery.value(BOOKMARK_NAME).toString();
+ bookmarkStruct.url = bookmarksQuery.value(BOOKMARK_URL).toString();
+ bookmarkStruct.parentFolderId = bookmarksQuery.value(PARENT_FOLDER_ID).toDouble();
bookmarkStruct.displayOrder = bookmarksQuery.value(DISPLAY_ORDER).toInt();
+ bookmarkStruct.isFolder = bookmarksQuery.value(IS_FOLDER).toBool();
+ bookmarkStruct.folderId = bookmarksQuery.value(FOLDER_ID).toDouble();
bookmarkStruct.favoriteIcon = QIcon(favoriteIconPixmap);
// Add the bookmark to the list.
return favoriteIconBase64String;
}
+QList<BookmarkStruct>* BookmarksDatabase::getFolderContents(const double folderId)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate a folder contents query.
+ QSqlQuery folderContentsQuery(bookmarksDatabase);
+
+ // Set the query to be forward only, which is more performant.
+ folderContentsQuery.setForwardOnly(true);
+
+ // Prepare the folder contents query.
+ folderContentsQuery.prepare("SELECT * FROM " + BOOKMARKS_TABLE + " WHERE " + PARENT_FOLDER_ID + " = :parent_folder_id ORDER BY " + DISPLAY_ORDER + " ASC");
+
+ // Bind the query values.
+ folderContentsQuery.bindValue(":parent_folder_id", folderId);
+
+ // Execute the query.
+ folderContentsQuery.exec();
+
+ // Create a folder contents list.
+ QList<BookmarkStruct> *folderContentsListPointer = new QList<BookmarkStruct>;
+
+ // Populate the folder contents list.
+ while (folderContentsQuery.next())
+ {
+ // Create a bookmark struct.
+ struct BookmarkStruct bookmarkStruct;
+
+ // Get the favorite icon base 64 byte array.
+ QByteArray favoriteIconByteArray = QByteArray::fromBase64(folderContentsQuery.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.databaseId = folderContentsQuery.value(ID).toInt();
+ bookmarkStruct.name = folderContentsQuery.value(BOOKMARK_NAME).toString();
+ bookmarkStruct.url = folderContentsQuery.value(BOOKMARK_URL).toString();
+ bookmarkStruct.parentFolderId = folderContentsQuery.value(PARENT_FOLDER_ID).toDouble();
+ bookmarkStruct.displayOrder = folderContentsQuery.value(DISPLAY_ORDER).toInt();
+ bookmarkStruct.isFolder = folderContentsQuery.value(IS_FOLDER).toBool();
+ bookmarkStruct.folderId = folderContentsQuery.value(FOLDER_ID).toDouble();
+ bookmarkStruct.favoriteIcon = QIcon(favoriteIconPixmap);
+
+ // Add the item to the list.
+ folderContentsListPointer->append(bookmarkStruct);
+ }
+
+ // Return the folder contents list.
+ return folderContentsListPointer;
+}
+
+QList<int>* BookmarksDatabase::getFolderContentsDatabaseIds(const double folderId)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate a folder contents query.
+ QSqlQuery folderContentsQuery(bookmarksDatabase);
+
+ // Set the query to be forward only, which is more performant.
+ folderContentsQuery.setForwardOnly(true);
+
+ // Prepare the folder contents query.
+ folderContentsQuery.prepare("SELECT " + ID + " FROM " + BOOKMARKS_TABLE + " WHERE " + PARENT_FOLDER_ID + " = :parent_folder_id");
+
+ // Bind the query values.
+ folderContentsQuery.bindValue(":parent_folder_id", folderId);
+
+ // Execute the query.
+ folderContentsQuery.exec();
+
+ // Create a folder contents database ID list.
+ QList<int> *folderContentsDatabaseIdsListPointer = new QList<int>;
+
+ // Populate the folder contents list.
+ while (folderContentsQuery.next())
+ {
+ // Add the database ID to the list.
+ folderContentsDatabaseIdsListPointer->append(folderContentsQuery.value(ID).toInt());
+ }
+
+ // Return the folder contents database ID list.
+ return folderContentsDatabaseIdsListPointer;
+}
+
+QList<int> *BookmarksDatabase::getFolderContentsDatabaseIdsRecursively(const double folderId)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate a folder contents query.
+ QSqlQuery folderContentsQuery(bookmarksDatabase);
+
+ // Set the query to be forward only, which is more performant.
+ folderContentsQuery.setForwardOnly(true);
+
+ // Prepare the folder contents query.
+ folderContentsQuery.prepare("SELECT " + ID + ", " + IS_FOLDER + ", " + FOLDER_ID + " FROM " + BOOKMARKS_TABLE + " WHERE " + PARENT_FOLDER_ID + " = :parent_folder_id");
+
+ // Bind the query values.
+ folderContentsQuery.bindValue(":parent_folder_id", folderId);
+
+ // Execute the query.
+ folderContentsQuery.exec();
+
+ // Create a folder contents database ID list.
+ QList<int> *folderContentsDatabaseIdsListPointer = new QList<int>;
+
+ // Populate the folder contents list.
+ while (folderContentsQuery.next())
+ {
+ // Add the database ID to the list.
+ folderContentsDatabaseIdsListPointer->append(folderContentsQuery.value(ID).toInt());
+
+ // Recursively get the contents if this is a subfolder.
+ if (folderContentsQuery.value(IS_FOLDER).toBool())
+ folderContentsDatabaseIdsListPointer->append(*getFolderContentsDatabaseIdsRecursively(folderContentsQuery.value(FOLDER_ID).toDouble()));
+ }
+
+ // Return the folder contents database ID list.
+ return folderContentsDatabaseIdsListPointer;
+}
+
+int BookmarksDatabase::getFolderDatabaseId(const double folderId)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate a folder database ID query.
+ QSqlQuery folderDatabaseIdQuery(bookmarksDatabase);
+
+ // Set the query to be forward only, which is more performant.
+ folderDatabaseIdQuery.setForwardOnly(true);
+
+ // Prepare the folder database ID query.
+ folderDatabaseIdQuery.prepare("SELECT " + ID + " FROM " + BOOKMARKS_TABLE + " WHERE " + FOLDER_ID + " = :folder_id");
+
+ // Bind the query values.
+ folderDatabaseIdQuery.bindValue(":folder_id", folderId);
+
+ // Execute the query.
+ folderDatabaseIdQuery.exec();
+
+ // Move to the first entry.
+ folderDatabaseIdQuery.first();
+
+ // Return the folder database ID.
+ return folderDatabaseIdQuery.value(ID).toInt();
+}
+
+double BookmarksDatabase::getFolderId(const int databaseId)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate a folder ID query.
+ QSqlQuery folderIdQuery(bookmarksDatabase);
+
+ // Set the query to be forward only, which is more performant.
+ folderIdQuery.setForwardOnly(true);
+
+ // Prepare the folder ID query.
+ folderIdQuery.prepare("SELECT " + FOLDER_ID + " FROM " + BOOKMARKS_TABLE + " WHERE " + ID + " = :database_id");
+
+ // Bind the query values.
+ folderIdQuery.bindValue(":database_id", databaseId);
+
+ // Execute the query.
+ folderIdQuery.exec();
+
+ // Move to the first entry.
+ folderIdQuery.first();
+
+ // Return the folder ID.
+ return folderIdQuery.value(FOLDER_ID).toDouble();
+}
+
+int BookmarksDatabase::getFolderItemCount(const double folderId)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate a folder contents query.
+ QSqlQuery folderContentsQuery(bookmarksDatabase);
+
+ // Set the query to be forward only, which is more performant.
+ folderContentsQuery.setForwardOnly(true);
+
+ // Prepare the folder contents query.
+ folderContentsQuery.prepare("SELECT " + ID + " FROM " + BOOKMARKS_TABLE + " WHERE " + PARENT_FOLDER_ID + " = :parent_folder_id");
+
+ // Bind the query values.
+ folderContentsQuery.bindValue(":parent_folder_id", folderId);
+
+ // Execute the query.
+ folderContentsQuery.exec();
+
+ // Move to the last row.
+ folderContentsQuery.last();
+
+ // Initialize an item count variable.
+ int itemCount = 0;
+
+ // Check to see if the query is valid (there is at least one item).
+ if (folderContentsQuery.isValid())
+ {
+ // Get the number of rows (which is zero based) and add one to calculate the number of bookmarks.
+ itemCount = folderContentsQuery.at() + 1;
+ }
+
+ // Return the item count.
+ return itemCount;
+}
+
+double BookmarksDatabase::getParentFolderId(const int databaseId)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate a parent folder ID query.
+ QSqlQuery parentFolderIdQuery(bookmarksDatabase);
+
+ // Set the query to be forward only, which is more performant.
+ parentFolderIdQuery.setForwardOnly(true);
+
+ // Prepare the parent folder ID query.
+ parentFolderIdQuery.prepare("SELECT " + PARENT_FOLDER_ID + " FROM " + BOOKMARKS_TABLE + " WHERE " + ID + " = :database_id");
+
+ // Bind the query values.
+ parentFolderIdQuery.bindValue(":database_id", databaseId);
+
+ // Execute the query.
+ parentFolderIdQuery.exec();
+
+ // Move to the first entry.
+ parentFolderIdQuery.first();
+
+ // Return the parent folder ID.
+ return parentFolderIdQuery.value(PARENT_FOLDER_ID).toDouble();
+}
+
+QList<BookmarkStruct>* BookmarksDatabase::getSubfolders(const double folderId)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate a subfolders query.
+ QSqlQuery subfoldersQuery(bookmarksDatabase);
+
+ // Set the query to be forward only, which is more performant.
+ subfoldersQuery.setForwardOnly(true);
+
+ // Prepare the subfolders query.
+ subfoldersQuery.prepare("SELECT * FROM " + BOOKMARKS_TABLE + " WHERE " + IS_FOLDER + " = 1 AND " + PARENT_FOLDER_ID + " = :parent_folder_id ORDER BY " + DISPLAY_ORDER + " ASC");
+
+ // Bind the query values.
+ subfoldersQuery.bindValue(":parent_folder_id", folderId);
+
+ // Execute the query.
+ subfoldersQuery.exec();
+
+ // Create a subfolder list.
+ QList<BookmarkStruct> *subfoldersListPointer = new QList<BookmarkStruct>;
+
+ // Populate the subfolder list.
+ while (subfoldersQuery.next())
+ {
+ // Create a bookmark struct.
+ struct BookmarkStruct bookmarkStruct;
+
+ // Get the favorite icon base 64 byte array.
+ QByteArray favoriteIconByteArray = QByteArray::fromBase64(subfoldersQuery.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.databaseId = subfoldersQuery.value(ID).toInt();
+ bookmarkStruct.name = subfoldersQuery.value(BOOKMARK_NAME).toString();
+ bookmarkStruct.parentFolderId = subfoldersQuery.value(PARENT_FOLDER_ID).toDouble();
+ bookmarkStruct.displayOrder = subfoldersQuery.value(DISPLAY_ORDER).toInt();
+ bookmarkStruct.isFolder = subfoldersQuery.value(IS_FOLDER).toBool();
+ bookmarkStruct.folderId = subfoldersQuery.value(FOLDER_ID).toDouble();
+ bookmarkStruct.favoriteIcon = QIcon(favoriteIconPixmap);
+
+ // Add the subfolder to the list.
+ subfoldersListPointer->append(bookmarkStruct);
+ }
+
+ // Return the subfolders list.
+ return subfoldersListPointer;
+}
+
+bool BookmarksDatabase::isFolder(const int databaseId)
+{
+ // Get a handle for the bookmarks database.
+ QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate an is folder query.
+ QSqlQuery isFolderQuery(bookmarksDatabase);
+
+ // Set the query to be forward only, which is more performant.
+ isFolderQuery.setForwardOnly(true);
+
+ // Prepare the is folder query.
+ isFolderQuery.prepare("SELECT " + IS_FOLDER + " FROM " + BOOKMARKS_TABLE + " WHERE " + ID + " = :id");
+
+ // Bind the query values.
+ isFolderQuery.bindValue(":id", databaseId);
+
+ // Execute the query.
+ isFolderQuery.exec();
+
+ // Move to the first entry.
+ isFolderQuery.first();
+
+ // Return the folder status.
+ return isFolderQuery.value(IS_FOLDER).toBool();
+}
+
void BookmarksDatabase::updateBookmark(const BookmarkStruct *bookmarkStructPointer)
{
// Get a handle for the bookmarks database.
QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
- // Instantiate an update bookmark name.
+ // Instantiate an update bookmark query.
QSqlQuery updateBookmarkQuery(bookmarksDatabase);
// Prepare the update bookmark query.
updateBookmarkQuery.prepare("UPDATE " + BOOKMARKS_TABLE + " SET " +
BOOKMARK_NAME + " = :bookmark_name, " +
BOOKMARK_URL + " = :bookmark_url, " +
+ PARENT_FOLDER_ID + " = :parent_folder_id, " +
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(":bookmark_name", bookmarkStructPointer->name);
+ updateBookmarkQuery.bindValue(":bookmark_url", bookmarkStructPointer->url);
+ updateBookmarkQuery.bindValue(":parent_folder_id", bookmarkStructPointer->parentFolderId);
updateBookmarkQuery.bindValue(":display_order", bookmarkStructPointer->displayOrder);
updateBookmarkQuery.bindValue(":favorite_icon", getFavoriteIconBase64String(bookmarkStructPointer->favoriteIcon));
- updateBookmarkQuery.bindValue(":id", bookmarkStructPointer->id);
+ updateBookmarkQuery.bindValue(":id", bookmarkStructPointer->databaseId);
// Execute the query.
updateBookmarkQuery.exec();
}
-void BookmarksDatabase::updateDisplayOrder(const int bookmarkId, const int displayOrder)
+void BookmarksDatabase::updateBookmarkName(const int databaseId, 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 query values.
+ updateBookmarkNameQuery.bindValue(":bookmark_name", bookmarkName);
+ updateBookmarkNameQuery.bindValue(":id", databaseId);
+
+ // Execute the query.
+ updateBookmarkNameQuery.exec();
+}
+
+void BookmarksDatabase::updateBookmarkUrl(const int databaseId, 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 query values.
+ updateBookmarkUrlQuery.bindValue(":bookmark_url", bookmarkUrl);
+ updateBookmarkUrlQuery.bindValue(":id", databaseId);
+
+ // Execute the query.
+ updateBookmarkUrlQuery.exec();
+}
+
+void BookmarksDatabase::updateDisplayOrder(const int databaseId, const int displayOrder)
{
// Get a handle for the bookmarks database.
QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
// Bind the query values.
updateBookmarkDisplayOrderQuery.bindValue(":display_order", displayOrder);
- updateBookmarkDisplayOrderQuery.bindValue(":id", bookmarkId);
+ updateBookmarkDisplayOrderQuery.bindValue(":id", databaseId);
// Execute the query.
updateBookmarkDisplayOrderQuery.exec();
}
-void BookmarksDatabase::updateBookmarkName(const int bookmarkId, const QString &bookmarkName)
+void BookmarksDatabase::updateFolderContentsDisplayOrder(const double folderId)
{
// Get a handle for the bookmarks database.
QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
- // Instantiate an update bookmark name query.
- QSqlQuery updateBookmarkNameQuery(bookmarksDatabase);
+ // Instantiate a folder contents query.
+ QSqlQuery folderContentsQuery(bookmarksDatabase);
- // Prepare the update bookmark name query.
- updateBookmarkNameQuery.prepare("UPDATE " + BOOKMARKS_TABLE +
- " SET " + BOOKMARK_NAME + " = :bookmark_name " +
- "WHERE " + ID + " = :id");
+ // Set the query to be forward only, which is more performant.
+ folderContentsQuery.setForwardOnly(true);
+
+ // Prepare the folder contents query.
+ folderContentsQuery.prepare("SELECT " + ID + ", " + DISPLAY_ORDER + " FROM " + BOOKMARKS_TABLE + " WHERE " + PARENT_FOLDER_ID + " = :parent_folder_id ORDER BY " + DISPLAY_ORDER + " ASC");
// Bind the query values.
- updateBookmarkNameQuery.bindValue(":bookmark_name", bookmarkName);
- updateBookmarkNameQuery.bindValue(":id", bookmarkId);
+ folderContentsQuery.bindValue(":parent_folder_id", folderId);
// Execute the query.
- updateBookmarkNameQuery.exec();
+ folderContentsQuery.exec();
+
+ // Define a new display order int.
+ int newDisplayOrder = 0;
+
+ // Populate the subfolder list.
+ while (folderContentsQuery.next())
+ {
+ // Update the display order if it has changed.
+ if (folderContentsQuery.value(DISPLAY_ORDER).toInt() != newDisplayOrder)
+ updateDisplayOrder(folderContentsQuery.value(ID).toInt(), newDisplayOrder);
+
+ // Increment the new display order.
+ ++newDisplayOrder;
+ }
}
-void BookmarksDatabase::updateBookmarkUrl(const int bookmarkId, const QString &bookmarkUrl)
+void BookmarksDatabase::updateParentFolderAndDisplayOrder(const int databaseId, const double parentFolderId, const int displayOrder)
{
// Get a handle for the bookmarks database.
QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
- // Instantiate an update bookmark URL query.
- QSqlQuery updateBookmarkUrlQuery(bookmarksDatabase);
+ // Instantiate an update bookmark display order query.
+ QSqlQuery updateBookmarkDisplayOrderQuery(bookmarksDatabase);
- // Prepare the update bookmark URL query.
- updateBookmarkUrlQuery.prepare("UPDATE " + BOOKMARKS_TABLE +
- " SET " + BOOKMARK_URL + " = :bookmark_url " +
- "WHERE " + ID + " = :id");
+ // Prepare the update bookmark display order query.
+ updateBookmarkDisplayOrderQuery.prepare("UPDATE " + BOOKMARKS_TABLE +
+ " SET " + PARENT_FOLDER_ID + " = :parent_folder_id " +
+ ", " + DISPLAY_ORDER + " = :display_order " +
+ "WHERE " + ID + " = :id");
// Bind the query values.
- updateBookmarkUrlQuery.bindValue(":bookmark_url", bookmarkUrl);
- updateBookmarkUrlQuery.bindValue(":id", bookmarkId);
+ updateBookmarkDisplayOrderQuery.bindValue(":parent_folder_id", parentFolderId);
+ updateBookmarkDisplayOrderQuery.bindValue(":display_order", displayOrder);
+ updateBookmarkDisplayOrderQuery.bindValue(":id", databaseId);
// Execute the query.
- updateBookmarkUrlQuery.exec();
+ updateBookmarkDisplayOrderQuery.exec();
}
// The public functions.
static void addBookmark(const BookmarkStruct *bookmarkStructPointer);
static void addDatabase();
- static void deleteBookmark(const int bookmarkId);
- static BookmarkStruct* getBookmark(int bookmarkId);
+ static void addFolder(const BookmarkStruct *bookmarkStructPointer);
+ static void deleteBookmark(const int databaseId);
+ static QList<QString>* getAllFolderUrls(const double folderId);
+ static BookmarkStruct* getBookmark(const int databaseId);
static std::list<BookmarkStruct>* getBookmarks();
- static QList<BookmarkStruct>* getBookmarksExcept(QList<int> *exceptDatabaseIdsListPointer);
+ static QList<BookmarkStruct>* getBookmarksInFolderExcept(const double folderId, QList<int> *exceptDatabaseIdsListPointer);
+ static QList<int>* getFolderContentsDatabaseIds(const double folderId);
+ static QList<int>* getFolderContentsDatabaseIdsRecursively(const double folderId);
+ static QList<BookmarkStruct>* getFolderContents(const double folderId);
+ static int getFolderDatabaseId(const double folderId);
+ static double getFolderId(const int databaseId);
+ static int getFolderItemCount(const double folderId);
+ static double getParentFolderId(const int databaseId);
+ static QList<BookmarkStruct>* getSubfolders(const double folderId);
+ static bool isFolder(const int databaseId);
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 void updateBookmarkName(const int databaseId, const QString &bookmarkName);
+ static void updateBookmarkUrl(const int databaseId, const QString &bookmarkUrl);
+ static void updateDisplayOrder(const int databaseId, const int displayOrder);
+ static void updateFolderContentsDisplayOrder(const double folderId);
+ static void updateParentFolderAndDisplayOrder(const int databaseId, const double parentFolderId, const int displayOrder);
// The public constants.
static const QString CONNECTION_NAME;
static const int SCHEMA_VERSION;
// The private functions.
+ static double generateFolderId();
static QString getFavoriteIconBase64String(const QIcon &favoriteIcon);
};
#endif
#include <QPushButton>
// Construct the class.
-AddBookmarkDialog::AddBookmarkDialog(const QString &bookmarkName, const QString &bookmarkUrl, const QIcon &favoriteIcon) : QDialog(nullptr)
+AddBookmarkDialog::AddBookmarkDialog(const QString &bookmarkName, const QString &bookmarkUrl, const QIcon &favoriteIcon, const double parentFolderId) : QDialog(nullptr)
{
// 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.
+ // Instantiate the add bookmark dialog UI.
Ui::AddBookmarkDialog addBookmarkDialogUi;
// Setup the UI.
// Get handles for the widgets.
defaultFavoriteIconRadioButtonPointer = addBookmarkDialogUi.defaultFavoriteIconRadioButton;
customFavoriteIconRadioButtonPointer = addBookmarkDialogUi.customFavoriteIconRadioButton;
- bookmarkNamePointer = addBookmarkDialogUi.bookmarkNameLineEdit;
- bookmarkUrlPointer = addBookmarkDialogUi.bookmarkUrlLineEdit;
+ parentFolderTreeWidgetPointer = addBookmarkDialogUi.parentFolderTreeWidget;
+ bookmarkNameLineEditPointer = addBookmarkDialogUi.bookmarkNameLineEdit;
+ bookmarkUrlLineEditPointer = addBookmarkDialogUi.bookmarkUrlLineEdit;
QPushButton *browseButtonPointer = addBookmarkDialogUi.browseButton;
QDialogButtonBox *dialogButtonBoxPointer = addBookmarkDialogUi.dialogButtonBox;
// Set the default favorite icon.
defaultFavoriteIconRadioButtonPointer->setIcon(favoriteIcon);
+ // Instantiate a folder helper.
+ folderHelperPointer = new FolderHelper();
+
+ // Set the parent folder tree widget column count.
+ parentFolderTreeWidgetPointer->setColumnCount(2);
+
+ // Hide the second column.
+ parentFolderTreeWidgetPointer->hideColumn(folderHelperPointer->FOLDER_ID_COLUMN);
+
+ // Set the column header.
+ parentFolderTreeWidgetPointer->setHeaderLabel(i18nc("The folder tree widget header", "Select Parent Folder"));
+
+ // Create a bookmarks tree widget item.
+ QTreeWidgetItem *bookmarksTreeWidgetItemPointer = new QTreeWidgetItem();
+
+ // Populate the bookmarks tree widget item.
+ bookmarksTreeWidgetItemPointer->setText(folderHelperPointer->FOLDER_NAME_COLUMN, i18nc("The bookmarks root tree widget name", "Bookmarks"));
+ bookmarksTreeWidgetItemPointer->setIcon(folderHelperPointer->FOLDER_NAME_COLUMN, QIcon::fromTheme("bookmarks"));
+ bookmarksTreeWidgetItemPointer->setText(folderHelperPointer->FOLDER_ID_COLUMN, QLatin1String("0"));
+
+ // Add the bookmarks tree widget item to the root of the tree.
+ parentFolderTreeWidgetPointer->addTopLevelItem(bookmarksTreeWidgetItemPointer);
+
+ // Select the root bookmarks folder if it is the initial parent folder.
+ if (parentFolderId == 0)
+ bookmarksTreeWidgetItemPointer->setSelected(true);
+
+ // Populate the subfolders.
+ folderHelperPointer->populateSubfolders(bookmarksTreeWidgetItemPointer, parentFolderId);
+
+ // Open all the folders.
+ parentFolderTreeWidgetPointer->expandAll();
+
// Populate the line edits.
- bookmarkNamePointer->setText(bookmarkName);
- bookmarkUrlPointer->setText(bookmarkUrl);
+ bookmarkNameLineEditPointer->setText(bookmarkName);
+ bookmarkUrlLineEditPointer->setText(bookmarkUrl);
// Scroll to the beginning of the line edits.
- bookmarkNamePointer->setCursorPosition(0);
- bookmarkUrlPointer->setCursorPosition(0);
+ bookmarkNameLineEditPointer->setCursorPosition(0);
+ bookmarkUrlLineEditPointer->setCursorPosition(0);
// Add buttons to the dialog button box.
- QPushButton *addBookmarkButtonPointer = dialogButtonBoxPointer->addButton(i18nc("The add bookmark button", "Add"), QDialogButtonBox::AcceptRole);
+ addButtonPointer = dialogButtonBoxPointer->addButton(i18nc("The add bookmark button", "Add"), QDialogButtonBox::AcceptRole);
// Set the button icons.
- addBookmarkButtonPointer->setIcon(QIcon::fromTheme("list-add"));
+ addButtonPointer->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()));
+
+ // Update the UI when the line edits change.
+ connect(bookmarkNameLineEditPointer, SIGNAL(textEdited(const QString&)), this, SLOT(updateUi()));
+ connect(bookmarkUrlLineEditPointer, SIGNAL(textEdited(const QString&)), this, SLOT(updateUi()));
+
+ // Set the initial UI status.
+ updateUi();
}
void AddBookmarkDialog::addBookmark()
{
+ // Get the selected folders list.
+ QList<QTreeWidgetItem*> selectedFoldersList = parentFolderTreeWidgetPointer->selectedItems();
+
+ // Get the selected folder.
+ QTreeWidgetItem *selectedFolderPointer = selectedFoldersList.first();
+
// Get the favorite icon.
QIcon favoriteIcon = defaultFavoriteIconRadioButtonPointer->isChecked() ? defaultFavoriteIconRadioButtonPointer->icon() : customFavoriteIconRadioButtonPointer->icon();
BookmarkStruct *bookmarkStructPointer = new BookmarkStruct;
// Populate the bookmark struct.
- bookmarkStructPointer->bookmarkName = bookmarkNamePointer->text();
- bookmarkStructPointer->bookmarkUrl = bookmarkUrlPointer->text();
+ bookmarkStructPointer->name = bookmarkNameLineEditPointer->text();
+ bookmarkStructPointer->url = bookmarkUrlLineEditPointer->text();
+ bookmarkStructPointer->parentFolderId = selectedFolderPointer->text(folderHelperPointer->FOLDER_ID_COLUMN).toDouble();
bookmarkStructPointer->favoriteIcon = favoriteIcon;
// Add the bookmark.
customFavoriteIconRadioButtonPointer->setChecked(true);
}
}
+
+void AddBookmarkDialog::updateUi()
+{
+ // Determine if both line edits are populated.
+ if (bookmarkNameLineEditPointer->text().isEmpty() || bookmarkUrlLineEditPointer->text().isEmpty()) // At least one of the line edits is empty.
+ {
+ // Disable the add button.
+ addButtonPointer->setEnabled(false);
+ }
+ else // Both of the line edits are populated.
+ {
+ // Enable the add button.
+ addButtonPointer->setEnabled(true);
+ }
+}
#ifndef ADDBOOKMARKDIALOG_H
#define ADDBOOKMARKDIALOG_H
+// Application headers.
+#include "helpers/FolderHelper.h"
+
// Qt toolkit headers.
#include <QDialog>
#include <QLineEdit>
#include <QRadioButton>
+#include <QTreeWidget>
class AddBookmarkDialog : public QDialog
{
public:
// The primary constructor.
- explicit AddBookmarkDialog(const QString &bookmarkName, const QString &bookmarkUrl, const QIcon &favoriteIcon);
+ explicit AddBookmarkDialog(const QString &bookmarkName, const QString &bookmarkUrl, const QIcon &favoriteIcon, const double parentFolderId = 0);
signals:
// The signals.
// The private slots.
void addBookmark();
void browse();
+ void updateUi();
private:
+ // The private variables.
+ FolderHelper *folderHelperPointer;
+
// The private widgets.
- QLineEdit *bookmarkNamePointer;
- QLineEdit *bookmarkUrlPointer;
+ QPushButton *addButtonPointer;
+ QLineEdit *bookmarkNameLineEditPointer;
+ QLineEdit *bookmarkUrlLineEditPointer;
QRadioButton *customFavoriteIconRadioButtonPointer;
QRadioButton *defaultFavoriteIconRadioButtonPointer;
+ QTreeWidget *parentFolderTreeWidgetPointer;
};
#endif
--- /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 "AddFolderDialog.h"
+#include "ui_AddFolderDialog.h"
+#include "databases/BookmarksDatabase.h"
+#include "helpers/FolderHelper.h"
+#include "structs/BookmarkStruct.h"
+
+// Qt toolkit headers.
+#include <QFileDialog>
+
+// Construct the class.
+AddFolderDialog::AddFolderDialog(const QIcon ¤tWebsiteFavoriteIcon, const double parentFolderId) : QDialog(nullptr)
+{
+ // Set the window title.
+ setWindowTitle(i18nc("The add folder dialog window title.", "Add Folder"));
+
+ // Set the window modality.
+ setWindowModality(Qt::WindowModality::ApplicationModal);
+
+ // Instantiate the add folder dialog UI.
+ Ui::AddFolderDialog addFolderDialogUi;
+
+ // Setup the UI.
+ addFolderDialogUi.setupUi(this);
+
+ // Get handles for the widgets.
+ defaultFolderIconRadioButtonPointer = addFolderDialogUi.defaultFolderIconRadioButton;
+ currentWebsiteFavoriteIconRadioButtonPointer = addFolderDialogUi.currentWebsiteFavoriteIconRadioButton;
+ customFolderIconRadioButtonPointer = addFolderDialogUi.customFolderIconRadioButton;
+ parentFolderTreeWidgetPointer = addFolderDialogUi.parentFolderTreeWidget;
+ folderNameLineEditPointer = addFolderDialogUi.folderNameLineEdit;
+ QPushButton *browseButtonPointer = addFolderDialogUi.browseButton;
+ QDialogButtonBox *dialogButtonBoxPointer = addFolderDialogUi.dialogButtonBox;
+
+ // Set the default favorite icon.
+ currentWebsiteFavoriteIconRadioButtonPointer->setIcon(currentWebsiteFavoriteIcon);
+
+ // Instantiate a folder helper.
+ folderHelperPointer = new FolderHelper();
+
+ // Set the parent folder tree widget column count.
+ parentFolderTreeWidgetPointer->setColumnCount(2);
+
+ // Hide the second column.
+ parentFolderTreeWidgetPointer->hideColumn(folderHelperPointer->FOLDER_ID_COLUMN);
+
+ // Set the column header.
+ parentFolderTreeWidgetPointer->setHeaderLabel(i18nc("The folder tree widget header", "Select Parent Folder"));
+
+ // Create a bookmarks tree widget item.
+ QTreeWidgetItem *bookmarksTreeWidgetItemPointer = new QTreeWidgetItem();
+
+ // Populate the bookmarks tree widget item.
+ bookmarksTreeWidgetItemPointer->setText(folderHelperPointer->FOLDER_NAME_COLUMN, i18nc("The bookmarks root tree widget name", "Bookmarks"));
+ bookmarksTreeWidgetItemPointer->setIcon(folderHelperPointer->FOLDER_NAME_COLUMN, QIcon::fromTheme("bookmarks"));
+ bookmarksTreeWidgetItemPointer->setText(folderHelperPointer->FOLDER_ID_COLUMN, QLatin1String("0"));
+
+ // Add the bookmarks tree widget item to the root of the tree.
+ parentFolderTreeWidgetPointer->addTopLevelItem(bookmarksTreeWidgetItemPointer);
+
+ // Select the root bookmarks folder if it is the initial parent folder.
+ if (parentFolderId == 0)
+ bookmarksTreeWidgetItemPointer->setSelected(true);
+
+ // Populate the subfolders.
+ folderHelperPointer->populateSubfolders(bookmarksTreeWidgetItemPointer, parentFolderId);
+
+ // Open all the folders.
+ parentFolderTreeWidgetPointer->expandAll();
+
+ // Focus the folder name line edit.
+ folderNameLineEditPointer->setFocus();
+
+ // Add buttons to the dialog button box.
+ addButtonPointer = dialogButtonBoxPointer->addButton(i18nc("The add folder button", "Add"), QDialogButtonBox::AcceptRole);
+
+ // Set the button icons.
+ addButtonPointer->setIcon(QIcon::fromTheme("list-add"));
+
+ // Connect the buttons.
+ connect(browseButtonPointer, SIGNAL(clicked()), this, SLOT(browse()));
+ connect(dialogButtonBoxPointer, SIGNAL(accepted()), this, SLOT(addFolder()));
+ connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
+
+ // Update the UI when the folder name changes.
+ connect(folderNameLineEditPointer, SIGNAL(textEdited(const QString&)), this, SLOT(updateUi(const QString&)));
+
+ // Set the initial UI status.
+ updateUi(folderNameLineEditPointer->text());
+}
+
+void AddFolderDialog::addFolder()
+{
+ // Get the parent folder ID.
+ QList<QTreeWidgetItem*> selectedFoldersList = parentFolderTreeWidgetPointer->selectedItems();
+
+ // Get the selected folder.
+ QTreeWidgetItem *selectedFolderPointer = selectedFoldersList.first();
+
+ // Create a favorite icon.
+ QIcon favoriteIcon;
+
+ // Get the favorite icon.
+ if (defaultFolderIconRadioButtonPointer->isChecked()) // The default folder icon is checked.
+ favoriteIcon = defaultFolderIconRadioButtonPointer->icon();
+ else if (currentWebsiteFavoriteIconRadioButtonPointer->isChecked()) // The current website favorite icon is checked.
+ favoriteIcon = currentWebsiteFavoriteIconRadioButtonPointer->icon();
+ else // The custom folder icon is checked.
+ favoriteIcon = customFolderIconRadioButtonPointer->icon();
+
+ // Create a bookmark struct.
+ BookmarkStruct *bookmarkStructPointer = new BookmarkStruct;
+
+ // Populate the bookmark struct.
+ bookmarkStructPointer->name = folderNameLineEditPointer->text();
+ bookmarkStructPointer->parentFolderId = selectedFolderPointer->text(folderHelperPointer->FOLDER_ID_COLUMN).toDouble();
+ bookmarkStructPointer->favoriteIcon = favoriteIcon;
+
+ // Add the folder.
+ BookmarksDatabase::addFolder(bookmarkStructPointer);
+
+ // Update the list of bookmarks in the menu and toolbar.
+ emit folderAdded();
+
+ // Close the dialog.
+ close();
+}
+
+void AddFolderDialog::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.
+ customFolderIconRadioButtonPointer->setIcon(QIcon(imageFileString));
+
+ // Check the custom favorite icon radio button.
+ customFolderIconRadioButtonPointer->setChecked(true);
+ }
+}
+
+void AddFolderDialog::updateUi(const QString &newFolderName)
+{
+ // Set the status of the add button based on the
+ addButtonPointer->setEnabled(!newFolderName.isEmpty());
+}
--- /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 ADDFOLDERDIALOG_H
+#define ADDFOLDERDIALOG_H
+
+// Application headers.
+#include "helpers/FolderHelper.h"
+
+// Qt toolkit headers.
+#include <QDialog>
+#include <QLineEdit>
+#include <QRadioButton>
+#include <QTreeWidget>
+
+class AddFolderDialog : public QDialog
+{
+ // Include the Q_OBJECT macro.
+ Q_OBJECT
+
+public:
+ // The primary constructor.
+ explicit AddFolderDialog(const QIcon ¤tWebsiteFavoriteIcon, const double parentFolderId = 0);
+
+signals:
+ // The signals.
+ void folderAdded() const;
+
+private Q_SLOTS:
+ // The private slots.
+ void addFolder();
+ void browse();
+ void updateUi(const QString &newFolderName);
+
+private:
+ // The private variables.
+ FolderHelper *folderHelperPointer;
+
+ // The private widgets.
+ QPushButton *addButtonPointer;
+ QRadioButton *currentWebsiteFavoriteIconRadioButtonPointer;
+ QRadioButton *customFolderIconRadioButtonPointer;
+ QRadioButton *defaultFolderIconRadioButtonPointer;
+ QLineEdit *folderNameLineEditPointer;
+ QTreeWidget *parentFolderTreeWidgetPointer;
+};
+#endif
#include "ui_BookmarksDialog.h"
#include "databases/BookmarksDatabase.h"
#include "dialogs/AddBookmarkDialog.h"
+#include "dialogs/AddFolderDialog.h"
#include "dialogs/EditBookmarkDialog.h"
+#include "dialogs/EditFolderDialog.h"
// KDE Frameworks headers.
#include <KLocalizedString>
#include <QStandardItemModel>
// Construct the class.
-BookmarksDialog::BookmarksDialog(QIcon currentWebsiteFavorieIcon) : QDialog(nullptr), websiteFavoriteIcon(currentWebsiteFavorieIcon)
+BookmarksDialog::BookmarksDialog(QString currentWebsiteTitle, QString currentWebsiteUrl, QIcon currentWebsiteFavorieIcon) :
+ QDialog(nullptr), websiteFavoriteIcon(currentWebsiteFavorieIcon), websiteTitle(currentWebsiteTitle), websiteUrl(currentWebsiteUrl)
{
// Set the dialog window title.
setWindowTitle(i18nc("The bookmarks dialog window title", "Bookmarks"));
treeSelectionModelPointer = draggableTreeViewPointer->selectionModel();
// Listen for selection changes.
- connect(treeSelectionModelPointer, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(updateUi()));
+ connect(treeSelectionModelPointer, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(updateSelection()));
// Repopulate the bookmarks when they are moved.
connect(draggableTreeViewPointer, SIGNAL(bookmarksMoved()), this, SLOT(refreshBookmarks()));
// Get handles for the buttons.
QPushButton *addBookmarkButtonPointer = bookmarksDialogUi.addBookmarkButton;
+ QPushButton *addFolderButtonPointer = bookmarksDialogUi.addFolderButton;
editButtonPointer = bookmarksDialogUi.editButton;
deleteItemsButtonPointer = bookmarksDialogUi.deleteItemsButton;
QDialogButtonBox *dialogButtonBoxPointer = bookmarksDialogUi.dialogButtonBox;
// Connect the buttons.
connect(addBookmarkButtonPointer, SIGNAL(clicked()), this, SLOT(showAddBookmarkDialog()));
+ connect(addFolderButtonPointer, SIGNAL(clicked()), this, SLOT(showAddFolderDialog()));
connect(editButtonPointer, SIGNAL(clicked()), this, SLOT(showEditDialog()));
connect(deleteItemsButtonPointer, SIGNAL(clicked()), this, SLOT(deleteItems()));
connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
void BookmarksDialog::deleteItems() const
{
+ // Create a parent folder ID standard C++ list (which can be sorted and from which duplicates can be removed).
+ std::list<double> parentFolderIdList;
+
// 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)
{
+ // Add the parent folder ID to the list.
+ parentFolderIdList.push_back(modelIndex.parent().siblingAtColumn(FOLDER_ID_COLUMN).data().toDouble());
+
// Delete the bookmark.
BookmarksDatabase::deleteBookmark(modelIndex.data().toInt());
}
+ // Sort the parent folder ID.
+ parentFolderIdList.sort();
+
+ // Remove duplicates from the parent folder ID list.
+ parentFolderIdList.unique();
+
+ // Update the folder contents display order for each folder with a deleted bookmark.
+ for (const double parentFolderId : parentFolderIdList)
+ BookmarksDatabase::updateFolderContentsDisplayOrder(parentFolderId);
+
// Repopulate the bookmarks in this dialog
populateBookmarks();
treeModelPointer->clear();
// Set the column count.
- treeModelPointer->setColumnCount(4);
+ treeModelPointer->setColumnCount(6);
- // 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"));
+ // Set the tree header data.
+ treeModelPointer->setHeaderData(NAME_COLUMN, Qt::Horizontal, i18nc("The bookmark Name header.", "Name"));
+ treeModelPointer->setHeaderData(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);
+ draggableTreeViewPointer->setColumnHidden(DISPLAY_ORDER_COLUMN, true);
+ draggableTreeViewPointer->setColumnHidden(IS_FOLDER_COLUMN, true);
+ draggableTreeViewPointer->setColumnHidden(FOLDER_ID_COLUMN, true);
+
+ // Create a bookmarks root item list.
+ QList<QStandardItem*> bookmarksRootItemList;
+
+ // Create the root items.
+ QStandardItem *rootItemNamePointer = new QStandardItem(QIcon::fromTheme("bookmarks"), i18nc("The bookmarks root tree widget name", "Bookmarks"));
+ QStandardItem *rootItemUrlPointer = new QStandardItem(QLatin1String(""));
+ QStandardItem *rootItemDatabaseIdPonter = new QStandardItem(QLatin1String("-1")); // The root item doesn't have a database ID.
+ QStandardItem *rootItemDisplayOrderPointer = new QStandardItem(QLatin1String("-1")); // The root item doesn't have a display order.
+ QStandardItem *rootItemIsFolderPointer = new QStandardItem(QLatin1String("1"));
+ QStandardItem *rootItemFolderIdPointer = new QStandardItem(QLatin1String("0"));
+
+ // Enable dropping on the root name column.
+ rootItemNamePointer->setDropEnabled(true);
+
+ // Disable dropping on the URL.
+ rootItemUrlPointer->setDropEnabled(false);
+
+ // Disable dragging of the bookmarks root item.
+ rootItemNamePointer->setDragEnabled(false);
+ rootItemUrlPointer->setDragEnabled(false);
+
+ // Disable selecting the URL.
+ rootItemUrlPointer->setSelectable(false);
- // Get the list of bookmarks.
- std::list<BookmarkStruct> *bookmarksListPointer = BookmarksDatabase::getBookmarks();
+ // Populate the bookmarks root item list.
+ bookmarksRootItemList.append(rootItemNamePointer);
+ bookmarksRootItemList.append(rootItemUrlPointer);
+ bookmarksRootItemList.append(rootItemDatabaseIdPonter);
+ bookmarksRootItemList.append(rootItemDisplayOrderPointer);
+ bookmarksRootItemList.append(rootItemIsFolderPointer);
+ bookmarksRootItemList.append(rootItemFolderIdPointer);
+
+ // Add the bookmarks root item to the tree.
+ treeModelPointer->appendRow(bookmarksRootItemList);
+
+ // Populate the subfolders, starting with the root folder ID (`0`).
+ populateSubfolders(rootItemNamePointer, 0);
+
+ // Expand all the folder.
+ draggableTreeViewPointer->expandAll();
+
+ // Update the UI.
+ updateUi();
+}
+
+void BookmarksDialog::populateSubfolders(QStandardItem *folderItemNamePointer, const double folderId) const
+{
+ // Get the folder contents.
+ QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(folderId);
// Populate the bookmarks tree view.
- for (const BookmarkStruct &bookmarkStruct : *bookmarksListPointer)
+ for (const BookmarkStruct &bookmarkStruct : *folderContentsListPointer)
{
- // Create a list for the bookmark items.
+ // Create a bookmark item list.
QList<QStandardItem*> bookmarkItemList;
// Create the bookmark items.
- 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));
-
+ QStandardItem *nameItemPointer = new QStandardItem(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
+ QStandardItem *urlItemPointer = new QStandardItem(bookmarkStruct.url);
+ QStandardItem *databaseIdItemPointer = new QStandardItem(QString::number(bookmarkStruct.databaseId));
+ QStandardItem *displayOrderItemPointer = new QStandardItem(QString::number(bookmarkStruct.displayOrder));
+ QStandardItem *isFolderItemPointer = new QStandardItem(QString::number(bookmarkStruct.isFolder));
+ QStandardItem *folderIdItemPointer = new QStandardItem(QString::number(bookmarkStruct.folderId, 'f', 0)); // Format the folder ID as a floating point with no trailing zeros.
+
+ // Enable dragging and dropping of the name column.
nameItemPointer->setDragEnabled(true);
- nameItemPointer->setDropEnabled(true);
- // Disable dragging the URL.
- urlItemPointer->setDragEnabled(false);
+ // Only allow dropping on the name if this is a folder.
+ nameItemPointer->setDropEnabled(bookmarkStruct.isFolder);
- // Disable dropping on the URL. For some reason this doesn't work.
+ // Disable dragging and dropping on the URL.
+ urlItemPointer->setDragEnabled(false);
urlItemPointer->setDropEnabled(false);
// Disable selecting the URL.
// Populate the bookmark item list.
bookmarkItemList.append(nameItemPointer);
bookmarkItemList.append(urlItemPointer);
- bookmarkItemList.append(idItemPointer);
- bookmarkItemList.append(displayOrderPointer);
+ bookmarkItemList.append(databaseIdItemPointer);
+ bookmarkItemList.append(displayOrderItemPointer);
+ bookmarkItemList.append(isFolderItemPointer);
+ bookmarkItemList.append(folderIdItemPointer);
- // Add the bookmark to the tree.
- treeModelPointer->appendRow(bookmarkItemList);
- }
+ // Add the bookmark to the parent folder.
+ folderItemNamePointer->appendRow(bookmarkItemList);
- // Update the UI.
- updateUi();
+ // Populate subfolders if this item is a folder.
+ if (bookmarkStruct.isFolder)
+ populateSubfolders(nameItemPointer, bookmarkStruct.folderId);
+ }
}
void BookmarksDialog::refreshBookmarks() const
emit bookmarkUpdated();
}
+void BookmarksDialog::selectSubfolderContents(const QModelIndex &parentModelIndex) const
+{
+ // Get the index model.
+ const QAbstractItemModel *modelIndexAbstractItemPointer = parentModelIndex.model();
+
+ // Get the number of items in the folder.
+ int numberOfChildrenInFolder = modelIndexAbstractItemPointer->rowCount(parentModelIndex);
+
+ // Select any child items.
+ if (numberOfChildrenInFolder > 0)
+ {
+ // Select the contents of any subfolders.
+ for (int i = 0; i < numberOfChildrenInFolder; ++i)
+ {
+ // Get the child model index.
+ QModelIndex childModelIndex = modelIndexAbstractItemPointer->index(i, 0, parentModelIndex);
+
+ // Select the subfolder contents if it is a folder.
+ if (childModelIndex.siblingAtColumn(IS_FOLDER_COLUMN).data().toBool())
+ selectSubfolderContents(childModelIndex);
+ }
+
+ // Get the first and last child model indexes.
+ QModelIndex firstChildModelIndex = modelIndexAbstractItemPointer->index(0, 0, parentModelIndex);
+ QModelIndex lastChildModelIndex = modelIndexAbstractItemPointer->index((numberOfChildrenInFolder - 1), 0, parentModelIndex);
+
+ // Create an item selection that includes all the child items.
+ QItemSelection folderChildItemsSelection = QItemSelection(firstChildModelIndex, lastChildModelIndex);
+
+ // Get the current selection.
+ QItemSelection currentSelection = treeSelectionModelPointer->selection();
+
+ // Combine the current selection and the folder child items selection.
+ currentSelection.merge(folderChildItemsSelection, QItemSelectionModel::SelectCurrent);
+
+ // Selected the updated list of items.
+ treeSelectionModelPointer->select(currentSelection, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
+ }
+}
+
void BookmarksDialog::showAddBookmarkDialog() const
{
+ // Return the most recently selected index.
+ QModelIndex currentIndex = treeSelectionModelPointer->currentIndex();
+
+ // Instantiate a parent folder ID.
+ double parentFolderId;
+
+ // Get the parent folder ID.
+ if (currentIndex.siblingAtColumn(IS_FOLDER_COLUMN).data().toInt() == 1) // The current index is a folder.
+ {
+ // Store the parent folder ID.
+ parentFolderId = currentIndex.siblingAtColumn(FOLDER_ID_COLUMN).data().toDouble();
+ }
+ else // The current index is not a folder.
+ {
+ // Store the parent folder ID of the folder that contains the bookmark.
+ parentFolderId = currentIndex.parent().siblingAtColumn(FOLDER_ID_COLUMN).data().toDouble();
+ }
+
// Instantiate an add bookmark dialog.
- AddBookmarkDialog *addBookmarkDialogPointer = new AddBookmarkDialog(QLatin1String(""), QLatin1String(""), websiteFavoriteIcon);
+ AddBookmarkDialog *addBookmarkDialogPointer = new AddBookmarkDialog(websiteTitle, websiteUrl, websiteFavoriteIcon, parentFolderId);
// Update the displayed bookmarks when a new one is added.
connect(addBookmarkDialogPointer, SIGNAL(bookmarkAdded()), this, SLOT(refreshBookmarks()));
addBookmarkDialogPointer->show();
}
+void BookmarksDialog::showAddFolderDialog() const
+{
+ // Get the most recently selected index.
+ QModelIndex currentIndex = treeSelectionModelPointer->currentIndex();
+
+ // Instantiate a parent folder ID.
+ double parentFolderId;
+
+ // Get the parent folder ID.
+ if (currentIndex.siblingAtColumn(IS_FOLDER_COLUMN).data().toInt() == 1) // The current index is a folder.
+ {
+ // Store the parent folder ID.
+ parentFolderId = currentIndex.siblingAtColumn(FOLDER_ID_COLUMN).data().toDouble();
+ }
+ else // The current index is not a folder.
+ {
+ // Store the parent folder ID of the folder that contains the bookmark.
+ parentFolderId = currentIndex.parent().siblingAtColumn(FOLDER_ID_COLUMN).data().toDouble();
+ }
+
+ // Instantiate an add folder dialog.
+ AddFolderDialog *addFolderDialogPointer = new AddFolderDialog(websiteFavoriteIcon, parentFolderId);
+
+ // Update the displayed bookmarks when a folder is added.
+ connect(addFolderDialogPointer, SIGNAL(folderAdded()), this, SLOT(refreshBookmarks()));
+
+ // Show the dialog.
+ addFolderDialogPointer->show();
+}
+
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);
+ // Check to see if the selected item is a folder.
+ if (currentIndex.siblingAtColumn(IS_FOLDER_COLUMN).data().toInt() == 1) // The selected item is a folder.
+ {
+ // Instantiate an edit folder dialog.
+ QDialog *editFolderDialogPointer = new EditFolderDialog(currentIndex.siblingAtColumn(DATABASE_ID_COLUMN).data().toInt(), websiteFavoriteIcon);
- // Show the dialog.
- editBookmarkDialogPointer->show();
+ // Show the dialog.
+ editFolderDialogPointer->show();
- // Process bookmark events.
- connect(editBookmarkDialogPointer, SIGNAL(bookmarkSaved()), this, SLOT(refreshBookmarks()));
+ // Update the bookmarks UI.
+ connect(editFolderDialogPointer, SIGNAL(folderSaved()), this, SLOT(refreshBookmarks()));
+ }
+ else // The selected item is a bookmark.
+ {
+ // Instantiate an edit bookmark dialog.
+ QDialog *editBookmarkDialogPointer = new EditBookmarkDialog(currentIndex.siblingAtColumn(DATABASE_ID_COLUMN).data().toInt(), websiteFavoriteIcon);
+
+ // Show the dialog.
+ editBookmarkDialogPointer->show();
+
+ // Update the bookmarks UI.
+ connect(editBookmarkDialogPointer, SIGNAL(bookmarkSaved()), this, SLOT(refreshBookmarks()));
+ }
}
void BookmarksDialog::updateBookmarkFromTree(QStandardItem *modifiedStandardItem)
int databaseId = databaseIdModelIndex.data().toInt();
// Check to see if the bookmark name or the URL was edited.
- if (modifiedStandardItem->column() == BOOKMARK_NAME_COLUMN) // The bookmark name was edited.
+ if (modifiedStandardItem->column() == NAME_COLUMN) // The bookmark name was edited.
{
// Update the bookmark name.
BookmarksDatabase::updateBookmarkName(databaseId, modifiedStandardItem->text());
emit bookmarkUpdated();
}
+void BookmarksDialog::updateSelection() const
+{
+ // Set the status of the buttons.
+ if (treeSelectionModelPointer->hasSelection()) // A bookmark or folder is selected.
+ {
+ // Get the list of selected model indexes.
+ QModelIndexList selectedRowsModelIndexList = treeSelectionModelPointer->selectedRows();
+
+ // Check to see if each selected item is a folder.
+ for(QModelIndex modelIndex : selectedRowsModelIndexList)
+ {
+ // If it is a folder, select all the children bookmarks.
+ if (modelIndex.siblingAtColumn(IS_FOLDER_COLUMN).data().toBool())
+ selectSubfolderContents(modelIndex);
+ }
+ }
+
+ // Update the UI.
+ updateUi();
+}
+
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);
+ // Get the currently selected index.
+ QModelIndex currentSelectedIndex = treeSelectionModelPointer->currentIndex();
+
+ // Get the list of selected model indexes.
+ QModelIndexList selectedRowsModelIndexList = treeSelectionModelPointer->selectedRows();
+
+ // Get the number of selected rows.
+ int numberOfSelectedRows = selectedRowsModelIndexList.count();
+
+ // Enable the edit button if a folder or only one bookmark is selected.
+ editButtonPointer->setEnabled(currentSelectedIndex.siblingAtColumn(IS_FOLDER_COLUMN).data().toBool() || (numberOfSelectedRows == 1));
+
+ // Check if the root folder is selected.
+ if (treeSelectionModelPointer->isRowSelected(0))
+ {
+ // Disable the edit button.
+ editButtonPointer->setEnabled(false);
+
+ // Decrease the number of selected rows by 1.
+ --numberOfSelectedRows;
+ }
+
+ // Enabled the delete button if at least one real bookmark or folder is selected.
+ deleteItemsButtonPointer->setEnabled(numberOfSelectedRows > 0);
// Update the delete items button text.
- deleteItemsButtonPointer->setText(i18ncp("Delete items button populated text.", "Delete %1 item", "Delete %1 items", treeSelectionModelPointer->selectedRows().count()));
+ if (numberOfSelectedRows > 0)
+ deleteItemsButtonPointer->setText(i18ncp("Delete items button populated text.", "Delete %1 item", "Delete %1 items", numberOfSelectedRows));
+ else
+ deleteItemsButtonPointer->setText(i18nc("Delete items button default text", "Delete items"));
}
else // Nothing is selected.
{
public:
// The primary constructor.
- explicit BookmarksDialog(QIcon currentWebsiteFavoriteIcon);
+ explicit BookmarksDialog(QString currentWebsiteTitle, QString currentWebsiteUrl, QIcon currentWebsiteFavoriteIcon);
// The public constants.
- static const int BOOKMARK_NAME_COLUMN = 0;
- static const int BOOKMARK_URL_COLUMN = 1;
+ static const int NAME_COLUMN = 0;
+ static const int URL_COLUMN = 1;
static const int DATABASE_ID_COLUMN = 2;
- static const int DISPLAY_ORDER = 3;
+ static const int DISPLAY_ORDER_COLUMN = 3;
+ static const int IS_FOLDER_COLUMN = 4;
+ static const int FOLDER_ID_COLUMN = 5;
signals:
// The signals.
void deleteItems() const;
void refreshBookmarks() const;
void showAddBookmarkDialog() const;
+ void showAddFolderDialog() const;
void showEditDialog();
void updateBookmarkFromTree(QStandardItem *modifiedStandardItem);
- void updateUi() const;
+ void updateSelection() const;
private:
- // The private functions.
- void populateBookmarks() const;
-
// The private variables.
QPushButton *deleteItemsButtonPointer;
QPushButton *editButtonPointer;
QItemSelectionModel *treeSelectionModelPointer;
DraggableTreeView *draggableTreeViewPointer;
QIcon websiteFavoriteIcon;
+ QString websiteTitle;
+ QString websiteUrl;
+
+ // The private functions.
+ void populateBookmarks() const;
+ void populateSubfolders(QStandardItem *folderItemNamePointer, const double folderId) const;
+ void selectSubfolderContents(const QModelIndex &parentModelIndex) const;
+ void updateUi() const;
};
#endif
# List the sources to include in the executable.
target_sources(privacybrowser PRIVATE
AddBookmarkDialog.cpp
+ AddFolderDialog.cpp
AddOrEditCookieDialog.cpp
BookmarksDialog.cpp
CookiesDialog.cpp
DomainSettingsDialog.cpp
DurableCookiesDialog.cpp
EditBookmarkDialog.cpp
+ EditFolderDialog.cpp
SaveDialog.cpp
)
#include <QFileDialog>
// Construct the class.
-EditBookmarkDialog::EditBookmarkDialog(const int bookmarkId, QIcon ¤tWebsiteFavoriteIcon) : QDialog(nullptr), bookmarkDatabaseId(bookmarkId)
+EditBookmarkDialog::EditBookmarkDialog(const int databaseId, QIcon ¤tWebsiteFavoriteIcon) : QDialog(nullptr), bookmarkDatabaseId(databaseId)
{
// 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.
+ // Instantiate the edit bookmark dialog UI.
Ui::EditBookmarkDialog editBookmarkDialogUi;
// Setup the UI.
// Get handles for the widgets.
currentFavoriteIconRadioButtonPointer = editBookmarkDialogUi.currentFavoriteIconRadioButton;
- currentWebsiteFavoritIconRadioButtonPointer = editBookmarkDialogUi.currentWebsiteFavoriteIconRadioButton;
+ currentWebsiteFavoriteIconRadioButtonPointer = editBookmarkDialogUi.currentWebsiteFavoriteIconRadioButton;
customFavoriteIconRadioButtonPointer = editBookmarkDialogUi.customFavoriteIconRadioButton;
- bookmarkNamePointer = editBookmarkDialogUi.bookmarkNameLineEdit;
- bookmarkUrlPointer = editBookmarkDialogUi.bookmarkUrlLineEdit;
+ parentFolderTreeWidgetPointer = editBookmarkDialogUi.parentFolderTreeWidget;
+ bookmarkNameLineEditPointer = editBookmarkDialogUi.bookmarkNameLineEdit;
+ bookmarkUrlLineEditPointer = editBookmarkDialogUi.bookmarkUrlLineEdit;
QPushButton *browseButtonPointer = editBookmarkDialogUi.browseButton;
QDialogButtonBox *dialogButtonBoxPointer = editBookmarkDialogUi.dialogButtonBox;
+ saveButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Save);
// Get the bookmark struct.
- bookmarkStructPointer = BookmarksDatabase::getBookmark(bookmarkId);
+ bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
// Set the favorite icons.
currentFavoriteIconRadioButtonPointer->setIcon(bookmarkStructPointer->favoriteIcon);
- currentWebsiteFavoritIconRadioButtonPointer->setIcon(currentWebsiteFavoriteIcon);
+ currentWebsiteFavoriteIconRadioButtonPointer->setIcon(currentWebsiteFavoriteIcon);
+
+ // Instantiate a folder helper.
+ folderHelperPointer = new FolderHelper();
+
+ // Set the parent folder tree widget column count.
+ parentFolderTreeWidgetPointer->setColumnCount(2);
+
+ // Hide the second column.
+ parentFolderTreeWidgetPointer->hideColumn(folderHelperPointer->FOLDER_ID_COLUMN);
+
+ // Set the column header.
+ parentFolderTreeWidgetPointer->setHeaderLabel(i18nc("The folder tree widget header", "Select Parent Folder"));
+
+ // Create a bookmarks tree widget item.
+ QTreeWidgetItem *bookmarksTreeWidgetItemPointer = new QTreeWidgetItem();
+
+ // Populate the bookmarks tree widget item.
+ bookmarksTreeWidgetItemPointer->setText(folderHelperPointer->FOLDER_NAME_COLUMN, i18nc("The bookmarks root tree widget name", "Bookmarks"));
+ bookmarksTreeWidgetItemPointer->setIcon(folderHelperPointer->FOLDER_NAME_COLUMN, QIcon::fromTheme("bookmarks"));
+ bookmarksTreeWidgetItemPointer->setText(folderHelperPointer->FOLDER_ID_COLUMN, QLatin1String("0"));
+
+ // Add the bookmarks tree widget item to the root of the tree.
+ parentFolderTreeWidgetPointer->addTopLevelItem(bookmarksTreeWidgetItemPointer);
+
+ // Select the root bookmarks folder if it is the initial parent folder.
+ if (bookmarkStructPointer->parentFolderId == 0)
+ bookmarksTreeWidgetItemPointer->setSelected(true);
+
+ // Populate the subfolders.
+ folderHelperPointer->populateSubfolders(bookmarksTreeWidgetItemPointer, bookmarkStructPointer->parentFolderId);
+
+ // Open all the folders.
+ parentFolderTreeWidgetPointer->expandAll();
// Populate the line edits.
- bookmarkNamePointer->setText(bookmarkStructPointer->bookmarkName);
- bookmarkUrlPointer->setText(bookmarkStructPointer->bookmarkUrl);
+ bookmarkNameLineEditPointer->setText(bookmarkStructPointer->name);
+ bookmarkUrlLineEditPointer->setText(bookmarkStructPointer->url);
// Scroll to the beginning of the line edits.
- bookmarkNamePointer->setCursorPosition(0);
- bookmarkUrlPointer->setCursorPosition(0);
+ bookmarkNameLineEditPointer->setCursorPosition(0);
+ bookmarkUrlLineEditPointer->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()));
+
+ // Update the UI when the line edits change.
+ connect(bookmarkNameLineEditPointer, SIGNAL(textEdited(const QString&)), this, SLOT(updateUi()));
+ connect(bookmarkUrlLineEditPointer, SIGNAL(textEdited(const QString&)), this, SLOT(updateUi()));
+
+ // Set the initial UI status.
+ updateUi();
}
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 (*)"));
+ QString imageFileString = QFileDialog::getOpenFileName(this, i18nc("The browse for favorite icon dialog header", "Favorite Icon Image"), QDir::homePath(),
+ i18nc("The browse for image files filter", "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())
void EditBookmarkDialog::save()
{
+ // Get the selected folders list.
+ QList<QTreeWidgetItem*> selectedFoldersList = parentFolderTreeWidgetPointer->selectedItems();
+
+ // Get the selected folder.
+ QTreeWidgetItem *selectedFolderPointer = selectedFoldersList.first();
+
+ // Get the parent folder ID.
+ double parentFolderId = selectedFolderPointer->text(folderHelperPointer->FOLDER_ID_COLUMN).toDouble();
+
+ // Get the original display order.
+ int displayOrder = bookmarkStructPointer->displayOrder;
+
+ // Get the new display order if the parent folder has changed.
+ if (parentFolderId != bookmarkStructPointer->parentFolderId)
+ displayOrder = BookmarksDatabase::getFolderItemCount(parentFolderId);
+
// 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 if (currentWebsiteFavoriteIconRadioButtonPointer->isChecked()) // The current website favorite icon is checked.
+ favoriteIcon = currentWebsiteFavoriteIconRadioButtonPointer->icon();
else // The custom favorite icon is checked.
favoriteIcon = customFavoriteIconRadioButtonPointer->icon();
- qDebug() << "Favorite icon: " << favoriteIcon;
-
// Create a bookmark struct.
- BookmarkStruct *bookmarkStructPointer = new BookmarkStruct;
+ BookmarkStruct *updatedBookmarkStructPointer = new BookmarkStruct;
// Populate the bookmark struct.
- bookmarkStructPointer->id = bookmarkDatabaseId;
- bookmarkStructPointer->bookmarkName = bookmarkNamePointer->text();
- bookmarkStructPointer->bookmarkUrl = bookmarkUrlPointer->text();
- bookmarkStructPointer->displayOrder = bookmarkStructPointer->displayOrder;
- bookmarkStructPointer->favoriteIcon = favoriteIcon;
+ updatedBookmarkStructPointer->databaseId = bookmarkDatabaseId;
+ updatedBookmarkStructPointer->name = bookmarkNameLineEditPointer->text();
+ updatedBookmarkStructPointer->url = bookmarkUrlLineEditPointer->text();
+ updatedBookmarkStructPointer->parentFolderId = parentFolderId;
+ updatedBookmarkStructPointer->displayOrder = displayOrder;
+ updatedBookmarkStructPointer->favoriteIcon = favoriteIcon;
// Update the bookmark.
- BookmarksDatabase::updateBookmark(bookmarkStructPointer);
+ BookmarksDatabase::updateBookmark(updatedBookmarkStructPointer);
+
+ // Update the display order of all the items in the previous folder.
+ BookmarksDatabase::updateFolderContentsDisplayOrder(bookmarkStructPointer->parentFolderId);
// Emit the bookmark saved signal.
emit bookmarkSaved();
// Close the dialog.
close();
}
+
+void EditBookmarkDialog::updateUi()
+{
+ // Determine if both line edits are populated.
+ if (bookmarkNameLineEditPointer->text().isEmpty() || bookmarkUrlLineEditPointer->text().isEmpty()) // At least one of the line edits is empty.
+ {
+ // Disable the save button.
+ saveButtonPointer->setEnabled(false);
+ }
+ else // Both of the line edits are populated.
+ {
+ // Enable the save button.
+ saveButtonPointer->setEnabled(true);
+ }
+}
#define EDITBOOKMARKDIALOG_H
// Application headers.
+#include "helpers/FolderHelper.h"
#include "structs/BookmarkStruct.h"
// Qt toolkit headers.
public:
// The primary constructor.
- explicit EditBookmarkDialog(const int bookmarkId, QIcon ¤tWebsiteFavoriteIcon);
+ explicit EditBookmarkDialog(const int databaseId, QIcon ¤tWebsiteFavoriteIcon);
signals:
// The signals.
// The private slots.
void browse();
void save();
+ void updateUi();
private:
+ // The private variables.
+ FolderHelper *folderHelperPointer;
+
// The private widgets.
int bookmarkDatabaseId;
- QLineEdit *bookmarkNamePointer;
+ QLineEdit *bookmarkNameLineEditPointer;
BookmarkStruct *bookmarkStructPointer;
- QLineEdit *bookmarkUrlPointer;
+ QLineEdit *bookmarkUrlLineEditPointer;
QRadioButton *currentFavoriteIconRadioButtonPointer;
- QRadioButton *currentWebsiteFavoritIconRadioButtonPointer;
+ QRadioButton *currentWebsiteFavoriteIconRadioButtonPointer;
QRadioButton *customFavoriteIconRadioButtonPointer;
+ QTreeWidget *parentFolderTreeWidgetPointer;
+ QPushButton *saveButtonPointer;
};
#endif
--- /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 "EditFolderDialog.h"
+#include "ui_EditFolderDialog.h"
+#include "databases/BookmarksDatabase.h"
+
+// Qt toolkit headers.
+#include <QFileDialog>
+
+// Construct the class.
+EditFolderDialog::EditFolderDialog(const int databaseId, QIcon ¤tWebsiteFavoriteIcon) : QDialog(nullptr), folderDatabaseId(databaseId)
+{
+ // Set the window title.
+ setWindowTitle(i18nc("The edit folder dialog window title.", "Edit Folder"));
+
+ // Set the window modality.
+ setWindowModality(Qt::WindowModality::ApplicationModal);
+
+ // Instantiate the edit folder dialog UI.
+ Ui::EditFolderDialog editFolderDialogUi;
+
+ // Setup the UI.
+ editFolderDialogUi.setupUi(this);
+
+ // Get handles for the widgets.
+ currentFolderIconRadioButtonPointer = editFolderDialogUi.currentFolderIconRadioButton;
+ currentWebsiteFavoriteIconRadioButtonPointer = editFolderDialogUi.currentWebsiteFavoriteIconRadioButton;
+ customFolderIconRadioButtonPointer = editFolderDialogUi.customFolderIconRadioButton;
+ parentFolderTreeWidgetPointer = editFolderDialogUi.parentFolderTreeWidget;
+ folderNameLineEditPointer = editFolderDialogUi.folderNameLineEdit;
+ QPushButton *browseButtonPointer = editFolderDialogUi.browseButton;
+ QDialogButtonBox *dialogButtonBoxPointer = editFolderDialogUi.dialogButtonBox;
+ saveButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Save);
+
+ // Get the bookmark struct.
+ bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
+
+ // Set the folder icons.
+ currentFolderIconRadioButtonPointer->setIcon(bookmarkStructPointer->favoriteIcon);
+ currentWebsiteFavoriteIconRadioButtonPointer->setIcon(currentWebsiteFavoriteIcon);
+
+ // Instantiate a folder helper.
+ folderHelperPointer = new FolderHelper();
+
+ // Set the parent folder tree widget column count.
+ parentFolderTreeWidgetPointer->setColumnCount(2);
+
+ // Hide the second column.
+ parentFolderTreeWidgetPointer->hideColumn(folderHelperPointer->FOLDER_ID_COLUMN);
+
+ // Set the column header.
+ parentFolderTreeWidgetPointer->setHeaderLabel(i18nc("The folder tree widget header", "Select Parent Folder"));
+
+ // Create a bookmarks tree widget item.
+ QTreeWidgetItem *bookmarksTreeWidgetItemPointer = new QTreeWidgetItem();
+
+ // Populate the bookmarks tree widget item.
+ bookmarksTreeWidgetItemPointer->setText(folderHelperPointer->FOLDER_NAME_COLUMN, i18nc("The bookmarks root tree widget name", "Bookmarks"));
+ bookmarksTreeWidgetItemPointer->setIcon(folderHelperPointer->FOLDER_NAME_COLUMN, QIcon::fromTheme("bookmarks"));
+ bookmarksTreeWidgetItemPointer->setText(folderHelperPointer->FOLDER_ID_COLUMN, QLatin1String("0"));
+
+ // Add the bookmarks tree widget item to the root of the tree.
+ parentFolderTreeWidgetPointer->addTopLevelItem(bookmarksTreeWidgetItemPointer);
+
+ // Select the root bookmarks folder if it is the initial parent folder.
+ if (bookmarkStructPointer->parentFolderId == 0)
+ bookmarksTreeWidgetItemPointer->setSelected(true);
+
+ // Populate the subfolders, except for the one being edited.
+ folderHelperPointer->populateSubfoldersExcept(databaseId, bookmarksTreeWidgetItemPointer, bookmarkStructPointer->parentFolderId);
+
+ // Open all the folders.
+ parentFolderTreeWidgetPointer->expandAll();
+
+ // Populate the line edits.
+ folderNameLineEditPointer->setText(bookmarkStructPointer->name);
+
+ // Scroll to the beginning of the line edits.
+ folderNameLineEditPointer->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()));
+
+ // Update the UI when the line edit changes.
+ connect(folderNameLineEditPointer, SIGNAL(textEdited(const QString&)), this, SLOT(updateUi()));
+
+ // Set the initial UI status.
+ updateUi();
+}
+
+void EditFolderDialog::browse()
+{
+ // Get an image file string from the user.
+ QString imageFileString = QFileDialog::getOpenFileName(this, i18nc("The browse for folder icon dialog header", "Folder Icon Image"), QDir::homePath(),
+ i18nc("The browse for image files filter", "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 folder icon.
+ customFolderIconRadioButtonPointer->setIcon(QIcon(imageFileString));
+
+ // Check the custom folder icon radio button.
+ customFolderIconRadioButtonPointer->setChecked(true);
+ }
+}
+
+void EditFolderDialog::save()
+{
+ // Get the selected folders list.
+ QList<QTreeWidgetItem*> selectedFoldersList = parentFolderTreeWidgetPointer->selectedItems();
+
+ // Get the selected folder.
+ QTreeWidgetItem *selectedFolderPointer = selectedFoldersList.first();
+
+ // Get the parent folder ID.
+ double parentFolderId = selectedFolderPointer->text(folderHelperPointer->FOLDER_ID_COLUMN).toDouble();
+
+ // Get the original display order.
+ int displayOrder = bookmarkStructPointer->displayOrder;
+
+ // Get the new display order if the parent folder has changed.
+ if (parentFolderId != bookmarkStructPointer->parentFolderId)
+ displayOrder = BookmarksDatabase::getFolderItemCount(parentFolderId);
+
+ // Create a favorite icon.
+ QIcon favoriteIcon;
+
+ // Get the favorite icon.
+ if (currentFolderIconRadioButtonPointer->isChecked()) // The current folder icon is checked.
+ favoriteIcon = currentFolderIconRadioButtonPointer->icon();
+ else if (currentWebsiteFavoriteIconRadioButtonPointer->isChecked()) // The current website favorite icon is checked.
+ favoriteIcon = currentWebsiteFavoriteIconRadioButtonPointer->icon();
+ else // The custom favorite icon is checked.
+ favoriteIcon = customFolderIconRadioButtonPointer->icon();
+
+ // Create a bookmark struct.
+ BookmarkStruct *updatedBookmarkStructPointer = new BookmarkStruct;
+
+ // Populate the bookmark struct.
+ updatedBookmarkStructPointer->databaseId = folderDatabaseId;
+ updatedBookmarkStructPointer->name = folderNameLineEditPointer->text();
+ updatedBookmarkStructPointer->parentFolderId = parentFolderId;
+ updatedBookmarkStructPointer->displayOrder = displayOrder;
+ updatedBookmarkStructPointer->favoriteIcon = favoriteIcon;
+
+ // Update the folder.
+ BookmarksDatabase::updateBookmark(updatedBookmarkStructPointer);
+
+ // Update the display order of all the items in the previous folder.
+ BookmarksDatabase::updateFolderContentsDisplayOrder(bookmarkStructPointer->parentFolderId);
+
+ // Emit the folder saved signal.
+ emit folderSaved();
+
+ // Close the dialog.
+ close();
+}
+
+void EditFolderDialog::updateUi()
+{
+ // Set the status of the save button.
+ saveButtonPointer->setEnabled(!folderNameLineEditPointer->text().isEmpty());
+}
--- /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 EDITFOLDERDIALOG_H
+#define EDITFOLDERDIALOG_H
+
+// Application headers.
+#include "helpers/FolderHelper.h"
+#include "structs/BookmarkStruct.h"
+
+// Qt toolkit headers.
+#include <QDialog>
+#include <QRadioButton>
+
+class EditFolderDialog : public QDialog
+{
+ // Include the Q_OBJECT macro.
+ Q_OBJECT
+
+public:
+ // The primary constructor.
+ explicit EditFolderDialog(const int databaseId, QIcon ¤tWebsiteFavoriteIcon);
+
+signals:
+ // The signals.
+ void folderSaved() const;
+
+private Q_SLOTS:
+ // The private slots.
+ void browse();
+ void save();
+ void updateUi();
+
+private:
+ // The private variables.
+ FolderHelper *folderHelperPointer;
+
+ // The private widgets.
+ BookmarkStruct *bookmarkStructPointer;
+ QRadioButton *currentFolderIconRadioButtonPointer;
+ QRadioButton *currentWebsiteFavoriteIconRadioButtonPointer;
+ QRadioButton *customFolderIconRadioButtonPointer;
+ int folderDatabaseId;
+ QLineEdit *folderNameLineEditPointer;
+ QTreeWidget *parentFolderTreeWidgetPointer;
+ QPushButton *saveButtonPointer;
+};
+#endif
# List the sources to include in the executable.
target_sources(privacybrowser PRIVATE
+ FolderHelper.cpp
SearchEngineHelper.cpp
UserAgentHelper.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 "FolderHelper.h"
+#include "databases/BookmarksDatabase.h"
+#include "structs/BookmarkStruct.h"
+
+// Construct the class.
+FolderHelper::FolderHelper() {}
+
+void FolderHelper::populateSubfolders(QTreeWidgetItem *treeWidgetItemPointer, const double initialParentFolderId)
+{
+ // Get the list of subfolders.
+ QList<BookmarkStruct> *subfoldersList = BookmarksDatabase::getSubfolders(treeWidgetItemPointer->text(FOLDER_ID_COLUMN).toDouble());
+
+ // Populate each subfolder.
+ for (BookmarkStruct bookmarkStruct : *subfoldersList)
+ {
+ // Create a tree widget item.
+ QTreeWidgetItem *subfolderWidgetItemPointer = new QTreeWidgetItem();
+
+ // Populate the tree widget item.
+ subfolderWidgetItemPointer->setText(FOLDER_NAME_COLUMN, bookmarkStruct.name);
+ subfolderWidgetItemPointer->setIcon(FOLDER_NAME_COLUMN, bookmarkStruct.favoriteIcon);
+ subfolderWidgetItemPointer->setText(FOLDER_ID_COLUMN, QString::number(bookmarkStruct.folderId, 'f', 0)); // Format the folder ID as a floating point with no trailing zeros.
+
+ // Add the subfolder to the tree widget item.
+ treeWidgetItemPointer->addChild(subfolderWidgetItemPointer);
+
+ // Select the folder if it is the initial parent folder.
+ if (bookmarkStruct.folderId == initialParentFolderId)
+ subfolderWidgetItemPointer->setSelected(true);
+
+ // Add any subfolders.
+ populateSubfolders(subfolderWidgetItemPointer, initialParentFolderId);
+ }
+}
+
+void FolderHelper::populateSubfoldersExcept(const double exceptSubfolderDatabaseId, QTreeWidgetItem *treeWidgetItemPointer, const double initialParentFolderId)
+{
+ // Get the list of subfolders.
+ QList<BookmarkStruct> *subfoldersList = BookmarksDatabase::getSubfolders(treeWidgetItemPointer->text(FOLDER_ID_COLUMN).toDouble());
+
+ // Populate each subfolder.
+ for (BookmarkStruct bookmarkStruct : *subfoldersList)
+ {
+ // Only populate the subfolder if it is not excepted.
+ if (bookmarkStruct.databaseId != exceptSubfolderDatabaseId)
+ {
+ // Create a tree widget item.
+ QTreeWidgetItem *subfolderWidgetItemPointer = new QTreeWidgetItem();
+
+ // Populate the tree widget item.
+ subfolderWidgetItemPointer->setText(FOLDER_NAME_COLUMN, bookmarkStruct.name);
+ subfolderWidgetItemPointer->setIcon(FOLDER_NAME_COLUMN, bookmarkStruct.favoriteIcon);
+ subfolderWidgetItemPointer->setText(FOLDER_ID_COLUMN, QString::number(bookmarkStruct.folderId, 'f', 0)); // Format the folder ID as a floating point with no trailing zeros.
+
+ // Add the subfolder to the tree widget item.
+ treeWidgetItemPointer->addChild(subfolderWidgetItemPointer);
+
+ // Select the folder if it is the initial parent folder.
+ if (bookmarkStruct.folderId == initialParentFolderId)
+ subfolderWidgetItemPointer->setSelected(true);
+
+ // Add any subfolders.
+ populateSubfoldersExcept(exceptSubfolderDatabaseId, subfolderWidgetItemPointer, initialParentFolderId);
+ }
+ }
+}
--- /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 FOLDERHELPER_H
+#define FOLDERHELPER_H
+
+// Qt toolkit headers.
+#include <QTreeWidgetItem>
+
+class FolderHelper
+{
+public:
+ // The default constructor.
+ explicit FolderHelper();
+
+ // The public constants.
+ const int FOLDER_NAME_COLUMN = 0;
+ const int FOLDER_ID_COLUMN = 1;
+
+ // The public functions.
+ void populateSubfolders(QTreeWidgetItem *treeWidgetItemPointer, const double initialParentFolderId);
+ void populateSubfoldersExcept(const double exceptSubfolderDatabaseId, QTreeWidgetItem *treeWidgetItemPointer, const double initialParentFolderId);
+};
+#endif
// KDE Frameworks headers.
#include <KAboutData>
#include <KCrash>
-#include <KLocalizedString>
#include <KDBusService>
+#include <KLocalizedString>
// Qt headers.
#include <QApplication>
struct BookmarkStruct
{
- int id;
- QString bookmarkName;
- QString bookmarkUrl;
+ int databaseId;
+ QString name;
+ QString url;
+ double parentFolderId;
int displayOrder;
+ bool isFolder;
+ double folderId;
QIcon favoriteIcon;
};
#endif
<!-- Bookmarks. -->
<Menu name="bookmarks">
+ <Action name="add_folder" />
+
+ <Separator />
+
<Action name="view_bookmarks_toolbar" />
<Separator />
</property>
</widget>
</item>
+
+ <!-- Spacer. -->
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </spacer>
+ </item>
</layout>
</item>
- <!-- Name and URL column. -->
+ <!-- Parent folder, name and URL column. -->
<item>
<layout class="QVBoxLayout">
<!-- First row. -->
<property name="alignment">
<enum>Qt::AlignLeft</enum>
</property>
+
+ <!-- Parent folder. -->
+ <item>
+ <widget class="QTreeWidget" name="parentFolderTreeWidget">
+ <property name="minimumSize">
+ <size>
+ <width>1000</width>
+ <height>700</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+
+ <!-- Second row. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="alignment">
+ <enum>Qt::AlignLeft</enum>
+ </property>
+
<!-- Bookmark name. -->
<item>
<widget class="QLabel">
</layout>
</item>
- <!-- Second row. -->
+ <!-- Third row. -->
<item>
<layout class="QHBoxLayout">
<property name="alignment">
<enum>Qt::AlignLeft</enum>
</property>
+
<!-- Bookmark URL. -->
<item>
<widget class="QLabel">
</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>
+ <widget class="QLineEdit" name="bookmarkUrlLineEdit" />
</item>
</layout>
</item>
</layout>
</item>
- <!-- Spacer. -->
- <item>
- <spacer>
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- </spacer>
- </item>
-
<!-- Buttons. -->
<item>
<layout class="QHBoxLayout">
--- /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>AddFolderDialog</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 folder icon. -->
+ <item>
+ <widget class="QRadioButton" name="defaultFolderIconRadioButton">
+ <property name="text">
+ <string>Default folder icon</string>
+ </property>
+
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+
+ <property name="icon">
+ <iconset theme="folder"/>
+ </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 folder icon. -->
+ <item>
+ <widget class="QRadioButton" name="customFolderIconRadioButton">
+ <property name="text">
+ <string>Custom folder icon</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="folder-symbolic"/>
+ </property>
+
+ <property name="iconSize">
+ <size>
+ <height>32</height>
+ <width>32</width>
+ </size>
+ </property>
+ </widget>
+ </item>
+
+ <!-- Spacer. -->
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+
+ <!-- Parent folder and name column. -->
+ <item>
+ <layout class="QVBoxLayout">
+ <!-- First row. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="alignment">
+ <enum>Qt::AlignLeft</enum>
+ </property>
+
+ <!-- Parent folder. -->
+ <item>
+ <widget class="QTreeWidget" name="parentFolderTreeWidget">
+ <property name="minimumSize">
+ <size>
+ <width>1000</width>
+ <height>700</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+
+ <!-- Second row. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="alignment">
+ <enum>Qt::AlignLeft</enum>
+ </property>
+
+ <!-- Folder name. -->
+ <item>
+ <widget class="QLabel">
+ <property name="toolTip">
+ <string>The folder name.</string>
+ </property>
+
+ <property name="text">
+ <string>Folder name</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="folderNameLineEdit" />
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </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>
+ </widget>
+</ui>
</widget>
</item>
+ <!-- Add folder button. -->
+ <item>
+ <widget class="QPushButton" name="addFolderButton">
+ <property name="text">
+ <string>Add folder</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="folder-add" />
+ </property>
+ </widget>
+ </item>
+
<!-- Edit button. -->
<item>
<widget class="QPushButton" name="editButton">
</property>
</widget>
</item>
+
+ <!-- Spacer. -->
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </spacer>
+ </item>
</layout>
</item>
- <!-- Name and URL column. -->
+ <!-- Parent folder, name and URL column. -->
<item>
<layout class="QVBoxLayout">
<!-- First row. -->
<property name="alignment">
<enum>Qt::AlignLeft</enum>
</property>
+
+ <!-- Parent folder. -->
+ <item>
+ <widget class="QTreeWidget" name="parentFolderTreeWidget">
+ <property name="minimumSize">
+ <size>
+ <width>1000</width>
+ <height>700</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+
+ <!-- Second row. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="alignment">
+ <enum>Qt::AlignLeft</enum>
+ </property>
+
<!-- Bookmark name. -->
<item>
<widget class="QLabel">
<property name="alignment">
<enum>Qt::AlignLeft</enum>
</property>
+
<!-- Bookmark URL. -->
<item>
<widget class="QLabel">
</layout>
</item>
- <!-- Spacer. -->
- <item>
- <spacer>
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- </spacer>
- </item>
-
<!-- Buttons. -->
<item>
<layout class="QHBoxLayout">
--- /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>EditFolderDialog</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 folder icon. -->
+ <item>
+ <widget class="QRadioButton" name="currentFolderIconRadioButton">
+ <property name="text">
+ <string>Default folder 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 folder icon. -->
+ <item>
+ <widget class="QRadioButton" name="customFolderIconRadioButton">
+ <property name="text">
+ <string>Custom folder icon</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="folder-symbolic"/>
+ </property>
+
+ <property name="iconSize">
+ <size>
+ <height>32</height>
+ <width>32</width>
+ </size>
+ </property>
+ </widget>
+ </item>
+
+ <!-- Spacer. -->
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+
+ <!-- Parent folder and name column. -->
+ <item>
+ <layout class="QVBoxLayout">
+ <!-- First row. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="alignment">
+ <enum>Qt::AlignLeft</enum>
+ </property>
+
+ <!-- Parent folder. -->
+ <item>
+ <widget class="QTreeWidget" name="parentFolderTreeWidget">
+ <property name="minimumSize">
+ <size>
+ <width>1000</width>
+ <height>700</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+
+ <!-- Second row. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="alignment">
+ <enum>Qt::AlignLeft</enum>
+ </property>
+
+ <!-- Folder name. -->
+ <item>
+ <widget class="QLabel">
+ <property name="toolTip">
+ <string>The folder name.</string>
+ </property>
+
+ <property name="text">
+ <string>Folder name</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="folderNameLineEdit" />
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </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>
// 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>;
+ // Create a list of selected database IDs.
+ QList<int> *selectedDatabaseIdsListPointer = new QList<int>;
- // Populate the list of moving database IDs.
+ // Populate the list of selected 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());
+ if (modelIndex.column() == BookmarksDialog::NAME_COLUMN)
+ selectedDatabaseIdsListPointer->append(modelIndex.siblingAtColumn(BookmarksDialog::DATABASE_ID_COLUMN).data().toInt());
}
+ // Get a list of root selected database IDs.
+ QList<int> *rootSelectedDatabaseIdsListPointer = getRootSelectedDatabaseIds(selectedDatabaseIdsListPointer);
+
// 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();
+ // Create a previous parent folder ID standard C++ list (which can be sorted and from which duplicates can be removed).
+ std::list<double> previousParentFolderIdList;
// Process the move according to the drop position.
switch (dropPosition)
{
case QAbstractItemView::OnItem:
- // TODO Implement for moving into a folder.
+ {
+ // Get the new parent folder ID.
+ double newParentFolderId = dropModelIndex.siblingAtColumn(BookmarksDialog::FOLDER_ID_COLUMN).data().toDouble();
+
+ // Get a list of all the items in the target folder except those selected.
+ QList<BookmarkStruct> *itemsInFolderExceptSelectedListPointer = BookmarksDatabase::getBookmarksInFolderExcept(newParentFolderId, selectedDatabaseIdsListPointer);
+
+ // Initialize a new display order tracker.
+ int newDisplayOrder = 0;
+
+ // Move all the items to the top of the target folder.
+ for (const int databaseId : *rootSelectedDatabaseIdsListPointer)
+ {
+ // Get the item's current parent folder ID.
+ double currentParentFolderId = BookmarksDatabase::getParentFolderId(databaseId);
+
+ // Add the parent folder ID to the list of previous parent folders if the item is from a different folder.
+ if (currentParentFolderId != newParentFolderId)
+ previousParentFolderIdList.push_back(currentParentFolderId);
+
+ // Update the parent folder and display order for each bookmark.
+ BookmarksDatabase::updateParentFolderAndDisplayOrder(databaseId, newParentFolderId, newDisplayOrder);
+
+ // Increment the new display order.
+ ++newDisplayOrder;
+ }
+
+ // Update the display order of the existing items in the folder.
+ for (const BookmarkStruct &bookmarkStruct : *itemsInFolderExceptSelectedListPointer)
+ {
+ // Set the bookmark's display order if it has changed.
+ if (bookmarkStruct.displayOrder != newDisplayOrder)
+ BookmarksDatabase::updateDisplayOrder(bookmarkStruct.databaseId, newDisplayOrder);
+
+ // Increment the new display order.
+ ++newDisplayOrder;
+ }
break;
+ }
case QAbstractItemView::AboveItem:
{
- // Get a list of all the bookmarks except those selected.
- QList<BookmarkStruct> *bookmarksExceptSelectedListPointer = BookmarksDatabase::getBookmarksExcept(databaseIdsMovingListPointer);
+ // Get the drop display order.
+ int dropDisplayOrder = dropModelIndex.siblingAtColumn(BookmarksDialog::DISPLAY_ORDER_COLUMN).data().toInt();
+
+ // Get the drop parent folder ID.
+ double dropParentFolderId = dropModelIndex.parent().siblingAtColumn(BookmarksDialog::FOLDER_ID_COLUMN).data().toInt();
+
+ // Get a list of all the items in the target folder except those selected.
+ QList<BookmarkStruct> *itemsInFolderExceptSelectedListPointer = BookmarksDatabase::getBookmarksInFolderExcept(dropParentFolderId, selectedDatabaseIdsListPointer);
// Initialize a new display order tracker.
int newDisplayOrder = 0;
- // Move the bookmarks.
- for (const BookmarkStruct &bookmarkStruct : *bookmarksExceptSelectedListPointer)
+ // Process all the items in the target folder, moving in the new ones.
+ for (const BookmarkStruct &bookmarkStruct : *itemsInFolderExceptSelectedListPointer)
{
// 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)
+ for (const int databaseId : *rootSelectedDatabaseIdsListPointer)
{
- // Update the display order for each bookmark.
- BookmarksDatabase::updateDisplayOrder(databaseId, newDisplayOrder);
+ // Get the item's current parent folder ID.
+ double currentParentFolderId = BookmarksDatabase::getParentFolderId(databaseId);
+
+ // Add the parent folder ID to the list of previous parent folders if the item is from a different folder.
+ if (currentParentFolderId != dropParentFolderId)
+ previousParentFolderIdList.push_back(currentParentFolderId);
+
+ // Update the parent folder and display order for each bookmark.
+ BookmarksDatabase::updateParentFolderAndDisplayOrder(databaseId, dropParentFolderId, 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);
+ BookmarksDatabase::updateDisplayOrder(bookmarkStruct.databaseId, 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);
+ // Get the drop display order.
+ int dropDisplayOrder = dropModelIndex.siblingAtColumn(BookmarksDialog::DISPLAY_ORDER_COLUMN).data().toInt();
+
+ // Get the drop parent folder ID.
+ double dropParentFolderId = dropModelIndex.parent().siblingAtColumn(BookmarksDialog::FOLDER_ID_COLUMN).data().toInt();
+
+ // Get a list of all the items in the target folder except those selected.
+ QList<BookmarkStruct> *itemsInFolderExceptSelectedListPointer = BookmarksDatabase::getBookmarksInFolderExcept(dropParentFolderId, selectedDatabaseIdsListPointer);
// Initialize a new display order tracker.
int newDisplayOrder = 0;
- // Move the bookmarks.
- for (const BookmarkStruct &bookmarkStruct : *bookmarksExceptSelectedListPointer)
+ // Process all the items in the target folder, moving in the new ones.
+ for (const BookmarkStruct &bookmarkStruct : *itemsInFolderExceptSelectedListPointer)
{
// Set the bookmark's display order if it has changed.
if (bookmarkStruct.displayOrder != newDisplayOrder)
- BookmarksDatabase::updateDisplayOrder(bookmarkStruct.id, newDisplayOrder);
+ BookmarksDatabase::updateDisplayOrder(bookmarkStruct.databaseId, newDisplayOrder);
// Increment the new display order.
++newDisplayOrder;
if (bookmarkStruct.displayOrder == dropDisplayOrder)
{
// Add all of the bookmarks being moved to this point.
- for (const int databaseId : *databaseIdsMovingListPointer)
+ for (const int databaseId : *rootSelectedDatabaseIdsListPointer)
{
- // Update the display order for each bookmark.
- BookmarksDatabase::updateDisplayOrder(databaseId, newDisplayOrder);
+ // Get the item's current parent folder ID.
+ double currentParentFolderId = BookmarksDatabase::getParentFolderId(databaseId);
+
+ // Add the parent folder ID to the list of previous parent folders if the item is from a different folder.
+ if (currentParentFolderId != dropParentFolderId)
+ previousParentFolderIdList.push_back(currentParentFolderId);
+
+ // Update the parent folder and display order for each bookmark.
+ BookmarksDatabase::updateParentFolderAndDisplayOrder(databaseId, dropParentFolderId, newDisplayOrder);
// Increment the new display order.
++newDisplayOrder;
}
}
}
-
break;
}
case QAbstractItemView::OnViewport:
+ {
+ // Get the drop parent folder ID.
+ double dropParentFolderId = 0;
- // Get a list of all the bookmarks except those selected.
- QList<BookmarkStruct> *bookmarksExceptSelectedListPointer = BookmarksDatabase::getBookmarksExcept(databaseIdsMovingListPointer);
+ // Get a list of all the items in the root folder except those selected.
+ QList<BookmarkStruct> *itemsInFolderExceptSelectedListPointer = BookmarksDatabase::getBookmarksInFolderExcept(dropParentFolderId, selectedDatabaseIdsListPointer);
// Initialize a new display order tracker.
int newDisplayOrder = 0;
- // Move the bookmarks.
- for (const BookmarkStruct &bookmarkStruct : *bookmarksExceptSelectedListPointer)
+ // Update the display order of the existing items in the folder.
+ for (const BookmarkStruct &bookmarkStruct : *itemsInFolderExceptSelectedListPointer)
{
// Set the bookmark's display order if it has changed.
if (bookmarkStruct.displayOrder != newDisplayOrder)
- BookmarksDatabase::updateDisplayOrder(bookmarkStruct.id, newDisplayOrder);
+ BookmarksDatabase::updateDisplayOrder(bookmarkStruct.databaseId, 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)
+ for (const int databaseId : *rootSelectedDatabaseIdsListPointer)
{
- // Update the display order for each bookmark.
- BookmarksDatabase::updateDisplayOrder(databaseId, newDisplayOrder);
+ // Get the item's current parent folder ID.
+ double currentParentFolderId = BookmarksDatabase::getParentFolderId(databaseId);
+
+ // Add the parent folder ID to the list of previous parent folders if the item is from a different folder.
+ if (currentParentFolderId != dropParentFolderId)
+ previousParentFolderIdList.push_back(currentParentFolderId);
+
+ // Update the parent folder and display order for each bookmark.
+ BookmarksDatabase::updateParentFolderAndDisplayOrder(databaseId, dropParentFolderId, newDisplayOrder);
// Increment the new display order.
++newDisplayOrder;
}
break;
+ }
}
+ // Sort the previous parent folder ID list.
+ previousParentFolderIdList.sort();
+
+ // Remove duplicates from the parent folder ID list.
+ previousParentFolderIdList.unique();
+
+ // Update the folder contents display order for each previous parent folder.
+ for (const double parentFolderId : previousParentFolderIdList)
+ BookmarksDatabase::updateFolderContentsDisplayOrder(parentFolderId);
+
// Emit the bookmarks moved signal.
emit bookmarksMoved();
}
+
+QList<int>* DraggableTreeView::getRootSelectedDatabaseIds(QList<int> *selectedDatabaseIdsPointer) const
+{
+ // Create a list of the database IDs of the contents of each selected folder.
+ QList<int> selectedFoldersContentsDatabaseIds;
+
+ // Populate the list of the database IDs of the contents of each selected folder.
+ for (const int databaseId : *selectedDatabaseIdsPointer)
+ {
+ // If this is not the root item and is a folder, get the database IDs of the contents.
+ if ((databaseId != -1) && BookmarksDatabase::isFolder(databaseId))
+ selectedFoldersContentsDatabaseIds.append(*BookmarksDatabase::getFolderContentsDatabaseIds(BookmarksDatabase::getFolderId(databaseId)));
+ }
+
+ // Create a root selected database IDs list.
+ QList<int>* rootSelectedDatabaseIdsListPointer = new QList<int>;
+
+ // Populate the root selected database IDs list.
+ for (const int databaseId : *selectedDatabaseIdsPointer)
+ {
+ // Add the database ID to the root selected database IDs list if it isn't the root item and it isn't contained in the selected folder contents database IDs list.
+ if ((databaseId != -1) && !selectedFoldersContentsDatabaseIds.contains(databaseId))
+ rootSelectedDatabaseIdsListPointer->append(databaseId);
+ }
+
+ // Return the root selected database IDs list.
+ return rootSelectedDatabaseIdsListPointer;
+}
protected:
void dropEvent(QDropEvent *event) override;
+
+private:
+ QList<int>* getRootSelectedDatabaseIds(QList<int> *selectedDatabaseIdsPointer) const;
};
#endif
#include "ui_SettingsSpellCheck.h"
#include "databases/BookmarksDatabase.h"
#include "dialogs/AddBookmarkDialog.h"
+#include "dialogs/AddFolderDialog.h"
#include "dialogs/BookmarksDialog.h"
#include "dialogs/CookiesDialog.h"
#include "dialogs/DomainSettingsDialog.h"
#include "dialogs/EditBookmarkDialog.h"
+#include "dialogs/EditFolderDialog.h"
#include "helpers/SearchEngineHelper.h"
#include "helpers/UserAgentHelper.h"
#include "structs/BookmarkStruct.h"
#include <QInputDialog>
#include <QNetworkCookie>
#include <QMenuBar>
+#include <QMessageBox>
#include <QShortcut>
#include <QStatusBar>
#include <QWebEngineFindTextResult>
searchEngineBingActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_bing"));
searchEngineYahooActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_yahoo"));
searchEngineCustomActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_custom"));
+ QAction *addFolderPointer = actionCollectionPointer->addAction(QLatin1String("add_folder"));
viewBookmarksToolBarActionPointer = actionCollectionPointer->addAction(QLatin1String("view_bookmarks_toolbar"));
QAction *domainSettingsActionPointer = actionCollectionPointer->addAction(QLatin1String("domain_settings"));
cookiesActionPointer = actionCollectionPointer->addAction(QLatin1String("cookies"));
searchEngineGoogleActionPointer->setText(i18nc("Search engine", "Google"));
searchEngineBingActionPointer->setText(i18nc("Search engine", "Bing"));
searchEngineYahooActionPointer->setText(i18nc("Search engine", "Yahoo"));
+ addFolderPointer->setText(i18nc("Add folder", "Add Folder"));
viewBookmarksToolBarActionPointer->setText(i18nc("View bookmarks toolbar", "View Bookmarks Toolbar"));
domainSettingsActionPointer->setText(i18nc("Domain Settings action", "Domain Settings"));
cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", 0));
searchEngineYahooActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-yahoo"), QIcon::fromTheme(QLatin1String("edit-find"))));
searchEngineCustomActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
zoomFactorActionPointer->setIcon(QIcon::fromTheme(QLatin1String("zoom-fit-best")));
+ addFolderPointer->setIcon(QIcon::fromTheme(QLatin1String("folder-add")));
viewBookmarksToolBarActionPointer->setIcon(QIcon::fromTheme(QLatin1String("bookmarks")));
domainSettingsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("settings-configure"), QIcon::fromTheme(QLatin1String("preferences-desktop"))));
cookiesActionPointer->setIcon(QIcon::fromTheme(QLatin1String("preferences-web-browser-cookies"), QIcon::fromTheme(QLatin1String("appointment-new"))));
QKeySequence ctrlShiftYKeySequence = QKeySequence(i18nc("The Yahoo search engine key sequence.", "Ctrl+Shift+Y"));
QKeySequence ctrlShiftCKeySequence = QKeySequence(i18nc("The custom search engine key sequence.", "Ctrl+Shift+C"));
QKeySequence ctrlAltShiftBKeySequence = QKeySequence(i18nc("The edit bookmarks key sequence.", "Ctrl+Alt+Shift+B"));
+ QKeySequence altFKeySequence = QKeySequence(i18nc("The add folder key sequence.", "Alt+F"));
QKeySequence ctrlAltBKeySequence = QKeySequence(i18nc("The view bookmarks toolbar key sequence.", "Ctrl+Alt+B"));
QKeySequence ctrlShiftDKeySequence = QKeySequence(i18nc("The domain settings key sequence.", "Ctrl+Shift+D"));
QKeySequence ctrlSemicolonKeySequence = QKeySequence(i18nc("The cookies dialog key sequence.", "Ctrl+;"));
actionCollectionPointer->setDefaultShortcut(searchEngineYahooActionPointer, ctrlShiftYKeySequence);
actionCollectionPointer->setDefaultShortcut(searchEngineCustomActionPointer, ctrlShiftCKeySequence);
actionCollectionPointer->setDefaultShortcut(editBookmarksActionPointer, ctrlAltShiftBKeySequence);
+ actionCollectionPointer->setDefaultShortcut(addFolderPointer, altFKeySequence);
actionCollectionPointer->setDefaultShortcut(viewBookmarksToolBarActionPointer, ctrlAltBKeySequence);
actionCollectionPointer->setDefaultShortcut(domainSettingsActionPointer, ctrlShiftDKeySequence);
actionCollectionPointer->setDefaultShortcut(cookiesActionPointer, ctrlSemicolonKeySequence);
connect(viewSourceActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewSource()));
connect(viewSourceInNewTabActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewSourceInNewTab()));
connect(zoomFactorActionPointer, SIGNAL(triggered()), this, SLOT(getZoomFactorFromUser()));
+ connect(addFolderPointer, SIGNAL(triggered()), this, SLOT(showAddFolderDialog()));
connect(viewBookmarksToolBarActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewBookmarksToolBar()));
connect(cookiesActionPointer, SIGNAL(triggered()), this, SLOT(showCookiesDialog()));
connect(domainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(showDomainSettingsDialog()));
bookmarksMenuPointer->addSeparator();
// Initialize the current bookmarks lists.
- bookmarksMenuCurrentActionList = QList<QAction*>();
- bookmarksToolBarCurrentActionList = QList<QAction*>();
+ bookmarksMenuActionList = QList<QPair<QMenu *, QAction *> *>();
+ bookmarksMenuSubmenuList = QList<QPair<QMenu *, QMenu *> *>();
+ bookmarksToolBarActionList = QList<QAction*>();
+ bookmarksToolBarSubfolderActionList = QList<QPair<QMenu *, QAction * > *>();
// Set the bookmarks toolbar context menu policy.
bookmarksToolBarPointer->setContextMenuPolicy(Qt::CustomContextMenu);
void BrowserWindow::editBookmarks() const
{
// Instantiate an edit bookmarks dialog.
- BookmarksDialog *bookmarksDialogPointer = new BookmarksDialog(tabWidgetPointer->getCurrentTabFavoritIcon());
+ BookmarksDialog *bookmarksDialogPointer = new BookmarksDialog(tabWidgetPointer->getCurrentTabTitle(), tabWidgetPointer->getCurrentTabUrl(), tabWidgetPointer->getCurrentTabFavoritIcon());
// Update the displayed bookmarks when edited.
connect(bookmarksDialogPointer, SIGNAL(bookmarkUpdated()), this, SLOT(populateBookmarks()));
void BrowserWindow::populateBookmarks()
{
// Remove all the current menu bookmarks.
- for (QAction *bookmarkAction : bookmarksMenuCurrentActionList)
+ for (QPair<QMenu *, QAction *> *bookmarkPairPointer : bookmarksMenuActionList)
{
// Remove the bookmark.
- bookmarksMenuPointer->removeAction(bookmarkAction);
+ bookmarkPairPointer->first->removeAction(bookmarkPairPointer->second);
+ }
+
+ // Remove all the current menu subfolders.
+ for (QPair<QMenu *, QMenu *> *submenuPairPointer : bookmarksMenuSubmenuList)
+ {
+ // Remove the submenu from the parent menu.
+ submenuPairPointer->first->removeAction(submenuPairPointer->second->menuAction());
+ }
+
+ // Remove all the current toolbar subfolders.
+ for (QPair<QMenu *, QAction *> *subfolderPairPointer : bookmarksToolBarSubfolderActionList)
+ {
+ // Remove the action from the subfolder.
+ subfolderPairPointer->first->removeAction(subfolderPairPointer->second);
}
// Remove all the current toolbar bookmarks.
- for (QAction *bookmarkAction : bookmarksToolBarCurrentActionList)
+ for (QAction *bookmarkAction : bookmarksToolBarActionList)
{
// Remove the bookmark.
bookmarksToolBarPointer->removeAction(bookmarkAction);
}
// Clear the current bookmark lists.
- bookmarksMenuCurrentActionList.clear();
- bookmarksToolBarCurrentActionList.clear();
+ bookmarksMenuActionList.clear();
+ bookmarksMenuSubmenuList.clear();
+ bookmarksToolBarActionList.clear();
+ bookmarksToolBarSubfolderActionList.clear();
- // Get a list of the bookmarks.
- std::list<BookmarkStruct> *bookmarkListPointer = BookmarksDatabase::getBookmarks();
+ // Populate the bookmarks subfolders, beginning with the root folder (`0`);
+ populateBookmarksMenuSubfolders(0, bookmarksMenuPointer);
- // Populate the bookmarks menu.
- for (BookmarkStruct bookmarkStruct : *bookmarkListPointer)
+ // Populate the bookmarks toolbar.
+ populateBookmarksToolBar();
+
+ // Get a handle for the bookmark toolbar layout.
+ QLayout *bookmarksToolBarLayoutPointer = bookmarksToolBarPointer->layout();
+
+ // Get the count of the bookmarks.
+ int bookmarkCount = bookmarksToolBarLayoutPointer->count();
+
+ // Set the layout of each bookmark to be left aligned.
+ for(int i = 0; i < bookmarkCount; ++i)
+ bookmarksToolBarLayoutPointer->itemAt(i)->setAlignment(Qt::AlignLeft);
+}
+
+void BrowserWindow::populateBookmarksMenuSubfolders(const double folderId, QMenu *menuPointer)
+{
+ // Get the folder contents.
+ QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(folderId);
+
+ // Populate the bookmarks menu and toolbar.
+ for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
{
- // Get the bookmark URL.
- QString bookmarkUrl = bookmarkStruct.bookmarkUrl;
+ // Process the item according to the type.
+ if (bookmarkStruct.isFolder) // This item is a folder.
+ {
+ // Add a submenu to the menu.
+ QMenu *submenuPointer = menuPointer->addMenu(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
+
+ // Add the submenu to the beginning of the list of menus to be deleted on repopulate.
+ bookmarksMenuSubmenuList.prepend(new QPair<QMenu *, QMenu *>(menuPointer, submenuPointer));
+
+ // Populate any subfolders.
+ populateBookmarksMenuSubfolders(bookmarkStruct.folderId, submenuPointer);
+ }
+ else // This item is a bookmark.
+ {
+ // Add the bookmark to the menu.
+ QAction *menuBookmarkActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
+ {
+ // Remove the focus from the URL line edit.
+ urlLineEditPointer->clearFocus();
+
+ // Load the URL.
+ tabWidgetPointer->loadUrlFromLineEdit(bookmarkStruct.url);
+ }
+ );
+
+ // Add the actions to the beginning of the list of bookmarks to be deleted on repopulate.
+ bookmarksMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, menuBookmarkActionPointer));
+ }
+ }
+}
+
+void BrowserWindow::populateBookmarksToolBar()
+{
+ // Get the root folder contents (which has a folder ID of `0`).
+ QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(0);
+
+ // Populate the bookmarks toolbar.
+ for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
+ {
+ // Process the item according to the type.
+ if (bookmarkStruct.isFolder) // This item is a folder.
+ {
+ // Add the subfolder action.
+ QAction *toolBarSubfolderActionPointer = bookmarksToolBarPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
+
+ // Add the bookmark database ID to the toolbar action.
+ toolBarSubfolderActionPointer->setData(bookmarkStruct.databaseId);
+
+ // Add the action to the beginning of the list of actions to be deleted on repopulate.
+ bookmarksToolBarActionList.prepend(toolBarSubfolderActionPointer);
+
+ // Create a subfolder menu.
+ QMenu *subfolderMenuPointer = new QMenu();
+
+ // Add the menu to the action.
+ toolBarSubfolderActionPointer->setMenu(subfolderMenuPointer);
+
+ // Add the submenu to the toolbar menu list.
+ bookmarksToolBarMenuList.append(new QPair<QMenu *, const double>(subfolderMenuPointer, bookmarkStruct.folderId));
+
+ // Set the popup mode for the menu.
+ dynamic_cast<QToolButton *>(bookmarksToolBarPointer->widgetForAction(toolBarSubfolderActionPointer))->setPopupMode(QToolButton::InstantPopup);
+
+ // Populate the subfolder.
+ populateBookmarksToolBarSubfolders(bookmarkStruct.folderId, subfolderMenuPointer);
+ }
+ else // This item is a bookmark.
+ {
+ // Add the bookmark to the toolbar.
+ QAction *toolBarBookmarkActionPointer = bookmarksToolBarPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
+ {
+ // Remove the focus from the URL line edit.
+ urlLineEditPointer->clearFocus();
+
+ // Load the URL.
+ tabWidgetPointer->loadUrlFromLineEdit(bookmarkStruct.url);
+ }
+ );
+
+ // Add the bookmark database ID to the toolbar action.
+ toolBarBookmarkActionPointer->setData(bookmarkStruct.databaseId);
+
+ // Add the actions to the beginning of the current bookmarks lists.
+ bookmarksToolBarActionList.prepend(toolBarBookmarkActionPointer);
+ }
+ }
+
+ // Add the extra items to the toolbar folder menus. The first item in the pair is the menu pointer. The second is the folder ID.
+ for (QPair<QMenu *, const double> *menuAndFolderIdPairPointer : bookmarksToolBarMenuList)
+ {
+ // Add a separator.
+ menuAndFolderIdPairPointer->first->addSeparator();
+
+ // Add the open folder in new tabs action to the menu.
+ menuAndFolderIdPairPointer->first->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("The open folder in new tabs action", "Open Folder in New Tabs"), [=]
+ {
+ // Get all the folder URLs.
+ QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(menuAndFolderIdPairPointer->second);
+
+ // Open the URLs in new tabs. `true` removes the URL line edit focus, `false` does not load a background tab.
+ for (QString url : *folderUrlsListPointer)
+ tabWidgetPointer->addTab(true, false, url);
+ }
+ );
+
+ // Add the open folder in background tabs action to the menu.
+ menuAndFolderIdPairPointer->first->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("The open folder in background tabs action", "Open Folder in Background Tabs"), [=]
+ {
+ // Get all the folder URLs.
+ QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(menuAndFolderIdPairPointer->second);
+
+ // Open the URLs in new tabs. `true` removes the URL line edit focus, `true` loads a background tab.
+ for (QString url : *folderUrlsListPointer)
+ tabWidgetPointer->addTab(true, true, url);
+ }
+ );
+
+ // Add the open folder in new window action to the menu.
+ menuAndFolderIdPairPointer->first->addAction(QIcon::fromTheme(QLatin1String("window-new")), i18nc("The open folder in new window action", "Open Folder in New Window"), [=]
+ {
+ // Get all the folder URLs.
+ QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(menuAndFolderIdPairPointer->second);
+
+ // Create a new browser window.
+ BrowserWindow *browserWindowPointer = new BrowserWindow(false, &folderUrlsListPointer->first());
+
+ // Get a count of the folder URLs.
+ const int folderUrls = folderUrlsListPointer->count();
- // Add the bookmark to the menu.
- QAction *menuBookmarkActionPointer = bookmarksMenuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.bookmarkName, [=]
+ // Load all the other URLs. `true` removes the URL line edit focus, `true` loads a background tab.
+ for (int i = 1; i < folderUrls; ++i)
+ browserWindowPointer->tabWidgetPointer->addTab(true, true, folderUrlsListPointer->value(i));
+
+ // Show the new browser window.
+ browserWindowPointer->show();
+ }
+ );
+
+ // Add a separator.
+ menuAndFolderIdPairPointer->first->addSeparator();
+
+ // Add the add bookmark action to the menu.
+ menuAndFolderIdPairPointer->first->addAction(QIcon::fromTheme(QLatin1String("bookmark-new")), i18nc("The add bookmark action", "Add Bookmark"), [=]
{
- // Remove the focus from the URL line edit.
- urlLineEditPointer->clearFocus();
+ // Instantiate an add bookmark dialog.
+ AddBookmarkDialog *addBookmarkDialogPointer = new AddBookmarkDialog(tabWidgetPointer->getCurrentTabTitle(), tabWidgetPointer->getCurrentTabUrl(),
+ tabWidgetPointer->getCurrentTabFavoritIcon(), menuAndFolderIdPairPointer->second);
+
+ // Update the displayed bookmarks when a new one is added.
+ connect(addBookmarkDialogPointer, SIGNAL(bookmarkAdded()), this, SLOT(populateBookmarks()));
- // Load the URL.
- tabWidgetPointer->loadUrlFromLineEdit(bookmarkUrl);
+ // Show the dialog.
+ addBookmarkDialogPointer->show();
}
);
- // Add the bookmark to the toolbar.
- QAction *toolBarBookmarkActionPointer = bookmarksToolBarPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.bookmarkName, [=]
+ // Add the add folder action to the menu.
+ menuAndFolderIdPairPointer->first->addAction(QIcon::fromTheme(QLatin1String("folder-add")), i18nc("The add folder action", "Add Folder"), [=]
{
- // Remove the focus from the URL line edit.
- urlLineEditPointer->clearFocus();
+ // Instantiate an add folder dialog.
+ AddFolderDialog *addFolderDialogPointer = new AddFolderDialog(tabWidgetPointer->getCurrentTabFavoritIcon(), menuAndFolderIdPairPointer->second);
+
+ // Update the displayed bookmarks when a folder is added.
+ connect(addFolderDialogPointer, SIGNAL(folderAdded()), this, SLOT(populateBookmarks()));
+
+ // Show the dialog.
+ addFolderDialogPointer->show();
+ }
+ );
+
+ // Add a separator.
+ menuAndFolderIdPairPointer->first->addSeparator();
+
+ // Add the edit folder action to the menu.
+ menuAndFolderIdPairPointer->first->addAction(QIcon::fromTheme(QLatin1String("edit-entry")), i18nc("The edit folder action", "Edit Folder"), [=]
+ {
+ // Get the current tab favorite icon.
+ QIcon currentTabFavoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
- // Load the URL.
- tabWidgetPointer->loadUrlFromLineEdit(bookmarkUrl);
+ // Instantiate an edit folder dialog.
+ QDialog *editFolderDialogPointer = new EditFolderDialog(BookmarksDatabase::getFolderDatabaseId(menuAndFolderIdPairPointer->second), currentTabFavoriteIcon);
+
+ // Show the dialog.
+ editFolderDialogPointer->show();
+
+ // Process bookmark events.
+ connect(editFolderDialogPointer, SIGNAL(folderSaved()), this, SLOT(populateBookmarks()));
}
);
- // Add the bookmark database ID to the toolbar action.
- toolBarBookmarkActionPointer->setData(bookmarkStruct.id);
+ // Add the delete folder action to the menu.
+ menuAndFolderIdPairPointer->first->addAction(QIcon::fromTheme(QLatin1String("delete")), i18nc("Delete folder context menu entry", "Delete Folder"), [=]
+ {
+ // Get the folder database ID.
+ int folderDatabaseId = BookmarksDatabase::getFolderDatabaseId(menuAndFolderIdPairPointer->second);
+
+ // Create an items to delete list.
+ QList<int>* itemsToDeleteListPointer = new QList<int>;
+
+ // Add the folder to the list of items to delete.
+ itemsToDeleteListPointer->append(folderDatabaseId);
+
+ // Add the folder contents to the list of items to delete.
+ itemsToDeleteListPointer->append(*BookmarksDatabase::getFolderContentsDatabaseIdsRecursively(menuAndFolderIdPairPointer->second));
+
+ // Instantiate a delete dialog message box.
+ QMessageBox deleteDialogMessageBox;
+
+ // Set the icon.
+ deleteDialogMessageBox.setIcon(QMessageBox::Warning);
+
+ // Set the window title.
+ deleteDialogMessageBox.setWindowTitle(i18nc("Delete bookmarks dialog title", "Delete Bookmarks"));
- // Add the actions to the current bookmarks lists.
- bookmarksMenuCurrentActionList.append(menuBookmarkActionPointer);
- bookmarksToolBarCurrentActionList.append(toolBarBookmarkActionPointer);
+ // Set the text.
+ deleteDialogMessageBox.setText(i18ncp("Delete bookmarks dialog main message", "Delete %1 bookmark item?", "Delete %1 bookmark items?", itemsToDeleteListPointer->count()));
+
+ // Set the informative text.
+ deleteDialogMessageBox.setInformativeText(i18nc("Delete bookmarks dialog secondary message", "This cannot be undone."));
+
+ // Set the standard buttons.
+ deleteDialogMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+
+ // Set the default button.
+ deleteDialogMessageBox.setDefaultButton(QMessageBox::No);
+
+ // Display the dialog and capture the return value.
+ int returnValue = deleteDialogMessageBox.exec();
+
+ // Delete the domain if instructed.
+ if (returnValue == QMessageBox::Yes)
+ {
+ // Get the parent folder ID.
+ double parentFolderId = BookmarksDatabase::getParentFolderId(folderDatabaseId);
+
+ // Delete the folder and its contents.
+ for (const int databaseId : *itemsToDeleteListPointer)
+ BookmarksDatabase::deleteBookmark(databaseId);
+
+ // Update the display order of the bookmarks in the parent folder.
+ BookmarksDatabase::updateFolderContentsDisplayOrder(parentFolderId);
+
+ // Repopulate the bookmarks.
+ populateBookmarks();
+ }
+ }
+ );
}
+}
- // Get a handle for the bookmark toolbar layout.
- QLayout *bookmarksToolBarLayoutPointer = bookmarksToolBarPointer->layout();
+void BrowserWindow::populateBookmarksToolBarSubfolders(const double folderId, QMenu *menuPointer)
+{
+ // Get the folder contents.
+ QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(folderId);
- // Get the count of the bookmarks.
- int bookmarkCount = bookmarksToolBarLayoutPointer->count();
+ // Populate the bookmarks folder.
+ for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
+ {
+ // Get the bookmark URL.
+ QString bookmarkUrl = bookmarkStruct.url;
- // Set the layout of each bookmark to be left aligned.
- for(int i = 0; i < bookmarkCount; ++i)
- bookmarksToolBarLayoutPointer->itemAt(i)->setAlignment(Qt::AlignLeft);
+ // Process the item according to the type.
+ if (bookmarkStruct.isFolder) // This item is a folder.
+ {
+ // Add the subfolder action.
+ QAction *toolBarSubfolderActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
+
+ // Add the action to the beginning of the list of actions to be deleted on repopulate.
+ bookmarksToolBarSubfolderActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, toolBarSubfolderActionPointer));
+
+ // Create a subfolder menu.
+ QMenu *subfolderMenuPointer = new QMenu();
+
+ // Add the submenu to the action.
+ toolBarSubfolderActionPointer->setMenu(subfolderMenuPointer);
+
+ // Add the submenu to the toolbar menu list.
+ bookmarksToolBarMenuList.append(new QPair<QMenu *, const double>(subfolderMenuPointer, bookmarkStruct.folderId));
+
+ // Populate the subfolder menu.
+ populateBookmarksToolBarSubfolders(bookmarkStruct.folderId, subfolderMenuPointer);
+ }
+ else // This item is a bookmark.
+ {
+ // Add the bookmark to the folder.
+ QAction *toolBarBookmarkActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
+ {
+ // Remove the focus from the URL line edit.
+ urlLineEditPointer->clearFocus();
+
+ // Load the URL.
+ tabWidgetPointer->loadUrlFromLineEdit(bookmarkUrl);
+ }
+ );
+
+ // Add the bookmark database ID to the toolbar action.
+ toolBarBookmarkActionPointer->setData(bookmarkStruct.databaseId);
+
+ // Add the action to the beginning of the list of actions to be deleted on repopulate.
+ bookmarksToolBarSubfolderActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, toolBarBookmarkActionPointer));
+ }
+ }
}
void BrowserWindow::refresh() const
addBookmarkDialogPointer->show();
}
+void BrowserWindow::showAddFolderDialog() const
+{
+ // Instantiate an add folder dialog.
+ AddFolderDialog *addFolderDialogPointer = new AddFolderDialog(tabWidgetPointer->getCurrentTabFavoritIcon());
+
+ // Update the displayed bookmarks when a folder is added.
+ connect(addFolderDialogPointer, SIGNAL(folderAdded()), this, SLOT(populateBookmarks()));
+
+ // Show the dialog.
+ addFolderDialogPointer->show();
+}
+
void BrowserWindow::showBookmarkContextMenu(const QPoint &point)
{
// Get the bookmark action.
QAction *bookmarkActionPointer = bookmarksToolBarPointer->actionAt(point);
- // Check to see if an bookmark was clicked.
- if (bookmarkActionPointer) // A bookmark was clicked.
+ // Check to see if an action was clicked.
+ if (bookmarkActionPointer) // An action was clicked.
{
// Create a bookmark context menu.
QMenu *bookmarkContextMenuPointer = new QMenu();
- // Get the bookmark ID from the action.
- int bookmarkId = bookmarkActionPointer->data().toInt();
-
- // Add the open in new tab action to the menu.
- bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("Open bookmark in new tab context menu entry", "Open in New Tab"), [=]
- {
- // Get the bookmark.
- BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(bookmarkId);
-
- // Open the bookmark in a new tab. `true` removes the URL line edit focus, `false` does not load a background tab.
- tabWidgetPointer->addTab(true, false, bookmarkStructPointer->bookmarkUrl);
- }
- );
+ // Get the database ID from the action.
+ int databaseId = bookmarkActionPointer->data().toInt();
- // Add the open in background tab action to the menu.
- bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("Open bookmark in background tab context menu entry", "Open in Background Tab"), [=]
- {
- // Get the bookmark.
- BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(bookmarkId);
-
- // Open the bookmark in a new tab. `true` removes the URL line edit focus, `true` loads a background tab.
- tabWidgetPointer->addTab(true, true, bookmarkStructPointer->bookmarkUrl);
- }
- );
-
- // Add the open in new window action to the menu.
- bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("window-new")), i18nc("Open bookmark in new window context menu entry", "Open in New Window"), [=]
- {
- // Get the bookmark.
- BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(bookmarkId);
-
- // Create a new browser window.
- BrowserWindow *browserWindowPointer = new BrowserWindow(false, &bookmarkStructPointer->bookmarkUrl);
+ // Create the menu according to the type.
+ if (BookmarksDatabase::isFolder(databaseId)) // A folder was clicked.
+ {
+ // Get the folder ID.
+ double folderId = BookmarksDatabase::getFolderId(databaseId);
+
+ // Add the open folder in new tabs action to the menu.
+ bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("The open folder in new tabs action", "Open Folder in New Tabs"), [=]
+ {
+ // Get all the folder URLs.
+ QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
+
+ // Open the URLs in new tabs. `true` removes the URL line edit focus, `false` does not load a background tab.
+ for (QString url : *folderUrlsListPointer)
+ tabWidgetPointer->addTab(true, false, url);
+ }
+ );
+
+ // Add the open folder in background tabs action to the menu.
+ bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("The open folder in background tabs action", "Open Folder in Background Tabs"), [=]
+ {
+ // Get all the folder URLs.
+ QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
+
+ // Open the URLs in new tabs. `true` removes the URL line edit focus, `true` loads a background tab.
+ for (QString url : *folderUrlsListPointer)
+ tabWidgetPointer->addTab(true, true, url);
+ }
+ );
+
+ // Add the open folder in new window action to the menu.
+ bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("window-new")), i18nc("The open folder in new window action", "Open Folder in New Window"), [=]
+ {
+ // Get all the folder URLs.
+ QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
+
+ // Create a new browser window.
+ BrowserWindow *browserWindowPointer = new BrowserWindow(false, &folderUrlsListPointer->first());
+
+ // Get a count of the folder URLs.
+ const int folderUrls = folderUrlsListPointer->count();
- // Show the new browser window.
- browserWindowPointer->show();
- }
- );
+ // Load all the other URLs. `true` removes the URL line edit focus, `true` loads a background tab.
+ for (int i = 1; i < folderUrls; ++i)
+ browserWindowPointer->tabWidgetPointer->addTab(true, true, folderUrlsListPointer->value(i));
+
+ // Show the new browser window.
+ browserWindowPointer->show();
+ }
+ );
+
+ // Add a separator.
+ bookmarkContextMenuPointer->addSeparator();
+
+ // Add the add bookmark action to the menu.
+ bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("bookmark-new")), i18nc("The add bookmark action", "Add Bookmark"), [=]
+ {
+ // Instantiate an add bookmark dialog.
+ AddBookmarkDialog *addBookmarkDialogPointer = new AddBookmarkDialog(tabWidgetPointer->getCurrentTabTitle(), tabWidgetPointer->getCurrentTabUrl(),
+ tabWidgetPointer->getCurrentTabFavoritIcon(), folderId);
+
+ // Update the displayed bookmarks when a new one is added.
+ connect(addBookmarkDialogPointer, SIGNAL(bookmarkAdded()), this, SLOT(populateBookmarks()));
+
+ // Show the dialog.
+ addBookmarkDialogPointer->show();
+ }
+ );
+
+ // Add the add folder action to the menu.
+ bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("folder-add")), i18nc("The add folder action", "Add Folder"), [=]
+ {
+ // Instantiate an add folder dialog.
+ AddFolderDialog *addFolderDialogPointer = new AddFolderDialog(tabWidgetPointer->getCurrentTabFavoritIcon(), folderId);
+
+ // Update the displayed bookmarks when a folder is added.
+ connect(addFolderDialogPointer, SIGNAL(folderAdded()), this, SLOT(populateBookmarks()));
+
+ // Show the dialog.
+ addFolderDialogPointer->show();
+ }
+ );
+
+ // Add a separator.
+ bookmarkContextMenuPointer->addSeparator();
+
+ // Add the edit folder action to the menu.
+ bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-entry")), i18nc("The edit folder action", "Edit Folder"), [=]
+ {
+ // Get the current tab favorite icon.
+ QIcon currentTabFavoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
+
+ // Instantiate an edit folder dialog.
+ QDialog *editFolderDialogPointer = new EditFolderDialog(BookmarksDatabase::getFolderDatabaseId(folderId), currentTabFavoriteIcon);
+
+ // Show the dialog.
+ editFolderDialogPointer->show();
+
+ // Process bookmark events.
+ connect(editFolderDialogPointer, SIGNAL(folderSaved()), this, SLOT(populateBookmarks()));
+ }
+ );
+
+ // Add the delete folder action to the menu.
+ bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("delete")), i18nc("Delete folder context menu entry", "Delete Folder"), [=]
+ {
+ // Get the folder database ID.
+ int folderDatabaseId = BookmarksDatabase::getFolderDatabaseId(folderId);
+
+ // Create an items to delete list.
+ QList<int>* itemsToDeleteListPointer = new QList<int>;
+
+ // Add the folder to the list of items to delete.
+ itemsToDeleteListPointer->append(folderDatabaseId);
+
+ // Add the folder contents to the list of items to delete.
+ itemsToDeleteListPointer->append(*BookmarksDatabase::getFolderContentsDatabaseIdsRecursively(folderId));
- // Add a separator.
- bookmarkContextMenuPointer->addSeparator();
+ // Instantiate a delete dialog message box.
+ QMessageBox deleteDialogMessageBox;
+
+ // Set the icon.
+ deleteDialogMessageBox.setIcon(QMessageBox::Warning);
- // Add the edit action to the menu.
- bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-entry")), i18nc("Edit bookmark context menu entry", "Edit"), [=]
- {
- // Get the current tab favorite icon.
- QIcon currentTabFavoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
+ // Set the window title.
+ deleteDialogMessageBox.setWindowTitle(i18nc("Delete bookmarks dialog title", "Delete Bookmarks"));
- // Instantiate an edit bookmark dialog.
- QDialog *editBookmarkDialogPointer = new EditBookmarkDialog(bookmarkId, currentTabFavoriteIcon);
+ // Set the text.
+ deleteDialogMessageBox.setText(i18ncp("Delete bookmarks dialog main message", "Delete %1 bookmark item?", "Delete %1 bookmark items?", itemsToDeleteListPointer->count()));
- // Show the dialog.
- editBookmarkDialogPointer->show();
+ // Set the informative text.
+ deleteDialogMessageBox.setInformativeText(i18nc("Delete bookmarks dialog secondary message", "This cannot be undone."));
- // Process bookmark events.
- connect(editBookmarkDialogPointer, SIGNAL(bookmarkSaved()), this, SLOT(populateBookmarks()));
- }
- );
+ // Set the standard buttons.
+ deleteDialogMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
- // Add the copy URL action to the menu.
- bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-copy")), i18nc("Copy bookmark url context menu entry", "Copy URL"), [=]
- {
- // Get the bookmark.
- BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(bookmarkId);
+ // Set the default button.
+ deleteDialogMessageBox.setDefaultButton(QMessageBox::No);
- // Get a handle for the clipboard.
- QClipboard *clipboard = QGuiApplication::clipboard();
+ // Display the dialog and capture the return value.
+ int returnValue = deleteDialogMessageBox.exec();
- // Place the URL on the keyboard.
- clipboard->setText(bookmarkStructPointer->bookmarkUrl);
- }
- );
+ // Delete the domain if instructed.
+ if (returnValue == QMessageBox::Yes)
+ {
+ // Get the parent folder ID.
+ double parentFolderId = BookmarksDatabase::getParentFolderId(folderDatabaseId);
- // Add a separator.
- bookmarkContextMenuPointer->addSeparator();
+ // Delete the folder and its contents.
+ for (const int databaseId : *itemsToDeleteListPointer)
+ BookmarksDatabase::deleteBookmark(databaseId);
- // Add the delete action to the menu.
- bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("delete")), i18nc("Delete bookmark context menu entry", "Delete"), [=]
- {
- // Delete the bookmark.
- BookmarksDatabase::deleteBookmark(bookmarkId);
+ // Update the display order of the bookmarks in the parent folder.
+ BookmarksDatabase::updateFolderContentsDisplayOrder(parentFolderId);
- // Repopulate the bookmarks.
- populateBookmarks();
- }
- );
+ // Repopulate the bookmarks.
+ populateBookmarks();
+ }
+ }
+ );
+ }
+ else // A bookmark was clicked.
+ {
+ // Add the open in new tab action to the menu.
+ bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("Open bookmark in new tab context menu entry", "Open in New Tab"), [=]
+ {
+ // Get the bookmark.
+ BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
+
+ // Open the bookmark in a new tab. `true` removes the URL line edit focus, `false` does not load a background tab.
+ tabWidgetPointer->addTab(true, false, bookmarkStructPointer->url);
+ }
+ );
+
+ // Add the open in background tab action to the menu.
+ bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("Open bookmark in background tab context menu entry", "Open in Background Tab"), [=]
+ {
+ // Get the bookmark.
+ BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
+
+ // Open the bookmark in a new tab. `true` removes the URL line edit focus, `true` loads a background tab.
+ tabWidgetPointer->addTab(true, true, bookmarkStructPointer->url);
+ }
+ );
+
+ // Add the open in new window action to the menu.
+ bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("window-new")), i18nc("Open bookmark in new window context menu entry", "Open in New Window"), [=]
+ {
+ // Get the bookmark.
+ BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
+
+ // Create a new browser window and load the first URL. `false` indicates it is not the first browser window.
+ BrowserWindow *browserWindowPointer = new BrowserWindow(false, &bookmarkStructPointer->url);
+
+ // Show the new browser window.
+ browserWindowPointer->show();
+ }
+ );
+
+ // Add a separator.
+ bookmarkContextMenuPointer->addSeparator();
+
+ // Add the edit action to the menu.
+ bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-entry")), i18nc("Edit bookmark context menu entry", "Edit"), [=]
+ {
+ // Get the current tab favorite icon.
+ QIcon currentTabFavoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
+
+ // Instantiate an edit bookmark dialog.
+ QDialog *editBookmarkDialogPointer = new EditBookmarkDialog(databaseId, currentTabFavoriteIcon);
+
+ // Show the dialog.
+ editBookmarkDialogPointer->show();
+
+ // Process bookmark events.
+ connect(editBookmarkDialogPointer, SIGNAL(bookmarkSaved()), this, SLOT(populateBookmarks()));
+ }
+ );
+
+ // Add the copy URL action to the menu.
+ bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-copy")), i18nc("Copy bookmark URL context menu entry", "Copy URL"), [=]
+ {
+ // Get the bookmark.
+ BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
+
+ // Get a handle for the clipboard.
+ QClipboard *clipboard = QGuiApplication::clipboard();
+
+ // Place the URL on the keyboard.
+ clipboard->setText(bookmarkStructPointer->url);
+ }
+ );
+
+ // Add a separator.
+ bookmarkContextMenuPointer->addSeparator();
+
+ // Add the delete action to the menu.
+ bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("delete")), i18nc("Delete bookmark context menu entry", "Delete"), [=]
+ {
+ // Get the parent folder ID.
+ double parentFolderId = BookmarksDatabase::getParentFolderId(databaseId);
+
+ // Delete the bookmark.
+ BookmarksDatabase::deleteBookmark(databaseId);
+
+ // Update the display order of the bookmarks in the parent folder.
+ BookmarksDatabase::updateFolderContentsDisplayOrder(parentFolderId);
+
+ // Repopulate the bookmarks.
+ populateBookmarks();
+ }
+ );
+ }
// Delete the menu from memory when it is closed.
bookmarkContextMenuPointer->setAttribute(Qt::WA_DeleteOnClose);
void refresh() const;
void reloadAndBypassCache() const;
void showAddBookmarkDialog() const;
+ void showAddFolderDialog() const;
void showBookmarkContextMenu(const QPoint &point);
void showCookiesDialog();
void showDownloadLocationBrowseDialog() const;
private:
// The private variables.
- QList<QAction*> bookmarksMenuCurrentActionList;
+ QList<QPair<QMenu *, QAction *> *> bookmarksMenuActionList;
QMenu *bookmarksMenuPointer;
- QList<QAction*> bookmarksToolBarCurrentActionList;
+ QList<QPair<QMenu *, QMenu *> *> bookmarksMenuSubmenuList;
+ QList<QAction*> bookmarksToolBarActionList;
+ QList<QPair<QMenu *, const double> *> bookmarksToolBarMenuList;
KToolBar *bookmarksToolBarPointer;
+ QList<QPair<QMenu *, QAction *> *> bookmarksToolBarSubfolderActionList;
bool bookmarksToolBarIsVisible = false;
bool bookmarksToolBarUninitialized = true;
KConfigDialog *configDialogPointer;
QPushButton *zoomMinusButtonPointer;
QAction *zoomOutActionPointer;
QPushButton *zoomPlusButtonPointer;
+
+ // The private functions.
+ void populateBookmarksMenuSubfolders(const double folderId, QMenu *menuPointer);
+ void populateBookmarksToolBar();
+ void populateBookmarksToolBarSubfolders(const double folderId, QMenu *menuPointer);
};
#endif