mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
DocDiff application: create document report, overlay
This commit is contained in:
@@ -26,6 +26,8 @@
|
||||
#include "pdfdocumentreader.h"
|
||||
#include "pdfdrawspacecontroller.h"
|
||||
#include "pdfdocumentmanipulator.h"
|
||||
#include "pdfdocumentbuilder.h"
|
||||
#include "pdfdocumentwriter.h"
|
||||
|
||||
#include <QToolBar>
|
||||
#include <QDesktopWidget>
|
||||
@@ -65,6 +67,7 @@ MainWindow::MainWindow(QWidget* parent) :
|
||||
m_settingsDockWidget = new SettingsDockWidget(&m_settings, this);
|
||||
addDockWidget(Qt::LeftDockWidgetArea, m_settingsDockWidget);;
|
||||
connect(m_settingsDockWidget, &SettingsDockWidget::colorsChanged, this, &MainWindow::onColorsChanged);
|
||||
connect(m_settingsDockWidget, &SettingsDockWidget::transparencySliderChanged, this, &MainWindow::updateOverlayTransparency);
|
||||
|
||||
m_differencesDockWidget = new DifferencesDockWidget(this, &m_diffResult, &m_filteredDiffResult, &m_diffNavigator, &m_settings);
|
||||
addDockWidget(Qt::LeftDockWidgetArea, m_differencesDockWidget);
|
||||
@@ -171,6 +174,7 @@ MainWindow::MainWindow(QWidget* parent) :
|
||||
|
||||
loadSettings();
|
||||
updateAll(false);
|
||||
updateOverlayTransparency();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
@@ -403,8 +407,10 @@ bool MainWindow::canPerformOperation(Operation operation) const
|
||||
return m_diffNavigator.canGoNext();
|
||||
|
||||
case Operation::CreateCompareReport:
|
||||
case Operation::ShowPageswithDifferences:
|
||||
case Operation::SaveDifferencesToXML:
|
||||
return m_filteredDiffResult.isChanged();
|
||||
|
||||
case Operation::ShowPageswithDifferences:
|
||||
return m_diffResult.isChanged();
|
||||
|
||||
case Operation::DisplayDifferences:
|
||||
@@ -610,9 +616,31 @@ void MainWindow::performOperation(Operation operation)
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Operation::CreateCompareReport:
|
||||
Q_ASSERT(false);
|
||||
{
|
||||
if (m_filteredDiffResult.isSame())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
QString saveFileName = QFileDialog::getSaveFileName(this, tr("Save As"), m_settings.directory, tr("Portable Document (*.pdf);;All files (*.*)"));
|
||||
if (!saveFileName.isEmpty())
|
||||
{
|
||||
pdf::PDFDocumentBuilder builder(m_pdfWidget->getDrawWidgetProxy()->getDocument());
|
||||
m_drawInterface.drawAnnotations(m_pdfWidget->getDrawWidgetProxy()->getDocument(), &builder);
|
||||
|
||||
pdf::PDFDocument document = builder.build();
|
||||
pdf::PDFDocumentWriter writer(m_progress);
|
||||
pdf::PDFOperationResult result = writer.write(saveFileName, &document, QFile::exists(saveFileName));
|
||||
if (!result)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), result.getErrorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
@@ -765,6 +793,14 @@ void MainWindow::updateCustomPageLayout()
|
||||
m_pdfWidget->getDrawWidgetProxy()->setPageLayout(pdf::PageLayout::Custom);
|
||||
}
|
||||
|
||||
void MainWindow::updateOverlayTransparency()
|
||||
{
|
||||
const pdf::PDFReal value = m_settingsDockWidget->getTransparencySliderValue() * 0.01;
|
||||
m_pdfWidget->getDrawWidgetProxy()->setGroupTransparency(1, true, 1.0 - value);
|
||||
m_pdfWidget->getDrawWidgetProxy()->setGroupTransparency(2, false, value);
|
||||
m_pdfWidget->update();
|
||||
}
|
||||
|
||||
std::optional<pdf::PDFDocument> MainWindow::openDocument()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Select PDF document"), m_settings.directory, tr("PDF document (*.pdf)"));
|
||||
|
@@ -114,6 +114,7 @@ private:
|
||||
void updateFilteredResult();
|
||||
void updateViewDocument();
|
||||
void updateCustomPageLayout();
|
||||
void updateOverlayTransparency();
|
||||
|
||||
std::optional<pdf::PDFDocument> openDocument();
|
||||
|
||||
|
@@ -43,6 +43,8 @@ SettingsDockWidget::SettingsDockWidget(Settings* settings, QWidget* parent) :
|
||||
|
||||
connect(comboBox, &QComboBox::editTextChanged, this, &SettingsDockWidget::onEditColorChanged);
|
||||
}
|
||||
|
||||
connect(ui->transparencySlider, &QSlider::valueChanged, this, &SettingsDockWidget::transparencySliderChanged);
|
||||
}
|
||||
|
||||
SettingsDockWidget::~SettingsDockWidget()
|
||||
@@ -101,6 +103,11 @@ void SettingsDockWidget::loadColors()
|
||||
loadColor(ui->moveColorCombo, m_settings->colorPageMove);
|
||||
}
|
||||
|
||||
int SettingsDockWidget::getTransparencySliderValue() const
|
||||
{
|
||||
return ui->transparencySlider->value();
|
||||
}
|
||||
|
||||
QIcon SettingsDockWidget::getIconForColor(QColor color) const
|
||||
{
|
||||
QIcon icon;
|
||||
|
@@ -52,8 +52,11 @@ public:
|
||||
void loadColors();
|
||||
void saveColors();
|
||||
|
||||
int getTransparencySliderValue() const;
|
||||
|
||||
signals:
|
||||
void colorsChanged();
|
||||
void transparencySliderChanged(int value);
|
||||
|
||||
private:
|
||||
QIcon getIconForColor(QColor color) const;
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>548</width>
|
||||
<height>417</height>
|
||||
<height>511</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="allowedAreas">
|
||||
@@ -79,6 +79,31 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="overlayGroupBox">
|
||||
<property name="title">
|
||||
<string>Transparency | Overlay View</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QSlider" name="transparencySlider">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksAbove</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="colorsGroupBox">
|
||||
<property name="title">
|
||||
|
@@ -16,8 +16,10 @@
|
||||
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "utils.h"
|
||||
#include "pdfutils.h"
|
||||
#include "pdfwidgetutils.h"
|
||||
#include "pdfpainterutils.h"
|
||||
#include "pdfdocumentbuilder.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
@@ -87,7 +89,7 @@ void ComparedDocumentMapper::update(ComparedDocumentMapper::Mode mode,
|
||||
{
|
||||
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);
|
||||
m_layout.emplace_back(0, i, -1, rect);
|
||||
yPos += pageSize.height() + 5;
|
||||
}
|
||||
}
|
||||
@@ -102,7 +104,7 @@ void ComparedDocumentMapper::update(ComparedDocumentMapper::Mode mode,
|
||||
|
||||
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);
|
||||
m_layout.emplace_back(0, item.leftPage, -1, rect);
|
||||
yPos += pageSize.height() + 5;
|
||||
}
|
||||
}
|
||||
@@ -126,7 +128,7 @@ void ComparedDocumentMapper::update(ComparedDocumentMapper::Mode mode,
|
||||
{
|
||||
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);
|
||||
m_layout.emplace_back(0, i, -1, rect);
|
||||
yPos += pageSize.height() + 5;
|
||||
}
|
||||
}
|
||||
@@ -141,7 +143,7 @@ void ComparedDocumentMapper::update(ComparedDocumentMapper::Mode mode,
|
||||
|
||||
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);
|
||||
m_layout.emplace_back(0, item.rightPage, -1, rect);
|
||||
yPos += pageSize.height() + 5;
|
||||
}
|
||||
}
|
||||
@@ -164,15 +166,20 @@ void ComparedDocumentMapper::update(ComparedDocumentMapper::Mode mode,
|
||||
{
|
||||
QSizeF pageSize = catalog->getPage(item.leftPage)->getRotatedMediaBoxMM().size();
|
||||
QRectF rect;
|
||||
pdf::PDFInteger groupIndex = -1;
|
||||
if (mode == ComparedDocumentMapper::Mode::Combined)
|
||||
{
|
||||
rect = QRectF(-pageSize.width() - 5, yPos, pageSize.width(), pageSize.height());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item.rightPage != -1)
|
||||
{
|
||||
groupIndex = 1;
|
||||
}
|
||||
rect = QRectF(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
|
||||
}
|
||||
m_layout.emplace_back(0, item.leftPage, rect);
|
||||
m_layout.emplace_back(0, item.leftPage, groupIndex, rect);
|
||||
yAdvance = pageSize.height() + 5;
|
||||
m_leftPageIndices[item.leftPage] = item.leftPage;
|
||||
}
|
||||
@@ -182,15 +189,20 @@ void ComparedDocumentMapper::update(ComparedDocumentMapper::Mode mode,
|
||||
pdf::PDFInteger rightPageIndex = item.rightPage + offset;
|
||||
QSizeF pageSize = catalog->getPage(rightPageIndex)->getRotatedMediaBoxMM().size();
|
||||
QRectF rect;
|
||||
pdf::PDFInteger groupIndex = -1;
|
||||
if (mode == ComparedDocumentMapper::Mode::Combined)
|
||||
{
|
||||
rect = QRectF(5, yPos, pageSize.width(), pageSize.height());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item.leftPage != -1)
|
||||
{
|
||||
groupIndex = 2;
|
||||
}
|
||||
rect = QRectF(-pageSize.width() * 0.5, yPos, pageSize.width(), pageSize.height());
|
||||
}
|
||||
m_layout.emplace_back(0, rightPageIndex, rect);
|
||||
m_layout.emplace_back(0, rightPageIndex, groupIndex, rect);
|
||||
yAdvance = qMax(yAdvance, pageSize.height() + 5);
|
||||
m_rightPageIndices[rightPageIndex] = item.rightPage;
|
||||
}
|
||||
@@ -414,6 +426,69 @@ void DifferencesDrawInterface::drawPostRendering(QPainter* painter, QRect rect)
|
||||
Q_UNUSED(rect);
|
||||
}
|
||||
|
||||
void DifferencesDrawInterface::drawAnnotations(const pdf::PDFDocument* document,
|
||||
pdf::PDFDocumentBuilder* builder)
|
||||
{
|
||||
pdf::PDFInteger pageCount = document->getCatalog()->getPageCount();
|
||||
|
||||
QString title = pdf::PDFSysUtils::getUserName();
|
||||
QString subject = tr("Difference");
|
||||
|
||||
for (pdf::PDFInteger pageIndex = 0; pageIndex < pageCount; ++pageIndex)
|
||||
{
|
||||
const size_t differencesCount = m_diffResult->getDifferencesCount();
|
||||
const pdf::PDFInteger leftPageIndex = m_mapper->getLeftPageIndex(pageIndex);
|
||||
const pdf::PDFInteger rightPageIndex = m_mapper->getRightPageIndex(pageIndex);
|
||||
|
||||
const pdf::PDFPage* page = document->getCatalog()->getPage(pageIndex);
|
||||
pdf::PDFObjectReference reference = page->getPageReference();
|
||||
|
||||
if (leftPageIndex != -1)
|
||||
{
|
||||
for (size_t i = 0; i < differencesCount; ++i)
|
||||
{
|
||||
auto leftRectangles = m_diffResult->getLeftRectangles(i);
|
||||
for (auto it = leftRectangles.first; it != leftRectangles.second; ++it)
|
||||
{
|
||||
const auto& item = *it;
|
||||
if (item.first == leftPageIndex)
|
||||
{
|
||||
QColor color = getColorForIndex(i);
|
||||
const QRectF& rect = item.second;
|
||||
QPolygonF polygon;
|
||||
polygon << rect.topLeft() << rect.topRight() << rect.bottomRight() << rect.bottomLeft();
|
||||
pdf::PDFObjectReference annotation = builder->createAnnotationPolygon(reference, polygon, 1.0, color, color, title, subject, m_diffResult->getMessage(i));
|
||||
builder->setAnnotationOpacity(annotation, 0.3);
|
||||
builder->updateAnnotationAppearanceStreams(annotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rightPageIndex != -1)
|
||||
{
|
||||
for (size_t i = 0; i < differencesCount; ++i)
|
||||
{
|
||||
auto rightRectangles = m_diffResult->getRightRectangles(i);
|
||||
for (auto it = rightRectangles.first; it != rightRectangles.second; ++it)
|
||||
{
|
||||
const auto& item = *it;
|
||||
if (item.first == rightPageIndex)
|
||||
{
|
||||
QColor color = getColorForIndex(i);
|
||||
const QRectF& rect = item.second;
|
||||
QPolygonF polygon;
|
||||
polygon << rect.topLeft() << rect.topRight() << rect.bottomRight() << rect.bottomLeft();
|
||||
pdf::PDFObjectReference annotation = builder->createAnnotationPolygon(reference, polygon, 1.0, color, color, title, subject, m_diffResult->getMessage(i));
|
||||
builder->setAnnotationOpacity(annotation, 0.3);
|
||||
builder->updateAnnotationAppearanceStreams(annotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DifferencesDrawInterface::drawRectangle(QPainter* painter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
const QRectF& rect,
|
||||
|
@@ -23,6 +23,13 @@
|
||||
#include "pdfdrawspacecontroller.h"
|
||||
#include "pdfdocumentdrawinterface.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
class PDFDocumentBuilder;
|
||||
} // namespace pdf
|
||||
|
||||
namespace pdfdocdiff
|
||||
{
|
||||
|
||||
@@ -77,6 +84,8 @@ private:
|
||||
|
||||
class DifferencesDrawInterface : public pdf::IDocumentDrawInterface
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(pdfdocdiff::DifferencesDrawInterface)
|
||||
|
||||
public:
|
||||
explicit DifferencesDrawInterface(const Settings* settings,
|
||||
const ComparedDocumentMapper* mapper,
|
||||
@@ -87,8 +96,14 @@ public:
|
||||
pdf::PDFTextLayoutGetter& layoutGetter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
QList<pdf::PDFRenderError>& errors) const override;
|
||||
|
||||
virtual void drawPostRendering(QPainter* painter, QRect rect) const override;
|
||||
|
||||
/// Draw annotations for differences
|
||||
/// \param document Document
|
||||
/// \param builder Builder
|
||||
void drawAnnotations(const pdf::PDFDocument* document, pdf::PDFDocumentBuilder* builder);
|
||||
|
||||
private:
|
||||
void drawRectangle(QPainter* painter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
|
Reference in New Issue
Block a user