From c57f28a3b58cc707af0a377604f09032a43af279 Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Sat, 7 Oct 2023 17:57:43 +0200 Subject: [PATCH] Issue #97: Add drag and drop capability to DocPage Organizer --- Pdf4QtDocPageOrganizer/mainwindow.cpp | 75 ++++++++++++++++++++++++ Pdf4QtDocPageOrganizer/mainwindow.h | 3 + Pdf4QtDocPageOrganizer/mainwindow.ui | 3 + Pdf4QtDocPageOrganizer/pageitemmodel.cpp | 41 +++++++++++++ Pdf4QtDocPageOrganizer/pageitemmodel.h | 7 +++ 5 files changed, 129 insertions(+) diff --git a/Pdf4QtDocPageOrganizer/mainwindow.cpp b/Pdf4QtDocPageOrganizer/mainwindow.cpp index 4bf16b2..e99ca6d 100644 --- a/Pdf4QtDocPageOrganizer/mainwindow.cpp +++ b/Pdf4QtDocPageOrganizer/mainwindow.cpp @@ -37,6 +37,8 @@ #include #include #include +#include +#include namespace pdfdocpage { @@ -952,4 +954,77 @@ void MainWindow::performOperation(Operation operation) updateActions(); } +void MainWindow::dragEnterEvent(QDragEnterEvent* event) +{ + const QMimeData* mimeData = event->mimeData(); + if (mimeData->hasImage() || mimeData->hasUrls()) + { + event->acceptProposedAction(); + } +} + +void MainWindow::dropEvent(QDropEvent* event) +{ + event->ignore(); + + const QMimeData* mimeData = event->mimeData(); + if (mimeData->hasImage()) + { + QImage image = mimeData->imageData().value(); + if (!image.isNull()) + { + QModelIndexList indexes = ui->documentItemsView->selectionModel()->selection().indexes(); + QModelIndex insertIndex = !indexes.isEmpty() ? indexes.front() : QModelIndex(); + m_model->insertImage(image, insertIndex); + event->accept(); + } + } + else if (mimeData->hasUrls()) + { + QModelIndexList indexes = ui->documentItemsView->selectionModel()->selection().indexes(); + QModelIndex insertIndex = !indexes.isEmpty() ? indexes.front() : QModelIndex(); + + QList urls = mimeData->urls(); + std::reverse(urls.begin(), urls.end()); + QList supportedImageFormats = QImageReader::supportedImageFormats(); + + for (QUrl url : urls) + { + event->accept(); + + if (url.isLocalFile()) + { + QString fileName = url.toLocalFile(); + QFileInfo fileInfo(fileName); + QString suffix = fileInfo.suffix().toLower(); + + if (supportedImageFormats.contains(suffix.toUtf8())) + { + if (m_model->insertImage(fileName, insertIndex) == -1) + { + // Exit the loop if the image was not inserted. + event->ignore(); + break; + } + } + else if (suffix == "pdf") + { + if (!insertDocument(url.toLocalFile(), insertIndex)) + { + // Exit the loop if the document was not inserted. This could be because + // the document requires a password and the user might have provided an incorrect one, + // or the file couldn't be opened. We don't want to proceed with the next file. + event->ignore(); + break; + } + } + else + { + // We ignore other file extensions. + } + } + } + } +} + } // namespace pdfdocpage diff --git a/Pdf4QtDocPageOrganizer/mainwindow.h b/Pdf4QtDocPageOrganizer/mainwindow.h index 8ff1779..b0eb2dc 100644 --- a/Pdf4QtDocPageOrganizer/mainwindow.h +++ b/Pdf4QtDocPageOrganizer/mainwindow.h @@ -42,6 +42,9 @@ public: explicit MainWindow(QWidget* parent); virtual ~MainWindow() override; + virtual void dragEnterEvent(QDragEnterEvent* event) override; + virtual void dropEvent(QDropEvent* event) override; + QSize getMinPageImageSize() const; QSize getDefaultPageImageSize() const; QSize getMaxPageImageSize() const; diff --git a/Pdf4QtDocPageOrganizer/mainwindow.ui b/Pdf4QtDocPageOrganizer/mainwindow.ui index 777d1ca..8025ad1 100644 --- a/Pdf4QtDocPageOrganizer/mainwindow.ui +++ b/Pdf4QtDocPageOrganizer/mainwindow.ui @@ -10,6 +10,9 @@ 600 + + true + Workspace diff --git a/Pdf4QtDocPageOrganizer/pageitemmodel.cpp b/Pdf4QtDocPageOrganizer/pageitemmodel.cpp index 83bc09d..9ea0261 100644 --- a/Pdf4QtDocPageOrganizer/pageitemmodel.cpp +++ b/Pdf4QtDocPageOrganizer/pageitemmodel.cpp @@ -167,6 +167,47 @@ int PageItemModel::insertImage(QString fileName, const QModelIndex& index) return -1; } +int PageItemModel::insertImage(QImage image, const QModelIndex& index) +{ + Modifier modifier(this); + + if (!image.isNull()) + { + ImageItem item; + item.image = image; + int newIndex = 1; + + if (!m_images.empty()) + { + newIndex = (m_images.rbegin()->first) + 1; + } + + m_images[newIndex] = qMove(item); + + // Insert image item + PageGroupItem newItem; + + newItem.groups.reserve(1); + + PageGroupItem::GroupItem groupItem; + groupItem.imageIndex = newIndex; + groupItem.rotatedPageDimensionsMM = m_images[newIndex].image.size() * 0.1; + groupItem.pageType = PT_Image; + newItem.groups.push_back(qMove(groupItem)); + + updateItemCaptionAndTags(newItem); + int insertRow = index.isValid() ? index.row() + 1 : int(m_pageGroupItems.size()); + + beginInsertRows(QModelIndex(), insertRow, insertRow); + m_pageGroupItems.insert(std::next(m_pageGroupItems.begin(), insertRow), qMove(newItem)); + endInsertRows(); + + return newIndex; + } + + return -1; +} + const PageGroupItem* PageItemModel::getItem(const QModelIndex& index) const { if (index.isValid()) diff --git a/Pdf4QtDocPageOrganizer/pageitemmodel.h b/Pdf4QtDocPageOrganizer/pageitemmodel.h index e2d1f77..11833cc 100644 --- a/Pdf4QtDocPageOrganizer/pageitemmodel.h +++ b/Pdf4QtDocPageOrganizer/pageitemmodel.h @@ -131,6 +131,13 @@ public: /// \returns Identifier of the image (internal index) int insertImage(QString fileName, const QModelIndex& index); + /// Adds image to the model, inserts one single page containing + /// the image. Returns index of a newly added image. + /// \param image Image + /// \param index Index, where image is inserted + /// \returns Identifier of the image (internal index) + int insertImage(QImage image, const QModelIndex& index); + /// Returns item at a given index. If item doesn't exist, /// then nullptr is returned. /// \param index Index