]> gitweb.stoutner.com Git - PrivacyBrowserPC.git/blobdiff - src/widgets/DraggableTreeView.cpp
Partial filter list implementation.
[PrivacyBrowserPC.git] / src / widgets / DraggableTreeView.cpp
index 1fa07a56498c74bf94d8a69c02bc83ec815ee26e..bbe086892c2dbc58ade9dd4038167c7610affcf5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2023-2024 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
  *
@@ -36,52 +36,72 @@ void DraggableTreeView::dropEvent(QDropEvent *dropEvent)
     // Get the list of currently selected items that are moving.
     QList<QModelIndex> indexesMovingList = selectedIndexes();
 
-    // Create a list of database IDs that are moving.
-    QList<int> *databaseIdsMovingListPointer = new QList<int>;
+    // 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> *previousParentFolderIdListPointer = new std::list<double>;
 
     // Process the move according to the drop position.
     switch (dropPosition)
     {
-        case QAbstractItemView::OnItem:
-            // TODO  Implement for moving into a folder.
+        case QAbstractItemView::OnItem:  // This will only ever be called for folders as `BookmarksDialog::populateSubfolders` creates bookmarks without `setDropEnabled`.
+        {
+            // Move everything to the beginning of the folder.
+            moveToBeginningOfFolder(dropModelIndex, selectedDatabaseIdsListPointer, rootSelectedDatabaseIdsListPointer, previousParentFolderIdListPointer);
+
             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().toDouble();
+
+            // 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)
+                            previousParentFolderIdListPointer->push_back(currentParentFolderId);
+
+                        // Update the parent folder and display order for each bookmark.
+                        BookmarksDatabase::updateParentFolderAndDisplayOrder(databaseId, dropParentFolderId, newDisplayOrder);
 
                         // Increment the new display order.
                         ++newDisplayOrder;
@@ -90,82 +110,192 @@ void DraggableTreeView::dropEvent(QDropEvent *dropEvent)
 
                 // 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);
+            // Check to see if the drop model index is an expanded folder.
+            if (dropModelIndex.siblingAtColumn(BookmarksDialog::IS_FOLDER_COLUMN).data().toBool() && isExpanded(dropModelIndex))  // The drop model index is an expanded folder.
+            {
+                // Move everything to the beginning of the folder.
+                moveToBeginningOfFolder(dropModelIndex, selectedDatabaseIdsListPointer, rootSelectedDatabaseIdsListPointer, previousParentFolderIdListPointer);
+            }
+            else  // The drop model index is not an expanded folder.
+            {
+                // Get the drop display order.
+                int dropDisplayOrder = dropModelIndex.siblingAtColumn(BookmarksDialog::DISPLAY_ORDER_COLUMN).data().toInt();
 
-            // Initialize a new display order tracker.
-            int newDisplayOrder = 0;
+                // Get the drop parent folder ID.
+                double dropParentFolderId = dropModelIndex.parent().siblingAtColumn(BookmarksDialog::FOLDER_ID_COLUMN).data().toDouble();
 
-            // Move the bookmarks.
-            for (const BookmarkStruct &bookmarkStruct : *bookmarksExceptSelectedListPointer)
-            {
-                // Set the bookmark's display order if it has changed.
-                if (bookmarkStruct.displayOrder != newDisplayOrder)
-                    BookmarksDatabase::updateDisplayOrder(bookmarkStruct.id, newDisplayOrder);
+                // Get a list of all the items in the target folder except those selected.
+                QList<BookmarkStruct> *itemsInFolderExceptSelectedListPointer = BookmarksDatabase::getBookmarksInFolderExcept(dropParentFolderId, selectedDatabaseIdsListPointer);
 
-                // Increment the new display order.
-                ++newDisplayOrder;
+                // Initialize a new display order tracker.
+                int newDisplayOrder = 0;
 
-                // Check to see if this is the drop display order.
-                if (bookmarkStruct.displayOrder == dropDisplayOrder)
+                // Process all the items in the target folder, moving in the new ones.
+                for (const BookmarkStruct &bookmarkStruct : *itemsInFolderExceptSelectedListPointer)
                 {
-                    // Add all of the bookmarks being moved to this point.
-                    for (const int databaseId : *databaseIdsMovingListPointer)
-                    {
-                        // Update the display order for each bookmark.
-                        BookmarksDatabase::updateDisplayOrder(databaseId, newDisplayOrder);
+                    // 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;
+                    // Increment the new display order.
+                    ++newDisplayOrder;
+
+                    // Check to see if this is the drop display order.
+                    if (bookmarkStruct.displayOrder == dropDisplayOrder)
+                    {
+                        // Add all of the bookmarks being moved to this point.
+                        for (const int databaseId : *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 != dropParentFolderId)
+                                previousParentFolderIdListPointer->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)
+                    previousParentFolderIdListPointer->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.
+    previousParentFolderIdListPointer->sort();
+
+    // Remove duplicates from the parent folder ID list.
+    previousParentFolderIdListPointer->unique();
+
+    // Update the folder contents display order for each previous parent folder.
+    for (const double parentFolderId : *previousParentFolderIdListPointer)
+        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;
+}
+
+void DraggableTreeView::moveToBeginningOfFolder(const QModelIndex &dropModelIndex, QList<int> *selectedDatabaseIdsListPointer, QList<int> *rootSelectedDatabaseIdsListPointer,
+                                                std::list<double> *previousParentFolderIdListPointer) const
+{
+    // 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)
+            previousParentFolderIdListPointer->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;
+            }
+}