diff --git a/Pdf4QtLibCore/sources/pdfdocumentmanipulator.cpp b/Pdf4QtLibCore/sources/pdfdocumentmanipulator.cpp index 4fc5fc1..4841369 100644 --- a/Pdf4QtLibCore/sources/pdfdocumentmanipulator.cpp +++ b/Pdf4QtLibCore/sources/pdfdocumentmanipulator.cpp @@ -37,6 +37,7 @@ PDFOperationResult PDFDocumentManipulator::assemble(const AssembledPages& pages) try { classify(pages); + const PDFDocument* singleDocument = nullptr; pdf::PDFDocumentBuilder documentBuilder; if (m_flags.testFlag(SingleDocument)) @@ -56,7 +57,8 @@ PDFOperationResult PDFDocumentManipulator::assemble(const AssembledPages& pages) throw PDFException(tr("Invalid document.")); } - documentBuilder.setDocument(m_documents.at(documentIndex)); + singleDocument = m_documents.at(documentIndex); + documentBuilder.setDocument(singleDocument); } else { @@ -72,9 +74,13 @@ PDFOperationResult PDFDocumentManipulator::assemble(const AssembledPages& pages) // Correct page tree (invalid parents are present) documentBuilder.flattenPageTree(); - if (!m_flags.testFlag(SingleDocument) || m_flags.testFlag(RemovedPages)) + if (!m_flags.testFlag(SingleDocument)) { documentBuilder.removeOutline(); + } + + if (!m_flags.testFlag(SingleDocument) || m_flags.testFlag(RemovedPages)) + { documentBuilder.removeThreads(); documentBuilder.removeDocumentActions(); documentBuilder.removeStructureTree(); @@ -86,6 +92,10 @@ PDFOperationResult PDFDocumentManipulator::assemble(const AssembledPages& pages) { addOutlineAndDocumentParts(documentBuilder, pages, adjustedPages); } + else if (m_flags.testFlag(RemovedPages) && singleDocument) + { + filterOutline(documentBuilder, singleDocument, adjustedPages); + } pdf::PDFDocument mergedDocument = documentBuilder.build(); @@ -487,6 +497,46 @@ void PDFDocumentManipulator::finalizeDocument(PDFDocument* document) m_assembledDocument = finalBuilder.build(); } +void PDFDocumentManipulator::filterOutline(PDFDocumentBuilder& documentBuilder, + const PDFDocument* singleDocument, + const std::vector& adjustedPages) +{ + QSharedPointer outline = singleDocument->getCatalog()->getOutlineRootPtr(); + if (outline) + { + outline = outline->clone(); + std::set adjustedPagesSet(adjustedPages.cbegin(), adjustedPages.cend()); + + std::function&)> filter = [&adjustedPagesSet](QSharedPointer& item) + { + for (size_t i = 0; i < item->getChildCount();) + { + bool shouldRemove = false; + const PDFOutlineItem* childItem = item->getChild(i); + const PDFAction* action = childItem->getAction(); + const PDFActionGoTo* actionGoTo = dynamic_cast(action); + if (actionGoTo) + { + const PDFObjectReference pageReference = actionGoTo->getDestination().getPageReference(); + shouldRemove = !adjustedPagesSet.count(pageReference); + } + + if (shouldRemove) + { + item->removeChild(i); + } + else + { + ++i; + } + } + }; + + filter(outline); + documentBuilder.setOutline(outline.data()); + } +} + void PDFDocumentManipulator::addOutlineAndDocumentParts(PDFDocumentBuilder& documentBuilder, const AssembledPages& pages, const std::vector& adjustedPages) diff --git a/Pdf4QtLibCore/sources/pdfdocumentmanipulator.h b/Pdf4QtLibCore/sources/pdfdocumentmanipulator.h index 0a1d208..559c20a 100644 --- a/Pdf4QtLibCore/sources/pdfdocumentmanipulator.h +++ b/Pdf4QtLibCore/sources/pdfdocumentmanipulator.h @@ -145,6 +145,9 @@ private: void addOutlineAndDocumentParts(PDFDocumentBuilder& documentBuilder, const AssembledPages& pages, const std::vector& adjustedPages); + void filterOutline(PDFDocumentBuilder& documentBuilder, + const PDFDocument* singleDocument, + const std::vector& adjustedPages); std::map m_documents; std::map m_images; diff --git a/RELEASES.txt b/RELEASES.txt index 2f2ef03..c2ad47b 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -1,4 +1,5 @@ CURRENT: + - Issue #244: PageMaster: united one document after remove pages leads to lose the outline - Issue #236: Highligting - Allow color selection and intensity [Enhancement] - Issue #229: Can't add picture to PDF - Issue #228: [feature] reverse pages order