From 3318a2a6d754d8a5d22beebe0927a73cd5ee708f Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Thu, 26 Aug 2021 21:09:26 +0200 Subject: [PATCH] AudioBook Plugin: Move selection up/down --- Pdf4QtLib/sources/pdfdocumenttextflow.cpp | 60 +++++++++++++++++++ Pdf4QtLib/sources/pdfdocumenttextflow.h | 10 ++++ .../pdfdocumenttextfloweditormodel.cpp | 22 +++++++ .../sources/pdfdocumenttextfloweditormodel.h | 2 + .../AudioBookPlugin/audiobookplugin.cpp | 26 ++++++++ .../AudioBookPlugin/audiobookplugin.h | 3 + 6 files changed, 123 insertions(+) diff --git a/Pdf4QtLib/sources/pdfdocumenttextflow.cpp b/Pdf4QtLib/sources/pdfdocumenttextflow.cpp index 83c221b..41f0025 100644 --- a/Pdf4QtLib/sources/pdfdocumenttextflow.cpp +++ b/Pdf4QtLib/sources/pdfdocumenttextflow.cpp @@ -905,6 +905,66 @@ void PDFDocumentTextFlowEditor::restoreOriginalTexts() } } +void PDFDocumentTextFlowEditor::moveSelectionUp() +{ + size_t originalSize = m_editedTextFlow.size(); + size_t firstSelectedIndex = originalSize; + + EditedItems selectedItems; + for (auto it = m_editedTextFlow.begin(); it != m_editedTextFlow.end();) + { + if (it->editedItemFlags.testFlag(Selected)) + { + if (firstSelectedIndex == originalSize) + { + firstSelectedIndex = std::distance(m_editedTextFlow.begin(), it); + } + + selectedItems.emplace_back(std::move(*it)); + it = m_editedTextFlow.erase(it); + } + else + { + ++it; + } + } + + if (firstSelectedIndex > 0) + { + --firstSelectedIndex; + } + + m_editedTextFlow.insert(std::next(m_editedTextFlow.begin(), firstSelectedIndex), std::make_move_iterator(selectedItems.begin()), std::make_move_iterator(selectedItems.end())); +} + +void PDFDocumentTextFlowEditor::moveSelectionDown() +{ + size_t originalSize = m_editedTextFlow.size(); + size_t lastSelectedIndex = originalSize; + + EditedItems selectedItems; + for (auto it = m_editedTextFlow.begin(); it != m_editedTextFlow.end();) + { + if (it->editedItemFlags.testFlag(Selected)) + { + lastSelectedIndex = std::distance(m_editedTextFlow.begin(), it); + selectedItems.emplace_back(std::move(*it)); + it = m_editedTextFlow.erase(it); + } + else + { + ++it; + } + } + + if (lastSelectedIndex < m_editedTextFlow.size()) + { + ++lastSelectedIndex; + } + + m_editedTextFlow.insert(std::next(m_editedTextFlow.begin(), lastSelectedIndex), std::make_move_iterator(selectedItems.begin()), std::make_move_iterator(selectedItems.end())); +} + PDFDocumentTextFlowEditor::PageIndicesMappingRange PDFDocumentTextFlowEditor::getItemsForPageIndex(PDFInteger pageIndex) const { auto comparator = [](const auto& l, const auto& r) diff --git a/Pdf4QtLib/sources/pdfdocumenttextflow.h b/Pdf4QtLib/sources/pdfdocumenttextflow.h index b6c57e0..b139a89 100644 --- a/Pdf4QtLib/sources/pdfdocumenttextflow.h +++ b/Pdf4QtLib/sources/pdfdocumenttextflow.h @@ -244,6 +244,16 @@ public: /// Restores original texts in selected items void restoreOriginalTexts(); + /// Move all selected items one position up. If multiple non-consecutive + /// items are selected, they are grouped into one group and move one item + /// up above first selected item. + void moveSelectionUp(); + + /// Move all selected items one position down. If multiple non-consecutive + /// items are selected, they are grouped into one group and move one item + /// down above first selected item. + void moveSelectionDown(); + /// Returns item indices for a given page index, i.e. /// index of items which are lying on a page. /// \param pageIndex Page index diff --git a/Pdf4QtLib/sources/pdfdocumenttextfloweditormodel.cpp b/Pdf4QtLib/sources/pdfdocumenttextfloweditormodel.cpp index 2b65c76..dc6a543 100644 --- a/Pdf4QtLib/sources/pdfdocumenttextfloweditormodel.cpp +++ b/Pdf4QtLib/sources/pdfdocumenttextfloweditormodel.cpp @@ -309,6 +309,28 @@ void PDFDocumentTextFlowEditorModel::restoreOriginalTexts() emit dataChanged(index(0, 0), index(rowCount(QModelIndex()) - 1, ColumnLast)); } +void PDFDocumentTextFlowEditorModel::moveSelectionUp() +{ + if (!m_editor || m_editor->isEmpty()) + { + return; + } + + m_editor->moveSelectionUp(); + notifyDataChanged(); +} + +void PDFDocumentTextFlowEditorModel::moveSelectionDown() +{ + if (!m_editor || m_editor->isEmpty()) + { + return; + } + + m_editor->moveSelectionDown(); + notifyDataChanged(); +} + void PDFDocumentTextFlowEditorModel::notifyDataChanged() { if (!m_editor || m_editor->isEmpty()) diff --git a/Pdf4QtLib/sources/pdfdocumenttextfloweditormodel.h b/Pdf4QtLib/sources/pdfdocumenttextfloweditormodel.h index 7cf07bb..ce68c27 100644 --- a/Pdf4QtLib/sources/pdfdocumenttextfloweditormodel.h +++ b/Pdf4QtLib/sources/pdfdocumenttextfloweditormodel.h @@ -69,6 +69,8 @@ public: void selectByRegularExpression(const QRegularExpression& expression); void selectByPageIndices(const pdf::PDFClosedIntervalSet& indices); void restoreOriginalTexts(); + void moveSelectionUp(); + void moveSelectionDown(); void notifyDataChanged(); private: diff --git a/Pdf4QtViewerPlugins/AudioBookPlugin/audiobookplugin.cpp b/Pdf4QtViewerPlugins/AudioBookPlugin/audiobookplugin.cpp index 7f35c1d..68bbf60 100644 --- a/Pdf4QtViewerPlugins/AudioBookPlugin/audiobookplugin.cpp +++ b/Pdf4QtViewerPlugins/AudioBookPlugin/audiobookplugin.cpp @@ -109,12 +109,15 @@ void AudioBookPlugin::setWidget(pdf::PDFWidget* widget) m_actionMoveSelectionUp = new QAction(QIcon(":/pdfplugins/audiobook/move-selection-up.svg"), tr("Move Selection Up"), this); m_actionMoveSelectionUp->setObjectName("actionAudioBook_MoveSelectionUp"); + connect(m_actionMoveSelectionUp, &QAction::triggered, this, &AudioBookPlugin::onMoveSelectionUp); m_actionMoveSelectionDown = new QAction(QIcon(":/pdfplugins/audiobook/move-selection-down.svg"), tr("Move Selection Down"), this); m_actionMoveSelectionDown->setObjectName("actionAudioBook_MoveSelectionDown"); + connect(m_actionMoveSelectionDown, &QAction::triggered, this, &AudioBookPlugin::onMoveSelectionDown); m_actionCreateAudioBook = new QAction(QIcon(":/pdfplugins/audiobook/create-audio-book.svg"), tr("Create Audio Book"), this); m_actionCreateAudioBook->setObjectName("actionAudioBook_CreateAudioBook"); + connect(m_actionRestoreOriginalText, &QAction::triggered, this, &AudioBookPlugin::onCreateAudioBook); m_actionClear = new QAction(QIcon(":/pdfplugins/audiobook/clear.svg"), tr("Clear Text Stream"), this); m_actionClear->setObjectName("actionAudioBook_Clear"); @@ -402,6 +405,29 @@ void AudioBookPlugin::onClear() } } +void AudioBookPlugin::onMoveSelectionUp() +{ + if (m_audioTextStreamEditorModel) + { + m_audioTextStreamEditorModel->moveSelectionUp(); + m_audioTextStreamDockWidget->getTextStreamView()->clearSelection(); + } +} + +void AudioBookPlugin::onMoveSelectionDown() +{ + if (m_audioTextStreamEditorModel) + { + m_audioTextStreamEditorModel->moveSelectionDown(); + m_audioTextStreamDockWidget->getTextStreamView()->clearSelection(); + } +} + +void AudioBookPlugin::onCreateAudioBook() +{ + +} + void AudioBookPlugin::onRectanglePicked(pdf::PDFInteger pageIndex, QRectF rectangle) { Q_UNUSED(pageIndex); diff --git a/Pdf4QtViewerPlugins/AudioBookPlugin/audiobookplugin.h b/Pdf4QtViewerPlugins/AudioBookPlugin/audiobookplugin.h index de5593c..0e1f322 100644 --- a/Pdf4QtViewerPlugins/AudioBookPlugin/audiobookplugin.h +++ b/Pdf4QtViewerPlugins/AudioBookPlugin/audiobookplugin.h @@ -80,6 +80,9 @@ private: void onEditedTextFlowChanged(); void onTextStreamTableSelectionChanged(); void onClear(); + void onMoveSelectionUp(); + void onMoveSelectionDown(); + void onCreateAudioBook(); void onRectanglePicked(pdf::PDFInteger pageIndex, QRectF rectangle);