mirror of https://github.com/JakubMelka/PDF4QT.git
DocDiff application: document view update
This commit is contained in:
parent
8975a18d93
commit
41889070fb
|
@ -41,3 +41,4 @@ Pdf4QtViewerPlugins.depends = Pdf4QtLib
|
||||||
Pdf4QtViewerProfi.depends = Pdf4QtViewer
|
Pdf4QtViewerProfi.depends = Pdf4QtViewer
|
||||||
Pdf4QtViewerLite.depends = Pdf4QtViewer
|
Pdf4QtViewerLite.depends = Pdf4QtViewer
|
||||||
Pdf4QtDocPageOrganizer.depends = Pdf4QtLib
|
Pdf4QtDocPageOrganizer.depends = Pdf4QtLib
|
||||||
|
Pdf4QtDocDiff.depends = Pdf4QtLib
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "pdfwidgetutils.h"
|
#include "pdfwidgetutils.h"
|
||||||
#include "pdfdocumentreader.h"
|
#include "pdfdocumentreader.h"
|
||||||
#include "pdfdrawspacecontroller.h"
|
#include "pdfdrawspacecontroller.h"
|
||||||
|
#include "pdfdocumentmanipulator.h"
|
||||||
|
|
||||||
#include <QToolBar>
|
#include <QToolBar>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
|
@ -206,6 +207,25 @@ void MainWindow::onComparationFinished()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create merged document
|
||||||
|
pdf::PDFDocumentManipulator manipulator;
|
||||||
|
manipulator.setOutlineMode(pdf::PDFDocumentManipulator::OutlineMode::NoOutline);
|
||||||
|
manipulator.addDocument(1, &m_leftDocument);
|
||||||
|
manipulator.addDocument(2, &m_rightDocument);
|
||||||
|
|
||||||
|
pdf::PDFDocumentManipulator::AssembledPages assembledPages1 = pdf::PDFDocumentManipulator::createAllDocumentPages(1, &m_leftDocument);
|
||||||
|
pdf::PDFDocumentManipulator::AssembledPages assembledPages2 = pdf::PDFDocumentManipulator::createAllDocumentPages(2, &m_rightDocument);
|
||||||
|
assembledPages1.insert(assembledPages1.end(), std::make_move_iterator(assembledPages2.begin()), std::make_move_iterator(assembledPages2.end()));
|
||||||
|
|
||||||
|
if (manipulator.assemble(assembledPages1))
|
||||||
|
{
|
||||||
|
m_combinedDocument = manipulator.takeAssembledDocument();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_combinedDocument = pdf::PDFDocument();
|
||||||
|
}
|
||||||
|
|
||||||
updateAll(true);
|
updateAll(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,8 +486,16 @@ void MainWindow::performOperation(Operation operation)
|
||||||
case Operation::FilterImages:
|
case Operation::FilterImages:
|
||||||
case Operation::FilterShading:
|
case Operation::FilterShading:
|
||||||
case Operation::FilterPageMovement:
|
case Operation::FilterPageMovement:
|
||||||
|
{
|
||||||
updateFilteredResult();
|
updateFilteredResult();
|
||||||
|
|
||||||
|
if (ui->actionShow_Pages_with_Differences->isChecked())
|
||||||
|
{
|
||||||
|
updateCustomPageLayout();
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Operation::ViewDifferences:
|
case Operation::ViewDifferences:
|
||||||
case Operation::ViewLeft:
|
case Operation::ViewLeft:
|
||||||
|
@ -477,6 +505,9 @@ void MainWindow::performOperation(Operation operation)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Operation::ShowPageswithDifferences:
|
case Operation::ShowPageswithDifferences:
|
||||||
|
updateCustomPageLayout();
|
||||||
|
break;
|
||||||
|
|
||||||
case Operation::SaveDifferencesToXML:
|
case Operation::SaveDifferencesToXML:
|
||||||
case Operation::CreateCompareReport:
|
case Operation::CreateCompareReport:
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
|
@ -492,7 +523,7 @@ void MainWindow::performOperation(Operation operation)
|
||||||
updateActions();
|
updateActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setViewDocument(pdf::PDFDocument* document)
|
void MainWindow::setViewDocument(pdf::PDFDocument* document, bool updateCustomPageLayout)
|
||||||
{
|
{
|
||||||
if (document != m_pdfWidget->getDrawWidgetProxy()->getDocument())
|
if (document != m_pdfWidget->getDrawWidgetProxy()->getDocument())
|
||||||
{
|
{
|
||||||
|
@ -514,11 +545,36 @@ void MainWindow::setViewDocument(pdf::PDFDocument* document)
|
||||||
m_pdfWidget->setDocument(pdf::PDFModifiedDocument());
|
m_pdfWidget->setDocument(pdf::PDFModifiedDocument());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (updateCustomPageLayout)
|
||||||
|
{
|
||||||
|
this->updateCustomPageLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ComparedDocumentMapper::Mode MainWindow::getDocumentViewMode() const
|
||||||
|
{
|
||||||
|
if (ui->actionView_Left->isChecked())
|
||||||
|
{
|
||||||
|
return ComparedDocumentMapper::Mode::Left;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ui->actionView_Right->isChecked())
|
||||||
|
{
|
||||||
|
return ComparedDocumentMapper::Mode::Right;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ui->actionView_Overlay->isChecked())
|
||||||
|
{
|
||||||
|
return ComparedDocumentMapper::Mode::Overlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ComparedDocumentMapper::Mode::Combined;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::clear(bool clearLeftDocument, bool clearRightDocument)
|
void MainWindow::clear(bool clearLeftDocument, bool clearRightDocument)
|
||||||
{
|
{
|
||||||
setViewDocument(nullptr);
|
setViewDocument(nullptr, true);
|
||||||
|
|
||||||
if (clearLeftDocument)
|
if (clearLeftDocument)
|
||||||
{
|
{
|
||||||
|
@ -575,22 +631,37 @@ void MainWindow::updateViewDocument()
|
||||||
{
|
{
|
||||||
pdf::PDFDocument* document = nullptr;
|
pdf::PDFDocument* document = nullptr;
|
||||||
|
|
||||||
if (ui->actionView_Left->isChecked())
|
switch (getDocumentViewMode())
|
||||||
{
|
{
|
||||||
|
case ComparedDocumentMapper::Mode::Left:
|
||||||
document = &m_leftDocument;
|
document = &m_leftDocument;
|
||||||
}
|
break;
|
||||||
|
|
||||||
if (ui->actionView_Right->isChecked())
|
case ComparedDocumentMapper::Mode::Right:
|
||||||
{
|
|
||||||
document = &m_rightDocument;
|
document = &m_rightDocument;
|
||||||
}
|
break;
|
||||||
|
|
||||||
if (ui->actionView_Differences->isChecked() || ui->actionView_Overlay->isChecked())
|
case ComparedDocumentMapper::Mode::Combined:
|
||||||
{
|
case ComparedDocumentMapper::Mode::Overlay:
|
||||||
document = &m_combinedDocument;
|
document = &m_combinedDocument;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
setViewDocument(document);
|
setViewDocument(document, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateCustomPageLayout()
|
||||||
|
{
|
||||||
|
m_documentMapper.update(getDocumentViewMode(),
|
||||||
|
ui->actionShow_Pages_with_Differences->isChecked(),
|
||||||
|
m_filteredDiffResult,
|
||||||
|
&m_leftDocument,
|
||||||
|
&m_rightDocument,
|
||||||
|
m_pdfWidget->getDrawWidgetProxy()->getDocument());
|
||||||
|
|
||||||
|
|
||||||
|
m_pdfWidget->getDrawWidgetProxy()->setCustomPageLayout(m_documentMapper.getLayout());
|
||||||
|
m_pdfWidget->getDrawWidgetProxy()->setPageLayout(pdf::PageLayout::Custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<pdf::PDFDocument> MainWindow::openDocument()
|
std::optional<pdf::PDFDocument> MainWindow::openDocument()
|
||||||
|
@ -652,4 +723,131 @@ void MainWindow::onProgressFinished()
|
||||||
m_progressTaskbarIndicator->hide();
|
m_progressTaskbarIndicator->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ComparedDocumentMapper::update(ComparedDocumentMapper::Mode mode,
|
||||||
|
bool filterDifferences,
|
||||||
|
const pdf::PDFDiffResult& diff,
|
||||||
|
const pdf::PDFDocument* leftDocument,
|
||||||
|
const pdf::PDFDocument* rightDocument,
|
||||||
|
const pdf::PDFDocument* currentDocument)
|
||||||
|
{
|
||||||
|
m_layout.clear();
|
||||||
|
|
||||||
|
if (!leftDocument || !rightDocument || !currentDocument)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jakub Melka
|
||||||
|
pdf::PDFDiffResult::PageSequence pageSequence = diff.getPageSequence();
|
||||||
|
const bool isEmpty = pageSequence.empty();
|
||||||
|
|
||||||
|
if (filterDifferences)
|
||||||
|
{
|
||||||
|
pdf::PDFDiffResult::PageSequence filteredPageSequence;
|
||||||
|
|
||||||
|
std::vector<pdf::PDFInteger> leftPageIndices = diff.getChangedLeftPageIndices();
|
||||||
|
std::vector<pdf::PDFInteger> rightPageIndices = diff.getChangedRightPageIndices();
|
||||||
|
|
||||||
|
for (const pdf::PDFDiffResult::PageSequenceItem& item : pageSequence)
|
||||||
|
{
|
||||||
|
const bool isLeftModified = std::binary_search(leftPageIndices.cbegin(), leftPageIndices.cend(), item.leftPage);
|
||||||
|
const bool isRightModified = std::binary_search(rightPageIndices.cbegin(), rightPageIndices.cend(), item.rightPage);
|
||||||
|
|
||||||
|
if (isLeftModified || isRightModified)
|
||||||
|
{
|
||||||
|
filteredPageSequence.push_back(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pageSequence = std::move(filteredPageSequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case ComparedDocumentMapper::Mode::Left:
|
||||||
|
{
|
||||||
|
Q_ASSERT(leftDocument == currentDocument);
|
||||||
|
|
||||||
|
double yPos = 0.0;
|
||||||
|
const pdf::PDFCatalog* catalog = leftDocument->getCatalog();
|
||||||
|
|
||||||
|
if (isEmpty)
|
||||||
|
{
|
||||||
|
// Just copy all pages
|
||||||
|
const size_t pageCount = catalog->getPageCount();
|
||||||
|
for (size_t i = 0; i < pageCount; ++i)
|
||||||
|
{
|
||||||
|
QSizeF pageSize = catalog->getPage(i)->getRotatedMediaBoxMM().size();
|
||||||
|
QRectF rect(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
|
||||||
|
m_layout.emplace_back(0, i, rect);
|
||||||
|
yPos += pageSize.height() + 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const pdf::PDFDiffResult::PageSequenceItem& item : pageSequence)
|
||||||
|
{
|
||||||
|
if (item.leftPage == -1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSizeF pageSize = catalog->getPage(item.leftPage)->getRotatedMediaBoxMM().size();
|
||||||
|
QRectF rect(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
|
||||||
|
m_layout.emplace_back(0, item.leftPage, rect);
|
||||||
|
yPos += pageSize.height() + 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ComparedDocumentMapper::Mode::Right:
|
||||||
|
{
|
||||||
|
Q_ASSERT(rightDocument == currentDocument);
|
||||||
|
|
||||||
|
double yPos = 0.0;
|
||||||
|
const pdf::PDFCatalog* catalog = rightDocument->getCatalog();
|
||||||
|
|
||||||
|
if (isEmpty)
|
||||||
|
{
|
||||||
|
// Just copy all pages
|
||||||
|
const size_t pageCount = catalog->getPageCount();
|
||||||
|
for (size_t i = 0; i < pageCount; ++i)
|
||||||
|
{
|
||||||
|
QSizeF pageSize = catalog->getPage(i)->getRotatedMediaBoxMM().size();
|
||||||
|
QRectF rect(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
|
||||||
|
m_layout.emplace_back(0, i, rect);
|
||||||
|
yPos += pageSize.height() + 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const pdf::PDFDiffResult::PageSequenceItem& item : pageSequence)
|
||||||
|
{
|
||||||
|
if (item.rightPage == -1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSizeF pageSize = catalog->getPage(item.rightPage)->getRotatedMediaBoxMM().size();
|
||||||
|
QRectF rect(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
|
||||||
|
m_layout.emplace_back(0, item.rightPage, rect);
|
||||||
|
yPos += pageSize.height() + 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ComparedDocumentMapper::Mode::Combined:
|
||||||
|
case ComparedDocumentMapper::Mode::Overlay:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Q_ASSERT(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace pdfdocdiff
|
} // namespace pdfdocdiff
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "pdfdrawwidget.h"
|
#include "pdfdrawwidget.h"
|
||||||
#include "pdfcms.h"
|
#include "pdfcms.h"
|
||||||
#include "pdfoptionalcontent.h"
|
#include "pdfoptionalcontent.h"
|
||||||
|
#include "pdfdrawspacecontroller.h"
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QSignalMapper>
|
#include <QSignalMapper>
|
||||||
|
@ -42,6 +43,33 @@ namespace pdfdocdiff
|
||||||
class SettingsDockWidget;
|
class SettingsDockWidget;
|
||||||
class DifferencesDockWidget;
|
class DifferencesDockWidget;
|
||||||
|
|
||||||
|
class ComparedDocumentMapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum class Mode
|
||||||
|
{
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
Combined,
|
||||||
|
Overlay
|
||||||
|
};
|
||||||
|
|
||||||
|
void update(Mode mode,
|
||||||
|
bool filterDifferences,
|
||||||
|
const pdf::PDFDiffResult& diff,
|
||||||
|
const pdf::PDFDocument* leftDocument,
|
||||||
|
const pdf::PDFDocument* rightDocument,
|
||||||
|
const pdf::PDFDocument* currentDocument);
|
||||||
|
|
||||||
|
const pdf::PDFDrawSpaceController::LayoutItems& getLayout() const { return m_layout; }
|
||||||
|
void setPageSequence(const pdf::PDFDiffResult::PageSequence& sequence) { m_pageSequence = sequence; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
pdf::PDFDrawSpaceController::LayoutItems m_layout;
|
||||||
|
pdf::PDFDiffResult::PageSequence m_pageSequence;
|
||||||
|
};
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
class MainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -98,7 +126,9 @@ private:
|
||||||
bool canPerformOperation(Operation operation) const;
|
bool canPerformOperation(Operation operation) const;
|
||||||
void performOperation(Operation operation);
|
void performOperation(Operation operation);
|
||||||
|
|
||||||
void setViewDocument(pdf::PDFDocument* document);
|
void setViewDocument(pdf::PDFDocument* document, bool updateCustomPageLayout);
|
||||||
|
|
||||||
|
ComparedDocumentMapper::Mode getDocumentViewMode() const;
|
||||||
|
|
||||||
/// Clears all data, and possibly documents also.
|
/// Clears all data, and possibly documents also.
|
||||||
/// View document is set to nullptr.
|
/// View document is set to nullptr.
|
||||||
|
@ -109,6 +139,7 @@ private:
|
||||||
void updateAll(bool resetFilters);
|
void updateAll(bool resetFilters);
|
||||||
void updateFilteredResult();
|
void updateFilteredResult();
|
||||||
void updateViewDocument();
|
void updateViewDocument();
|
||||||
|
void updateCustomPageLayout();
|
||||||
|
|
||||||
std::optional<pdf::PDFDocument> openDocument();
|
std::optional<pdf::PDFDocument> openDocument();
|
||||||
|
|
||||||
|
@ -136,6 +167,7 @@ private:
|
||||||
pdf::PDFDiffResult m_diffResult;
|
pdf::PDFDiffResult m_diffResult;
|
||||||
pdf::PDFDiffResult m_filteredDiffResult; ///< Difference result with filters applied
|
pdf::PDFDiffResult m_filteredDiffResult; ///< Difference result with filters applied
|
||||||
pdf::PDFDiffResultNavigator m_diffNavigator; ///< Difference navigator
|
pdf::PDFDiffResultNavigator m_diffNavigator; ///< Difference navigator
|
||||||
|
ComparedDocumentMapper m_documentMapper;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pdfdocdiff
|
} // namespace pdfdocdiff
|
||||||
|
|
|
@ -44,7 +44,8 @@ enum class PageLayout
|
||||||
TwoColumnLeft, ///< Display pages in two continuous columns, odd numbered pages are on the left
|
TwoColumnLeft, ///< Display pages in two continuous columns, odd numbered pages are on the left
|
||||||
TwoColumnRight, ///< Display pages in two continuous columns, even numbered pages are on the left
|
TwoColumnRight, ///< Display pages in two continuous columns, even numbered pages are on the left
|
||||||
TwoPagesLeft, ///< Display two pages on the screen, odd numbered pages are on the left
|
TwoPagesLeft, ///< Display two pages on the screen, odd numbered pages are on the left
|
||||||
TwoPagesRight ///< Display two pages on the screen, even numbered pages are on the left
|
TwoPagesRight, ///< Display two pages on the screen, even numbered pages are on the left
|
||||||
|
Custom ///< Custom layout, multiple columns can be used, -1 as page index means page is omitted
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Specifies, how the document should be displayed in the viewer application.
|
/// Specifies, how the document should be displayed in the viewer application.
|
||||||
|
|
|
@ -1200,6 +1200,32 @@ bool PDFDiffResult::isReplaceDifference(size_t index) const
|
||||||
return getTypeFlags(index) & FLAGS_TYPE_REPLACE;
|
return getTypeFlags(index) & FLAGS_TYPE_REPLACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<PDFInteger> PDFDiffResult::getChangedLeftPageIndices() const
|
||||||
|
{
|
||||||
|
std::set<PDFInteger> changedPageIndices;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < m_differences.size(); ++i)
|
||||||
|
{
|
||||||
|
changedPageIndices.insert(getLeftPage(i));
|
||||||
|
}
|
||||||
|
changedPageIndices.erase(-1);
|
||||||
|
|
||||||
|
return std::vector<PDFInteger>(changedPageIndices.cbegin(), changedPageIndices.cend());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<PDFInteger> PDFDiffResult::getChangedRightPageIndices() const
|
||||||
|
{
|
||||||
|
std::set<PDFInteger> changedPageIndices;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < m_differences.size(); ++i)
|
||||||
|
{
|
||||||
|
changedPageIndices.insert(getRightPage(i));
|
||||||
|
}
|
||||||
|
changedPageIndices.erase(-1);
|
||||||
|
|
||||||
|
return std::vector<PDFInteger>(changedPageIndices.cbegin(), changedPageIndices.cend());
|
||||||
|
}
|
||||||
|
|
||||||
PDFDiffResult PDFDiffResult::filter(bool filterPageMoveDifferences,
|
PDFDiffResult PDFDiffResult::filter(bool filterPageMoveDifferences,
|
||||||
bool filterTextDifferences,
|
bool filterTextDifferences,
|
||||||
bool filterVectorGraphicsDifferences,
|
bool filterVectorGraphicsDifferences,
|
||||||
|
|
|
@ -106,6 +106,12 @@ public:
|
||||||
bool hasImageDifferences() const { return m_typeFlags & FLAGS_IMAGE; }
|
bool hasImageDifferences() const { return m_typeFlags & FLAGS_IMAGE; }
|
||||||
bool hasShadingDifferences() const { return m_typeFlags & FLAGS_SHADING; }
|
bool hasShadingDifferences() const { return m_typeFlags & FLAGS_SHADING; }
|
||||||
|
|
||||||
|
/// Returns sorted changed page indices from left document
|
||||||
|
std::vector<PDFInteger> getChangedLeftPageIndices() const;
|
||||||
|
|
||||||
|
/// Returns sorted changed page indices from right document
|
||||||
|
std::vector<PDFInteger> getChangedRightPageIndices() const;
|
||||||
|
|
||||||
/// Filters results using given critera
|
/// Filters results using given critera
|
||||||
/// \param filterPageMoveDifferences Filter page move differences?
|
/// \param filterPageMoveDifferences Filter page move differences?
|
||||||
/// \param filterTextDifferences Filter text diffferences?
|
/// \param filterTextDifferences Filter text diffferences?
|
||||||
|
|
|
@ -99,6 +99,31 @@ PDFOperationResult PDFDocumentManipulator::assemble(const AssembledPages& pages)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFDocumentManipulator::AssembledPages PDFDocumentManipulator::createAllDocumentPages(int documentIndex, const PDFDocument* document)
|
||||||
|
{
|
||||||
|
AssembledPages assembledPages;
|
||||||
|
size_t pageCount = document->getCatalog()->getPageCount();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < pageCount; ++i)
|
||||||
|
{
|
||||||
|
pdf::PDFDocumentManipulator::AssembledPage assembledPage;
|
||||||
|
|
||||||
|
assembledPage.documentIndex = documentIndex;
|
||||||
|
assembledPage.imageIndex = -1;
|
||||||
|
assembledPage.pageIndex = i;
|
||||||
|
|
||||||
|
const pdf::PDFPage* page = document->getCatalog()->getPage(i);
|
||||||
|
const pdf::PageRotation originalPageRotation = page->getPageRotation();
|
||||||
|
|
||||||
|
assembledPage.pageRotation = originalPageRotation;
|
||||||
|
assembledPage.pageSize = page->getMediaBox().size();
|
||||||
|
|
||||||
|
assembledPages.emplace_back(assembledPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return assembledPages;
|
||||||
|
}
|
||||||
|
|
||||||
PDFDocumentManipulator::ProcessedPages PDFDocumentManipulator::processPages(PDFDocumentBuilder& documentBuilder, const AssembledPages& pages)
|
PDFDocumentManipulator::ProcessedPages PDFDocumentManipulator::processPages(PDFDocumentBuilder& documentBuilder, const AssembledPages& pages)
|
||||||
{
|
{
|
||||||
ProcessedPages processedPages;
|
ProcessedPages processedPages;
|
||||||
|
|
|
@ -91,6 +91,8 @@ public:
|
||||||
/// \returns Assembled document
|
/// \returns Assembled document
|
||||||
PDFDocument&& takeAssembledDocument() { return std::move(m_assembledDocument); }
|
PDFDocument&& takeAssembledDocument() { return std::move(m_assembledDocument); }
|
||||||
|
|
||||||
|
static AssembledPages createAllDocumentPages(int documentIndex, const PDFDocument* document);
|
||||||
|
|
||||||
static constexpr AssembledPage createDocumentPage(int documentIndex, int pageIndex, QSizeF pageSize, PageRotation pageRotation) { return AssembledPage{ documentIndex, -1, pageIndex, pageSize, pageRotation}; }
|
static constexpr AssembledPage createDocumentPage(int documentIndex, int pageIndex, QSizeF pageSize, PageRotation pageRotation) { return AssembledPage{ documentIndex, -1, pageIndex, pageSize, pageRotation}; }
|
||||||
static constexpr AssembledPage createImagePage(int imageIndex, QSizeF pageSize, PageRotation pageRotation) { return AssembledPage{ -1, imageIndex, -1, pageSize, pageRotation}; }
|
static constexpr AssembledPage createImagePage(int imageIndex, QSizeF pageSize, PageRotation pageRotation) { return AssembledPage{ -1, imageIndex, -1, pageSize, pageRotation}; }
|
||||||
static constexpr AssembledPage createBlankPage(QSizeF pageSize, PageRotation pageRotation) { return AssembledPage{ -1, -1, -1, pageSize, pageRotation}; }
|
static constexpr AssembledPage createBlankPage(QSizeF pageSize, PageRotation pageRotation) { return AssembledPage{ -1, -1, -1, pageSize, pageRotation}; }
|
||||||
|
|
|
@ -154,6 +154,20 @@ void PDFDrawSpaceController::setPageRotation(PageRotation pageRotation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFDrawSpaceController::setCustomLayout(LayoutItems customLayoutItems)
|
||||||
|
{
|
||||||
|
if (m_customLayoutItems != customLayoutItems)
|
||||||
|
{
|
||||||
|
m_customLayoutItems = std::move(customLayoutItems);
|
||||||
|
|
||||||
|
if (m_pageLayoutMode == PageLayout::Custom)
|
||||||
|
{
|
||||||
|
// Recalculate only, if custom layout is active
|
||||||
|
recalculate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PDFDrawSpaceController::recalculate()
|
void PDFDrawSpaceController::recalculate()
|
||||||
{
|
{
|
||||||
if (!m_document)
|
if (!m_document)
|
||||||
|
@ -361,6 +375,54 @@ void PDFDrawSpaceController::recalculate()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case PageLayout::Custom:
|
||||||
|
{
|
||||||
|
m_layoutItems = m_customLayoutItems;
|
||||||
|
|
||||||
|
// We do not support page rotation for custom layout
|
||||||
|
Q_ASSERT(m_pageRotation == PageRotation::None);
|
||||||
|
|
||||||
|
// Assure, that layout items are sorted by block
|
||||||
|
auto comparator = [](const LayoutItem& l, const LayoutItem& r)
|
||||||
|
{
|
||||||
|
return l.blockIndex < r.blockIndex;
|
||||||
|
};
|
||||||
|
std::stable_sort(m_layoutItems.begin(), m_layoutItems.end(), comparator);
|
||||||
|
|
||||||
|
// Now, compute blocks
|
||||||
|
if (!m_layoutItems.empty())
|
||||||
|
{
|
||||||
|
m_blockItems.reserve(m_layoutItems.back().blockIndex + 1);
|
||||||
|
|
||||||
|
QRectF currentBoundingRect;
|
||||||
|
PDFInteger blockIndex = -1;
|
||||||
|
|
||||||
|
for (const LayoutItem& layoutItem : m_layoutItems)
|
||||||
|
{
|
||||||
|
if (blockIndex != layoutItem.blockIndex)
|
||||||
|
{
|
||||||
|
blockIndex = layoutItem.blockIndex;
|
||||||
|
|
||||||
|
if (currentBoundingRect.isValid())
|
||||||
|
{
|
||||||
|
m_blockItems.push_back(LayoutBlock(currentBoundingRect));
|
||||||
|
currentBoundingRect = QRectF();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentBoundingRect = currentBoundingRect.united(layoutItem.pageRectMM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentBoundingRect.isValid())
|
||||||
|
{
|
||||||
|
m_blockItems.push_back(LayoutBlock(currentBoundingRect));
|
||||||
|
currentBoundingRect = QRectF();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
|
@ -1156,6 +1218,15 @@ void PDFDrawWidgetProxy::setPageLayout(PageLayout pageLayout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFDrawWidgetProxy::setCustomPageLayout(PDFDrawSpaceController::LayoutItems layoutItems)
|
||||||
|
{
|
||||||
|
if (m_controller->getCustomLayout() != layoutItems)
|
||||||
|
{
|
||||||
|
m_controller->setCustomLayout(std::move(layoutItems));
|
||||||
|
emit pageLayoutChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QRectF PDFDrawWidgetProxy::fromDeviceSpace(const QRectF& rect) const
|
QRectF PDFDrawWidgetProxy::fromDeviceSpace(const QRectF& rect) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(rect.isValid());
|
Q_ASSERT(rect.isValid());
|
||||||
|
@ -1185,6 +1256,9 @@ bool PDFDrawWidgetProxy::isBlockMode() const
|
||||||
case PageLayout::TwoPagesLeft:
|
case PageLayout::TwoPagesLeft:
|
||||||
case PageLayout::TwoPagesRight:
|
case PageLayout::TwoPagesRight:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case PageLayout::Custom:
|
||||||
|
return m_controller->getBlockCount() > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
|
@ -1217,6 +1291,10 @@ void PDFDrawWidgetProxy::prefetchPages(PDFInteger pageIndex)
|
||||||
prefetchCount = 2;
|
prefetchCount = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PageLayout::Custom:
|
||||||
|
prefetchCount = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -81,6 +81,8 @@ public:
|
||||||
constexpr inline explicit LayoutItem(PDFInteger blockIndex, PDFInteger pageIndex, const QRectF& pageRectMM) :
|
constexpr inline explicit LayoutItem(PDFInteger blockIndex, PDFInteger pageIndex, const QRectF& pageRectMM) :
|
||||||
blockIndex(blockIndex), pageIndex(pageIndex), pageRectMM(pageRectMM) { }
|
blockIndex(blockIndex), pageIndex(pageIndex), pageRectMM(pageRectMM) { }
|
||||||
|
|
||||||
|
bool operator ==(const LayoutItem&) const = default;
|
||||||
|
|
||||||
bool isValid() const { return pageIndex != -1; }
|
bool isValid() const { return pageIndex != -1; }
|
||||||
|
|
||||||
PDFInteger blockIndex;
|
PDFInteger blockIndex;
|
||||||
|
@ -123,6 +125,15 @@ public:
|
||||||
/// Sets page rotation
|
/// Sets page rotation
|
||||||
void setPageRotation(PageRotation pageRotation);
|
void setPageRotation(PageRotation pageRotation);
|
||||||
|
|
||||||
|
/// Set custom layout. Custom layout provides a way how to define
|
||||||
|
/// custom page layout, including blocks. Block indices must be properly defined,
|
||||||
|
/// that means block index must start by zero and must be continuous. If this
|
||||||
|
/// criteria are not fulfilled, behaviour is undefined.
|
||||||
|
void setCustomLayout(LayoutItems customLayoutItems);
|
||||||
|
|
||||||
|
/// Returns custom layout
|
||||||
|
const LayoutItems& getCustomLayout() const { return m_customLayoutItems; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void drawSpaceChanged();
|
void drawSpaceChanged();
|
||||||
void repaintNeeded();
|
void repaintNeeded();
|
||||||
|
@ -155,6 +166,7 @@ private:
|
||||||
PDFReal m_verticalSpacingMM;
|
PDFReal m_verticalSpacingMM;
|
||||||
PDFReal m_horizontalSpacingMM;
|
PDFReal m_horizontalSpacingMM;
|
||||||
PageRotation m_pageRotation;
|
PageRotation m_pageRotation;
|
||||||
|
LayoutItems m_customLayoutItems;
|
||||||
|
|
||||||
/// Font cache
|
/// Font cache
|
||||||
PDFFontCache m_fontCache;
|
PDFFontCache m_fontCache;
|
||||||
|
@ -282,6 +294,11 @@ public:
|
||||||
/// \param pageLayout Page layout
|
/// \param pageLayout Page layout
|
||||||
void setPageLayout(PageLayout pageLayout);
|
void setPageLayout(PageLayout pageLayout);
|
||||||
|
|
||||||
|
/// Sets custom page layout. If this function is used, page layout mode
|
||||||
|
/// must be set to 'Custom'.
|
||||||
|
/// \param layoutItems Layout items
|
||||||
|
void setCustomPageLayout(PDFDrawSpaceController::LayoutItems layoutItems);
|
||||||
|
|
||||||
/// Returns the page layout
|
/// Returns the page layout
|
||||||
PageLayout getPageLayout() const { return m_controller->getPageLayout(); }
|
PageLayout getPageLayout() const { return m_controller->getPageLayout(); }
|
||||||
|
|
||||||
|
@ -360,7 +377,7 @@ public:
|
||||||
signals:
|
signals:
|
||||||
void drawSpaceChanged();
|
void drawSpaceChanged();
|
||||||
void pageLayoutChanged();
|
void pageLayoutChanged();
|
||||||
void renderingError(PDFInteger pageIndex, const QList<PDFRenderError>& errors);
|
void renderingError(pdf::PDFInteger pageIndex, const QList<pdf::PDFRenderError>& errors);
|
||||||
void repaintNeeded();
|
void repaintNeeded();
|
||||||
void pageImageChanged(bool all, const std::vector<PDFInteger>& pages);
|
void pageImageChanged(bool all, const std::vector<PDFInteger>& pages);
|
||||||
void textLayoutChanged();
|
void textLayoutChanged();
|
||||||
|
|
Loading…
Reference in New Issue