From 83eb35e1c08458eeffdbc2c45bfa0748222dab34 Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Fri, 16 Jul 2021 18:43:34 +0200 Subject: [PATCH] Inserting blank pages --- Pdf4QtDocPageOrganizer/mainwindow.cpp | 25 +++++++ Pdf4QtDocPageOrganizer/mainwindow.h | 9 ++- Pdf4QtDocPageOrganizer/pageitemmodel.cpp | 95 +++++++++++++++++++++++- Pdf4QtDocPageOrganizer/pageitemmodel.h | 15 +++- 4 files changed, 139 insertions(+), 5 deletions(-) diff --git a/Pdf4QtDocPageOrganizer/mainwindow.cpp b/Pdf4QtDocPageOrganizer/mainwindow.cpp index fa74f57..f925b0a 100644 --- a/Pdf4QtDocPageOrganizer/mainwindow.cpp +++ b/Pdf4QtDocPageOrganizer/mainwindow.cpp @@ -27,6 +27,7 @@ #include #include #include +#include namespace pdfdocpage { @@ -69,6 +70,11 @@ MainWindow::MainWindow(QWidget* parent) : ui->actionUnited_Document->setData(int(Operation::Unite)); ui->actionSeparate_to_Multiple_Documents->setData(int(Operation::Separate)); ui->actionSeparate_to_Multiple_Documents_Grouped->setData(int(Operation::SeparateGrouped)); + ui->actionInsert_Image->setData(int(Operation::InsertImage)); + ui->actionInsert_Empty_Page->setData(int(Operation::InsertEmptyPage)); + ui->actionInsert_Page_from_PDF->setData(int(Operation::InsertPDF)); + ui->actionGet_Source->setData(int(Operation::GetSource)); + ui->actionAbout->setData(int(Operation::About)); QToolBar* mainToolbar = addToolBar(tr("Main")); mainToolbar->setObjectName("main_toolbar"); @@ -312,6 +318,13 @@ bool MainWindow::canPerformOperation(Operation operation) const case Operation::SeparateGrouped: return !isModelEmpty; + case Operation::InsertImage: + case Operation::InsertEmptyPage: + case Operation::InsertPDF: + case Operation::GetSource: + case Operation::About: + return true; + default: Q_ASSERT(false); break; @@ -462,6 +475,18 @@ void MainWindow::performOperation(Operation operation) Q_ASSERT(false); break; + case Operation::GetSource: + QDesktopServices::openUrl(QUrl("https://github.com/JakubMelka/PdfForQt")); + break; + + case Operation::InsertEmptyPage: + m_model->insertEmptyPage(ui->documentItemsView->selectionModel()->selection().indexes()); + break; + + case Operation::InsertImage: + case Operation::InsertPDF: + case Operation::About: + case Operation::Unite: case Operation::Separate: case Operation::SeparateGrouped: diff --git a/Pdf4QtDocPageOrganizer/mainwindow.h b/Pdf4QtDocPageOrganizer/mainwindow.h index df948bc..2d05138 100644 --- a/Pdf4QtDocPageOrganizer/mainwindow.h +++ b/Pdf4QtDocPageOrganizer/mainwindow.h @@ -75,7 +75,14 @@ public: Unite, Separate, - SeparateGrouped + SeparateGrouped, + + InsertImage, + InsertEmptyPage, + InsertPDF, + + GetSource, + About }; private slots: diff --git a/Pdf4QtDocPageOrganizer/pageitemmodel.cpp b/Pdf4QtDocPageOrganizer/pageitemmodel.cpp index d6a4cc9..4f48e53 100644 --- a/Pdf4QtDocPageOrganizer/pageitemmodel.cpp +++ b/Pdf4QtDocPageOrganizer/pageitemmodel.cpp @@ -344,6 +344,46 @@ void PageItemModel::removeSelection(const QModelIndexList& list) endResetModel(); } +void PageItemModel::insertEmptyPage(const QModelIndexList& list) +{ + if (list.isEmpty()) + { + insertEmptyPage(QModelIndex()); + } + else + { + QModelIndexList listCopy = list; + std::sort(listCopy.begin(), listCopy.end()); + std::reverse(listCopy.begin(), listCopy.end()); + + for (const QModelIndex& index: listCopy) + { + insertEmptyPage(index); + } + } +} + +void PageItemModel::insertEmptyPage(const QModelIndex& index) +{ + int insertRow = index.isValid()? index.row() + 1 : int(m_pageGroupItems.size()); + + const int templateRow = index.isValid() ? index.row() : int(m_pageGroupItems.size()) - 1; + const bool isTemplateRowValid = templateRow > -1; + + PageGroupItem::GroupItem groupItem; + groupItem.pageAdditionalRotation = isTemplateRowValid ? m_pageGroupItems[templateRow].groups.back().pageAdditionalRotation : pdf::PageRotation::None; + groupItem.pageType = PT_Empty; + groupItem.rotatedPageDimensionsMM = isTemplateRowValid ? m_pageGroupItems[templateRow].groups.back().rotatedPageDimensionsMM : QSizeF(210, 297); + + PageGroupItem blankPageItem; + blankPageItem.groups.push_back(groupItem); + updateItemCaptionAndTags(blankPageItem); + + beginInsertRows(QModelIndex(), insertRow, insertRow); + m_pageGroupItems.insert(std::next(m_pageGroupItems.begin(), insertRow), std::move(blankPageItem)); + endInsertRows(); +} + void PageItemModel::rotateLeft(const QModelIndexList& list) { if (list.isEmpty()) @@ -460,6 +500,11 @@ void PageItemModel::createDocumentGroup(int index) QString PageItemModel::getGroupNameFromDocument(int index) const { + if (index == -1) + { + return tr("Page Group"); + } + const DocumentItem& item = m_documents.at(index); QString title = item.document.getInfo()->title; @@ -482,7 +527,10 @@ void PageItemModel::updateItemCaptionAndTags(PageGroupItem& item) const pdf::PDFClosedIntervalSet pageSet; for (const auto& groupItem : item.groups) { - pageSet.addInterval(groupItem.pageIndex, groupItem.pageIndex); + if (groupItem.pageIndex != -1) + { + pageSet.addInterval(groupItem.pageIndex, groupItem.pageIndex); + } } item.groupName = getGroupNameFromDocument(*documentIndices.begin()); @@ -494,6 +542,41 @@ void PageItemModel::updateItemCaptionAndTags(PageGroupItem& item) const item.pagesCaption = tr("Page Count: %1").arg(item.groups.size()); } + bool hasImages = false; + bool hasEmptyPage = false; + + size_t imageCount = 0; + size_t emptyPageCount = 0; + + for (const PageGroupItem::GroupItem& group : item.groups) + { + switch (group.pageType) + { + case pdfdocpage::PT_DocumentPage: + break; + + case pdfdocpage::PT_Image: + hasImages = true; + ++imageCount; + break; + + case pdfdocpage::PT_Empty: + hasEmptyPage = true; + ++emptyPageCount; + break; + } + } + + if (imageCount == pageCount) + { + item.groupName = imageCount == 1 ? tr("Image") : tr("Images"); + } + + if (emptyPageCount == pageCount) + { + item.groupName = emptyPageCount == 1 ? tr("Blank Page") : tr("Blank Pages"); + } + item.tags.clear(); if (pageCount > 1) { @@ -501,7 +584,15 @@ void PageItemModel::updateItemCaptionAndTags(PageGroupItem& item) const } if (documentIndices.size() > 1) { - item.tags << QString("#BBBB00@Collection"); + item.tags << tr("#BBBB00@Collection"); + } + if (hasEmptyPage) + { + item.tags << tr("#D98335@Blank"); + } + if (hasImages) + { + item.tags << tr("#24A5EA@Image"); } } diff --git a/Pdf4QtDocPageOrganizer/pageitemmodel.h b/Pdf4QtDocPageOrganizer/pageitemmodel.h index 0e2b1b8..fb70491 100644 --- a/Pdf4QtDocPageOrganizer/pageitemmodel.h +++ b/Pdf4QtDocPageOrganizer/pageitemmodel.h @@ -26,6 +26,13 @@ namespace pdfdocpage { +enum PageType +{ + PT_DocumentPage, + PT_Image, + PT_Empty +}; + struct PageGroupItem { QString groupName; @@ -36,10 +43,12 @@ struct PageGroupItem { auto operator<=>(const GroupItem&) const = default; - int documentIndex = 0; - pdf::PDFInteger pageIndex; + int documentIndex = -1; + pdf::PDFInteger pageIndex = -1; + pdf::PDFInteger imageIndex = -1; QSizeF rotatedPageDimensionsMM; pdf::PageRotation pageAdditionalRotation = pdf::PageRotation::None; + PageType pageType = PT_DocumentPage; }; std::vector groups; @@ -122,6 +131,7 @@ public: QModelIndexList restoreRemovedItems(); QModelIndexList cloneSelection(const QModelIndexList& list); void removeSelection(const QModelIndexList& list); + void insertEmptyPage(const QModelIndexList& list); void rotateLeft(const QModelIndexList& list); void rotateRight(const QModelIndexList& list); @@ -132,6 +142,7 @@ private: void createDocumentGroup(int index); QString getGroupNameFromDocument(int index) const; void updateItemCaptionAndTags(PageGroupItem& item) const; + void insertEmptyPage(const QModelIndex& index); QItemSelection getSelectionImpl(std::function filter) const;