From 708a465068c77827684622449e43523c3027eef0 Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Mon, 18 Oct 2021 18:49:30 +0200 Subject: [PATCH] command line diff tool --- Pdf4QtDocDiff/mainwindow.ui | 68 ++++++++ Pdf4QtDocDiff/resources.qrc | 17 ++ .../resources/create-compare-report.svg | 108 +++++++++++++ .../resources/display-differences.svg | 108 +++++++++++++ Pdf4QtDocDiff/resources/display-markers.svg | 108 +++++++++++++ Pdf4QtDocDiff/resources/filter-images.svg | 108 +++++++++++++ .../resources/filter-page-movement.svg | 108 +++++++++++++ Pdf4QtDocDiff/resources/filter-shading.svg | 108 +++++++++++++ Pdf4QtDocDiff/resources/filter-text.svg | 108 +++++++++++++ .../resources/filter-vector-graphics.svg | 108 +++++++++++++ Pdf4QtDocDiff/resources/next-diff.svg | 108 +++++++++++++ Pdf4QtDocDiff/resources/prev-diff.svg | 108 +++++++++++++ Pdf4QtDocDiff/resources/save-diff-to-xml.svg | 108 +++++++++++++ Pdf4QtDocDiff/resources/show-p-with-diff.svg | 108 +++++++++++++ Pdf4QtDocDiff/resources/synchronize-view.svg | 108 +++++++++++++ Pdf4QtDocDiff/resources/view-differences.svg | 108 +++++++++++++ Pdf4QtDocDiff/resources/view-left.svg | 108 +++++++++++++ Pdf4QtDocDiff/resources/view-overlay.svg | 108 +++++++++++++ Pdf4QtDocDiff/resources/view-right.svg | 108 +++++++++++++ Pdf4QtLib/sources/pdfdiff.cpp | 43 +++++ Pdf4QtLib/sources/pdfdiff.h | 4 + Pdf4QtViewer/pdfprogramcontroller.cpp | 4 + PdfTool/PdfTool.pro | 2 + PdfTool/pdftoolabstractapplication.cpp | 11 ++ PdfTool/pdftoolabstractapplication.h | 4 + PdfTool/pdftooldiff.cpp | 152 ++++++++++++++++++ PdfTool/pdftooldiff.h | 36 +++++ 27 files changed, 2177 insertions(+) create mode 100644 Pdf4QtDocDiff/resources/create-compare-report.svg create mode 100644 Pdf4QtDocDiff/resources/display-differences.svg create mode 100644 Pdf4QtDocDiff/resources/display-markers.svg create mode 100644 Pdf4QtDocDiff/resources/filter-images.svg create mode 100644 Pdf4QtDocDiff/resources/filter-page-movement.svg create mode 100644 Pdf4QtDocDiff/resources/filter-shading.svg create mode 100644 Pdf4QtDocDiff/resources/filter-text.svg create mode 100644 Pdf4QtDocDiff/resources/filter-vector-graphics.svg create mode 100644 Pdf4QtDocDiff/resources/next-diff.svg create mode 100644 Pdf4QtDocDiff/resources/prev-diff.svg create mode 100644 Pdf4QtDocDiff/resources/save-diff-to-xml.svg create mode 100644 Pdf4QtDocDiff/resources/show-p-with-diff.svg create mode 100644 Pdf4QtDocDiff/resources/synchronize-view.svg create mode 100644 Pdf4QtDocDiff/resources/view-differences.svg create mode 100644 Pdf4QtDocDiff/resources/view-left.svg create mode 100644 Pdf4QtDocDiff/resources/view-overlay.svg create mode 100644 Pdf4QtDocDiff/resources/view-right.svg create mode 100644 PdfTool/pdftooldiff.cpp create mode 100644 PdfTool/pdftooldiff.h diff --git a/Pdf4QtDocDiff/mainwindow.ui b/Pdf4QtDocDiff/mainwindow.ui index 01d75b5..73670a4 100644 --- a/Pdf4QtDocDiff/mainwindow.ui +++ b/Pdf4QtDocDiff/mainwindow.ui @@ -162,6 +162,10 @@ + + + :/pdfdocdiff/resources/prev-diff.svg:/pdfdocdiff/resources/prev-diff.svg + Previous Difference @@ -170,6 +174,10 @@ + + + :/pdfdocdiff/resources/next-diff.svg:/pdfdocdiff/resources/next-diff.svg + Next Difference @@ -178,6 +186,10 @@ + + + :/pdfdocdiff/resources/create-compare-report.svg:/pdfdocdiff/resources/create-compare-report.svg + Create Compare Report @@ -186,6 +198,10 @@ true + + + :/pdfdocdiff/resources/filter-text.svg:/pdfdocdiff/resources/filter-text.svg + Filter Text @@ -194,6 +210,10 @@ true + + + :/pdfdocdiff/resources/filter-vector-graphics.svg:/pdfdocdiff/resources/filter-vector-graphics.svg + Filter Vector Graphics @@ -202,6 +222,10 @@ true + + + :/pdfdocdiff/resources/filter-images.svg:/pdfdocdiff/resources/filter-images.svg + Filter Images @@ -210,6 +234,10 @@ true + + + :/pdfdocdiff/resources/filter-shading.svg:/pdfdocdiff/resources/filter-shading.svg + Filter Shading @@ -218,6 +246,10 @@ true + + + :/pdfdocdiff/resources/filter-page-movement.svg:/pdfdocdiff/resources/filter-page-movement.svg + Filter Page Movement @@ -226,6 +258,10 @@ true + + + :/pdfdocdiff/resources/view-differences.svg:/pdfdocdiff/resources/view-differences.svg + View Differences @@ -234,6 +270,10 @@ true + + + :/pdfdocdiff/resources/view-left.svg:/pdfdocdiff/resources/view-left.svg + View Left @@ -242,6 +282,10 @@ true + + + :/pdfdocdiff/resources/view-right.svg:/pdfdocdiff/resources/view-right.svg + View Right @@ -250,6 +294,10 @@ true + + + :/pdfdocdiff/resources/view-overlay.svg:/pdfdocdiff/resources/view-overlay.svg + View Overlay @@ -258,6 +306,10 @@ true + + + :/pdfdocdiff/resources/show-p-with-diff.svg:/pdfdocdiff/resources/show-p-with-diff.svg + Show Pages with Differences @@ -266,6 +318,10 @@ + + + :/pdfdocdiff/resources/save-diff-to-xml.svg:/pdfdocdiff/resources/save-diff-to-xml.svg + Save Differences to XML @@ -274,6 +330,10 @@ true + + + :/pdfdocdiff/resources/synchronize-view.svg:/pdfdocdiff/resources/synchronize-view.svg + Synchronize View with Differences @@ -282,6 +342,10 @@ true + + + :/pdfdocdiff/resources/display-differences.svg:/pdfdocdiff/resources/display-differences.svg + Display Differences @@ -290,6 +354,10 @@ true + + + :/pdfdocdiff/resources/display-markers.svg:/pdfdocdiff/resources/display-markers.svg + Display Markers diff --git a/Pdf4QtDocDiff/resources.qrc b/Pdf4QtDocDiff/resources.qrc index 5b734bb..d77d0d1 100644 --- a/Pdf4QtDocDiff/resources.qrc +++ b/Pdf4QtDocDiff/resources.qrc @@ -6,5 +6,22 @@ resources/get-source.svg resources/open-left.svg resources/open-right.svg + resources/create-compare-report.svg + resources/filter-images.svg + resources/filter-page-movement.svg + resources/filter-shading.svg + resources/filter-text.svg + resources/filter-vector-graphics.svg + resources/next-diff.svg + resources/prev-diff.svg + resources/save-diff-to-xml.svg + resources/show-p-with-diff.svg + resources/synchronize-view.svg + resources/view-differences.svg + resources/view-left.svg + resources/view-overlay.svg + resources/view-right.svg + resources/display-differences.svg + resources/display-markers.svg diff --git a/Pdf4QtDocDiff/resources/create-compare-report.svg b/Pdf4QtDocDiff/resources/create-compare-report.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/create-compare-report.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/display-differences.svg b/Pdf4QtDocDiff/resources/display-differences.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/display-differences.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/display-markers.svg b/Pdf4QtDocDiff/resources/display-markers.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/display-markers.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/filter-images.svg b/Pdf4QtDocDiff/resources/filter-images.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/filter-images.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/filter-page-movement.svg b/Pdf4QtDocDiff/resources/filter-page-movement.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/filter-page-movement.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/filter-shading.svg b/Pdf4QtDocDiff/resources/filter-shading.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/filter-shading.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/filter-text.svg b/Pdf4QtDocDiff/resources/filter-text.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/filter-text.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/filter-vector-graphics.svg b/Pdf4QtDocDiff/resources/filter-vector-graphics.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/filter-vector-graphics.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/next-diff.svg b/Pdf4QtDocDiff/resources/next-diff.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/next-diff.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/prev-diff.svg b/Pdf4QtDocDiff/resources/prev-diff.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/prev-diff.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/save-diff-to-xml.svg b/Pdf4QtDocDiff/resources/save-diff-to-xml.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/save-diff-to-xml.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/show-p-with-diff.svg b/Pdf4QtDocDiff/resources/show-p-with-diff.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/show-p-with-diff.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/synchronize-view.svg b/Pdf4QtDocDiff/resources/synchronize-view.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/synchronize-view.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/view-differences.svg b/Pdf4QtDocDiff/resources/view-differences.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/view-differences.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/view-left.svg b/Pdf4QtDocDiff/resources/view-left.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/view-left.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/view-overlay.svg b/Pdf4QtDocDiff/resources/view-overlay.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/view-overlay.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtDocDiff/resources/view-right.svg b/Pdf4QtDocDiff/resources/view-right.svg new file mode 100644 index 0000000..d7478b4 --- /dev/null +++ b/Pdf4QtDocDiff/resources/view-right.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + diff --git a/Pdf4QtLib/sources/pdfdiff.cpp b/Pdf4QtLib/sources/pdfdiff.cpp index 5563803..838b01c 100644 --- a/Pdf4QtLib/sources/pdfdiff.cpp +++ b/Pdf4QtLib/sources/pdfdiff.cpp @@ -1312,6 +1312,49 @@ PDFDiffResult::Type PDFDiffResult::getType(size_t index) const return m_differences[index].type; } +QString PDFDiffResult::getTypeDescription(size_t index) const +{ + switch (getType(index)) + { + case Type::Invalid: + return PDFDiff::tr("Invalid"); + case Type::PageMoved: + return PDFDiff::tr("Page moved"); + case Type::PageAdded: + return PDFDiff::tr("Page added"); + case Type::PageRemoved: + return PDFDiff::tr("Page removed"); + case Type::RemovedTextCharContent: + return PDFDiff::tr("Removed text character"); + case Type::RemovedVectorGraphicContent: + return PDFDiff::tr("Removed vector graphics"); + case Type::RemovedImageContent: + return PDFDiff::tr("Removed image"); + case Type::RemovedShadingContent: + return PDFDiff::tr("Removed shading"); + case Type::AddedTextCharContent: + return PDFDiff::tr("Added text character"); + case Type::AddedVectorGraphicContent: + return PDFDiff::tr("Added vector graphics"); + case Type::AddedImageContent: + return PDFDiff::tr("Added image"); + case Type::AddedShadingContent: + return PDFDiff::tr("Added shading"); + case Type::TextAdded: + return PDFDiff::tr("Text added"); + case Type::TextRemoved: + return PDFDiff::tr("Text removed"); + case Type::TextReplaced: + return PDFDiff::tr("Text replaced"); + + default: + Q_ASSERT(false); + break; + } + + return QString(); +} + std::pair PDFDiffResult::getLeftRectangles(size_t index) const { if (index >= m_differences.size()) diff --git a/Pdf4QtLib/sources/pdfdiff.h b/Pdf4QtLib/sources/pdfdiff.h index 93ed911..f5f5952 100644 --- a/Pdf4QtLib/sources/pdfdiff.h +++ b/Pdf4QtLib/sources/pdfdiff.h @@ -103,6 +103,10 @@ public: /// \param index Index Type getType(size_t index) const; + /// Returns text description of type + /// \param index Index + QString getTypeDescription(size_t index) const; + /// Returns iterator range for rectangles of "left" pages of an item std::pair getLeftRectangles(size_t index) const; diff --git a/Pdf4QtViewer/pdfprogramcontroller.cpp b/Pdf4QtViewer/pdfprogramcontroller.cpp index 9bbb231..0ed5d5f 100644 --- a/Pdf4QtViewer/pdfprogramcontroller.cpp +++ b/Pdf4QtViewer/pdfprogramcontroller.cpp @@ -2151,6 +2151,10 @@ void PDFProgramController::onActionDeveloperCreateInstaller() addComponentMeta("pdf4qt_dpo", tr("DocPage Organizer"), tr("Document page organizer (split/merge documents, insert/remove/move/clone pages, insert blank pages and images to create a new document)."), pdf::PDF_LIBRARY_VERSION, "pdf4qt_dpo", false, true, false); addFileContent("pdf4qt_dpo", "Pdf4QtDocPageOrganizer.exe"); + addStartMenuShortcut("pdf4qt_diff", "Pdf4QtDocDiff", tr("PDF4QT DocDiff")); + addComponentMeta("pdf4qt_diff", tr("DocDiff"), tr("Compare content of two documents."), pdf::PDF_LIBRARY_VERSION, "pdf4qt_diff", false, true, false); + addFileContent("pdf4qt_diff", "Pdf4QtDocDiff.exe"); + addStartMenuShortcut("pdf4qt_tool", "PdfTool", tr("PDF4QT Command Line Tool")); addComponentMeta("pdf4qt_tool", tr("PdfTool"), tr("Command line tool for manipulation of PDF files with many functions."), pdf::PDF_LIBRARY_VERSION, "pdf4qt_tool", false, false, false); addFileContent("pdf4qt_tool", "PdfTool.exe"); diff --git a/PdfTool/PdfTool.pro b/PdfTool/PdfTool.pro index 88ee7f5..8b7c55a 100644 --- a/PdfTool/PdfTool.pro +++ b/PdfTool/PdfTool.pro @@ -47,6 +47,7 @@ SOURCES += \ pdftoolcertstore.cpp \ pdftoolcolorprofiles.cpp \ pdftooldecrypt.cpp \ + pdftooldiff.cpp \ pdftoolencrypt.cpp \ pdftoolfetchimages.cpp \ pdftoolfetchtext.cpp \ @@ -80,6 +81,7 @@ HEADERS += \ pdftoolcertstore.h \ pdftoolcolorprofiles.h \ pdftooldecrypt.h \ + pdftooldiff.h \ pdftoolencrypt.h \ pdftoolfetchimages.h \ pdftoolfetchtext.h \ diff --git a/PdfTool/pdftoolabstractapplication.cpp b/PdfTool/pdftoolabstractapplication.cpp index 1d529fb..8508fc8 100644 --- a/PdfTool/pdftoolabstractapplication.cpp +++ b/PdfTool/pdftoolabstractapplication.cpp @@ -175,6 +175,12 @@ void PDFToolAbstractApplication::initializeCommandLineParser(QCommandLineParser* parser->addPositionalArgument("target", "Merged document filename."); } + if (optionFlags.testFlag(Diff)) + { + parser->addPositionalArgument("left", "Left (old) document to be compared."); + parser->addPositionalArgument("right", "Right (new) document to be compared."); + } + if (optionFlags.testFlag(SignatureVerification)) { parser->addOption(QCommandLineOption("ver-no-user-cert", "Disable user certificate store.")); @@ -882,6 +888,11 @@ PDFToolOptions PDFToolAbstractApplication::getOptions(QCommandLineParser* parser options.uniteFiles = positionalArguments; } + if (optionFlags.testFlag(Diff)) + { + options.diffFiles = positionalArguments; + } + if (optionFlags.testFlag(Optimize)) { options.optimizeFlags = pdf::PDFOptimizer::None; diff --git a/PdfTool/pdftoolabstractapplication.h b/PdfTool/pdftoolabstractapplication.h index 7a4504e..782883f 100644 --- a/PdfTool/pdftoolabstractapplication.h +++ b/PdfTool/pdftoolabstractapplication.h @@ -136,6 +136,9 @@ struct PDFToolOptions // For option 'Unite' QStringList uniteFiles; + // For option 'Diff' + QStringList diffFiles; + // For option 'Optimize' pdf::PDFOptimizer::OptimizationFlags optimizeFlags = pdf::PDFOptimizer::None; @@ -238,6 +241,7 @@ public: CertStore = 0x00200000, ///< Settings for certificate store tool CertStoreInstall = 0x00400000, ///< Settings for certificate store install certificate tool Encrypt = 0x00800000, ///< Encryption settings + Diff = 0x01000000, ///< Diff settings (compare documents) }; Q_DECLARE_FLAGS(Options, Option) diff --git a/PdfTool/pdftooldiff.cpp b/PdfTool/pdftooldiff.cpp new file mode 100644 index 0000000..8e5a5ee --- /dev/null +++ b/PdfTool/pdftooldiff.cpp @@ -0,0 +1,152 @@ +// Copyright (C) 2021 Jakub Melka +// +// This file is part of PDF4QT. +// +// PDF4QT is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// with the written consent of the copyright owner, any later version. +// +// PDF4QT is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with PDF4QT. If not, see . + +#include "pdftooldiff.h" + +#include "pdfdiff.h" +#include "pdfdocumentreader.h" + +namespace pdftool +{ + +static PDFToolDiff s_toolDiffApplication; + +QString PDFToolDiff::getStandardString(PDFToolAbstractApplication::StandardString standardString) const +{ + switch (standardString) + { + case Command: + return "diff"; + + case Name: + return PDFToolTranslationContext::tr("Compare documents"); + + case Description: + return PDFToolTranslationContext::tr("Compare contents of two documents."); + + default: + Q_ASSERT(false); + break; + } + + return QString(); +} + +int PDFToolDiff::execute(const PDFToolOptions& options) +{ + if (options.diffFiles.size() != 2) + { + PDFConsole::writeError(PDFToolTranslationContext::tr("Exactly two documents must be specified."), options.outputCodec); + return ErrorInvalidArguments; + } + + pdf::PDFDocumentReader reader(nullptr, [](bool* ok) { *ok = false; return QString(); }, options.permissiveReading, false); + + pdf::PDFDocument leftDocument = reader.readFromFile(options.diffFiles.front()); + if (reader.getReadingResult() != pdf::PDFDocumentReader::Result::OK) + { + PDFConsole::writeError(PDFToolTranslationContext::tr("Cannot open document '%1'.").arg(options.diffFiles.front()), options.outputCodec); + return ErrorDocumentReading; + } + + pdf::PDFDocument rightDocument = reader.readFromFile(options.diffFiles.back()); + if (reader.getReadingResult() != pdf::PDFDocumentReader::Result::OK) + { + PDFConsole::writeError(PDFToolTranslationContext::tr("Cannot open document '%1'.").arg(options.diffFiles.back()), options.outputCodec); + return ErrorDocumentReading; + } + + pdf::PDFClosedIntervalSet leftPages; + leftPages.addInterval(0, leftDocument.getCatalog()->getPageCount() - 1); + + pdf::PDFClosedIntervalSet rightPages; + rightPages.addInterval(0, rightDocument.getCatalog()->getPageCount() - 1); + + pdf::PDFDiff diff(nullptr); + diff.setOption(pdf::PDFDiff::Asynchronous, false); + diff.setLeftDocument(&leftDocument); + diff.setRightDocument(&rightDocument); + diff.setPagesForLeftDocument(std::move(leftPages)); + diff.setPagesForRightDocument(std::move(rightPages)); + diff.start(); + + QLocale locale; + + const pdf::PDFDiffResult& result = diff.getResult(); + if (result.getResult()) + { + PDFOutputFormatter formatter(options.outputStyle, options.outputCodec); + formatter.beginDocument("diff", PDFToolTranslationContext::tr("Difference Report").arg(options.document)); + formatter.endl(); + + formatter.beginTable("differences", PDFToolTranslationContext::tr("Differences")); + + formatter.beginTableHeaderRow("header"); + formatter.writeTableHeaderColumn("no", PDFToolTranslationContext::tr("No."), Qt::AlignLeft); + formatter.writeTableHeaderColumn("type", PDFToolTranslationContext::tr("Type"), Qt::AlignLeft); + formatter.writeTableHeaderColumn("left-page-number", PDFToolTranslationContext::tr("Left Page"), Qt::AlignLeft); + formatter.writeTableHeaderColumn("right-page-number", PDFToolTranslationContext::tr("Right Page"), Qt::AlignLeft); + formatter.writeTableHeaderColumn("description", PDFToolTranslationContext::tr("Description"), Qt::AlignLeft); + formatter.endTableHeaderRow(); + + const size_t size = result.getDifferencesCount(); + for (size_t i = 0; i < size; ++i) + { + pdf::PDFInteger leftPageIndex = result.getLeftPage(i); + pdf::PDFInteger rightPageIndex = result.getRightPage(i); + + QString leftPageDescription = leftPageIndex != -1 ? locale.toString(leftPageIndex + 1) : QString(); + QString rightPageDescription = rightPageIndex != -1 ? locale.toString(rightPageIndex + 1) : QString(); + + formatter.beginTableRow("difference", int(i)); + formatter.writeTableColumn("no", locale.toString(i + 1), Qt::AlignRight); + formatter.writeTableColumn("type", result.getTypeDescription(i), Qt::AlignLeft); + formatter.writeTableColumn("left-page-number", leftPageDescription, Qt::AlignRight); + formatter.writeTableColumn("right-page-number", rightPageDescription, Qt::AlignRight); + formatter.writeTableColumn("description", result.getMessage(i), Qt::AlignLeft); + formatter.endTableRow(); + } + + formatter.endTable(); + formatter.endDocument(); + + if (options.outputStyle == PDFOutputFormatter::Style::Xml) + { + QString xml; + result.saveToXML(&xml); + PDFConsole::writeText(xml, options.outputCodec); + } + else + { + PDFConsole::writeText(formatter.getString(), options.outputCodec); + } + } + else + { + PDFConsole::writeError(result.getResult().getErrorMessage(), options.outputCodec); + return ErrorUnknown; + } + + return ExitSuccess; +} + +PDFToolAbstractApplication::Options PDFToolDiff::getOptionsFlags() const +{ + return ConsoleFormat | Diff; +} + +} // namespace pdftool diff --git a/PdfTool/pdftooldiff.h b/PdfTool/pdftooldiff.h new file mode 100644 index 0000000..0a53851 --- /dev/null +++ b/PdfTool/pdftooldiff.h @@ -0,0 +1,36 @@ +// Copyright (C) 2021 Jakub Melka +// +// This file is part of PDF4QT. +// +// PDF4QT is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// with the written consent of the copyright owner, any later version. +// +// PDF4QT is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with PDF4QT. If not, see . + +#ifndef PDFTOOLDIFF_H +#define PDFTOOLDIFF_H + +#include "pdftoolabstractapplication.h" + +namespace pdftool +{ + +class PDFToolDiff : public PDFToolAbstractApplication +{ +public: + virtual QString getStandardString(StandardString standardString) const override; + virtual int execute(const PDFToolOptions& options) override; + virtual Options getOptionsFlags() const override; +}; + +} // namespace pdftool + +#endif // PDFTOOLDIFF_H