From 7b768d3b0914f9c4dd56262a53977d0c3a76a090 Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Tue, 13 Jul 2021 18:16:59 +0200 Subject: [PATCH] DocPage Organizer: clone/remove/restore actions --- Pdf4QtDocPageOrganizer/mainwindow.cpp | 34 +++++++-- Pdf4QtDocPageOrganizer/mainwindow.ui | 6 ++ Pdf4QtDocPageOrganizer/pageitemmodel.cpp | 88 ++++++++++++++++++++++++ Pdf4QtDocPageOrganizer/pageitemmodel.h | 4 ++ 4 files changed, 126 insertions(+), 6 deletions(-) diff --git a/Pdf4QtDocPageOrganizer/mainwindow.cpp b/Pdf4QtDocPageOrganizer/mainwindow.cpp index c630325..fa82f59 100644 --- a/Pdf4QtDocPageOrganizer/mainwindow.cpp +++ b/Pdf4QtDocPageOrganizer/mainwindow.cpp @@ -97,6 +97,7 @@ MainWindow::MainWindow(QWidget* parent) : for (QToolBar* toolbar : toolbars) { toolbar->setIconSize(iconSize); + ui->menuWindow->addAction(toolbar->toggleViewAction()); } connect(&m_mapper, QOverload::of(&QSignalMapper::mapped), this, &MainWindow::onMappedActionTriggered); @@ -329,13 +330,28 @@ void MainWindow::performOperation(Operation operation) break; } case Operation::CloneSelection: - case Operation::RemoveSelection: - case Operation::ReplaceSelection: - case Operation::RestoreRemovedItems: - case Operation::RotateLeft: - case Operation::RotateRight: - Q_ASSERT(false); + { + m_model->cloneSelection(ui->documentItemsView->selectionModel()->selection().indexes()); break; + } + + case Operation::RemoveSelection: + { + m_model->removeSelection(ui->documentItemsView->selectionModel()->selection().indexes()); + break; + } + + case Operation::RestoreRemovedItems: + { + QModelIndexList restoredItemIndices = m_model->restoreRemovedItems(); + QItemSelection itemSelection; + for (const QModelIndex& index : restoredItemIndices) + { + itemSelection.select(index, index); + } + ui->documentItemsView->selectionModel()->select(itemSelection, QItemSelectionModel::ClearAndSelect); + break; + } case Operation::Cut: case Operation::Copy: @@ -434,6 +450,12 @@ void MainWindow::performOperation(Operation operation) break; } + case Operation::RotateLeft: + case Operation::RotateRight: + case Operation::ReplaceSelection: + Q_ASSERT(false); + break; + case Operation::Unite: case Operation::Separate: case Operation::SeparateGrouped: diff --git a/Pdf4QtDocPageOrganizer/mainwindow.ui b/Pdf4QtDocPageOrganizer/mainwindow.ui index 3304a0c..3edb567 100644 --- a/Pdf4QtDocPageOrganizer/mainwindow.ui +++ b/Pdf4QtDocPageOrganizer/mainwindow.ui @@ -115,11 +115,17 @@ + + + Window + + + diff --git a/Pdf4QtDocPageOrganizer/pageitemmodel.cpp b/Pdf4QtDocPageOrganizer/pageitemmodel.cpp index a8571a7..6ed051d 100644 --- a/Pdf4QtDocPageOrganizer/pageitemmodel.cpp +++ b/Pdf4QtDocPageOrganizer/pageitemmodel.cpp @@ -19,6 +19,8 @@ #include +#include + namespace pdfdocpage { @@ -256,6 +258,92 @@ void PageItemModel::ungroup(const QModelIndexList& list) } } +QModelIndexList PageItemModel::restoreRemovedItems() +{ + QModelIndexList result; + + if (m_trashBin.empty()) + { + // Jakub Melka: nothing to do + return result; + } + + const int trashBinSize = int(m_trashBin.size()); + const int rowCount = this->rowCount(QModelIndex()); + beginInsertRows(QModelIndex(), rowCount, rowCount + trashBinSize - 1); + m_pageGroupItems.insert(m_pageGroupItems.end(), std::make_move_iterator(m_trashBin.begin()), std::make_move_iterator(m_trashBin.end())); + m_trashBin.clear(); + endInsertRows(); + + result.reserve(trashBinSize); + for (int i = rowCount; i < rowCount + trashBinSize; ++i) + { + result << index(i, 0, QModelIndex()); + } + + return result; +} + +QModelIndexList PageItemModel::cloneSelection(const QModelIndexList& list) +{ + QModelIndexList result; + + if (list.empty()) + { + // Jakub Melka: nothing to do + return result; + } + + std::vector rows; + rows.reserve(list.size()); + std::transform(list.cbegin(), list.cend(), std::back_inserter(rows), [](const auto& index) { return index.row(); }); + + std::vector clonedGroups; + clonedGroups.reserve(rows.size()); + + for (int row : rows) + { + clonedGroups.push_back(m_pageGroupItems[row]); + } + + const int insertRow = rows.back() + 1; + const int lastRow = insertRow + int(rows.size()); + + beginResetModel(); + m_pageGroupItems.insert(std::next(m_pageGroupItems.begin(), insertRow), clonedGroups.begin(), clonedGroups.end()); + endResetModel(); + + result.reserve(int(rows.size())); + for (int i = insertRow; i < lastRow; ++i) + { + result << index(i, 0, QModelIndex()); + } + + return result; +} + +void PageItemModel::removeSelection(const QModelIndexList& list) +{ + if (list.empty()) + { + // Jakub Melka: nothing to do + return; + } + + std::vector rows; + rows.reserve(list.size()); + std::transform(list.cbegin(), list.cend(), std::back_inserter(rows), [](const auto& index) { return index.row(); }); + std::sort(rows.begin(), rows.end(), std::greater()); + + beginResetModel(); + for (int row : rows) + { + m_trashBin.emplace_back(qMove(m_pageGroupItems[row])); + m_pageGroupItems.erase(std::next(m_pageGroupItems.begin(), row)); + } + endResetModel(); +} + QItemSelection PageItemModel::getSelectionImpl(std::function filter) const { QItemSelection result; diff --git a/Pdf4QtDocPageOrganizer/pageitemmodel.h b/Pdf4QtDocPageOrganizer/pageitemmodel.h index 6c8398a..bac2e3c 100644 --- a/Pdf4QtDocPageOrganizer/pageitemmodel.h +++ b/Pdf4QtDocPageOrganizer/pageitemmodel.h @@ -115,6 +115,10 @@ public: void group(const QModelIndexList& list); void ungroup(const QModelIndexList& list); + QModelIndexList restoreRemovedItems(); + QModelIndexList cloneSelection(const QModelIndexList& list); + void removeSelection(const QModelIndexList& list); + static QString getMimeDataType() { return QLatin1String("application/pagemodel.PDF4QtDocPageOrganizer"); } private: