mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-04-18 04:07:32 +02:00
Object inspector dialog
This commit is contained in:
parent
0dee75a692
commit
2745c7828c
@ -38,7 +38,7 @@ class PDFDocumentBuilder;
|
|||||||
|
|
||||||
/// Storage for objects. This class is not thread safe for writing (calling non-const functions). Caller must ensure
|
/// Storage for objects. This class is not thread safe for writing (calling non-const functions). Caller must ensure
|
||||||
/// locking, if this object is used from multiple threads. Calling const functions should be thread safe.
|
/// locking, if this object is used from multiple threads. Calling const functions should be thread safe.
|
||||||
class PDFObjectStorage
|
class Pdf4QtLIBSHARED_EXPORT PDFObjectStorage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline PDFObjectStorage() = default;
|
inline PDFObjectStorage() = default;
|
||||||
|
@ -36,7 +36,7 @@ class PDFOptionalContentActivity;
|
|||||||
class PDFDrawWidgetProxy;
|
class PDFDrawWidgetProxy;
|
||||||
|
|
||||||
/// Represents tree item in the GUI tree
|
/// Represents tree item in the GUI tree
|
||||||
class PDFTreeItem
|
class Pdf4QtLIBSHARED_EXPORT PDFTreeItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline explicit PDFTreeItem() = default;
|
inline explicit PDFTreeItem() = default;
|
||||||
@ -60,6 +60,7 @@ public:
|
|||||||
int getRow() const { return m_parent->m_children.indexOf(const_cast<PDFTreeItem*>(this)); }
|
int getRow() const { return m_parent->m_children.indexOf(const_cast<PDFTreeItem*>(this)); }
|
||||||
int getChildCount() const { return m_children.size(); }
|
int getChildCount() const { return m_children.size(); }
|
||||||
const PDFTreeItem* getChild(int index) const { return m_children.at(index); }
|
const PDFTreeItem* getChild(int index) const { return m_children.at(index); }
|
||||||
|
PDFTreeItem* getChild(int index) { return m_children.at(index); }
|
||||||
const PDFTreeItem* getParent() const { return m_parent; }
|
const PDFTreeItem* getParent() const { return m_parent; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -307,7 +307,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Represents an array of objects in the PDF file.
|
/// Represents an array of objects in the PDF file.
|
||||||
class PDFArray : public PDFObjectContent
|
class Pdf4QtLIBSHARED_EXPORT PDFArray : public PDFObjectContent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline PDFArray() = default;
|
inline PDFArray() = default;
|
||||||
@ -460,7 +460,7 @@ private:
|
|||||||
|
|
||||||
/// Represents a stream object in the PDF file. Stream consists of dictionary
|
/// Represents a stream object in the PDF file. Stream consists of dictionary
|
||||||
/// and stream content - byte array.
|
/// and stream content - byte array.
|
||||||
class PDFStream : public PDFObjectContent
|
class Pdf4QtLIBSHARED_EXPORT PDFStream : public PDFObjectContent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline explicit PDFStream() = default;
|
inline explicit PDFStream() = default;
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"Name" : "ObjectInspector",
|
||||||
|
"Author" : "Jakub Melka",
|
||||||
|
"Version" : "1.0.0",
|
||||||
|
"License" : "LGPL v3",
|
||||||
|
"Description" : "Explore internal structure of a document. View decompressed streams and images. Modify objects directly."
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
# 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
TEMPLATE = lib
|
||||||
|
DEFINES += OBJECTINSPECTORPLUGIN_LIBRARY
|
||||||
|
|
||||||
|
QT += gui widgets
|
||||||
|
|
||||||
|
LIBS += -L$$OUT_PWD/../..
|
||||||
|
|
||||||
|
LIBS += -lPdf4QtLib
|
||||||
|
|
||||||
|
QMAKE_CXXFLAGS += /std:c++latest /utf-8
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../../Pdf4QtLib/Sources
|
||||||
|
|
||||||
|
DESTDIR = $$OUT_PWD/../../pdfplugins
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
objectinspectordialog.cpp \
|
||||||
|
objectinspectorplugin.cpp \
|
||||||
|
pdfobjectinspectortreeitemmodel.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
objectinspectordialog.h \
|
||||||
|
objectinspectorplugin.h \
|
||||||
|
pdfobjectinspectortreeitemmodel.h
|
||||||
|
|
||||||
|
CONFIG += force_debug_info
|
||||||
|
|
||||||
|
DISTFILES += \
|
||||||
|
ObjectInspectorPlugin.json
|
||||||
|
|
||||||
|
RESOURCES += \
|
||||||
|
icons.qrc
|
||||||
|
|
||||||
|
FORMS += \
|
||||||
|
objectinspectordialog.ui
|
5
Pdf4QtViewerPlugins/ObjectInspectorPlugin/icons.qrc
Normal file
5
Pdf4QtViewerPlugins/ObjectInspectorPlugin/icons.qrc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/pdfplugins/objectinspector">
|
||||||
|
<file>object-inspector.svg</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
178
Pdf4QtViewerPlugins/ObjectInspectorPlugin/object-inspector.svg
Normal file
178
Pdf4QtViewerPlugins/ObjectInspectorPlugin/object-inspector.svg
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="30mm"
|
||||||
|
height="30mm"
|
||||||
|
viewBox="0 0 30 30"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||||
|
sodipodi:docname="object-inspector.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="spiro"
|
||||||
|
id="path-effect831"
|
||||||
|
is_visible="true" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="3.959798"
|
||||||
|
inkscape:cx="205.45683"
|
||||||
|
inkscape:cy="58.526376"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2035"
|
||||||
|
inkscape:window-x="-13"
|
||||||
|
inkscape:window-y="-13"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
<cc:license
|
||||||
|
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
|
||||||
|
<dc:creator>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>Jakub Melka</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:creator>
|
||||||
|
</cc:Work>
|
||||||
|
<cc:License
|
||||||
|
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Notice" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
|
||||||
|
</cc:License>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Vrstva 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-267)">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 11.646391,283.58184 v 0 0"
|
||||||
|
id="path837"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path838"
|
||||||
|
sodipodi:type="arc"
|
||||||
|
sodipodi:cx="19.111422"
|
||||||
|
sodipodi:cy="286.55841"
|
||||||
|
sodipodi:rx="6.1184897"
|
||||||
|
sodipodi:ry="6.8035712"
|
||||||
|
sodipodi:start="5.1487213"
|
||||||
|
sodipodi:end="0"
|
||||||
|
d="m 21.697207,280.39228 a 6.1184897,6.8035712 0 0 1 3.532704,6.16613 h -6.118489 z" />
|
||||||
|
<path
|
||||||
|
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path838-5"
|
||||||
|
sodipodi:type="arc"
|
||||||
|
sodipodi:cx="18.674374"
|
||||||
|
sodipodi:cy="295.12213"
|
||||||
|
sodipodi:rx="6.1184897"
|
||||||
|
sodipodi:ry="6.8035712"
|
||||||
|
sodipodi:start="5.1487213"
|
||||||
|
sodipodi:end="0"
|
||||||
|
d="m 21.260159,288.956 a 6.1184897,6.8035712 0 0 1 3.532704,6.16613 h -6.118489 z" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 5.3389135,271.81734 V 295.3936"
|
||||||
|
id="path857"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 5.5279017,275.12463 H 13.512649"
|
||||||
|
id="path859"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 5.2916666,282.58966 h 8.1264884 v 12.70945 h 5.905878"
|
||||||
|
id="path861"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 13.819059,286.74977 h 6.945312"
|
||||||
|
id="path863"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<ellipse
|
||||||
|
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path865"
|
||||||
|
cx="5.3483629"
|
||||||
|
cy="271.34488"
|
||||||
|
rx="0.51971716"
|
||||||
|
ry="0.4724721" />
|
||||||
|
<ellipse
|
||||||
|
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path865-8"
|
||||||
|
cx="13.701637"
|
||||||
|
cy="275.07736"
|
||||||
|
rx="0.51971716"
|
||||||
|
ry="0.4724721" />
|
||||||
|
<ellipse
|
||||||
|
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path865-0"
|
||||||
|
cx="13.559896"
|
||||||
|
cy="282.44791"
|
||||||
|
rx="0.51971716"
|
||||||
|
ry="0.4724721" />
|
||||||
|
<ellipse
|
||||||
|
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path865-09"
|
||||||
|
cx="13.559896"
|
||||||
|
cy="286.79465"
|
||||||
|
rx="0.51971716"
|
||||||
|
ry="0.4724721" />
|
||||||
|
<ellipse
|
||||||
|
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path865-9"
|
||||||
|
cx="13.418155"
|
||||||
|
cy="295.06287"
|
||||||
|
rx="0.51971716"
|
||||||
|
ry="0.4724721" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 5.3459697,278.6176 H 13.330714"
|
||||||
|
id="path859-4"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<ellipse
|
||||||
|
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path865-8-6"
|
||||||
|
cx="13.519706"
|
||||||
|
cy="278.57034"
|
||||||
|
rx="0.51971716"
|
||||||
|
ry="0.4724721" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 7.3 KiB |
@ -0,0 +1,71 @@
|
|||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "objectinspectordialog.h"
|
||||||
|
#include "ui_objectinspectordialog.h"
|
||||||
|
|
||||||
|
#include "pdfwidgetutils.h"
|
||||||
|
#include "pdfobjectinspectortreeitemmodel.h"
|
||||||
|
|
||||||
|
#include <QSplitter>
|
||||||
|
|
||||||
|
namespace pdfplugin
|
||||||
|
{
|
||||||
|
|
||||||
|
ObjectInspectorDialog::ObjectInspectorDialog(const pdf::PDFDocument* document, QWidget* parent) :
|
||||||
|
QDialog(parent, Qt::Dialog | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint),
|
||||||
|
ui(new Ui::ObjectInspectorDialog),
|
||||||
|
m_document(document),
|
||||||
|
m_model(nullptr)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
ui->modeComboBox->addItem(tr("Document"), int(PDFObjectInspectorTreeItemModel::Document));
|
||||||
|
ui->modeComboBox->addItem(tr("Pages"), int(PDFObjectInspectorTreeItemModel::Page));
|
||||||
|
ui->modeComboBox->addItem(tr("Images"), int(PDFObjectInspectorTreeItemModel::Image));
|
||||||
|
ui->modeComboBox->addItem(tr("Object List"), int(PDFObjectInspectorTreeItemModel::List));
|
||||||
|
|
||||||
|
ui->modeComboBox->setCurrentIndex(ui->modeComboBox->findData(int(PDFObjectInspectorTreeItemModel::Document)));
|
||||||
|
connect(ui->modeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ObjectInspectorDialog::onModeChanged);
|
||||||
|
|
||||||
|
m_model = new PDFObjectInspectorTreeItemModel(this);
|
||||||
|
onModeChanged();
|
||||||
|
m_model->setDocument(pdf::PDFModifiedDocument(const_cast<pdf::PDFDocument*>(document), nullptr, pdf::PDFModifiedDocument::Reset));
|
||||||
|
|
||||||
|
ui->objectTreeView->setRootIsDecorated(true);
|
||||||
|
ui->objectTreeView->setModel(m_model);
|
||||||
|
|
||||||
|
QSplitter* splitter = new QSplitter(this);
|
||||||
|
splitter->addWidget(ui->objectTreeView);
|
||||||
|
splitter->addWidget(ui->tabWidget);
|
||||||
|
|
||||||
|
ui->objectTreeView->setMinimumWidth(pdf::PDFWidgetUtils::scaleDPI_x(this, 200));
|
||||||
|
setMinimumSize(pdf::PDFWidgetUtils::scaleDPI(this, QSize(800, 600)));
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectInspectorDialog::~ObjectInspectorDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectInspectorDialog::onModeChanged()
|
||||||
|
{
|
||||||
|
const PDFObjectInspectorTreeItemModel::Mode mode = static_cast<const PDFObjectInspectorTreeItemModel::Mode>(ui->modeComboBox->currentData().toInt());
|
||||||
|
m_model->setMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace pdfplugin
|
@ -0,0 +1,52 @@
|
|||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef OBJECTINSPECTORDIALOG_H
|
||||||
|
#define OBJECTINSPECTORDIALOG_H
|
||||||
|
|
||||||
|
#include "pdfdocument.h"
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class ObjectInspectorDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace pdfplugin
|
||||||
|
{
|
||||||
|
class PDFObjectInspectorTreeItemModel;
|
||||||
|
|
||||||
|
class ObjectInspectorDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ObjectInspectorDialog(const pdf::PDFDocument* document, QWidget* parent);
|
||||||
|
virtual ~ObjectInspectorDialog() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onModeChanged();
|
||||||
|
|
||||||
|
Ui::ObjectInspectorDialog* ui;
|
||||||
|
const pdf::PDFDocument* m_document;
|
||||||
|
PDFObjectInspectorTreeItemModel* m_model;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace pdfplugin
|
||||||
|
|
||||||
|
#endif // OBJECTINSPECTORDIALOG_H
|
@ -0,0 +1,88 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ObjectInspectorDialog</class>
|
||||||
|
<widget class="QDialog" name="ObjectInspectorDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>742</width>
|
||||||
|
<height>666</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Object Inspector</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QTreeView" name="objectTreeView">
|
||||||
|
<attribute name="headerVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="2">
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QComboBox" name="modeComboBox"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" rowspan="2">
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<widget class="QWidget" name="tab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Tab 1</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_2">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Tab 2</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>ObjectInspectorDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>ObjectInspectorDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
@ -0,0 +1,84 @@
|
|||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "objectinspectorplugin.h"
|
||||||
|
|
||||||
|
#include "pdfcms.h"
|
||||||
|
#include "pdfutils.h"
|
||||||
|
#include "pdfdrawwidget.h"
|
||||||
|
|
||||||
|
#include "objectinspectordialog.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
|
||||||
|
namespace pdfplugin
|
||||||
|
{
|
||||||
|
|
||||||
|
ObjectInspectorPlugin::ObjectInspectorPlugin() :
|
||||||
|
pdf::PDFPlugin(nullptr),
|
||||||
|
m_objectInspectorAction(nullptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectInspectorPlugin::setWidget(pdf::PDFWidget* widget)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!m_widget);
|
||||||
|
|
||||||
|
BaseClass::setWidget(widget);
|
||||||
|
|
||||||
|
m_objectInspectorAction = new QAction(QIcon(":/pdfplugins/objectinspector/object-inspector.svg"), tr("Object Inspector"), this);
|
||||||
|
m_objectInspectorAction->setCheckable(false);
|
||||||
|
m_objectInspectorAction->setObjectName("actionObjectInspector_ObjectInspector");
|
||||||
|
|
||||||
|
connect(m_objectInspectorAction, &QAction::triggered, this, &ObjectInspectorPlugin::onObjectInspectorTriggered);
|
||||||
|
|
||||||
|
updateActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectInspectorPlugin::setCMSManager(pdf::PDFCMSManager* manager)
|
||||||
|
{
|
||||||
|
BaseClass::setCMSManager(manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectInspectorPlugin::setDocument(const pdf::PDFModifiedDocument& document)
|
||||||
|
{
|
||||||
|
BaseClass::setDocument(document);
|
||||||
|
|
||||||
|
if (document.hasReset())
|
||||||
|
{
|
||||||
|
updateActions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<QAction*> ObjectInspectorPlugin::getActions() const
|
||||||
|
{
|
||||||
|
return { m_objectInspectorAction };
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectInspectorPlugin::onObjectInspectorTriggered()
|
||||||
|
{
|
||||||
|
ObjectInspectorDialog dialog(m_document, m_widget);
|
||||||
|
dialog.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectInspectorPlugin::updateActions()
|
||||||
|
{
|
||||||
|
m_objectInspectorAction->setEnabled(m_widget && m_document);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef OBJECTINSPECTORPLUGIN_H
|
||||||
|
#define OBJECTINSPECTORPLUGIN_H
|
||||||
|
|
||||||
|
#include "pdfplugin.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace pdfplugin
|
||||||
|
{
|
||||||
|
|
||||||
|
class ObjectInspectorPlugin : public pdf::PDFPlugin
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PLUGIN_METADATA(IID "Pdf4Qt.ObjectInspectorPlugin" FILE "ObjectInspectorPlugin.json")
|
||||||
|
|
||||||
|
private:
|
||||||
|
using BaseClass = pdf::PDFPlugin;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ObjectInspectorPlugin();
|
||||||
|
|
||||||
|
virtual void setWidget(pdf::PDFWidget* widget) override;
|
||||||
|
virtual void setCMSManager(pdf::PDFCMSManager* manager) override;
|
||||||
|
virtual void setDocument(const pdf::PDFModifiedDocument& document) override;
|
||||||
|
virtual std::vector<QAction*> getActions() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onObjectInspectorTriggered();
|
||||||
|
|
||||||
|
void updateActions();
|
||||||
|
|
||||||
|
QAction* m_objectInspectorAction;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace pdfplugin
|
||||||
|
|
||||||
|
#endif // OBJECTINSPECTORPLUGIN_H
|
@ -0,0 +1,425 @@
|
|||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "pdfobjectinspectortreeitemmodel.h"
|
||||||
|
#include "pdfdocument.h"
|
||||||
|
#include "pdfvisitor.h"
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
#include <QLocale>
|
||||||
|
|
||||||
|
namespace pdfplugin
|
||||||
|
{
|
||||||
|
|
||||||
|
class PDFObjectInspectorTreeItem : public pdf::PDFTreeItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
inline explicit PDFObjectInspectorTreeItem() = default;
|
||||||
|
inline explicit PDFObjectInspectorTreeItem(PDFObjectInspectorTreeItem* parent) : pdf::PDFTreeItem(parent) { }
|
||||||
|
inline explicit PDFObjectInspectorTreeItem(pdf::PDFObject object, PDFObjectInspectorTreeItem* parent) : pdf::PDFTreeItem(parent), m_object(std::move(object)) { }
|
||||||
|
inline explicit PDFObjectInspectorTreeItem(QByteArray dictionaryKey, pdf::PDFObject object, PDFObjectInspectorTreeItem* parent) : pdf::PDFTreeItem(parent), m_dictionaryKey(std::move(dictionaryKey)), m_object(std::move(object)) { }
|
||||||
|
inline explicit PDFObjectInspectorTreeItem(pdf::PDFObjectReference reference, pdf::PDFObject object, PDFObjectInspectorTreeItem* parent) : pdf::PDFTreeItem(parent), m_reference(std::move(reference)), m_object(std::move(object)) { }
|
||||||
|
|
||||||
|
virtual ~PDFObjectInspectorTreeItem() override { }
|
||||||
|
|
||||||
|
|
||||||
|
QByteArray getDictionaryKey() const;
|
||||||
|
void setDictionaryKey(const QByteArray& dictionaryKey);
|
||||||
|
|
||||||
|
pdf::PDFObjectReference getReference() const;
|
||||||
|
void setReference(const pdf::PDFObjectReference& reference);
|
||||||
|
|
||||||
|
const pdf::PDFObject& getObject() const;
|
||||||
|
void setObject(const pdf::PDFObject& object);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QByteArray m_dictionaryKey;
|
||||||
|
pdf::PDFObjectReference m_reference;
|
||||||
|
pdf::PDFObject m_object;
|
||||||
|
};
|
||||||
|
|
||||||
|
QByteArray PDFObjectInspectorTreeItem::getDictionaryKey() const
|
||||||
|
{
|
||||||
|
return m_dictionaryKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFObjectInspectorTreeItem::setDictionaryKey(const QByteArray& dictionaryKey)
|
||||||
|
{
|
||||||
|
m_dictionaryKey = dictionaryKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdf::PDFObjectReference PDFObjectInspectorTreeItem::getReference() const
|
||||||
|
{
|
||||||
|
return m_reference;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFObjectInspectorTreeItem::setReference(const pdf::PDFObjectReference& reference)
|
||||||
|
{
|
||||||
|
m_reference = reference;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pdf::PDFObject& PDFObjectInspectorTreeItem::getObject() const
|
||||||
|
{
|
||||||
|
return m_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFObjectInspectorTreeItem::setObject(const pdf::PDFObject& object)
|
||||||
|
{
|
||||||
|
m_object = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObjectInspectorTreeItemModel::PDFObjectInspectorTreeItemModel(QObject* parent) :
|
||||||
|
pdf::PDFTreeItemModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PDFObjectInspectorTreeItemModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(section);
|
||||||
|
Q_UNUSED(orientation);
|
||||||
|
Q_UNUSED(role);
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
int PDFObjectInspectorTreeItemModel::columnCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PDFObjectInspectorTreeItemModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
{
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role != Qt::DisplayRole)
|
||||||
|
{
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
const PDFObjectInspectorTreeItem* item = static_cast<const PDFObjectInspectorTreeItem*>(index.internalPointer());
|
||||||
|
const PDFObjectInspectorTreeItem* parent = static_cast<const PDFObjectInspectorTreeItem*>(index.parent().internalPointer());
|
||||||
|
|
||||||
|
QStringList data;
|
||||||
|
if (item->getReference().isValid() && parent && !parent->getReference().isValid())
|
||||||
|
{
|
||||||
|
data << QString("%1 %2 R").arg(item->getReference().objectNumber).arg(item->getReference().generation);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray dictionaryKey = item->getDictionaryKey();
|
||||||
|
if (!dictionaryKey.isEmpty())
|
||||||
|
{
|
||||||
|
data << QString("/%1").arg(QString::fromLatin1(dictionaryKey.toPercentEncoding()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QLocale locale;
|
||||||
|
|
||||||
|
const pdf::PDFObject& object = item->getObject();
|
||||||
|
switch (object.getType())
|
||||||
|
{
|
||||||
|
case pdf::PDFObject::Type::Null:
|
||||||
|
data << tr("null");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case pdf::PDFObject::Type::Bool:
|
||||||
|
data << (object.getBool() ? tr("true") : tr("false"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case pdf::PDFObject::Type::Int:
|
||||||
|
data << locale.toString(object.getInteger());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case pdf::PDFObject::Type::Real:
|
||||||
|
data << locale.toString(object.getReal());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case pdf::PDFObject::Type::String:
|
||||||
|
data << QString("\"%1\"").arg(QString::fromLatin1(object.getString().toPercentEncoding()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case pdf::PDFObject::Type::Name:
|
||||||
|
data << QString("/%1").arg(QString::fromLatin1(object.getString().toPercentEncoding()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case pdf::PDFObject::Type::Array:
|
||||||
|
data << tr("Array [%1 items]").arg(locale.toString(object.getArray()->getCount()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case pdf::PDFObject::Type::Dictionary:
|
||||||
|
data << tr("Dictionary [%1 items]").arg(locale.toString(object.getDictionary()->getCount()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case pdf::PDFObject::Type::Stream:
|
||||||
|
data << tr("Stream [%1 items, %2 data bytes]").arg(locale.toString(object.getStream()->getDictionary()->getCount())).arg(locale.toString(object.getStream()->getContent()->size()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case pdf::PDFObject::Type::Reference:
|
||||||
|
data << QString("%1 %2 R").arg(object.getReference().objectNumber).arg(object.getReference().generation);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Q_ASSERT(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.join(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFObjectInspectorTreeItemModel::update()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
|
||||||
|
m_rootItem.reset();
|
||||||
|
|
||||||
|
if (m_document)
|
||||||
|
{
|
||||||
|
std::set<pdf::PDFObjectReference> usedReferences;
|
||||||
|
|
||||||
|
switch (m_mode)
|
||||||
|
{
|
||||||
|
case pdfplugin::PDFObjectInspectorTreeItemModel::Document:
|
||||||
|
{
|
||||||
|
m_rootItem.reset(new PDFObjectInspectorTreeItem());
|
||||||
|
const pdf::PDFObjectStorage& storage = m_document->getStorage();
|
||||||
|
createObjectItem(getRootItem(), pdf::PDFObjectReference(), storage.getTrailerDictionary(), true, usedReferences);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case pdfplugin::PDFObjectInspectorTreeItemModel::Page:
|
||||||
|
{
|
||||||
|
m_rootItem.reset(new PDFObjectInspectorTreeItem());
|
||||||
|
|
||||||
|
const size_t pageCount = m_document->getCatalog()->getPageCount();
|
||||||
|
for (size_t i = 0; i < pageCount; ++i)
|
||||||
|
{
|
||||||
|
if (const pdf::PDFPage* page = m_document->getCatalog()->getPage(i))
|
||||||
|
{
|
||||||
|
pdf::PDFObjectReference reference = page->getPageReference();
|
||||||
|
pdf::PDFObject object = m_document->getStorage().getObjectByReference(reference);
|
||||||
|
createObjectItem(getRootItem(), reference, object, true, usedReferences);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case pdfplugin::PDFObjectInspectorTreeItemModel::Image:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case pdfplugin::PDFObjectInspectorTreeItemModel::List:
|
||||||
|
{
|
||||||
|
m_rootItem.reset(new PDFObjectInspectorTreeItem());
|
||||||
|
|
||||||
|
const pdf::PDFObjectStorage& storage = m_document->getStorage();
|
||||||
|
createObjectItem(getRootItem(), pdf::PDFObjectReference(), storage.getTrailerDictionary(), false, usedReferences);
|
||||||
|
const pdf::PDFObjectStorage::PDFObjects& objects = storage.getObjects();
|
||||||
|
for (size_t i = 0; i < objects.size(); ++i)
|
||||||
|
{
|
||||||
|
pdf::PDFObjectReference reference(i, objects[i].generation);
|
||||||
|
pdf::PDFObject object = objects[i].object;
|
||||||
|
|
||||||
|
if (object.isNull())
|
||||||
|
{
|
||||||
|
// We skip null objects
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
createObjectItem(getRootItem(), reference, object, false, usedReferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
Q_ASSERT(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFObjectInspectorTreeItemModel::setMode(Mode mode)
|
||||||
|
{
|
||||||
|
if (m_mode != mode)
|
||||||
|
{
|
||||||
|
m_mode = mode;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PDFCreateObjectInspectorTreeItemFromObjectVisitor : public pdf::PDFAbstractVisitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit PDFCreateObjectInspectorTreeItemFromObjectVisitor(std::set<pdf::PDFObjectReference>* usedReferences,
|
||||||
|
const pdf::PDFDocument* document,
|
||||||
|
bool followReferences,
|
||||||
|
pdf::PDFObjectReference reference,
|
||||||
|
PDFObjectInspectorTreeItem* parent) :
|
||||||
|
m_usedReferences(usedReferences),
|
||||||
|
m_document(document),
|
||||||
|
m_followReferences(followReferences),
|
||||||
|
m_reference(reference)
|
||||||
|
{
|
||||||
|
m_parents.push(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~PDFCreateObjectInspectorTreeItemFromObjectVisitor() override
|
||||||
|
{
|
||||||
|
m_parents.pop();
|
||||||
|
Q_ASSERT(m_parents.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void visitNull() override;
|
||||||
|
virtual void visitBool(bool value) override;
|
||||||
|
virtual void visitInt(pdf::PDFInteger value) override;
|
||||||
|
virtual void visitReal(pdf::PDFReal value) override;
|
||||||
|
virtual void visitString(pdf::PDFStringRef string) override;
|
||||||
|
virtual void visitName(pdf::PDFStringRef name) override;
|
||||||
|
virtual void visitArray(const pdf::PDFArray* array) override;
|
||||||
|
virtual void visitDictionary(const pdf::PDFDictionary* dictionary) override;
|
||||||
|
virtual void visitStream(const pdf::PDFStream* stream) override;
|
||||||
|
virtual void visitReference(const pdf::PDFObjectReference reference) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::set<pdf::PDFObjectReference>* m_usedReferences;
|
||||||
|
const pdf::PDFDocument* m_document;
|
||||||
|
bool m_followReferences;
|
||||||
|
pdf::PDFObjectReference m_reference;
|
||||||
|
std::stack<PDFObjectInspectorTreeItem*> m_parents;
|
||||||
|
};
|
||||||
|
|
||||||
|
void PDFCreateObjectInspectorTreeItemFromObjectVisitor::visitNull()
|
||||||
|
{
|
||||||
|
m_parents.top()->addCreatedChild(new PDFObjectInspectorTreeItem(m_reference, pdf::PDFObject::createNull(), m_parents.top()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFCreateObjectInspectorTreeItemFromObjectVisitor::visitBool(bool value)
|
||||||
|
{
|
||||||
|
m_parents.top()->addCreatedChild(new PDFObjectInspectorTreeItem(m_reference, pdf::PDFObject::createBool(value), m_parents.top()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFCreateObjectInspectorTreeItemFromObjectVisitor::visitInt(pdf::PDFInteger value)
|
||||||
|
{
|
||||||
|
m_parents.top()->addCreatedChild(new PDFObjectInspectorTreeItem(m_reference, pdf::PDFObject::createInteger(value), m_parents.top()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFCreateObjectInspectorTreeItemFromObjectVisitor::visitReal(pdf::PDFReal value)
|
||||||
|
{
|
||||||
|
m_parents.top()->addCreatedChild(new PDFObjectInspectorTreeItem(m_reference, pdf::PDFObject::createReal(value), m_parents.top()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFCreateObjectInspectorTreeItemFromObjectVisitor::visitString(pdf::PDFStringRef string)
|
||||||
|
{
|
||||||
|
m_parents.top()->addCreatedChild(new PDFObjectInspectorTreeItem(m_reference, pdf::PDFObject::createString(string.getString()), m_parents.top()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFCreateObjectInspectorTreeItemFromObjectVisitor::visitName(pdf::PDFStringRef name)
|
||||||
|
{
|
||||||
|
m_parents.top()->addCreatedChild(new PDFObjectInspectorTreeItem(m_reference, pdf::PDFObject::createName(name), m_parents.top()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFCreateObjectInspectorTreeItemFromObjectVisitor::visitArray(const pdf::PDFArray* array)
|
||||||
|
{
|
||||||
|
PDFObjectInspectorTreeItem* arrayRoot = new PDFObjectInspectorTreeItem(m_reference, pdf::PDFObject::createArray(std::make_shared<pdf::PDFArray>(*array)), m_parents.top());
|
||||||
|
m_parents.top()->addCreatedChild(arrayRoot);
|
||||||
|
m_parents.push(arrayRoot);
|
||||||
|
acceptArray(array);
|
||||||
|
m_parents.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFCreateObjectInspectorTreeItemFromObjectVisitor::visitDictionary(const pdf::PDFDictionary* dictionary)
|
||||||
|
{
|
||||||
|
PDFObjectInspectorTreeItem* dictionaryRoot = new PDFObjectInspectorTreeItem(m_reference, pdf::PDFObject::createDictionary(std::make_shared<pdf::PDFDictionary>(*dictionary)), m_parents.top());
|
||||||
|
m_parents.top()->addCreatedChild(dictionaryRoot);
|
||||||
|
m_parents.push(dictionaryRoot);
|
||||||
|
|
||||||
|
acceptDictionary(dictionary);
|
||||||
|
|
||||||
|
Q_ASSERT(dictionaryRoot->getChildCount() == dictionary->getCount());
|
||||||
|
for (size_t i = 0, count = dictionary->getCount(); i < count; ++i)
|
||||||
|
{
|
||||||
|
PDFObjectInspectorTreeItem* child = static_cast<PDFObjectInspectorTreeItem*>(dictionaryRoot->getChild(int(i)));
|
||||||
|
child->setDictionaryKey(dictionary->getKey(i).getString());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_parents.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFCreateObjectInspectorTreeItemFromObjectVisitor::visitStream(const pdf::PDFStream* stream)
|
||||||
|
{
|
||||||
|
PDFObjectInspectorTreeItem* streamRoot = new PDFObjectInspectorTreeItem(m_reference, pdf::PDFObject::createStream(std::make_shared<pdf::PDFStream>(*stream)), m_parents.top());
|
||||||
|
m_parents.top()->addCreatedChild(streamRoot);
|
||||||
|
m_parents.push(streamRoot);
|
||||||
|
|
||||||
|
const pdf::PDFDictionary* dictionary = stream->getDictionary();
|
||||||
|
acceptDictionary(dictionary);
|
||||||
|
|
||||||
|
Q_ASSERT(streamRoot->getChildCount() == dictionary->getCount());
|
||||||
|
for (size_t i = 0, count = dictionary->getCount(); i < count; ++i)
|
||||||
|
{
|
||||||
|
PDFObjectInspectorTreeItem* child = static_cast<PDFObjectInspectorTreeItem*>(streamRoot->getChild(int(i)));
|
||||||
|
child->setDictionaryKey(dictionary->getKey(i).getString());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_parents.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFCreateObjectInspectorTreeItemFromObjectVisitor::visitReference(const pdf::PDFObjectReference reference)
|
||||||
|
{
|
||||||
|
PDFObjectInspectorTreeItem* referenceRoot = new PDFObjectInspectorTreeItem(m_reference, pdf::PDFObject::createReference(reference), m_parents.top());
|
||||||
|
m_parents.top()->addCreatedChild(referenceRoot);
|
||||||
|
|
||||||
|
if (m_followReferences && reference.isValid())
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_usedReferences);
|
||||||
|
|
||||||
|
if (!m_usedReferences->count(reference))
|
||||||
|
{
|
||||||
|
// Reference already followed
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_usedReferences->insert(reference);
|
||||||
|
|
||||||
|
m_parents.push(referenceRoot);
|
||||||
|
const pdf::PDFObject& object = m_document->getObjectByReference(reference);
|
||||||
|
object.accept(this);
|
||||||
|
m_parents.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFObjectInspectorTreeItemModel::createObjectItem(PDFObjectInspectorTreeItem* parent,
|
||||||
|
pdf::PDFObjectReference reference,
|
||||||
|
pdf::PDFObject object,
|
||||||
|
bool followRef,
|
||||||
|
std::set<pdf::PDFObjectReference>& usedReferences) const
|
||||||
|
{
|
||||||
|
PDFCreateObjectInspectorTreeItemFromObjectVisitor visitor(&usedReferences, m_document, followRef, reference, parent);
|
||||||
|
object.accept(&visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObjectInspectorTreeItem* PDFObjectInspectorTreeItemModel::getRootItem()
|
||||||
|
{
|
||||||
|
return static_cast<PDFObjectInspectorTreeItem*>(m_rootItem.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace pdfplugin
|
@ -0,0 +1,67 @@
|
|||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef PDFOBJECTINSPECTORTREEITEMMODEL_H
|
||||||
|
#define PDFOBJECTINSPECTORTREEITEMMODEL_H
|
||||||
|
|
||||||
|
#include "pdfitemmodels.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
namespace pdfplugin
|
||||||
|
{
|
||||||
|
|
||||||
|
class PDFObjectInspectorTreeItem;
|
||||||
|
|
||||||
|
class PDFObjectInspectorTreeItemModel : public pdf::PDFTreeItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum Mode
|
||||||
|
{
|
||||||
|
Document,
|
||||||
|
Page,
|
||||||
|
Image,
|
||||||
|
List
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit PDFObjectInspectorTreeItemModel(QObject* parent);
|
||||||
|
|
||||||
|
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||||
|
virtual int columnCount(const QModelIndex& parent) const override;
|
||||||
|
virtual QVariant data(const QModelIndex& index, int role) const override;
|
||||||
|
virtual void update() override;
|
||||||
|
|
||||||
|
void setMode(Mode mode);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void createObjectItem(PDFObjectInspectorTreeItem* parent,
|
||||||
|
pdf::PDFObjectReference reference,
|
||||||
|
pdf::PDFObject object,
|
||||||
|
bool followRef,
|
||||||
|
std::set<pdf::PDFObjectReference>& usedReferences) const;
|
||||||
|
|
||||||
|
PDFObjectInspectorTreeItem* getRootItem();
|
||||||
|
|
||||||
|
Mode m_mode = List;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace pdfplugin
|
||||||
|
|
||||||
|
#endif // PDFOBJECTINSPECTORTREEITEMMODEL_H
|
@ -22,6 +22,7 @@ SUBDIRS += \
|
|||||||
DimensionsPlugin \
|
DimensionsPlugin \
|
||||||
SoftProofingPlugin \
|
SoftProofingPlugin \
|
||||||
RedactPlugin \
|
RedactPlugin \
|
||||||
OutputPreviewPlugin
|
OutputPreviewPlugin \
|
||||||
|
ObjectInspectorPlugin
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user