Issue #244: PageMaster: united one document after remove pages leads to lose the outline

This commit is contained in:
Jakub Melka
2025-03-02 19:41:41 +01:00
parent 63d81e751d
commit abeb1dd458
3 changed files with 56 additions and 2 deletions

View File

@ -37,6 +37,7 @@ PDFOperationResult PDFDocumentManipulator::assemble(const AssembledPages& pages)
try try
{ {
classify(pages); classify(pages);
const PDFDocument* singleDocument = nullptr;
pdf::PDFDocumentBuilder documentBuilder; pdf::PDFDocumentBuilder documentBuilder;
if (m_flags.testFlag(SingleDocument)) if (m_flags.testFlag(SingleDocument))
@ -56,7 +57,8 @@ PDFOperationResult PDFDocumentManipulator::assemble(const AssembledPages& pages)
throw PDFException(tr("Invalid document.")); throw PDFException(tr("Invalid document."));
} }
documentBuilder.setDocument(m_documents.at(documentIndex)); singleDocument = m_documents.at(documentIndex);
documentBuilder.setDocument(singleDocument);
} }
else else
{ {
@ -72,9 +74,13 @@ PDFOperationResult PDFDocumentManipulator::assemble(const AssembledPages& pages)
// Correct page tree (invalid parents are present) // Correct page tree (invalid parents are present)
documentBuilder.flattenPageTree(); documentBuilder.flattenPageTree();
if (!m_flags.testFlag(SingleDocument) || m_flags.testFlag(RemovedPages)) if (!m_flags.testFlag(SingleDocument))
{ {
documentBuilder.removeOutline(); documentBuilder.removeOutline();
}
if (!m_flags.testFlag(SingleDocument) || m_flags.testFlag(RemovedPages))
{
documentBuilder.removeThreads(); documentBuilder.removeThreads();
documentBuilder.removeDocumentActions(); documentBuilder.removeDocumentActions();
documentBuilder.removeStructureTree(); documentBuilder.removeStructureTree();
@ -86,6 +92,10 @@ PDFOperationResult PDFDocumentManipulator::assemble(const AssembledPages& pages)
{ {
addOutlineAndDocumentParts(documentBuilder, pages, adjustedPages); addOutlineAndDocumentParts(documentBuilder, pages, adjustedPages);
} }
else if (m_flags.testFlag(RemovedPages) && singleDocument)
{
filterOutline(documentBuilder, singleDocument, adjustedPages);
}
pdf::PDFDocument mergedDocument = documentBuilder.build(); pdf::PDFDocument mergedDocument = documentBuilder.build();
@ -487,6 +497,46 @@ void PDFDocumentManipulator::finalizeDocument(PDFDocument* document)
m_assembledDocument = finalBuilder.build(); m_assembledDocument = finalBuilder.build();
} }
void PDFDocumentManipulator::filterOutline(PDFDocumentBuilder& documentBuilder,
const PDFDocument* singleDocument,
const std::vector<PDFObjectReference>& adjustedPages)
{
QSharedPointer<PDFOutlineItem> outline = singleDocument->getCatalog()->getOutlineRootPtr();
if (outline)
{
outline = outline->clone();
std::set<PDFObjectReference> adjustedPagesSet(adjustedPages.cbegin(), adjustedPages.cend());
std::function<void(QSharedPointer<PDFOutlineItem>&)> filter = [&adjustedPagesSet](QSharedPointer<PDFOutlineItem>& 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<const PDFActionGoTo*>(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, void PDFDocumentManipulator::addOutlineAndDocumentParts(PDFDocumentBuilder& documentBuilder,
const AssembledPages& pages, const AssembledPages& pages,
const std::vector<PDFObjectReference>& adjustedPages) const std::vector<PDFObjectReference>& adjustedPages)

View File

@ -145,6 +145,9 @@ private:
void addOutlineAndDocumentParts(PDFDocumentBuilder& documentBuilder, void addOutlineAndDocumentParts(PDFDocumentBuilder& documentBuilder,
const AssembledPages& pages, const AssembledPages& pages,
const std::vector<PDFObjectReference>& adjustedPages); const std::vector<PDFObjectReference>& adjustedPages);
void filterOutline(PDFDocumentBuilder& documentBuilder,
const PDFDocument* singleDocument,
const std::vector<PDFObjectReference>& adjustedPages);
std::map<PDFInteger, const PDFDocument*> m_documents; std::map<PDFInteger, const PDFDocument*> m_documents;
std::map<PDFInteger, QImage> m_images; std::map<PDFInteger, QImage> m_images;

View File

@ -1,4 +1,5 @@
CURRENT: 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 #236: Highligting - Allow color selection and intensity [Enhancement]
- Issue #229: Can't add picture to PDF - Issue #229: Can't add picture to PDF
- Issue #228: [feature] reverse pages order - Issue #228: [feature] reverse pages order