mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Use LF instead of CRLF
This commit is contained in:
@@ -1,7 +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."
|
||||
}
|
||||
{
|
||||
"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."
|
||||
}
|
||||
|
@@ -1,63 +1,63 @@
|
||||
# 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 \
|
||||
objectstatisticsdialog.cpp \
|
||||
objectviewerwidget.cpp \
|
||||
pdfobjectinspectortreeitemmodel.cpp \
|
||||
statisticsgraphwidget.cpp
|
||||
|
||||
HEADERS += \
|
||||
objectinspectordialog.h \
|
||||
objectinspectorplugin.h \
|
||||
objectstatisticsdialog.h \
|
||||
objectviewerwidget.h \
|
||||
pdfobjectinspectortreeitemmodel.h \
|
||||
statisticsgraphwidget.h
|
||||
|
||||
CONFIG += force_debug_info
|
||||
|
||||
DISTFILES += \
|
||||
ObjectInspectorPlugin.json
|
||||
|
||||
RESOURCES += \
|
||||
icons.qrc
|
||||
|
||||
FORMS += \
|
||||
objectinspectordialog.ui \
|
||||
objectstatisticsdialog.ui \
|
||||
objectviewerwidget.ui \
|
||||
statisticsgraphwidget.ui
|
||||
# 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 \
|
||||
objectstatisticsdialog.cpp \
|
||||
objectviewerwidget.cpp \
|
||||
pdfobjectinspectortreeitemmodel.cpp \
|
||||
statisticsgraphwidget.cpp
|
||||
|
||||
HEADERS += \
|
||||
objectinspectordialog.h \
|
||||
objectinspectorplugin.h \
|
||||
objectstatisticsdialog.h \
|
||||
objectviewerwidget.h \
|
||||
pdfobjectinspectortreeitemmodel.h \
|
||||
statisticsgraphwidget.h
|
||||
|
||||
CONFIG += force_debug_info
|
||||
|
||||
DISTFILES += \
|
||||
ObjectInspectorPlugin.json
|
||||
|
||||
RESOURCES += \
|
||||
icons.qrc
|
||||
|
||||
FORMS += \
|
||||
objectinspectordialog.ui \
|
||||
objectstatisticsdialog.ui \
|
||||
objectviewerwidget.ui \
|
||||
statisticsgraphwidget.ui
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<RCC>
|
||||
<qresource prefix="/pdfplugins/objectinspector">
|
||||
<file>object-inspector.svg</file>
|
||||
<file>object-statistics.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
<RCC>
|
||||
<qresource prefix="/pdfplugins/objectinspector">
|
||||
<file>object-inspector.svg</file>
|
||||
<file>object-statistics.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -1,171 +1,171 @@
|
||||
// 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::PDFCMS* cms, const pdf::PDFDocument* document, QWidget* parent) :
|
||||
QDialog(parent, Qt::Dialog | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint),
|
||||
ui(new Ui::ObjectInspectorDialog),
|
||||
m_cms(cms),
|
||||
m_document(document),
|
||||
m_model(nullptr)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_objectClassifier.classify(document);
|
||||
|
||||
ui->currentObjectWidget->setCms(cms);
|
||||
ui->currentObjectWidget->setDocument(document);
|
||||
|
||||
ui->modeComboBox->addItem(tr("Document"), int(PDFObjectInspectorTreeItemModel::Document));
|
||||
ui->modeComboBox->addItem(tr("Pages"), int(PDFObjectInspectorTreeItemModel::Page));
|
||||
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::ContentStream))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Content streams"), int(PDFObjectInspectorTreeItemModel::ContentStream));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::GraphicState))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Graphic states"), int(PDFObjectInspectorTreeItemModel::GraphicState));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::ColorSpace))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Color spaces"), int(PDFObjectInspectorTreeItemModel::ColorSpace));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::Pattern))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Patterns"), int(PDFObjectInspectorTreeItemModel::Pattern));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::Shading))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Shadings"), int(PDFObjectInspectorTreeItemModel::Shading));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::Image))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Images"), int(PDFObjectInspectorTreeItemModel::Image));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::Form))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Forms"), int(PDFObjectInspectorTreeItemModel::Form));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::Font))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Fonts"), int(PDFObjectInspectorTreeItemModel::Font));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::Action))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Actions"), int(PDFObjectInspectorTreeItemModel::Action));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::Annotation))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Annotations"), int(PDFObjectInspectorTreeItemModel::Annotation));
|
||||
}
|
||||
|
||||
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(&m_objectClassifier, 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);
|
||||
|
||||
ui->splitter->setStretchFactor(0, 0);
|
||||
ui->splitter->setStretchFactor(1, 1);
|
||||
ui->splitter->setCollapsible(0, true);
|
||||
ui->splitter->setCollapsible(1, true);
|
||||
ui->splitter->setSizes(QList<int>() << pdf::PDFWidgetUtils::scaleDPI_x(this, 300) << pdf::PDFWidgetUtils::scaleDPI_x(this, 200));
|
||||
|
||||
connect(ui->objectTreeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ObjectInspectorDialog::onCurrentIndexChanged);
|
||||
connect(ui->currentObjectWidget, &ObjectViewerWidget::pinRequest, this, &ObjectInspectorDialog::onPinRequest);
|
||||
connect(ui->currentObjectWidget, &ObjectViewerWidget::unpinRequest, this, &ObjectInspectorDialog::onUnpinRequest);
|
||||
|
||||
ui->objectTreeView->setMinimumWidth(pdf::PDFWidgetUtils::scaleDPI_x(this, 200));
|
||||
setMinimumSize(pdf::PDFWidgetUtils::scaleDPI(this, QSize(800, 600)));
|
||||
pdf::PDFWidgetUtils::style(this);
|
||||
}
|
||||
|
||||
ObjectInspectorDialog::~ObjectInspectorDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ObjectInspectorDialog::onModeChanged()
|
||||
{
|
||||
const PDFObjectInspectorTreeItemModel::Mode mode = static_cast<const PDFObjectInspectorTreeItemModel::Mode>(ui->modeComboBox->currentData().toInt());
|
||||
m_model->setMode(mode);
|
||||
}
|
||||
|
||||
void ObjectInspectorDialog::onPinRequest()
|
||||
{
|
||||
ObjectViewerWidget* source = qobject_cast<ObjectViewerWidget*>(sender());
|
||||
|
||||
if (!source || source != ui->currentObjectWidget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectViewerWidget* cloned = ui->currentObjectWidget->clone(true, this);
|
||||
connect(cloned, &ObjectViewerWidget::pinRequest, this, &ObjectInspectorDialog::onPinRequest);
|
||||
connect(cloned, &ObjectViewerWidget::unpinRequest, this, &ObjectInspectorDialog::onUnpinRequest);
|
||||
ui->tabWidget->addTab(cloned, cloned->getTitleText());
|
||||
}
|
||||
|
||||
void ObjectInspectorDialog::onUnpinRequest()
|
||||
{
|
||||
ObjectViewerWidget* source = qobject_cast<ObjectViewerWidget*>(sender());
|
||||
|
||||
if (!source || source == ui->currentObjectWidget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ui->tabWidget->removeTab(ui->tabWidget->indexOf(source));
|
||||
source->deleteLater();
|
||||
}
|
||||
|
||||
void ObjectInspectorDialog::onCurrentIndexChanged(const QModelIndex& current, const QModelIndex& previous)
|
||||
{
|
||||
Q_UNUSED(previous);
|
||||
|
||||
pdf::PDFObject object = m_model->getObjectFromIndex(current);
|
||||
pdf::PDFObjectReference reference = m_model->getObjectReferenceFromIndex(current);
|
||||
bool isRoot = m_model->isRootObject(current);
|
||||
|
||||
if (!isRoot && object.isReference())
|
||||
{
|
||||
reference = object.getReference();
|
||||
object = m_document->getObjectByReference(reference);
|
||||
isRoot = true;
|
||||
}
|
||||
|
||||
ui->currentObjectWidget->setData(reference, qMove(object), isRoot);
|
||||
}
|
||||
|
||||
} // namespace pdfplugin
|
||||
// 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::PDFCMS* cms, const pdf::PDFDocument* document, QWidget* parent) :
|
||||
QDialog(parent, Qt::Dialog | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint),
|
||||
ui(new Ui::ObjectInspectorDialog),
|
||||
m_cms(cms),
|
||||
m_document(document),
|
||||
m_model(nullptr)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_objectClassifier.classify(document);
|
||||
|
||||
ui->currentObjectWidget->setCms(cms);
|
||||
ui->currentObjectWidget->setDocument(document);
|
||||
|
||||
ui->modeComboBox->addItem(tr("Document"), int(PDFObjectInspectorTreeItemModel::Document));
|
||||
ui->modeComboBox->addItem(tr("Pages"), int(PDFObjectInspectorTreeItemModel::Page));
|
||||
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::ContentStream))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Content streams"), int(PDFObjectInspectorTreeItemModel::ContentStream));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::GraphicState))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Graphic states"), int(PDFObjectInspectorTreeItemModel::GraphicState));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::ColorSpace))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Color spaces"), int(PDFObjectInspectorTreeItemModel::ColorSpace));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::Pattern))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Patterns"), int(PDFObjectInspectorTreeItemModel::Pattern));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::Shading))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Shadings"), int(PDFObjectInspectorTreeItemModel::Shading));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::Image))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Images"), int(PDFObjectInspectorTreeItemModel::Image));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::Form))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Forms"), int(PDFObjectInspectorTreeItemModel::Form));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::Font))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Fonts"), int(PDFObjectInspectorTreeItemModel::Font));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::Action))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Actions"), int(PDFObjectInspectorTreeItemModel::Action));
|
||||
}
|
||||
if (m_objectClassifier.hasType(pdf::PDFObjectClassifier::Annotation))
|
||||
{
|
||||
ui->modeComboBox->addItem(tr("Annotations"), int(PDFObjectInspectorTreeItemModel::Annotation));
|
||||
}
|
||||
|
||||
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(&m_objectClassifier, 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);
|
||||
|
||||
ui->splitter->setStretchFactor(0, 0);
|
||||
ui->splitter->setStretchFactor(1, 1);
|
||||
ui->splitter->setCollapsible(0, true);
|
||||
ui->splitter->setCollapsible(1, true);
|
||||
ui->splitter->setSizes(QList<int>() << pdf::PDFWidgetUtils::scaleDPI_x(this, 300) << pdf::PDFWidgetUtils::scaleDPI_x(this, 200));
|
||||
|
||||
connect(ui->objectTreeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ObjectInspectorDialog::onCurrentIndexChanged);
|
||||
connect(ui->currentObjectWidget, &ObjectViewerWidget::pinRequest, this, &ObjectInspectorDialog::onPinRequest);
|
||||
connect(ui->currentObjectWidget, &ObjectViewerWidget::unpinRequest, this, &ObjectInspectorDialog::onUnpinRequest);
|
||||
|
||||
ui->objectTreeView->setMinimumWidth(pdf::PDFWidgetUtils::scaleDPI_x(this, 200));
|
||||
setMinimumSize(pdf::PDFWidgetUtils::scaleDPI(this, QSize(800, 600)));
|
||||
pdf::PDFWidgetUtils::style(this);
|
||||
}
|
||||
|
||||
ObjectInspectorDialog::~ObjectInspectorDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ObjectInspectorDialog::onModeChanged()
|
||||
{
|
||||
const PDFObjectInspectorTreeItemModel::Mode mode = static_cast<const PDFObjectInspectorTreeItemModel::Mode>(ui->modeComboBox->currentData().toInt());
|
||||
m_model->setMode(mode);
|
||||
}
|
||||
|
||||
void ObjectInspectorDialog::onPinRequest()
|
||||
{
|
||||
ObjectViewerWidget* source = qobject_cast<ObjectViewerWidget*>(sender());
|
||||
|
||||
if (!source || source != ui->currentObjectWidget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectViewerWidget* cloned = ui->currentObjectWidget->clone(true, this);
|
||||
connect(cloned, &ObjectViewerWidget::pinRequest, this, &ObjectInspectorDialog::onPinRequest);
|
||||
connect(cloned, &ObjectViewerWidget::unpinRequest, this, &ObjectInspectorDialog::onUnpinRequest);
|
||||
ui->tabWidget->addTab(cloned, cloned->getTitleText());
|
||||
}
|
||||
|
||||
void ObjectInspectorDialog::onUnpinRequest()
|
||||
{
|
||||
ObjectViewerWidget* source = qobject_cast<ObjectViewerWidget*>(sender());
|
||||
|
||||
if (!source || source == ui->currentObjectWidget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ui->tabWidget->removeTab(ui->tabWidget->indexOf(source));
|
||||
source->deleteLater();
|
||||
}
|
||||
|
||||
void ObjectInspectorDialog::onCurrentIndexChanged(const QModelIndex& current, const QModelIndex& previous)
|
||||
{
|
||||
Q_UNUSED(previous);
|
||||
|
||||
pdf::PDFObject object = m_model->getObjectFromIndex(current);
|
||||
pdf::PDFObjectReference reference = m_model->getObjectReferenceFromIndex(current);
|
||||
bool isRoot = m_model->isRootObject(current);
|
||||
|
||||
if (!isRoot && object.isReference())
|
||||
{
|
||||
reference = object.getReference();
|
||||
object = m_document->getObjectByReference(reference);
|
||||
isRoot = true;
|
||||
}
|
||||
|
||||
ui->currentObjectWidget->setData(reference, qMove(object), isRoot);
|
||||
}
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
@@ -1,59 +1,59 @@
|
||||
// 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 "pdfobjectutils.h"
|
||||
#include "pdfcms.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ObjectInspectorDialog;
|
||||
}
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
class PDFObjectInspectorTreeItemModel;
|
||||
|
||||
class ObjectInspectorDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ObjectInspectorDialog(const pdf::PDFCMS* cms, const pdf::PDFDocument* document, QWidget* parent);
|
||||
virtual ~ObjectInspectorDialog() override;
|
||||
|
||||
private:
|
||||
void onModeChanged();
|
||||
void onPinRequest();
|
||||
void onUnpinRequest();
|
||||
void onCurrentIndexChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||
|
||||
Ui::ObjectInspectorDialog* ui;
|
||||
const pdf::PDFCMS* m_cms;
|
||||
const pdf::PDFDocument* m_document;
|
||||
pdf::PDFObjectClassifier m_objectClassifier;
|
||||
PDFObjectInspectorTreeItemModel* m_model;
|
||||
};
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
||||
#endif // OBJECTINSPECTORDIALOG_H
|
||||
// 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 "pdfobjectutils.h"
|
||||
#include "pdfcms.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ObjectInspectorDialog;
|
||||
}
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
class PDFObjectInspectorTreeItemModel;
|
||||
|
||||
class ObjectInspectorDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ObjectInspectorDialog(const pdf::PDFCMS* cms, const pdf::PDFDocument* document, QWidget* parent);
|
||||
virtual ~ObjectInspectorDialog() override;
|
||||
|
||||
private:
|
||||
void onModeChanged();
|
||||
void onPinRequest();
|
||||
void onUnpinRequest();
|
||||
void onCurrentIndexChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||
|
||||
Ui::ObjectInspectorDialog* ui;
|
||||
const pdf::PDFCMS* m_cms;
|
||||
const pdf::PDFDocument* m_document;
|
||||
pdf::PDFObjectClassifier m_objectClassifier;
|
||||
PDFObjectInspectorTreeItemModel* m_model;
|
||||
};
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
||||
#endif // OBJECTINSPECTORDIALOG_H
|
||||
|
@@ -1,114 +1,114 @@
|
||||
<?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="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="objectViewGroupBox">
|
||||
<property name="title">
|
||||
<string>Objects</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="modeComboBox"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="objectTreeView">
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="movable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="currentObjectTab">
|
||||
<attribute name="title">
|
||||
<string>Current Object</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="pdfplugin::ObjectViewerWidget" name="currentObjectWidget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<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>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>pdfplugin::ObjectViewerWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>objectviewerwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<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>
|
||||
<?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="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="objectViewGroupBox">
|
||||
<property name="title">
|
||||
<string>Objects</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="modeComboBox"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="objectTreeView">
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="movable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="currentObjectTab">
|
||||
<attribute name="title">
|
||||
<string>Current Object</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="pdfplugin::ObjectViewerWidget" name="currentObjectWidget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<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>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>pdfplugin::ObjectViewerWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>objectviewerwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<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>
|
||||
|
@@ -1,100 +1,100 @@
|
||||
// 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 "objectstatisticsdialog.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
ObjectInspectorPlugin::ObjectInspectorPlugin() :
|
||||
pdf::PDFPlugin(nullptr),
|
||||
m_objectInspectorAction(nullptr),
|
||||
m_objectStatisticsAction(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);
|
||||
|
||||
m_objectStatisticsAction = new QAction(QIcon(":/pdfplugins/objectinspector/object-statistics.svg"), tr("Object Statistics"), this);
|
||||
m_objectStatisticsAction->setCheckable(false);
|
||||
m_objectStatisticsAction->setObjectName("actionObjectInspector_ObjectStatistics");
|
||||
|
||||
connect(m_objectStatisticsAction, &QAction::triggered, this, &ObjectInspectorPlugin::onObjectStatisticsTriggered);
|
||||
|
||||
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, m_objectStatisticsAction };
|
||||
}
|
||||
|
||||
void ObjectInspectorPlugin::onObjectInspectorTriggered()
|
||||
{
|
||||
pdf::PDFCMSPointer cms = m_cmsManager->getCurrentCMS();
|
||||
ObjectInspectorDialog dialog(cms.data(), m_document, m_widget);
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void ObjectInspectorPlugin::onObjectStatisticsTriggered()
|
||||
{
|
||||
ObjectStatisticsDialog dialog(m_document, m_widget);
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void ObjectInspectorPlugin::updateActions()
|
||||
{
|
||||
m_objectInspectorAction->setEnabled(m_widget && m_document);
|
||||
m_objectStatisticsAction->setEnabled(m_widget && m_document);
|
||||
}
|
||||
|
||||
}
|
||||
// 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 "objectstatisticsdialog.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
ObjectInspectorPlugin::ObjectInspectorPlugin() :
|
||||
pdf::PDFPlugin(nullptr),
|
||||
m_objectInspectorAction(nullptr),
|
||||
m_objectStatisticsAction(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);
|
||||
|
||||
m_objectStatisticsAction = new QAction(QIcon(":/pdfplugins/objectinspector/object-statistics.svg"), tr("Object Statistics"), this);
|
||||
m_objectStatisticsAction->setCheckable(false);
|
||||
m_objectStatisticsAction->setObjectName("actionObjectInspector_ObjectStatistics");
|
||||
|
||||
connect(m_objectStatisticsAction, &QAction::triggered, this, &ObjectInspectorPlugin::onObjectStatisticsTriggered);
|
||||
|
||||
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, m_objectStatisticsAction };
|
||||
}
|
||||
|
||||
void ObjectInspectorPlugin::onObjectInspectorTriggered()
|
||||
{
|
||||
pdf::PDFCMSPointer cms = m_cmsManager->getCurrentCMS();
|
||||
ObjectInspectorDialog dialog(cms.data(), m_document, m_widget);
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void ObjectInspectorPlugin::onObjectStatisticsTriggered()
|
||||
{
|
||||
ObjectStatisticsDialog dialog(m_document, m_widget);
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void ObjectInspectorPlugin::updateActions()
|
||||
{
|
||||
m_objectInspectorAction->setEnabled(m_widget && m_document);
|
||||
m_objectStatisticsAction->setEnabled(m_widget && m_document);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,56 +1,56 @@
|
||||
// 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 onObjectStatisticsTriggered();
|
||||
|
||||
void updateActions();
|
||||
|
||||
QAction* m_objectInspectorAction;
|
||||
QAction* m_objectStatisticsAction;
|
||||
};
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
||||
#endif // OBJECTINSPECTORPLUGIN_H
|
||||
// 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 onObjectStatisticsTriggered();
|
||||
|
||||
void updateActions();
|
||||
|
||||
QAction* m_objectInspectorAction;
|
||||
QAction* m_objectStatisticsAction;
|
||||
};
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
||||
#endif // OBJECTINSPECTORPLUGIN_H
|
||||
|
@@ -1,169 +1,169 @@
|
||||
// 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 "objectstatisticsdialog.h"
|
||||
#include "ui_objectstatisticsdialog.h"
|
||||
|
||||
#include "pdfwidgetutils.h"
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
ObjectStatisticsDialog::ObjectStatisticsDialog(const pdf::PDFDocument* document, QWidget *parent) :
|
||||
QDialog(parent, Qt::Dialog | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint),
|
||||
ui(new Ui::ObjectStatisticsDialog),
|
||||
m_document(document)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->comboBox->addItem(tr("Statistics by Object Function"), int(ByObjectClass));
|
||||
ui->comboBox->addItem(tr("Statistics by Object Type"), int(ByObjectType));
|
||||
ui->comboBox->setCurrentIndex(ui->comboBox->findData(int(ByObjectClass), Qt::UserRole, Qt::MatchExactly));
|
||||
connect(ui->comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ObjectStatisticsDialog::updateStatisticsWidget);
|
||||
|
||||
pdf::PDFObjectClassifier classifier;
|
||||
classifier.classify(document);
|
||||
m_statistics = classifier.calculateStatistics(document);
|
||||
|
||||
updateStatisticsWidget();
|
||||
pdf::PDFWidgetUtils::style(this);
|
||||
}
|
||||
|
||||
ObjectStatisticsDialog::~ObjectStatisticsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ObjectStatisticsDialog::updateStatisticsWidget()
|
||||
{
|
||||
StatisticsGraphWidget::Statistics statistics;
|
||||
|
||||
QLocale locale;
|
||||
|
||||
std::array colors = {
|
||||
Qt::green,
|
||||
Qt::red,
|
||||
Qt::blue,
|
||||
Qt::cyan,
|
||||
Qt::magenta,
|
||||
Qt::yellow,
|
||||
Qt::darkGreen,
|
||||
Qt::darkRed,
|
||||
Qt::darkBlue,
|
||||
Qt::darkCyan,
|
||||
Qt::darkMagenta,
|
||||
Qt::darkYellow
|
||||
};
|
||||
|
||||
const StatisticsType statisticsType = static_cast<StatisticsType>(ui->comboBox->currentData().toInt());
|
||||
switch (statisticsType)
|
||||
{
|
||||
case pdfplugin::ObjectStatisticsDialog::ByObjectClass:
|
||||
{
|
||||
statistics.title = tr("Statistics by Object Class");
|
||||
statistics.headers = QStringList() << tr("Class") << tr("Percentage [%]") << tr("Count [#]") << tr("Space Usage [bytes]");
|
||||
|
||||
size_t colorId = 0;
|
||||
qint64 totalBytesCount = 0;
|
||||
for (const auto& item : m_statistics.statistics)
|
||||
{
|
||||
totalBytesCount += item.second.bytes;
|
||||
}
|
||||
|
||||
auto addItem = [&, this](pdf::PDFObjectClassifier::Type type, QString classText)
|
||||
{
|
||||
auto it = m_statistics.statistics.find(type);
|
||||
|
||||
if (it == m_statistics.statistics.cend())
|
||||
{
|
||||
// Jakub Melka: no type found
|
||||
return;
|
||||
}
|
||||
|
||||
const pdf::PDFObjectClassifier::StatisticsItem& statisticsItem = it->second;
|
||||
|
||||
qreal percentage = qreal(100.0) * qreal(statisticsItem.bytes) / qreal(totalBytesCount);
|
||||
|
||||
StatisticsGraphWidget::StatisticsItem item;
|
||||
item.portion = percentage / qreal(100.0);
|
||||
item.color = colors[colorId++ % colors.size()];
|
||||
item.texts = QStringList() << classText << locale.toString(percentage, 'f', 2) << locale.toString(statisticsItem.count) << locale.toString(statisticsItem.bytes);
|
||||
statistics.items.emplace_back(qMove(item));
|
||||
};
|
||||
|
||||
addItem(pdf::PDFObjectClassifier::Page, tr("Page"));
|
||||
addItem(pdf::PDFObjectClassifier::ContentStream, tr("Content Stream"));
|
||||
addItem(pdf::PDFObjectClassifier::GraphicState, tr("Graphic State"));
|
||||
addItem(pdf::PDFObjectClassifier::ColorSpace, tr("Color Space"));
|
||||
addItem(pdf::PDFObjectClassifier::Pattern, tr("Pattern"));
|
||||
addItem(pdf::PDFObjectClassifier::Shading, tr("Shading"));
|
||||
addItem(pdf::PDFObjectClassifier::Image, tr("Image"));
|
||||
addItem(pdf::PDFObjectClassifier::Form, tr("Form"));
|
||||
addItem(pdf::PDFObjectClassifier::Font, tr("Font"));
|
||||
addItem(pdf::PDFObjectClassifier::Action, tr("Action"));
|
||||
addItem(pdf::PDFObjectClassifier::Annotation, tr("Annotation"));
|
||||
addItem(pdf::PDFObjectClassifier::None, tr("Other"));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pdfplugin::ObjectStatisticsDialog::ByObjectType:
|
||||
{
|
||||
statistics.title = tr("Statistics by Object Type");
|
||||
statistics.headers = QStringList() << tr("Type") << tr("Percentage [%]") << tr("Count [#]");
|
||||
|
||||
qint64 totalObjectCount = 0;
|
||||
for (pdf::PDFObject::Type type : pdf::PDFObject::getTypes())
|
||||
{
|
||||
const qint64 currentObjectCount = m_statistics.objectCountByType[size_t(type)];
|
||||
totalObjectCount += currentObjectCount;
|
||||
}
|
||||
|
||||
if (totalObjectCount > 0)
|
||||
{
|
||||
size_t colorId = 0;
|
||||
for (pdf::PDFObject::Type type : pdf::PDFObject::getTypes())
|
||||
{
|
||||
const qint64 currentObjectCount = m_statistics.objectCountByType[size_t(type)];
|
||||
|
||||
if (currentObjectCount == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
qreal percentage = qreal(100.0) * qreal(currentObjectCount) / qreal(totalObjectCount);
|
||||
|
||||
StatisticsGraphWidget::StatisticsItem item;
|
||||
item.portion = percentage / qreal(100.0);
|
||||
item.color = colors[colorId++ % colors.size()];
|
||||
item.texts = QStringList() << pdf::PDFObjectUtils::getObjectTypeName(type) << locale.toString(percentage, 'f', 2) << locale.toString(currentObjectCount);
|
||||
statistics.items.emplace_back(qMove(item));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
ui->graphWidget->setStatistics(qMove(statistics));
|
||||
}
|
||||
|
||||
} // namespace pdfplugin
|
||||
// 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 "objectstatisticsdialog.h"
|
||||
#include "ui_objectstatisticsdialog.h"
|
||||
|
||||
#include "pdfwidgetutils.h"
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
ObjectStatisticsDialog::ObjectStatisticsDialog(const pdf::PDFDocument* document, QWidget *parent) :
|
||||
QDialog(parent, Qt::Dialog | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint),
|
||||
ui(new Ui::ObjectStatisticsDialog),
|
||||
m_document(document)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->comboBox->addItem(tr("Statistics by Object Function"), int(ByObjectClass));
|
||||
ui->comboBox->addItem(tr("Statistics by Object Type"), int(ByObjectType));
|
||||
ui->comboBox->setCurrentIndex(ui->comboBox->findData(int(ByObjectClass), Qt::UserRole, Qt::MatchExactly));
|
||||
connect(ui->comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ObjectStatisticsDialog::updateStatisticsWidget);
|
||||
|
||||
pdf::PDFObjectClassifier classifier;
|
||||
classifier.classify(document);
|
||||
m_statistics = classifier.calculateStatistics(document);
|
||||
|
||||
updateStatisticsWidget();
|
||||
pdf::PDFWidgetUtils::style(this);
|
||||
}
|
||||
|
||||
ObjectStatisticsDialog::~ObjectStatisticsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ObjectStatisticsDialog::updateStatisticsWidget()
|
||||
{
|
||||
StatisticsGraphWidget::Statistics statistics;
|
||||
|
||||
QLocale locale;
|
||||
|
||||
std::array colors = {
|
||||
Qt::green,
|
||||
Qt::red,
|
||||
Qt::blue,
|
||||
Qt::cyan,
|
||||
Qt::magenta,
|
||||
Qt::yellow,
|
||||
Qt::darkGreen,
|
||||
Qt::darkRed,
|
||||
Qt::darkBlue,
|
||||
Qt::darkCyan,
|
||||
Qt::darkMagenta,
|
||||
Qt::darkYellow
|
||||
};
|
||||
|
||||
const StatisticsType statisticsType = static_cast<StatisticsType>(ui->comboBox->currentData().toInt());
|
||||
switch (statisticsType)
|
||||
{
|
||||
case pdfplugin::ObjectStatisticsDialog::ByObjectClass:
|
||||
{
|
||||
statistics.title = tr("Statistics by Object Class");
|
||||
statistics.headers = QStringList() << tr("Class") << tr("Percentage [%]") << tr("Count [#]") << tr("Space Usage [bytes]");
|
||||
|
||||
size_t colorId = 0;
|
||||
qint64 totalBytesCount = 0;
|
||||
for (const auto& item : m_statistics.statistics)
|
||||
{
|
||||
totalBytesCount += item.second.bytes;
|
||||
}
|
||||
|
||||
auto addItem = [&, this](pdf::PDFObjectClassifier::Type type, QString classText)
|
||||
{
|
||||
auto it = m_statistics.statistics.find(type);
|
||||
|
||||
if (it == m_statistics.statistics.cend())
|
||||
{
|
||||
// Jakub Melka: no type found
|
||||
return;
|
||||
}
|
||||
|
||||
const pdf::PDFObjectClassifier::StatisticsItem& statisticsItem = it->second;
|
||||
|
||||
qreal percentage = qreal(100.0) * qreal(statisticsItem.bytes) / qreal(totalBytesCount);
|
||||
|
||||
StatisticsGraphWidget::StatisticsItem item;
|
||||
item.portion = percentage / qreal(100.0);
|
||||
item.color = colors[colorId++ % colors.size()];
|
||||
item.texts = QStringList() << classText << locale.toString(percentage, 'f', 2) << locale.toString(statisticsItem.count) << locale.toString(statisticsItem.bytes);
|
||||
statistics.items.emplace_back(qMove(item));
|
||||
};
|
||||
|
||||
addItem(pdf::PDFObjectClassifier::Page, tr("Page"));
|
||||
addItem(pdf::PDFObjectClassifier::ContentStream, tr("Content Stream"));
|
||||
addItem(pdf::PDFObjectClassifier::GraphicState, tr("Graphic State"));
|
||||
addItem(pdf::PDFObjectClassifier::ColorSpace, tr("Color Space"));
|
||||
addItem(pdf::PDFObjectClassifier::Pattern, tr("Pattern"));
|
||||
addItem(pdf::PDFObjectClassifier::Shading, tr("Shading"));
|
||||
addItem(pdf::PDFObjectClassifier::Image, tr("Image"));
|
||||
addItem(pdf::PDFObjectClassifier::Form, tr("Form"));
|
||||
addItem(pdf::PDFObjectClassifier::Font, tr("Font"));
|
||||
addItem(pdf::PDFObjectClassifier::Action, tr("Action"));
|
||||
addItem(pdf::PDFObjectClassifier::Annotation, tr("Annotation"));
|
||||
addItem(pdf::PDFObjectClassifier::None, tr("Other"));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pdfplugin::ObjectStatisticsDialog::ByObjectType:
|
||||
{
|
||||
statistics.title = tr("Statistics by Object Type");
|
||||
statistics.headers = QStringList() << tr("Type") << tr("Percentage [%]") << tr("Count [#]");
|
||||
|
||||
qint64 totalObjectCount = 0;
|
||||
for (pdf::PDFObject::Type type : pdf::PDFObject::getTypes())
|
||||
{
|
||||
const qint64 currentObjectCount = m_statistics.objectCountByType[size_t(type)];
|
||||
totalObjectCount += currentObjectCount;
|
||||
}
|
||||
|
||||
if (totalObjectCount > 0)
|
||||
{
|
||||
size_t colorId = 0;
|
||||
for (pdf::PDFObject::Type type : pdf::PDFObject::getTypes())
|
||||
{
|
||||
const qint64 currentObjectCount = m_statistics.objectCountByType[size_t(type)];
|
||||
|
||||
if (currentObjectCount == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
qreal percentage = qreal(100.0) * qreal(currentObjectCount) / qreal(totalObjectCount);
|
||||
|
||||
StatisticsGraphWidget::StatisticsItem item;
|
||||
item.portion = percentage / qreal(100.0);
|
||||
item.color = colors[colorId++ % colors.size()];
|
||||
item.texts = QStringList() << pdf::PDFObjectUtils::getObjectTypeName(type) << locale.toString(percentage, 'f', 2) << locale.toString(currentObjectCount);
|
||||
statistics.items.emplace_back(qMove(item));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
ui->graphWidget->setStatistics(qMove(statistics));
|
||||
}
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
@@ -1,59 +1,59 @@
|
||||
// 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 OBJECTSTATISTICSDIALOG_H
|
||||
#define OBJECTSTATISTICSDIALOG_H
|
||||
|
||||
#include "pdfdocument.h"
|
||||
#include "pdfobjectutils.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ObjectStatisticsDialog;
|
||||
}
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
class ObjectStatisticsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ObjectStatisticsDialog(const pdf::PDFDocument* document, QWidget* parent);
|
||||
virtual ~ObjectStatisticsDialog() override;
|
||||
|
||||
private:
|
||||
Ui::ObjectStatisticsDialog* ui;
|
||||
|
||||
enum StatisticsType
|
||||
{
|
||||
ByObjectClass,
|
||||
ByObjectType
|
||||
};
|
||||
|
||||
void updateStatisticsWidget();
|
||||
|
||||
const pdf::PDFDocument* m_document;
|
||||
pdf::PDFObjectClassifier::Statistics m_statistics;
|
||||
};
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
||||
#endif // OBJECTSTATISTICSDIALOG_H
|
||||
// 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 OBJECTSTATISTICSDIALOG_H
|
||||
#define OBJECTSTATISTICSDIALOG_H
|
||||
|
||||
#include "pdfdocument.h"
|
||||
#include "pdfobjectutils.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ObjectStatisticsDialog;
|
||||
}
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
class ObjectStatisticsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ObjectStatisticsDialog(const pdf::PDFDocument* document, QWidget* parent);
|
||||
virtual ~ObjectStatisticsDialog() override;
|
||||
|
||||
private:
|
||||
Ui::ObjectStatisticsDialog* ui;
|
||||
|
||||
enum StatisticsType
|
||||
{
|
||||
ByObjectClass,
|
||||
ByObjectType
|
||||
};
|
||||
|
||||
void updateStatisticsWidget();
|
||||
|
||||
const pdf::PDFDocument* m_document;
|
||||
pdf::PDFObjectClassifier::Statistics m_statistics;
|
||||
};
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
||||
#endif // OBJECTSTATISTICSDIALOG_H
|
||||
|
@@ -1,35 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ObjectStatisticsDialog</class>
|
||||
<widget class="QDialog" name="ObjectStatisticsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>924</width>
|
||||
<height>504</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Object Statistics</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="pdfplugin::StatisticsGraphWidget" name="graphWidget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>pdfplugin::StatisticsGraphWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>StatisticsGraphWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ObjectStatisticsDialog</class>
|
||||
<widget class="QDialog" name="ObjectStatisticsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>924</width>
|
||||
<height>504</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Object Statistics</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="pdfplugin::StatisticsGraphWidget" name="graphWidget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>pdfplugin::StatisticsGraphWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>StatisticsGraphWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@@ -1,315 +1,315 @@
|
||||
// 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 "objectviewerwidget.h"
|
||||
#include "ui_objectviewerwidget.h"
|
||||
|
||||
#include "pdfimage.h"
|
||||
#include "pdfencoding.h"
|
||||
#include "pdfdocumentwriter.h"
|
||||
#include "pdfexception.h"
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
ObjectViewerWidget::ObjectViewerWidget(QWidget *parent) :
|
||||
ObjectViewerWidget(false, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ObjectViewerWidget::ObjectViewerWidget(bool isPinned, QWidget* parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::ObjectViewerWidget),
|
||||
m_isPinned(isPinned),
|
||||
m_cms(nullptr),
|
||||
m_document(nullptr),
|
||||
m_isRootObject(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_printableCharacters = pdf::PDFEncoding::getPrintableCharacters();
|
||||
m_printableCharacters.push_back('\n');
|
||||
|
||||
connect(ui->pinButton, &QPushButton::clicked, this, &ObjectViewerWidget::pinRequest);
|
||||
connect(ui->unpinButton, &QPushButton::clicked, this, &ObjectViewerWidget::unpinRequest);
|
||||
|
||||
updateUi();
|
||||
updatePinnedUi();
|
||||
}
|
||||
|
||||
ObjectViewerWidget::~ObjectViewerWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
ObjectViewerWidget* ObjectViewerWidget::clone(bool isPinned, QWidget* parent)
|
||||
{
|
||||
ObjectViewerWidget* cloned = new ObjectViewerWidget(isPinned, parent);
|
||||
|
||||
cloned->setDocument(m_document);
|
||||
cloned->setCms(m_cms);
|
||||
cloned->setData(m_currentReference, m_currentObject, m_isRootObject);
|
||||
|
||||
|
||||
return cloned;
|
||||
}
|
||||
|
||||
void ObjectViewerWidget::setPinned(bool isPinned)
|
||||
{
|
||||
if (m_isPinned != isPinned)
|
||||
{
|
||||
m_isPinned = isPinned;
|
||||
updatePinnedUi();
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectViewerWidget::setData(pdf::PDFObjectReference currentReference, pdf::PDFObject currentObject, bool isRootObject)
|
||||
{
|
||||
if (m_currentReference != currentReference ||
|
||||
m_currentObject != currentObject ||
|
||||
m_isRootObject != isRootObject)
|
||||
{
|
||||
m_currentReference = currentReference;
|
||||
m_currentObject = currentObject;
|
||||
m_isRootObject = isRootObject;
|
||||
|
||||
updateUi();
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectViewerWidget::updateUi()
|
||||
{
|
||||
if (m_currentReference.isValid())
|
||||
{
|
||||
QString referenceText = tr("%1 %2 R").arg(m_currentReference.objectNumber).arg(m_currentReference.generation);
|
||||
|
||||
if (m_isRootObject)
|
||||
{
|
||||
ui->referenceEdit->setText(referenceText);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->referenceEdit->setText(tr("Part of object %1").arg(referenceText));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->referenceEdit->setText(tr("<none>"));
|
||||
}
|
||||
|
||||
switch (m_currentObject.getType())
|
||||
{
|
||||
case pdf::PDFObject::Type::Null:
|
||||
ui->typeEdit->setText(tr("Null"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Bool:
|
||||
ui->typeEdit->setText(tr("Bool"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Int:
|
||||
ui->typeEdit->setText(tr("Integer"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Real:
|
||||
ui->typeEdit->setText(tr("Real"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::String:
|
||||
ui->typeEdit->setText(tr("String"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Name:
|
||||
ui->typeEdit->setText(tr("Name"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Array:
|
||||
ui->typeEdit->setText(tr("Array"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Dictionary:
|
||||
ui->typeEdit->setText(tr("Dictionary"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Stream:
|
||||
ui->typeEdit->setText(tr("Stream"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Reference:
|
||||
ui->typeEdit->setText(tr("Reference"));
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
QLocale locale;
|
||||
|
||||
switch (m_currentObject.getType())
|
||||
{
|
||||
case pdf::PDFObject::Type::Null:
|
||||
ui->descriptionEdit->setText(tr("null"));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Bool:
|
||||
ui->descriptionEdit->setText(m_currentObject.getBool() ? tr("true") : tr("false"));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Int:
|
||||
ui->descriptionEdit->setText(locale.toString(m_currentObject.getInteger()));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Real:
|
||||
ui->descriptionEdit->setText(locale.toString(m_currentObject.getReal()));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::String:
|
||||
ui->descriptionEdit->setText(QString("\"%1\"").arg(pdf::PDFEncoding::convertSmartFromByteStringToRepresentableQString(m_currentObject.getString())));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Name:
|
||||
ui->descriptionEdit->setText(QString("/%1").arg(QString::fromLatin1(m_currentObject.getString().toPercentEncoding(m_printableCharacters))));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Array:
|
||||
ui->descriptionEdit->setText(tr("Array [%1 items]").arg(locale.toString(m_currentObject.getArray()->getCount())));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Dictionary:
|
||||
ui->descriptionEdit->setText(tr("Dictionary [%1 items]").arg(locale.toString(m_currentObject.getDictionary()->getCount())));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Stream:
|
||||
ui->descriptionEdit->setText(tr("Stream [%1 items, %2 data bytes]").arg(locale.toString(m_currentObject.getStream()->getDictionary()->getCount()), locale.toString(m_currentObject.getStream()->getContent()->size())));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Reference:
|
||||
ui->descriptionEdit->setText(QString("%1 %2 R").arg(m_currentObject.getReference().objectNumber).arg(m_currentObject.getReference().generation));
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_currentObject.isStream())
|
||||
{
|
||||
try
|
||||
{
|
||||
pdf::PDFDocumentDataLoaderDecorator loader(m_document);
|
||||
const pdf::PDFStream* stream = m_currentObject.getStream();
|
||||
const pdf::PDFDictionary* dictionary = stream->getDictionary();
|
||||
|
||||
if (loader.readNameFromDictionary(dictionary, "Type") == "XObject" &&
|
||||
loader.readNameFromDictionary(dictionary, "Subtype") == "Image")
|
||||
{
|
||||
pdf::PDFColorSpacePointer colorSpace;
|
||||
|
||||
if (dictionary->hasKey("ColorSpace"))
|
||||
{
|
||||
const pdf::PDFObject& colorSpaceObject = m_document->getObject(dictionary->get("ColorSpace"));
|
||||
if (colorSpaceObject.isName() || colorSpaceObject.isArray())
|
||||
{
|
||||
pdf::PDFDictionary dummyColorSpaceDictionary;
|
||||
colorSpace = pdf::PDFAbstractColorSpace::createColorSpace(&dummyColorSpaceDictionary, m_document, colorSpaceObject);
|
||||
}
|
||||
else if (!colorSpaceObject.isNull())
|
||||
{
|
||||
throw pdf::PDFException(tr("Invalid color space of the image."));
|
||||
}
|
||||
}
|
||||
|
||||
pdf::PDFRenderErrorReporterDummy dummyErrorReporter;
|
||||
pdf::PDFImage pdfImage = pdf::PDFImage::createImage(m_document, stream, qMove(colorSpace), false, pdf::RenderingIntent::Perceptual, &dummyErrorReporter);
|
||||
QImage image = pdfImage.getImage(m_cms, &dummyErrorReporter);
|
||||
ui->stackedWidget->setCurrentWidget(ui->imageBrowserPage);
|
||||
ui->imageBrowser->setPixmap(QPixmap::fromImage(image));
|
||||
|
||||
const int width = image.width();
|
||||
const int height = image.height();
|
||||
const int depth = loader.readIntegerFromDictionary(dictionary, "BitsPerComponent", 8);
|
||||
|
||||
QString textDescription = tr("Image Stream [%1 items, %2 data bytes, %3 x %4 pixels, %5 bits per component]");
|
||||
ui->descriptionEdit->setText(textDescription.arg(locale.toString(m_currentObject.getStream()->getDictionary()->getCount()),
|
||||
locale.toString(m_currentObject.getStream()->getContent()->size()),
|
||||
locale.toString(width),
|
||||
locale.toString(height),
|
||||
locale.toString(depth)));
|
||||
}
|
||||
else
|
||||
{
|
||||
QByteArray data = m_document->getDecodedStream(stream);
|
||||
data.replace('\r', ' ');
|
||||
QByteArray percentEncodedData = data.toPercentEncoding(m_printableCharacters);
|
||||
ui->contentTextBrowser->setText(QString::fromLatin1(percentEncodedData));
|
||||
ui->stackedWidget->setCurrentWidget(ui->contentTextBrowserPage);
|
||||
}
|
||||
}
|
||||
catch (pdf::PDFException exception)
|
||||
{
|
||||
ui->contentTextBrowser->setText(exception.getMessage());
|
||||
ui->stackedWidget->setCurrentWidget(ui->contentTextBrowserPage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QByteArray serializedObject = pdf::PDFDocumentWriter::getSerializedObject(m_currentObject);
|
||||
QByteArray percentEncodedData = serializedObject.toPercentEncoding(m_printableCharacters);
|
||||
ui->contentTextBrowser->setText(QString::fromLatin1(percentEncodedData));
|
||||
ui->stackedWidget->setCurrentWidget(ui->contentTextBrowserPage);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectViewerWidget::updatePinnedUi()
|
||||
{
|
||||
ui->pinButton->setEnabled(!m_isPinned);
|
||||
ui->unpinButton->setEnabled(m_isPinned);
|
||||
}
|
||||
|
||||
const pdf::PDFCMS* ObjectViewerWidget::getCms() const
|
||||
{
|
||||
return m_cms;
|
||||
}
|
||||
|
||||
void ObjectViewerWidget::setCms(const pdf::PDFCMS* cms)
|
||||
{
|
||||
m_cms = cms;
|
||||
}
|
||||
|
||||
QString ObjectViewerWidget::getTitleText() const
|
||||
{
|
||||
if (!m_currentReference.isValid())
|
||||
{
|
||||
return tr("[Unknown]");
|
||||
}
|
||||
|
||||
QString referenceString = tr("%1 %2 R").arg(m_currentReference.objectNumber).arg(m_currentReference.generation);
|
||||
|
||||
if (m_isRootObject)
|
||||
{
|
||||
return referenceString;
|
||||
}
|
||||
else
|
||||
{
|
||||
return tr("%1 (part)").arg(referenceString);
|
||||
}
|
||||
}
|
||||
|
||||
const pdf::PDFDocument* ObjectViewerWidget::getDocument() const
|
||||
{
|
||||
return m_document;
|
||||
}
|
||||
|
||||
void ObjectViewerWidget::setDocument(const pdf::PDFDocument* document)
|
||||
{
|
||||
m_document = document;
|
||||
}
|
||||
|
||||
} // namespace pdfplugin
|
||||
// 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 "objectviewerwidget.h"
|
||||
#include "ui_objectviewerwidget.h"
|
||||
|
||||
#include "pdfimage.h"
|
||||
#include "pdfencoding.h"
|
||||
#include "pdfdocumentwriter.h"
|
||||
#include "pdfexception.h"
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
ObjectViewerWidget::ObjectViewerWidget(QWidget *parent) :
|
||||
ObjectViewerWidget(false, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ObjectViewerWidget::ObjectViewerWidget(bool isPinned, QWidget* parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::ObjectViewerWidget),
|
||||
m_isPinned(isPinned),
|
||||
m_cms(nullptr),
|
||||
m_document(nullptr),
|
||||
m_isRootObject(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_printableCharacters = pdf::PDFEncoding::getPrintableCharacters();
|
||||
m_printableCharacters.push_back('\n');
|
||||
|
||||
connect(ui->pinButton, &QPushButton::clicked, this, &ObjectViewerWidget::pinRequest);
|
||||
connect(ui->unpinButton, &QPushButton::clicked, this, &ObjectViewerWidget::unpinRequest);
|
||||
|
||||
updateUi();
|
||||
updatePinnedUi();
|
||||
}
|
||||
|
||||
ObjectViewerWidget::~ObjectViewerWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
ObjectViewerWidget* ObjectViewerWidget::clone(bool isPinned, QWidget* parent)
|
||||
{
|
||||
ObjectViewerWidget* cloned = new ObjectViewerWidget(isPinned, parent);
|
||||
|
||||
cloned->setDocument(m_document);
|
||||
cloned->setCms(m_cms);
|
||||
cloned->setData(m_currentReference, m_currentObject, m_isRootObject);
|
||||
|
||||
|
||||
return cloned;
|
||||
}
|
||||
|
||||
void ObjectViewerWidget::setPinned(bool isPinned)
|
||||
{
|
||||
if (m_isPinned != isPinned)
|
||||
{
|
||||
m_isPinned = isPinned;
|
||||
updatePinnedUi();
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectViewerWidget::setData(pdf::PDFObjectReference currentReference, pdf::PDFObject currentObject, bool isRootObject)
|
||||
{
|
||||
if (m_currentReference != currentReference ||
|
||||
m_currentObject != currentObject ||
|
||||
m_isRootObject != isRootObject)
|
||||
{
|
||||
m_currentReference = currentReference;
|
||||
m_currentObject = currentObject;
|
||||
m_isRootObject = isRootObject;
|
||||
|
||||
updateUi();
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectViewerWidget::updateUi()
|
||||
{
|
||||
if (m_currentReference.isValid())
|
||||
{
|
||||
QString referenceText = tr("%1 %2 R").arg(m_currentReference.objectNumber).arg(m_currentReference.generation);
|
||||
|
||||
if (m_isRootObject)
|
||||
{
|
||||
ui->referenceEdit->setText(referenceText);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->referenceEdit->setText(tr("Part of object %1").arg(referenceText));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->referenceEdit->setText(tr("<none>"));
|
||||
}
|
||||
|
||||
switch (m_currentObject.getType())
|
||||
{
|
||||
case pdf::PDFObject::Type::Null:
|
||||
ui->typeEdit->setText(tr("Null"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Bool:
|
||||
ui->typeEdit->setText(tr("Bool"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Int:
|
||||
ui->typeEdit->setText(tr("Integer"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Real:
|
||||
ui->typeEdit->setText(tr("Real"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::String:
|
||||
ui->typeEdit->setText(tr("String"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Name:
|
||||
ui->typeEdit->setText(tr("Name"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Array:
|
||||
ui->typeEdit->setText(tr("Array"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Dictionary:
|
||||
ui->typeEdit->setText(tr("Dictionary"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Stream:
|
||||
ui->typeEdit->setText(tr("Stream"));
|
||||
break;
|
||||
case pdf::PDFObject::Type::Reference:
|
||||
ui->typeEdit->setText(tr("Reference"));
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
QLocale locale;
|
||||
|
||||
switch (m_currentObject.getType())
|
||||
{
|
||||
case pdf::PDFObject::Type::Null:
|
||||
ui->descriptionEdit->setText(tr("null"));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Bool:
|
||||
ui->descriptionEdit->setText(m_currentObject.getBool() ? tr("true") : tr("false"));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Int:
|
||||
ui->descriptionEdit->setText(locale.toString(m_currentObject.getInteger()));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Real:
|
||||
ui->descriptionEdit->setText(locale.toString(m_currentObject.getReal()));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::String:
|
||||
ui->descriptionEdit->setText(QString("\"%1\"").arg(pdf::PDFEncoding::convertSmartFromByteStringToRepresentableQString(m_currentObject.getString())));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Name:
|
||||
ui->descriptionEdit->setText(QString("/%1").arg(QString::fromLatin1(m_currentObject.getString().toPercentEncoding(m_printableCharacters))));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Array:
|
||||
ui->descriptionEdit->setText(tr("Array [%1 items]").arg(locale.toString(m_currentObject.getArray()->getCount())));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Dictionary:
|
||||
ui->descriptionEdit->setText(tr("Dictionary [%1 items]").arg(locale.toString(m_currentObject.getDictionary()->getCount())));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Stream:
|
||||
ui->descriptionEdit->setText(tr("Stream [%1 items, %2 data bytes]").arg(locale.toString(m_currentObject.getStream()->getDictionary()->getCount()), locale.toString(m_currentObject.getStream()->getContent()->size())));
|
||||
break;
|
||||
|
||||
case pdf::PDFObject::Type::Reference:
|
||||
ui->descriptionEdit->setText(QString("%1 %2 R").arg(m_currentObject.getReference().objectNumber).arg(m_currentObject.getReference().generation));
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_currentObject.isStream())
|
||||
{
|
||||
try
|
||||
{
|
||||
pdf::PDFDocumentDataLoaderDecorator loader(m_document);
|
||||
const pdf::PDFStream* stream = m_currentObject.getStream();
|
||||
const pdf::PDFDictionary* dictionary = stream->getDictionary();
|
||||
|
||||
if (loader.readNameFromDictionary(dictionary, "Type") == "XObject" &&
|
||||
loader.readNameFromDictionary(dictionary, "Subtype") == "Image")
|
||||
{
|
||||
pdf::PDFColorSpacePointer colorSpace;
|
||||
|
||||
if (dictionary->hasKey("ColorSpace"))
|
||||
{
|
||||
const pdf::PDFObject& colorSpaceObject = m_document->getObject(dictionary->get("ColorSpace"));
|
||||
if (colorSpaceObject.isName() || colorSpaceObject.isArray())
|
||||
{
|
||||
pdf::PDFDictionary dummyColorSpaceDictionary;
|
||||
colorSpace = pdf::PDFAbstractColorSpace::createColorSpace(&dummyColorSpaceDictionary, m_document, colorSpaceObject);
|
||||
}
|
||||
else if (!colorSpaceObject.isNull())
|
||||
{
|
||||
throw pdf::PDFException(tr("Invalid color space of the image."));
|
||||
}
|
||||
}
|
||||
|
||||
pdf::PDFRenderErrorReporterDummy dummyErrorReporter;
|
||||
pdf::PDFImage pdfImage = pdf::PDFImage::createImage(m_document, stream, qMove(colorSpace), false, pdf::RenderingIntent::Perceptual, &dummyErrorReporter);
|
||||
QImage image = pdfImage.getImage(m_cms, &dummyErrorReporter);
|
||||
ui->stackedWidget->setCurrentWidget(ui->imageBrowserPage);
|
||||
ui->imageBrowser->setPixmap(QPixmap::fromImage(image));
|
||||
|
||||
const int width = image.width();
|
||||
const int height = image.height();
|
||||
const int depth = loader.readIntegerFromDictionary(dictionary, "BitsPerComponent", 8);
|
||||
|
||||
QString textDescription = tr("Image Stream [%1 items, %2 data bytes, %3 x %4 pixels, %5 bits per component]");
|
||||
ui->descriptionEdit->setText(textDescription.arg(locale.toString(m_currentObject.getStream()->getDictionary()->getCount()),
|
||||
locale.toString(m_currentObject.getStream()->getContent()->size()),
|
||||
locale.toString(width),
|
||||
locale.toString(height),
|
||||
locale.toString(depth)));
|
||||
}
|
||||
else
|
||||
{
|
||||
QByteArray data = m_document->getDecodedStream(stream);
|
||||
data.replace('\r', ' ');
|
||||
QByteArray percentEncodedData = data.toPercentEncoding(m_printableCharacters);
|
||||
ui->contentTextBrowser->setText(QString::fromLatin1(percentEncodedData));
|
||||
ui->stackedWidget->setCurrentWidget(ui->contentTextBrowserPage);
|
||||
}
|
||||
}
|
||||
catch (pdf::PDFException exception)
|
||||
{
|
||||
ui->contentTextBrowser->setText(exception.getMessage());
|
||||
ui->stackedWidget->setCurrentWidget(ui->contentTextBrowserPage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QByteArray serializedObject = pdf::PDFDocumentWriter::getSerializedObject(m_currentObject);
|
||||
QByteArray percentEncodedData = serializedObject.toPercentEncoding(m_printableCharacters);
|
||||
ui->contentTextBrowser->setText(QString::fromLatin1(percentEncodedData));
|
||||
ui->stackedWidget->setCurrentWidget(ui->contentTextBrowserPage);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectViewerWidget::updatePinnedUi()
|
||||
{
|
||||
ui->pinButton->setEnabled(!m_isPinned);
|
||||
ui->unpinButton->setEnabled(m_isPinned);
|
||||
}
|
||||
|
||||
const pdf::PDFCMS* ObjectViewerWidget::getCms() const
|
||||
{
|
||||
return m_cms;
|
||||
}
|
||||
|
||||
void ObjectViewerWidget::setCms(const pdf::PDFCMS* cms)
|
||||
{
|
||||
m_cms = cms;
|
||||
}
|
||||
|
||||
QString ObjectViewerWidget::getTitleText() const
|
||||
{
|
||||
if (!m_currentReference.isValid())
|
||||
{
|
||||
return tr("[Unknown]");
|
||||
}
|
||||
|
||||
QString referenceString = tr("%1 %2 R").arg(m_currentReference.objectNumber).arg(m_currentReference.generation);
|
||||
|
||||
if (m_isRootObject)
|
||||
{
|
||||
return referenceString;
|
||||
}
|
||||
else
|
||||
{
|
||||
return tr("%1 (part)").arg(referenceString);
|
||||
}
|
||||
}
|
||||
|
||||
const pdf::PDFDocument* ObjectViewerWidget::getDocument() const
|
||||
{
|
||||
return m_document;
|
||||
}
|
||||
|
||||
void ObjectViewerWidget::setDocument(const pdf::PDFDocument* document)
|
||||
{
|
||||
m_document = document;
|
||||
}
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
@@ -1,77 +1,77 @@
|
||||
// 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 OBJECTVIEWERWIDGET_H
|
||||
#define OBJECTVIEWERWIDGET_H
|
||||
|
||||
#include "pdfdocument.h"
|
||||
#include "pdfcms.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ObjectViewerWidget;
|
||||
}
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
class ObjectViewerWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ObjectViewerWidget(QWidget* parent);
|
||||
explicit ObjectViewerWidget(bool isPinned, QWidget* parent);
|
||||
virtual ~ObjectViewerWidget() override;
|
||||
|
||||
ObjectViewerWidget* clone(bool isPinned, QWidget* parent);
|
||||
|
||||
void setPinned(bool isPinned);
|
||||
void setData(pdf::PDFObjectReference currentReference, pdf::PDFObject currentObject, bool isRootObject);
|
||||
|
||||
const pdf::PDFDocument* getDocument() const;
|
||||
void setDocument(const pdf::PDFDocument* document);
|
||||
|
||||
const pdf::PDFCMS* getCms() const;
|
||||
void setCms(const pdf::PDFCMS* cms);
|
||||
|
||||
QString getTitleText() const;
|
||||
|
||||
signals:
|
||||
void pinRequest();
|
||||
void unpinRequest();
|
||||
|
||||
private:
|
||||
void updateUi();
|
||||
void updatePinnedUi();
|
||||
|
||||
Ui::ObjectViewerWidget* ui;
|
||||
const pdf::PDFCMS* m_cms;
|
||||
const pdf::PDFDocument* m_document;
|
||||
bool m_isPinned;
|
||||
|
||||
pdf::PDFObjectReference m_currentReference;
|
||||
pdf::PDFObject m_currentObject;
|
||||
bool m_isRootObject;
|
||||
QByteArray m_printableCharacters;
|
||||
};
|
||||
|
||||
} // pdfplugin
|
||||
|
||||
#endif // OBJECTVIEWERWIDGET_H
|
||||
// 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 OBJECTVIEWERWIDGET_H
|
||||
#define OBJECTVIEWERWIDGET_H
|
||||
|
||||
#include "pdfdocument.h"
|
||||
#include "pdfcms.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ObjectViewerWidget;
|
||||
}
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
class ObjectViewerWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ObjectViewerWidget(QWidget* parent);
|
||||
explicit ObjectViewerWidget(bool isPinned, QWidget* parent);
|
||||
virtual ~ObjectViewerWidget() override;
|
||||
|
||||
ObjectViewerWidget* clone(bool isPinned, QWidget* parent);
|
||||
|
||||
void setPinned(bool isPinned);
|
||||
void setData(pdf::PDFObjectReference currentReference, pdf::PDFObject currentObject, bool isRootObject);
|
||||
|
||||
const pdf::PDFDocument* getDocument() const;
|
||||
void setDocument(const pdf::PDFDocument* document);
|
||||
|
||||
const pdf::PDFCMS* getCms() const;
|
||||
void setCms(const pdf::PDFCMS* cms);
|
||||
|
||||
QString getTitleText() const;
|
||||
|
||||
signals:
|
||||
void pinRequest();
|
||||
void unpinRequest();
|
||||
|
||||
private:
|
||||
void updateUi();
|
||||
void updatePinnedUi();
|
||||
|
||||
Ui::ObjectViewerWidget* ui;
|
||||
const pdf::PDFCMS* m_cms;
|
||||
const pdf::PDFDocument* m_document;
|
||||
bool m_isPinned;
|
||||
|
||||
pdf::PDFObjectReference m_currentReference;
|
||||
pdf::PDFObject m_currentObject;
|
||||
bool m_isRootObject;
|
||||
QByteArray m_printableCharacters;
|
||||
};
|
||||
|
||||
} // pdfplugin
|
||||
|
||||
#endif // OBJECTVIEWERWIDGET_H
|
||||
|
@@ -1,153 +1,153 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ObjectViewerWidget</class>
|
||||
<widget class="QWidget" name="ObjectViewerWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>773</width>
|
||||
<height>602</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,1">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pinButton">
|
||||
<property name="text">
|
||||
<string>Pin</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="unpinButton">
|
||||
<property name="text">
|
||||
<string>Unpin</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="informationGroupBox">
|
||||
<property name="title">
|
||||
<string>Information</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="parentReferenceLabel">
|
||||
<property name="text">
|
||||
<string>Reference</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="referenceEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="typeLabel">
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="typeEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="descriptionLabel">
|
||||
<property name="text">
|
||||
<string>Description</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="descriptionEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="contentsGroupBox">
|
||||
<property name="title">
|
||||
<string>Contents</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<widget class="QWidget" name="contentTextBrowserPage">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="contentTextBrowser"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="imageBrowserPage">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>98</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="imageBrowser">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ObjectViewerWidget</class>
|
||||
<widget class="QWidget" name="ObjectViewerWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>773</width>
|
||||
<height>602</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,1">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pinButton">
|
||||
<property name="text">
|
||||
<string>Pin</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="unpinButton">
|
||||
<property name="text">
|
||||
<string>Unpin</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="informationGroupBox">
|
||||
<property name="title">
|
||||
<string>Information</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="parentReferenceLabel">
|
||||
<property name="text">
|
||||
<string>Reference</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="referenceEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="typeLabel">
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="typeEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="descriptionLabel">
|
||||
<property name="text">
|
||||
<string>Description</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="descriptionEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="contentsGroupBox">
|
||||
<property name="title">
|
||||
<string>Contents</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<widget class="QWidget" name="contentTextBrowserPage">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="contentTextBrowser"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="imageBrowserPage">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>98</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="imageBrowser">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,82 +1,82 @@
|
||||
// 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 "pdfobjectutils.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
class PDFObjectInspectorTreeItem;
|
||||
|
||||
class PDFObjectInspectorTreeItemModel : public pdf::PDFTreeItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
enum Mode
|
||||
{
|
||||
Document,
|
||||
Page,
|
||||
ContentStream,
|
||||
GraphicState,
|
||||
ColorSpace,
|
||||
Pattern,
|
||||
Shading,
|
||||
Image,
|
||||
Form,
|
||||
Font,
|
||||
Action,
|
||||
Annotation,
|
||||
List
|
||||
};
|
||||
|
||||
explicit PDFObjectInspectorTreeItemModel(const pdf::PDFObjectClassifier* classifier, 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);
|
||||
|
||||
pdf::PDFObject getObjectFromIndex(const QModelIndex& index) const;
|
||||
pdf::PDFObjectReference getObjectReferenceFromIndex(const QModelIndex& index) const;
|
||||
bool isRootObject(const QModelIndex& index) const;
|
||||
|
||||
private:
|
||||
void createObjectItem(PDFObjectInspectorTreeItem* parent,
|
||||
pdf::PDFObjectReference reference,
|
||||
pdf::PDFObject object,
|
||||
bool followRef,
|
||||
std::set<pdf::PDFObjectReference>& usedReferences) const;
|
||||
|
||||
PDFObjectInspectorTreeItem* getRootItem();
|
||||
|
||||
const pdf::PDFObjectClassifier* m_classifier;
|
||||
Mode m_mode = List;
|
||||
};
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
||||
#endif // PDFOBJECTINSPECTORTREEITEMMODEL_H
|
||||
// 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 "pdfobjectutils.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
class PDFObjectInspectorTreeItem;
|
||||
|
||||
class PDFObjectInspectorTreeItemModel : public pdf::PDFTreeItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
enum Mode
|
||||
{
|
||||
Document,
|
||||
Page,
|
||||
ContentStream,
|
||||
GraphicState,
|
||||
ColorSpace,
|
||||
Pattern,
|
||||
Shading,
|
||||
Image,
|
||||
Form,
|
||||
Font,
|
||||
Action,
|
||||
Annotation,
|
||||
List
|
||||
};
|
||||
|
||||
explicit PDFObjectInspectorTreeItemModel(const pdf::PDFObjectClassifier* classifier, 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);
|
||||
|
||||
pdf::PDFObject getObjectFromIndex(const QModelIndex& index) const;
|
||||
pdf::PDFObjectReference getObjectReferenceFromIndex(const QModelIndex& index) const;
|
||||
bool isRootObject(const QModelIndex& index) const;
|
||||
|
||||
private:
|
||||
void createObjectItem(PDFObjectInspectorTreeItem* parent,
|
||||
pdf::PDFObjectReference reference,
|
||||
pdf::PDFObject object,
|
||||
bool followRef,
|
||||
std::set<pdf::PDFObjectReference>& usedReferences) const;
|
||||
|
||||
PDFObjectInspectorTreeItem* getRootItem();
|
||||
|
||||
const pdf::PDFObjectClassifier* m_classifier;
|
||||
Mode m_mode = List;
|
||||
};
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
||||
#endif // PDFOBJECTINSPECTORTREEITEMMODEL_H
|
||||
|
@@ -1,308 +1,308 @@
|
||||
// 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 "statisticsgraphwidget.h"
|
||||
#include "ui_statisticsgraphwidget.h"
|
||||
|
||||
#include "pdfwidgetutils.h"
|
||||
#include "pdfpainterutils.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
StatisticsGraphWidget::StatisticsGraphWidget(QWidget* parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::StatisticsGraphWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
StatisticsGraphWidget::~StatisticsGraphWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void StatisticsGraphWidget::setStatistics(Statistics statistics)
|
||||
{
|
||||
if (m_statistics != statistics)
|
||||
{
|
||||
m_statistics = qMove(statistics);
|
||||
updateGeometry();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
StatisticsGraphWidget::GeometryHint StatisticsGraphWidget::getGeometryHint() const
|
||||
{
|
||||
GeometryHint hint;
|
||||
|
||||
int fivePixelsX = pdf::PDFWidgetUtils::scaleDPI_x(this, 5);
|
||||
int fivePixelsY = pdf::PDFWidgetUtils::scaleDPI_y(this, 5);
|
||||
int textMargin = fivePixelsX;
|
||||
|
||||
hint.margins = QMargins(fivePixelsX, fivePixelsY, fivePixelsX, fivePixelsY);
|
||||
hint.colorRectangleWidth = pdf::PDFWidgetUtils::scaleDPI_x(this, 80);
|
||||
hint.linesWidthLeft = pdf::PDFWidgetUtils::scaleDPI_x(this, 15);
|
||||
hint.linesWidthRight = pdf::PDFWidgetUtils::scaleDPI_x(this, 5);
|
||||
hint.markerSize = fivePixelsX;
|
||||
hint.normalLineWidth = pdf::PDFWidgetUtils::scaleDPI_y(this, 2);
|
||||
hint.selectedLineWidth = pdf::PDFWidgetUtils::scaleDPI_y(this, 3);
|
||||
hint.colorRectangeLeftMargin = pdf::PDFWidgetUtils::scaleDPI_x(this, 40);
|
||||
|
||||
QFontMetrics fontMetricsTitle(getTitleFont());
|
||||
hint.titleWidth = fontMetricsTitle.horizontalAdvance(m_statistics.title);
|
||||
hint.titleHeight = fontMetricsTitle.lineSpacing();
|
||||
|
||||
QFontMetrics fontMetricsHeader(getHeaderFont());
|
||||
hint.textHeight = fontMetricsHeader.lineSpacing();
|
||||
|
||||
QFontMetrics fontMetricsText(getTextFont());
|
||||
hint.textHeight += fontMetricsText.lineSpacing() * int(m_statistics.items.size());
|
||||
|
||||
hint.textMargin = textMargin;
|
||||
hint.textLineHeight = fontMetricsText.lineSpacing();
|
||||
|
||||
// Determine text header width
|
||||
hint.textWidths.resize(m_statistics.headers.size(), 0);
|
||||
|
||||
for (int i = 0; i < m_statistics.headers.size(); ++i)
|
||||
{
|
||||
hint.textWidths[i] = fontMetricsHeader.horizontalAdvance(m_statistics.headers[i]);
|
||||
}
|
||||
|
||||
for (const auto& item : m_statistics.items)
|
||||
{
|
||||
Q_ASSERT(item.texts.size() == hint.textWidths.size());
|
||||
|
||||
for (int i = 0; i < item.texts.size(); ++i)
|
||||
{
|
||||
hint.textWidths[i] = qMax(hint.textWidths[i], fontMetricsHeader.horizontalAdvance(item.texts[i]));
|
||||
}
|
||||
}
|
||||
|
||||
int totalTextWidth = textMargin;
|
||||
for (int& textWidth : hint.textWidths)
|
||||
{
|
||||
textWidth += 2 * textMargin;
|
||||
totalTextWidth += textWidth;
|
||||
}
|
||||
|
||||
const int widthHint = hint.margins.left() + hint.colorRectangeLeftMargin + hint.colorRectangleWidth + hint.linesWidthLeft + hint.linesWidthRight + qMax(totalTextWidth, hint.titleWidth) + hint.margins.right();
|
||||
const int heightHint = hint.margins.top() + hint.titleHeight + qMax(pdf::PDFWidgetUtils::scaleDPI_y(this, 100), hint.textHeight) + hint.margins.bottom();
|
||||
|
||||
hint.minimalWidgetSize = QSize(widthHint, heightHint).expandedTo(pdf::PDFWidgetUtils::scaleDPI(this, QSize(400, 300)));
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
void StatisticsGraphWidget::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
QPainter painter(this);
|
||||
QRect rect = this->rect();
|
||||
|
||||
painter.fillRect(rect, Qt::white);
|
||||
|
||||
GeometryHint geometryHint = getGeometryHint();
|
||||
rect = rect.marginsRemoved(geometryHint.margins);
|
||||
|
||||
if (!m_statistics.title.isEmpty())
|
||||
{
|
||||
pdf::PDFPainterStateGuard guard(&painter);
|
||||
|
||||
QRect titleRect = rect;
|
||||
titleRect.setHeight(geometryHint.titleHeight);
|
||||
|
||||
painter.setFont(getHeaderFont());
|
||||
painter.drawText(titleRect, Qt::AlignCenter, m_statistics.title);
|
||||
|
||||
rect.setTop(titleRect.bottom());
|
||||
}
|
||||
|
||||
rect.setLeft(rect.left() + geometryHint.colorRectangeLeftMargin);
|
||||
|
||||
// Color boxes
|
||||
m_colorBoxes.clear();
|
||||
const int height = rect.height();
|
||||
|
||||
QColor selectedColor = Qt::darkYellow;
|
||||
|
||||
int top = rect.top();
|
||||
for (size_t i = 0; i < m_statistics.items.size(); ++i)
|
||||
{
|
||||
const StatisticsItem& item = m_statistics.items[i];
|
||||
QRect currentRect(rect.left(), top, geometryHint.colorRectangleWidth, height * item.portion);
|
||||
top = currentRect.bottom();
|
||||
|
||||
QColor color = (m_selectedColorBox == i) ? selectedColor: item.color;
|
||||
color.setAlphaF(0.8);
|
||||
painter.fillRect(currentRect, color);
|
||||
m_colorBoxes.push_back(currentRect);
|
||||
}
|
||||
|
||||
QPoint minLinePoint;
|
||||
QPoint maxLinePoint;
|
||||
|
||||
// Marked lines
|
||||
{
|
||||
pdf::PDFPainterStateGuard guard(&painter);
|
||||
for (size_t i = 0; i < m_statistics.items.size(); ++i)
|
||||
{
|
||||
QPen pen = painter.pen();
|
||||
pen.setColor((i == m_selectedColorBox) ? selectedColor : Qt::black);
|
||||
pen.setWidth(geometryHint.markerSize);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
painter.setPen(pen);
|
||||
|
||||
QRect colorBox = m_colorBoxes[i];
|
||||
QPoint marker = colorBox.center();
|
||||
marker.setX(colorBox.right());
|
||||
|
||||
painter.drawPoint(marker);
|
||||
|
||||
pen.setWidth((i == m_selectedColorBox) ? geometryHint.selectedLineWidth : geometryHint.normalLineWidth);
|
||||
painter.setPen(pen);
|
||||
|
||||
QPoint lineEnd = marker + QPoint(geometryHint.linesWidthLeft, 0);
|
||||
painter.drawLine(marker, lineEnd);
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
minLinePoint = lineEnd;
|
||||
}
|
||||
maxLinePoint = lineEnd;
|
||||
}
|
||||
}
|
||||
|
||||
// Texts
|
||||
{
|
||||
pdf::PDFPainterStateGuard guard(&painter);
|
||||
|
||||
QFont headerFont = getHeaderFont();
|
||||
QFont textFont = getTextFont();
|
||||
|
||||
QRect textRect = rect;
|
||||
textRect.setLeft(maxLinePoint.x() + geometryHint.textMargin);
|
||||
textRect.setHeight(geometryHint.textLineHeight);
|
||||
|
||||
std::vector<QLine> horizontalLines;
|
||||
horizontalLines.reserve(m_statistics.items.size());
|
||||
|
||||
auto drawTexts = [&](const QStringList& texts, bool isHeader)
|
||||
{
|
||||
pdf::PDFPainterStateGuard guard(&painter);
|
||||
painter.setFont(isHeader ? headerFont : textFont);
|
||||
|
||||
const int y = textRect.center().y();
|
||||
minLinePoint.ry() = qMin(minLinePoint.ry(), y);
|
||||
maxLinePoint.ry() = qMax(maxLinePoint.ry(), y);
|
||||
|
||||
QRect cellRect = textRect;
|
||||
for (int i = 0; i < texts.size(); ++i)
|
||||
{
|
||||
cellRect.setWidth(geometryHint.textWidths[i]);
|
||||
QRect finalCellRect = cellRect.marginsRemoved(QMargins(geometryHint.textMargin, 0, geometryHint.textMargin, 0));
|
||||
QString text = texts[i];
|
||||
Qt::Alignment alignment = (i == 0) ? Qt::Alignment(Qt::AlignLeft | Qt::AlignVCenter) : Qt::Alignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
painter.drawText(finalCellRect, alignment, text);
|
||||
cellRect.translate(cellRect.width(), 0);
|
||||
}
|
||||
|
||||
if (!isHeader)
|
||||
{
|
||||
QPoint startPoint = textRect.center();
|
||||
startPoint.setX(textRect.left());
|
||||
|
||||
QPoint endPoint(maxLinePoint.x(), startPoint.y());
|
||||
horizontalLines.emplace_back(startPoint, endPoint);
|
||||
}
|
||||
|
||||
textRect.translate(0, textRect.height());
|
||||
};
|
||||
|
||||
if (!m_statistics.headers.isEmpty())
|
||||
{
|
||||
drawTexts(m_statistics.headers, true);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_statistics.items.size(); ++i)
|
||||
{
|
||||
const StatisticsItem& item = m_statistics.items[i];
|
||||
drawTexts(item.texts, i == m_selectedColorBox);
|
||||
}
|
||||
|
||||
QPen pen = painter.pen();
|
||||
pen.setColor(Qt::black);
|
||||
pen.setWidth(geometryHint.normalLineWidth);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
painter.setPen(pen);
|
||||
|
||||
painter.drawLine(minLinePoint, maxLinePoint);
|
||||
|
||||
for (const QLine& line : horizontalLines)
|
||||
{
|
||||
painter.drawLine(line);
|
||||
}
|
||||
|
||||
pen = painter.pen();
|
||||
pen.setColor(Qt::black);
|
||||
pen.setWidth(geometryHint.markerSize);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
painter.setPen(pen);
|
||||
|
||||
for (const QLine& line : horizontalLines)
|
||||
{
|
||||
painter.drawPoint(line.p1());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QFont StatisticsGraphWidget::getTitleFont() const
|
||||
{
|
||||
QFont font = this->font();
|
||||
font.setPointSize(font.pointSize() * 2);
|
||||
font.setBold(true);
|
||||
return font;
|
||||
}
|
||||
|
||||
QFont StatisticsGraphWidget::getHeaderFont() const
|
||||
{
|
||||
QFont font = this->font();
|
||||
font.setBold(true);
|
||||
return font;
|
||||
}
|
||||
|
||||
QFont StatisticsGraphWidget::getTextFont() const
|
||||
{
|
||||
return this->font();
|
||||
}
|
||||
|
||||
QSize StatisticsGraphWidget::sizeHint() const
|
||||
{
|
||||
return getGeometryHint().minimalWidgetSize + pdf::PDFWidgetUtils::scaleDPI(this, QSize(100, 100));
|
||||
}
|
||||
|
||||
QSize StatisticsGraphWidget::minimumSizeHint() const
|
||||
{
|
||||
return getGeometryHint().minimalWidgetSize;
|
||||
}
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
||||
// 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 "statisticsgraphwidget.h"
|
||||
#include "ui_statisticsgraphwidget.h"
|
||||
|
||||
#include "pdfwidgetutils.h"
|
||||
#include "pdfpainterutils.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
StatisticsGraphWidget::StatisticsGraphWidget(QWidget* parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::StatisticsGraphWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
StatisticsGraphWidget::~StatisticsGraphWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void StatisticsGraphWidget::setStatistics(Statistics statistics)
|
||||
{
|
||||
if (m_statistics != statistics)
|
||||
{
|
||||
m_statistics = qMove(statistics);
|
||||
updateGeometry();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
StatisticsGraphWidget::GeometryHint StatisticsGraphWidget::getGeometryHint() const
|
||||
{
|
||||
GeometryHint hint;
|
||||
|
||||
int fivePixelsX = pdf::PDFWidgetUtils::scaleDPI_x(this, 5);
|
||||
int fivePixelsY = pdf::PDFWidgetUtils::scaleDPI_y(this, 5);
|
||||
int textMargin = fivePixelsX;
|
||||
|
||||
hint.margins = QMargins(fivePixelsX, fivePixelsY, fivePixelsX, fivePixelsY);
|
||||
hint.colorRectangleWidth = pdf::PDFWidgetUtils::scaleDPI_x(this, 80);
|
||||
hint.linesWidthLeft = pdf::PDFWidgetUtils::scaleDPI_x(this, 15);
|
||||
hint.linesWidthRight = pdf::PDFWidgetUtils::scaleDPI_x(this, 5);
|
||||
hint.markerSize = fivePixelsX;
|
||||
hint.normalLineWidth = pdf::PDFWidgetUtils::scaleDPI_y(this, 2);
|
||||
hint.selectedLineWidth = pdf::PDFWidgetUtils::scaleDPI_y(this, 3);
|
||||
hint.colorRectangeLeftMargin = pdf::PDFWidgetUtils::scaleDPI_x(this, 40);
|
||||
|
||||
QFontMetrics fontMetricsTitle(getTitleFont());
|
||||
hint.titleWidth = fontMetricsTitle.horizontalAdvance(m_statistics.title);
|
||||
hint.titleHeight = fontMetricsTitle.lineSpacing();
|
||||
|
||||
QFontMetrics fontMetricsHeader(getHeaderFont());
|
||||
hint.textHeight = fontMetricsHeader.lineSpacing();
|
||||
|
||||
QFontMetrics fontMetricsText(getTextFont());
|
||||
hint.textHeight += fontMetricsText.lineSpacing() * int(m_statistics.items.size());
|
||||
|
||||
hint.textMargin = textMargin;
|
||||
hint.textLineHeight = fontMetricsText.lineSpacing();
|
||||
|
||||
// Determine text header width
|
||||
hint.textWidths.resize(m_statistics.headers.size(), 0);
|
||||
|
||||
for (int i = 0; i < m_statistics.headers.size(); ++i)
|
||||
{
|
||||
hint.textWidths[i] = fontMetricsHeader.horizontalAdvance(m_statistics.headers[i]);
|
||||
}
|
||||
|
||||
for (const auto& item : m_statistics.items)
|
||||
{
|
||||
Q_ASSERT(item.texts.size() == hint.textWidths.size());
|
||||
|
||||
for (int i = 0; i < item.texts.size(); ++i)
|
||||
{
|
||||
hint.textWidths[i] = qMax(hint.textWidths[i], fontMetricsHeader.horizontalAdvance(item.texts[i]));
|
||||
}
|
||||
}
|
||||
|
||||
int totalTextWidth = textMargin;
|
||||
for (int& textWidth : hint.textWidths)
|
||||
{
|
||||
textWidth += 2 * textMargin;
|
||||
totalTextWidth += textWidth;
|
||||
}
|
||||
|
||||
const int widthHint = hint.margins.left() + hint.colorRectangeLeftMargin + hint.colorRectangleWidth + hint.linesWidthLeft + hint.linesWidthRight + qMax(totalTextWidth, hint.titleWidth) + hint.margins.right();
|
||||
const int heightHint = hint.margins.top() + hint.titleHeight + qMax(pdf::PDFWidgetUtils::scaleDPI_y(this, 100), hint.textHeight) + hint.margins.bottom();
|
||||
|
||||
hint.minimalWidgetSize = QSize(widthHint, heightHint).expandedTo(pdf::PDFWidgetUtils::scaleDPI(this, QSize(400, 300)));
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
void StatisticsGraphWidget::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
QPainter painter(this);
|
||||
QRect rect = this->rect();
|
||||
|
||||
painter.fillRect(rect, Qt::white);
|
||||
|
||||
GeometryHint geometryHint = getGeometryHint();
|
||||
rect = rect.marginsRemoved(geometryHint.margins);
|
||||
|
||||
if (!m_statistics.title.isEmpty())
|
||||
{
|
||||
pdf::PDFPainterStateGuard guard(&painter);
|
||||
|
||||
QRect titleRect = rect;
|
||||
titleRect.setHeight(geometryHint.titleHeight);
|
||||
|
||||
painter.setFont(getHeaderFont());
|
||||
painter.drawText(titleRect, Qt::AlignCenter, m_statistics.title);
|
||||
|
||||
rect.setTop(titleRect.bottom());
|
||||
}
|
||||
|
||||
rect.setLeft(rect.left() + geometryHint.colorRectangeLeftMargin);
|
||||
|
||||
// Color boxes
|
||||
m_colorBoxes.clear();
|
||||
const int height = rect.height();
|
||||
|
||||
QColor selectedColor = Qt::darkYellow;
|
||||
|
||||
int top = rect.top();
|
||||
for (size_t i = 0; i < m_statistics.items.size(); ++i)
|
||||
{
|
||||
const StatisticsItem& item = m_statistics.items[i];
|
||||
QRect currentRect(rect.left(), top, geometryHint.colorRectangleWidth, height * item.portion);
|
||||
top = currentRect.bottom();
|
||||
|
||||
QColor color = (m_selectedColorBox == i) ? selectedColor: item.color;
|
||||
color.setAlphaF(0.8);
|
||||
painter.fillRect(currentRect, color);
|
||||
m_colorBoxes.push_back(currentRect);
|
||||
}
|
||||
|
||||
QPoint minLinePoint;
|
||||
QPoint maxLinePoint;
|
||||
|
||||
// Marked lines
|
||||
{
|
||||
pdf::PDFPainterStateGuard guard(&painter);
|
||||
for (size_t i = 0; i < m_statistics.items.size(); ++i)
|
||||
{
|
||||
QPen pen = painter.pen();
|
||||
pen.setColor((i == m_selectedColorBox) ? selectedColor : Qt::black);
|
||||
pen.setWidth(geometryHint.markerSize);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
painter.setPen(pen);
|
||||
|
||||
QRect colorBox = m_colorBoxes[i];
|
||||
QPoint marker = colorBox.center();
|
||||
marker.setX(colorBox.right());
|
||||
|
||||
painter.drawPoint(marker);
|
||||
|
||||
pen.setWidth((i == m_selectedColorBox) ? geometryHint.selectedLineWidth : geometryHint.normalLineWidth);
|
||||
painter.setPen(pen);
|
||||
|
||||
QPoint lineEnd = marker + QPoint(geometryHint.linesWidthLeft, 0);
|
||||
painter.drawLine(marker, lineEnd);
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
minLinePoint = lineEnd;
|
||||
}
|
||||
maxLinePoint = lineEnd;
|
||||
}
|
||||
}
|
||||
|
||||
// Texts
|
||||
{
|
||||
pdf::PDFPainterStateGuard guard(&painter);
|
||||
|
||||
QFont headerFont = getHeaderFont();
|
||||
QFont textFont = getTextFont();
|
||||
|
||||
QRect textRect = rect;
|
||||
textRect.setLeft(maxLinePoint.x() + geometryHint.textMargin);
|
||||
textRect.setHeight(geometryHint.textLineHeight);
|
||||
|
||||
std::vector<QLine> horizontalLines;
|
||||
horizontalLines.reserve(m_statistics.items.size());
|
||||
|
||||
auto drawTexts = [&](const QStringList& texts, bool isHeader)
|
||||
{
|
||||
pdf::PDFPainterStateGuard guard(&painter);
|
||||
painter.setFont(isHeader ? headerFont : textFont);
|
||||
|
||||
const int y = textRect.center().y();
|
||||
minLinePoint.ry() = qMin(minLinePoint.ry(), y);
|
||||
maxLinePoint.ry() = qMax(maxLinePoint.ry(), y);
|
||||
|
||||
QRect cellRect = textRect;
|
||||
for (int i = 0; i < texts.size(); ++i)
|
||||
{
|
||||
cellRect.setWidth(geometryHint.textWidths[i]);
|
||||
QRect finalCellRect = cellRect.marginsRemoved(QMargins(geometryHint.textMargin, 0, geometryHint.textMargin, 0));
|
||||
QString text = texts[i];
|
||||
Qt::Alignment alignment = (i == 0) ? Qt::Alignment(Qt::AlignLeft | Qt::AlignVCenter) : Qt::Alignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
painter.drawText(finalCellRect, alignment, text);
|
||||
cellRect.translate(cellRect.width(), 0);
|
||||
}
|
||||
|
||||
if (!isHeader)
|
||||
{
|
||||
QPoint startPoint = textRect.center();
|
||||
startPoint.setX(textRect.left());
|
||||
|
||||
QPoint endPoint(maxLinePoint.x(), startPoint.y());
|
||||
horizontalLines.emplace_back(startPoint, endPoint);
|
||||
}
|
||||
|
||||
textRect.translate(0, textRect.height());
|
||||
};
|
||||
|
||||
if (!m_statistics.headers.isEmpty())
|
||||
{
|
||||
drawTexts(m_statistics.headers, true);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_statistics.items.size(); ++i)
|
||||
{
|
||||
const StatisticsItem& item = m_statistics.items[i];
|
||||
drawTexts(item.texts, i == m_selectedColorBox);
|
||||
}
|
||||
|
||||
QPen pen = painter.pen();
|
||||
pen.setColor(Qt::black);
|
||||
pen.setWidth(geometryHint.normalLineWidth);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
painter.setPen(pen);
|
||||
|
||||
painter.drawLine(minLinePoint, maxLinePoint);
|
||||
|
||||
for (const QLine& line : horizontalLines)
|
||||
{
|
||||
painter.drawLine(line);
|
||||
}
|
||||
|
||||
pen = painter.pen();
|
||||
pen.setColor(Qt::black);
|
||||
pen.setWidth(geometryHint.markerSize);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
painter.setPen(pen);
|
||||
|
||||
for (const QLine& line : horizontalLines)
|
||||
{
|
||||
painter.drawPoint(line.p1());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QFont StatisticsGraphWidget::getTitleFont() const
|
||||
{
|
||||
QFont font = this->font();
|
||||
font.setPointSize(font.pointSize() * 2);
|
||||
font.setBold(true);
|
||||
return font;
|
||||
}
|
||||
|
||||
QFont StatisticsGraphWidget::getHeaderFont() const
|
||||
{
|
||||
QFont font = this->font();
|
||||
font.setBold(true);
|
||||
return font;
|
||||
}
|
||||
|
||||
QFont StatisticsGraphWidget::getTextFont() const
|
||||
{
|
||||
return this->font();
|
||||
}
|
||||
|
||||
QSize StatisticsGraphWidget::sizeHint() const
|
||||
{
|
||||
return getGeometryHint().minimalWidgetSize + pdf::PDFWidgetUtils::scaleDPI(this, QSize(100, 100));
|
||||
}
|
||||
|
||||
QSize StatisticsGraphWidget::minimumSizeHint() const
|
||||
{
|
||||
return getGeometryHint().minimalWidgetSize;
|
||||
}
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
||||
|
@@ -1,106 +1,106 @@
|
||||
// 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 STATISTICSGRAPHWIDGET_H
|
||||
#define STATISTICSGRAPHWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class StatisticsGraphWidget;
|
||||
}
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
class StatisticsGraphWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
struct StatisticsItem
|
||||
{
|
||||
bool operator==(const StatisticsItem&) const = default;
|
||||
|
||||
qreal portion;
|
||||
QColor color;
|
||||
QStringList texts;
|
||||
};
|
||||
|
||||
struct Statistics
|
||||
{
|
||||
bool operator==(const Statistics&) const = default;
|
||||
|
||||
QString title;
|
||||
QStringList headers;
|
||||
std::vector<StatisticsItem> items;
|
||||
};
|
||||
|
||||
explicit StatisticsGraphWidget(QWidget* parent);
|
||||
virtual ~StatisticsGraphWidget() override;
|
||||
|
||||
virtual QSize sizeHint() const override;
|
||||
virtual QSize minimumSizeHint() const override;
|
||||
|
||||
void setStatistics(Statistics statistics);
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent* event) override;
|
||||
|
||||
private:
|
||||
Ui::StatisticsGraphWidget* ui;
|
||||
|
||||
struct GeometryHint
|
||||
{
|
||||
QMargins margins;
|
||||
int colorRectangleWidth = 0;
|
||||
int linesWidthLeft = 0;
|
||||
int linesWidthRight = 0;
|
||||
int markerSize = 0;
|
||||
int normalLineWidth = 0;
|
||||
int selectedLineWidth = 0;
|
||||
int colorRectangeLeftMargin = 0;
|
||||
|
||||
int titleWidth = 0;
|
||||
int titleHeight = 0;
|
||||
int textHeight = 0;
|
||||
int textMargin = 0;
|
||||
int textLineHeight = 0;
|
||||
|
||||
std::vector<int> textWidths;
|
||||
|
||||
QSize minimalWidgetSize;
|
||||
};
|
||||
|
||||
GeometryHint getGeometryHint() const;
|
||||
|
||||
QFont getTitleFont() const;
|
||||
QFont getHeaderFont() const;
|
||||
QFont getTextFont() const;
|
||||
|
||||
Statistics m_statistics;
|
||||
std::vector<QRect> m_colorBoxes;
|
||||
size_t m_selectedColorBox = -1;
|
||||
};
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
||||
#endif // STATISTICSGRAPHWIDGET_H
|
||||
// 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 STATISTICSGRAPHWIDGET_H
|
||||
#define STATISTICSGRAPHWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class StatisticsGraphWidget;
|
||||
}
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
class StatisticsGraphWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
struct StatisticsItem
|
||||
{
|
||||
bool operator==(const StatisticsItem&) const = default;
|
||||
|
||||
qreal portion;
|
||||
QColor color;
|
||||
QStringList texts;
|
||||
};
|
||||
|
||||
struct Statistics
|
||||
{
|
||||
bool operator==(const Statistics&) const = default;
|
||||
|
||||
QString title;
|
||||
QStringList headers;
|
||||
std::vector<StatisticsItem> items;
|
||||
};
|
||||
|
||||
explicit StatisticsGraphWidget(QWidget* parent);
|
||||
virtual ~StatisticsGraphWidget() override;
|
||||
|
||||
virtual QSize sizeHint() const override;
|
||||
virtual QSize minimumSizeHint() const override;
|
||||
|
||||
void setStatistics(Statistics statistics);
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent* event) override;
|
||||
|
||||
private:
|
||||
Ui::StatisticsGraphWidget* ui;
|
||||
|
||||
struct GeometryHint
|
||||
{
|
||||
QMargins margins;
|
||||
int colorRectangleWidth = 0;
|
||||
int linesWidthLeft = 0;
|
||||
int linesWidthRight = 0;
|
||||
int markerSize = 0;
|
||||
int normalLineWidth = 0;
|
||||
int selectedLineWidth = 0;
|
||||
int colorRectangeLeftMargin = 0;
|
||||
|
||||
int titleWidth = 0;
|
||||
int titleHeight = 0;
|
||||
int textHeight = 0;
|
||||
int textMargin = 0;
|
||||
int textLineHeight = 0;
|
||||
|
||||
std::vector<int> textWidths;
|
||||
|
||||
QSize minimalWidgetSize;
|
||||
};
|
||||
|
||||
GeometryHint getGeometryHint() const;
|
||||
|
||||
QFont getTitleFont() const;
|
||||
QFont getHeaderFont() const;
|
||||
QFont getTextFont() const;
|
||||
|
||||
Statistics m_statistics;
|
||||
std::vector<QRect> m_colorBoxes;
|
||||
size_t m_selectedColorBox = -1;
|
||||
};
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
||||
#endif // STATISTICSGRAPHWIDGET_H
|
||||
|
@@ -1,19 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>StatisticsGraphWidget</class>
|
||||
<widget class="QWidget" name="StatisticsGraphWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>StatisticsGraphWidget</class>
|
||||
<widget class="QWidget" name="StatisticsGraphWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
Reference in New Issue
Block a user