mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-02-18 20:50:50 +01:00
Mapper commiting
This commit is contained in:
parent
112ba7beb9
commit
3e2f351c0e
@ -283,7 +283,7 @@ PDFObjectFactory& PDFObjectFactory::operator<<(AnnotationBorderStyle style)
|
||||
|
||||
PDFObjectFactory& PDFObjectFactory::operator<<(const QDateTime& dateTime)
|
||||
{
|
||||
addObject(PDFObject::createString(PDFEncoding::converDateTimeToString(dateTime)));
|
||||
addObject(PDFObject::createString(PDFEncoding::convertDateTimeToString(dateTime)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -527,7 +527,7 @@ PDFObjectFactory& PDFObjectFactory::operator<<(WrapAnnotationColor color)
|
||||
|
||||
PDFObjectFactory& PDFObjectFactory::operator<<(WrapCurrentDateTime)
|
||||
{
|
||||
addObject(PDFObject::createString(PDFEncoding::converDateTimeToString(QDateTime::currentDateTime())));
|
||||
addObject(PDFObject::createString(PDFEncoding::convertDateTimeToString(QDateTime::currentDateTime())));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -2308,7 +2308,7 @@ QDateTime PDFEncoding::convertToDateTime(const QByteArray& stream)
|
||||
return QDateTime();
|
||||
}
|
||||
|
||||
QByteArray PDFEncoding::converDateTimeToString(QDateTime dateTime)
|
||||
QByteArray PDFEncoding::convertDateTimeToString(QDateTime dateTime)
|
||||
{
|
||||
QDateTime utcDateTime = dateTime.toUTC();
|
||||
QString convertedDateTime = QString("D:%1").arg(utcDateTime.toString("yyyyMMddhhmmss"));
|
||||
|
@ -105,7 +105,7 @@ public:
|
||||
/// Convert date/time to string according to PDF Reference 1.7, Chapter 3.8.1.
|
||||
/// If date is invalid, empty byte array is returned.
|
||||
/// \param dateTime Date and time to be converted
|
||||
static QByteArray converDateTimeToString(QDateTime dateTime);
|
||||
static QByteArray convertDateTimeToString(QDateTime dateTime);
|
||||
|
||||
/// Returns conversion table for particular encoding
|
||||
/// \param encoding Encoding
|
||||
|
@ -101,6 +101,12 @@ bool PDFObjectEditorAbstractModel::queryAttribute(size_t index, Question questio
|
||||
case Question::IsAttributeEditable:
|
||||
return queryAttribute(index, Question::HasAttribute) && !attribute.attributeFlags.testFlag(PDFObjectEditorModelAttribute::Readonly);
|
||||
|
||||
case Question::IsSelector:
|
||||
return attribute.attributeFlags.type == ObjectEditorAttributeType::Selector;
|
||||
|
||||
case Question::IsPersisted:
|
||||
return !queryAttribute(index, Question::IsSelector) && !attribute.dictionaryAttribute.isEmpty();
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -113,6 +119,45 @@ bool PDFObjectEditorAbstractModel::getSelectorValue(size_t index) const
|
||||
return m_attributes.at(index).selectorAttributeValue;
|
||||
}
|
||||
|
||||
void PDFObjectEditorAbstractModel::setSelectorValue(size_t index, bool value)
|
||||
{
|
||||
m_attributes.at(index).selectorAttributeValue = value;
|
||||
}
|
||||
|
||||
std::vector<size_t> PDFObjectEditorAbstractModel::getSelectorAttributes() const
|
||||
{
|
||||
std::vector<size_t> result;
|
||||
result.reserve(8); // Estimate maximal number of selectors
|
||||
|
||||
const size_t count = getAttributeCount();
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (queryAttribute(i, Question::IsSelector))
|
||||
{
|
||||
result.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<size_t> PDFObjectEditorAbstractModel::getSelectorDependentAttributes(size_t selector) const
|
||||
{
|
||||
std::vector<size_t> result;
|
||||
result.reserve(16); // Estimate maximal number of selector's attributes
|
||||
|
||||
const size_t count = getAttributeCount();
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (m_attributes.at(i).selectorAttribute == selector)
|
||||
{
|
||||
result.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PDFObject PDFObjectEditorAbstractModel::getValue(size_t index) const
|
||||
{
|
||||
const QByteArrayList& dictionaryAttribute = m_attributes.at(index).dictionaryAttribute;
|
||||
@ -147,6 +192,44 @@ PDFObject PDFObjectEditorAbstractModel::getDefaultValue(size_t index) const
|
||||
return m_attributes.at(index).defaultValue;
|
||||
}
|
||||
|
||||
void PDFObjectEditorAbstractModel::setEditedObject(PDFObject object)
|
||||
{
|
||||
if (m_editedObject != object)
|
||||
{
|
||||
m_editedObject = qMove(object);
|
||||
emit editedObjectChanged();
|
||||
}
|
||||
}
|
||||
|
||||
PDFObject PDFObjectEditorAbstractModel::writeAttributeValueToObject(size_t attribute, PDFObject object, PDFObject value) const
|
||||
{
|
||||
Q_ASSERT(queryAttribute(attribute, Question::IsPersisted));
|
||||
|
||||
PDFObjectFactory factory;
|
||||
factory.beginDictionary();
|
||||
|
||||
const QByteArrayList& dictionaryAttribute = m_attributes.at(index).dictionaryAttribute;
|
||||
const int pathDepth = dictionaryAttribute.size() - 1;
|
||||
for (int i = 0; i < pathDepth; ++i)
|
||||
{
|
||||
factory.beginDictionaryItem(dictionaryAttribute[i]);
|
||||
factory.beginDictionary();
|
||||
}
|
||||
|
||||
factory.beginDictionaryItem(dictionaryAttribute.back());
|
||||
factory << qMove(value);
|
||||
factory.endDictionaryItem();
|
||||
|
||||
for (int i = 0; i < pathDepth; ++i)
|
||||
{
|
||||
factory.endDictionary();
|
||||
factory.endDictionaryItem();
|
||||
}
|
||||
|
||||
factory.endDictionaryItem();
|
||||
return PDFObjectManipulator::merge(qMove(object), factory.takeObject(), PDFObjectManipulator::RemoveNullObjects);
|
||||
}
|
||||
|
||||
size_t PDFObjectEditorAbstractModel::createAttribute(ObjectEditorAttributeType type,
|
||||
QByteArray attributeName,
|
||||
QString category,
|
||||
|
@ -128,19 +128,41 @@ public:
|
||||
|
||||
enum class Question
|
||||
{
|
||||
IsMapped,
|
||||
HasAttribute,
|
||||
IsAttributeEditable
|
||||
IsMapped, ///< Is attribute mapped in gui?
|
||||
IsSelector, ///< Is attribute's role a selector for other attributes?
|
||||
IsPersisted, ///< Is attribute persisted to edited object?
|
||||
HasAttribute, ///< Does current object has given attribute?
|
||||
IsAttributeEditable ///< Is current attribute editable (this implies previous flag) ?
|
||||
};
|
||||
|
||||
bool queryAttribute(size_t index, Question question) const;
|
||||
|
||||
bool getSelectorValue(size_t index) const;
|
||||
void setSelectorValue(size_t index, bool value);
|
||||
|
||||
/// Returns vector of attributes, which are of type selector
|
||||
std::vector<size_t> getSelectorAttributes() const;
|
||||
|
||||
/// Returns vector of attributes, which are turned on/off
|
||||
/// by this selector.
|
||||
std::vector<size_t> getSelectorDependentAttributes(size_t selector) const;
|
||||
|
||||
PDFObject getValue(size_t index) const;
|
||||
PDFObject getDefaultValue(size_t index) const;
|
||||
PDFObject getEditedObject() const { return m_editedObject; }
|
||||
void setEditedObject(PDFObject object);
|
||||
|
||||
/// Writes attribute value to the object.
|
||||
/// \param attribute Attribute
|
||||
/// \param object Old object
|
||||
/// \param value Value
|
||||
PDFObject writeAttributeValueToObject(size_t attribute, PDFObject object, PDFObject value) const;
|
||||
|
||||
const PDFObjectStorage* getStorage() const { return m_storage; }
|
||||
|
||||
signals:
|
||||
void editedObjectChanged();
|
||||
|
||||
protected:
|
||||
size_t createAttribute(ObjectEditorAttributeType type,
|
||||
QByteArray attributeName,
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "pdfobjecteditorwidget.h"
|
||||
#include "pdfobjecteditorwidget_impl.h"
|
||||
#include "pdfdocumentbuilder.h"
|
||||
#include "pdfencoding.h"
|
||||
|
||||
#include <QTabWidget>
|
||||
#include <QVBoxLayout>
|
||||
@ -29,11 +30,14 @@
|
||||
#include <QLineEdit>
|
||||
#include <QTextBrowser>
|
||||
#include <QPushButton>
|
||||
#include <QDateTimeEdit>
|
||||
#include <QCheckBox>
|
||||
#include <QDialogButtonBox>
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
|
||||
PDFObjectEditorWidget::PDFObjectEditorWidget(PDFObjectEditorAbstractModel* model, QWidget* parent) :
|
||||
PDFObjectEditorWidget::PDFObjectEditorWidget(EditObjectType type, QWidget* parent) :
|
||||
BaseClass(parent),
|
||||
m_mapper(nullptr),
|
||||
m_tabWidget(nullptr)
|
||||
@ -42,15 +46,29 @@ PDFObjectEditorWidget::PDFObjectEditorWidget(PDFObjectEditorAbstractModel* model
|
||||
m_tabWidget = new QTabWidget(this);
|
||||
layout->addWidget(m_tabWidget);
|
||||
|
||||
PDFObjectEditorAbstractModel* model = nullptr;
|
||||
switch (type)
|
||||
{
|
||||
case EditObjectType::Annotation:
|
||||
model = new PDFObjectEditorAnnotationsModel(this);
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
Q_ASSERT(model);
|
||||
|
||||
m_mapper = new PDFObjectEditorWidgetMapper(model, this);
|
||||
m_mapper->initialize(m_tabWidget);
|
||||
}
|
||||
|
||||
PDFObjectEditorWidgetMapper::PDFObjectEditorWidgetMapper(PDFObjectEditorAbstractModel* model, QObject* parent) :
|
||||
BaseClass(parent),
|
||||
m_model(model)
|
||||
m_model(model),
|
||||
m_isCommitingDisabled(false)
|
||||
{
|
||||
|
||||
connect(model, &PDFObjectEditorAbstractModel::editedObjectChanged, this, &PDFObjectEditorWidgetMapper::onEditedObjectChanged);
|
||||
}
|
||||
|
||||
void PDFObjectEditorWidgetMapper::initialize(QTabWidget* tabWidget)
|
||||
@ -99,6 +117,78 @@ void PDFObjectEditorWidgetMapper::initialize(QTabWidget* tabWidget)
|
||||
}
|
||||
}
|
||||
|
||||
void PDFObjectEditorWidgetMapper::onEditedObjectChanged()
|
||||
{
|
||||
if (!m_isCommitingDisabled)
|
||||
{
|
||||
loadWidgets();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFObjectEditorWidgetMapper::onCommitRequested(size_t attribute)
|
||||
{
|
||||
if (m_isCommitingDisabled)
|
||||
{
|
||||
// Jakub Melka: Commit is disabled
|
||||
return;
|
||||
}
|
||||
|
||||
PDFTemporaryValueChange guard(&m_isCommitingDisabled, true);
|
||||
|
||||
// We will create a new object using several steps. We merge
|
||||
// the resulting object with old one (so data, that are not
|
||||
// edited, will remain). Steps:
|
||||
// 1) If object is selector attribute, and it is turned on,
|
||||
// set default values to selector's attributes and set
|
||||
// selector value.
|
||||
// 2) If object is selector attributem and it is turned off,
|
||||
// set null values to selector's attributes and set selector
|
||||
// value.
|
||||
// 3) For ordinary attributes, commit new value of the attribute
|
||||
// to the object.
|
||||
// 4) Iterate each attribute, and if it doesn't exist, then set
|
||||
// it to null in the object. If it exists, and it is constant,
|
||||
// then add constant to the object.
|
||||
// 5) Set final object as new object
|
||||
|
||||
PDFObject object = m_model->getEditedObject();
|
||||
|
||||
// Steps 1) and 2)
|
||||
if (m_model->queryAttribute(attribute, PDFObjectEditorAbstractModel::Question::IsSelector))
|
||||
{
|
||||
const bool isChecked = m_adapters[attribute]->getValue().getBool();
|
||||
m_model->setSelectorValue(attribute, isChecked);
|
||||
|
||||
std::vector<size_t> dependentAttributes = m_model->getSelectorDependentAttributes(attribute);
|
||||
if (isChecked)
|
||||
{
|
||||
for (size_t dependentAttribute : dependentAttributes)
|
||||
{
|
||||
object = m_model->writeAttributeValueToObject(dependentAttribute, object, m_model->getDefaultValue(dependentAttribute));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t dependentAttribute : dependentAttributes)
|
||||
{
|
||||
object = m_model->writeAttributeValueToObject(dependentAttribute, object, PDFObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Step 3) - normal attribute
|
||||
object = m_model->writeAttributeValueToObject(attribute, object, m_adapters[attribute]->getValue());
|
||||
}
|
||||
|
||||
// Step 4)
|
||||
s
|
||||
|
||||
m_model->setEditedObject(object);
|
||||
|
||||
loadWidgets();
|
||||
}
|
||||
|
||||
void PDFObjectEditorWidgetMapper::createMappedAdapter(QGroupBox* groupBox, QGridLayout* layout, size_t attribute)
|
||||
{
|
||||
auto setAdapter = [this, attribute](PDFObjectEditorMappedWidgetAdapter* adapter)
|
||||
@ -156,6 +246,7 @@ void PDFObjectEditorWidgetMapper::createMappedAdapter(QGroupBox* groupBox, QGrid
|
||||
|
||||
QLabel* label = new QLabel(groupBox);
|
||||
QPushButton* pushButton = new QPushButton(groupBox);
|
||||
pushButton->setText(tr("Rectangle"));
|
||||
pushButton->setFlat(true);
|
||||
|
||||
layout->addWidget(label, row, 0);
|
||||
@ -165,16 +256,84 @@ void PDFObjectEditorWidgetMapper::createMappedAdapter(QGroupBox* groupBox, QGrid
|
||||
break;
|
||||
}
|
||||
|
||||
case ObjectEditorAttributeType::DateTime:
|
||||
{
|
||||
int row = layout->rowCount();
|
||||
|
||||
QLabel* label = new QLabel(groupBox);
|
||||
QDateTimeEdit* dateTimeEdit = new QDateTimeEdit(groupBox);
|
||||
|
||||
layout->addWidget(label, row, 0);
|
||||
layout->addWidget(dateTimeEdit, row, 1);
|
||||
|
||||
setAdapter(new PDFObjectEditorMappedDateTimeAdapter(label, dateTimeEdit, m_model, attribute, this));
|
||||
break;
|
||||
}
|
||||
|
||||
case ObjectEditorAttributeType::Flags:
|
||||
{
|
||||
int row = layout->rowCount();
|
||||
int column = 0;
|
||||
|
||||
std::vector<std::pair<uint32_t, QCheckBox*>> flagCheckboxes;
|
||||
const PDFObjectEditorModelAttributeEnumItems& flagItems = m_model->getAttributeEnumItems(attribute);
|
||||
flagCheckboxes.reserve(flagItems.size());
|
||||
|
||||
for (const PDFObjectEditorModelAttributeEnumItem& flagItem : flagItems)
|
||||
{
|
||||
if (column == 2)
|
||||
{
|
||||
row++;
|
||||
column = 0;
|
||||
}
|
||||
|
||||
QCheckBox* checkBox = new QCheckBox(flagItem.name, groupBox);
|
||||
layout->addWidget(checkBox, row, column);
|
||||
flagCheckboxes.emplace_back(flagItem.flags, checkBox);
|
||||
|
||||
++column;
|
||||
}
|
||||
|
||||
setAdapter(new PDFObjectEditorMappedFlagsAdapter(qMove(flagCheckboxes), m_model, attribute, this));
|
||||
break;
|
||||
}
|
||||
|
||||
case ObjectEditorAttributeType::Selector:
|
||||
case ObjectEditorAttributeType::Boolean:
|
||||
{
|
||||
int row = layout->rowCount();
|
||||
|
||||
QLabel* label = new QLabel(groupBox);
|
||||
QCheckBox* checkBox = new QCheckBox(groupBox);
|
||||
|
||||
layout->addWidget(label, row, 0);
|
||||
layout->addWidget(checkBox, row, 1);
|
||||
|
||||
setAdapter(new PDFObjectEditorMappedCheckBoxAdapter(label, checkBox, m_model, attribute, this));
|
||||
break;
|
||||
}
|
||||
|
||||
case ObjectEditorAttributeType::Color:
|
||||
{
|
||||
int row = layout->rowCount();
|
||||
|
||||
QLabel* label = new QLabel(groupBox);
|
||||
QPushButton* pushButton = new QPushButton(groupBox);
|
||||
pushButton->setText(tr("Color"));
|
||||
pushButton->setFlat(true);
|
||||
|
||||
layout->addWidget(label, row, 0);
|
||||
layout->addWidget(pushButton, row, 1);
|
||||
|
||||
setAdapter(new PDFObjectEditorMappedColorAdapter(label, pushButton, m_model, attribute, this));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
x
|
||||
/*
|
||||
DateTime, ///< Date/time
|
||||
Flags, ///< Flags
|
||||
Selector, ///< Selector attribute, it is not persisted
|
||||
Color, ///< Color
|
||||
Boolean, ///< Check box*/
|
||||
|
||||
connect(m_adapters[attribute], &PDFObjectEditorMappedWidgetAdapter::commitRequested, this, &PDFObjectEditorWidgetMapper::onCommitRequested);
|
||||
}
|
||||
|
||||
PDFObjectEditorWidgetMapper::Category* PDFObjectEditorWidgetMapper::getOrCreateCategory(QString categoryName)
|
||||
@ -334,7 +493,7 @@ PDFObjectEditorMappedRectangleAdapter::PDFObjectEditorMappedRectangleAdapter(QLa
|
||||
QPushButton* pushButton,
|
||||
PDFObjectEditorAbstractModel* model,
|
||||
size_t attribute,
|
||||
QObject* parent):
|
||||
QObject* parent) :
|
||||
BaseClass(model, attribute, parent),
|
||||
m_label(label),
|
||||
m_pushButton(pushButton)
|
||||
@ -352,4 +511,159 @@ void PDFObjectEditorMappedRectangleAdapter::setValue(PDFObject object)
|
||||
m_rectangle = qMove(object);
|
||||
}
|
||||
|
||||
PDFObjectEditorMappedDateTimeAdapter::PDFObjectEditorMappedDateTimeAdapter(QLabel* label,
|
||||
QDateTimeEdit* dateTimeEdit,
|
||||
PDFObjectEditorAbstractModel* model,
|
||||
size_t attribute,
|
||||
QObject* parent) :
|
||||
BaseClass(model, attribute, parent),
|
||||
m_label(label),
|
||||
m_dateTimeEdit(dateTimeEdit)
|
||||
{
|
||||
initLabel(label);
|
||||
|
||||
connect(dateTimeEdit, &QDateTimeEdit::editingFinished, this, [this, attribute](){ emit commitRequested(attribute); });
|
||||
}
|
||||
|
||||
PDFObject PDFObjectEditorMappedDateTimeAdapter::getValue() const
|
||||
{
|
||||
QDateTime dateTime = m_dateTimeEdit->dateTime();
|
||||
|
||||
if (dateTime.isValid())
|
||||
{
|
||||
return PDFObject::createString(PDFEncoding::convertDateTimeToString(dateTime));
|
||||
}
|
||||
|
||||
return PDFObject();
|
||||
}
|
||||
|
||||
void PDFObjectEditorMappedDateTimeAdapter::setValue(PDFObject object)
|
||||
{
|
||||
PDFDocumentDataLoaderDecorator loader(m_model->getStorage());
|
||||
QByteArray string = loader.readString(object);
|
||||
|
||||
QDateTime dateTime = PDFEncoding::convertToDateTime(string);
|
||||
m_dateTimeEdit->setDateTime(dateTime);
|
||||
}
|
||||
|
||||
PDFObjectEditorMappedFlagsAdapter::PDFObjectEditorMappedFlagsAdapter(std::vector<std::pair<uint32_t, QCheckBox*>> flagCheckBoxes,
|
||||
PDFObjectEditorAbstractModel* model,
|
||||
size_t attribute,
|
||||
QObject* parent) :
|
||||
BaseClass(model, attribute, parent),
|
||||
m_flagCheckBoxes(qMove(flagCheckBoxes))
|
||||
{
|
||||
for (const auto& item : m_flagCheckBoxes)
|
||||
{
|
||||
QCheckBox* checkBox = item.second;
|
||||
connect(checkBox, &QCheckBox::clicked, this, [this, attribute](){ emit commitRequested(attribute); });
|
||||
}
|
||||
}
|
||||
|
||||
PDFObject PDFObjectEditorMappedFlagsAdapter::getValue() const
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
|
||||
for (const auto& item : m_flagCheckBoxes)
|
||||
{
|
||||
if (item.second->isChecked())
|
||||
{
|
||||
flags = flags | item.first;
|
||||
}
|
||||
}
|
||||
|
||||
return PDFObject::createInteger(PDFInteger(flags));
|
||||
}
|
||||
|
||||
void PDFObjectEditorMappedFlagsAdapter::setValue(PDFObject object)
|
||||
{
|
||||
PDFDocumentDataLoaderDecorator loader(m_model->getStorage());
|
||||
uint32_t flags = static_cast<uint32_t>(loader.readInteger(object, 0));
|
||||
|
||||
for (const auto& item : m_flagCheckBoxes)
|
||||
{
|
||||
const bool checked = flags & item.first;
|
||||
item.second->setChecked(checked);
|
||||
}
|
||||
}
|
||||
|
||||
PDFObjectEditorMappedCheckBoxAdapter::PDFObjectEditorMappedCheckBoxAdapter(QLabel* label,
|
||||
QCheckBox* checkBox,
|
||||
PDFObjectEditorAbstractModel* model,
|
||||
size_t attribute,
|
||||
QObject* parent) :
|
||||
BaseClass(model, attribute, parent),
|
||||
m_label(label),
|
||||
m_checkBox(checkBox)
|
||||
{
|
||||
initLabel(label);
|
||||
connect(checkBox, &QCheckBox::clicked, this, [this, attribute](){ emit commitRequested(attribute); });
|
||||
}
|
||||
|
||||
PDFObject PDFObjectEditorMappedCheckBoxAdapter::getValue() const
|
||||
{
|
||||
return PDFObject::createBool(m_checkBox->isChecked());
|
||||
}
|
||||
|
||||
void PDFObjectEditorMappedCheckBoxAdapter::setValue(PDFObject object)
|
||||
{
|
||||
PDFDocumentDataLoaderDecorator loader(m_model->getStorage());
|
||||
m_checkBox->setChecked(loader.readBoolean(object, false));
|
||||
}
|
||||
|
||||
|
||||
PDFObjectEditorMappedColorAdapter::PDFObjectEditorMappedColorAdapter(QLabel* label,
|
||||
QPushButton* pushButton,
|
||||
PDFObjectEditorAbstractModel* model,
|
||||
size_t attribute,
|
||||
QObject* parent) :
|
||||
BaseClass(model, attribute, parent),
|
||||
m_label(label),
|
||||
m_pushButton(pushButton),
|
||||
m_color(Qt::black)
|
||||
{
|
||||
initLabel(label);
|
||||
}
|
||||
|
||||
PDFObject PDFObjectEditorMappedColorAdapter::getValue() const
|
||||
{
|
||||
PDFObjectFactory factory;
|
||||
factory << m_color;
|
||||
return factory.takeObject();
|
||||
}
|
||||
|
||||
void PDFObjectEditorMappedColorAdapter::setValue(PDFObject object)
|
||||
{
|
||||
m_color = Qt::black;
|
||||
|
||||
PDFDocumentDataLoaderDecorator loader(m_model->getStorage());
|
||||
std::vector<PDFReal> colors = loader.readNumberArray(object, { });
|
||||
|
||||
if (colors.size() == 3)
|
||||
{
|
||||
const PDFReal red = qBound(0.0, colors[0], 1.0);
|
||||
const PDFReal green = qBound(0.0, colors[1], 1.0);
|
||||
const PDFReal blue = qBound(0.0, colors[2], 1.0);
|
||||
m_color = QColor::fromRgbF(red, green, blue);
|
||||
}
|
||||
}
|
||||
|
||||
PDFEditObjectDialog::PDFEditObjectDialog(EditObjectType type, QWidget* parent) :
|
||||
BaseClass(parent),
|
||||
m_widget(nullptr),
|
||||
m_buttonBox(nullptr)
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(QMargins());
|
||||
|
||||
m_widget = new PDFObjectEditorWidget(type, this);
|
||||
layout->addWidget(m_widget);
|
||||
|
||||
m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
|
||||
layout->addWidget(m_buttonBox);
|
||||
|
||||
connect(m_buttonBox, &QDialogButtonBox::accepted, this, &PDFEditObjectDialog::accept);
|
||||
connect(m_buttonBox, &QDialogButtonBox::rejected, this, &PDFEditObjectDialog::reject);
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
@ -21,13 +21,20 @@
|
||||
#include "pdfobjecteditormodel.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
|
||||
class QTabWidget;
|
||||
class QDialogButtonBox;
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
class PDFObjectEditorWidgetMapper;
|
||||
|
||||
enum class EditObjectType
|
||||
{
|
||||
Annotation
|
||||
};
|
||||
|
||||
class PDFObjectEditorWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -36,13 +43,28 @@ private:
|
||||
using BaseClass = QWidget;
|
||||
|
||||
public:
|
||||
explicit PDFObjectEditorWidget(PDFObjectEditorAbstractModel* model, QWidget* parent);
|
||||
explicit PDFObjectEditorWidget(EditObjectType type, QWidget* parent);
|
||||
|
||||
private:
|
||||
PDFObjectEditorWidgetMapper* m_mapper;
|
||||
QTabWidget* m_tabWidget;
|
||||
};
|
||||
|
||||
class PDFEditObjectDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = QDialog;
|
||||
|
||||
public:
|
||||
explicit PDFEditObjectDialog(EditObjectType type, QWidget* parent);
|
||||
|
||||
private:
|
||||
PDFObjectEditorWidget* m_widget;
|
||||
QDialogButtonBox* m_buttonBox;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
||||
#endif // PDFOBJECTEDITORWIDGET_H
|
||||
|
@ -28,6 +28,8 @@ class QGridLayout;
|
||||
class QLineEdit;
|
||||
class QTextBrowser;
|
||||
class QPushButton;
|
||||
class QDateTimeEdit;
|
||||
class QCheckBox;
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
@ -59,6 +61,46 @@ protected:
|
||||
size_t m_attribute;
|
||||
};
|
||||
|
||||
class PDFObjectEditorWidgetMapper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = QObject;
|
||||
|
||||
public:
|
||||
explicit PDFObjectEditorWidgetMapper(PDFObjectEditorAbstractModel* model, QObject* parent);
|
||||
|
||||
void initialize(QTabWidget* tabWidget);
|
||||
|
||||
private:
|
||||
struct Subcategory
|
||||
{
|
||||
QString name;
|
||||
std::vector<size_t> attributes;
|
||||
};
|
||||
|
||||
struct Category
|
||||
{
|
||||
QString name;
|
||||
std::vector<Subcategory> subcategories;
|
||||
QWidget* page = nullptr;
|
||||
|
||||
Subcategory* getOrCreateSubcategory(QString name);
|
||||
};
|
||||
|
||||
void loadWidgets();
|
||||
void onEditedObjectChanged();
|
||||
void onCommitRequested(size_t attribute);
|
||||
void createMappedAdapter(QGroupBox* groupBox, QGridLayout* layout, size_t attribute);
|
||||
Category* getOrCreateCategory(QString categoryName);
|
||||
|
||||
PDFObjectEditorAbstractModel* m_model;
|
||||
std::vector<Category> m_categories;
|
||||
std::map<size_t, PDFObjectEditorMappedWidgetAdapter*> m_adapters;
|
||||
bool m_isCommitingDisabled;
|
||||
};
|
||||
|
||||
class PDFObjectEditorMappedComboBoxAdapter : public PDFObjectEditorMappedWidgetAdapter
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -113,42 +155,6 @@ private:
|
||||
QTextBrowser* m_textBrowser;
|
||||
};
|
||||
|
||||
class PDFObjectEditorWidgetMapper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = QObject;
|
||||
|
||||
public:
|
||||
explicit PDFObjectEditorWidgetMapper(PDFObjectEditorAbstractModel* model, QObject* parent);
|
||||
|
||||
void initialize(QTabWidget* tabWidget);
|
||||
|
||||
private:
|
||||
struct Subcategory
|
||||
{
|
||||
QString name;
|
||||
std::vector<size_t> attributes;
|
||||
};
|
||||
|
||||
struct Category
|
||||
{
|
||||
QString name;
|
||||
std::vector<Subcategory> subcategories;
|
||||
QWidget* page = nullptr;
|
||||
|
||||
Subcategory* getOrCreateSubcategory(QString name);
|
||||
};
|
||||
|
||||
void createMappedAdapter(QGroupBox* groupBox, QGridLayout* layout, size_t attribute);
|
||||
Category* getOrCreateCategory(QString categoryName);
|
||||
|
||||
PDFObjectEditorAbstractModel* m_model;
|
||||
std::vector<Category> m_categories;
|
||||
std::map<size_t, PDFObjectEditorMappedWidgetAdapter*> m_adapters;
|
||||
};
|
||||
|
||||
class PDFObjectEditorMappedRectangleAdapter : public PDFObjectEditorMappedWidgetAdapter
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -168,6 +174,81 @@ private:
|
||||
PDFObject m_rectangle;
|
||||
};
|
||||
|
||||
class PDFObjectEditorMappedDateTimeAdapter : public PDFObjectEditorMappedWidgetAdapter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = PDFObjectEditorMappedWidgetAdapter;
|
||||
|
||||
public:
|
||||
explicit PDFObjectEditorMappedDateTimeAdapter(QLabel* label, QDateTimeEdit* dateTimeEdit, PDFObjectEditorAbstractModel* model, size_t attribute, QObject* parent);
|
||||
|
||||
virtual PDFObject getValue() const override;
|
||||
virtual void setValue(PDFObject object) override;
|
||||
|
||||
private:
|
||||
QLabel* m_label;
|
||||
QDateTimeEdit* m_dateTimeEdit;
|
||||
};
|
||||
|
||||
class PDFObjectEditorMappedFlagsAdapter : public PDFObjectEditorMappedWidgetAdapter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = PDFObjectEditorMappedWidgetAdapter;
|
||||
|
||||
public:
|
||||
explicit PDFObjectEditorMappedFlagsAdapter(std::vector<std::pair<uint32_t, QCheckBox*>> flagCheckBoxes,
|
||||
PDFObjectEditorAbstractModel* model,
|
||||
size_t attribute,
|
||||
QObject* parent);
|
||||
|
||||
virtual PDFObject getValue() const override;
|
||||
virtual void setValue(PDFObject object) override;
|
||||
|
||||
private:
|
||||
std::vector<std::pair<uint32_t, QCheckBox*>> m_flagCheckBoxes;
|
||||
};
|
||||
|
||||
class PDFObjectEditorMappedCheckBoxAdapter : public PDFObjectEditorMappedWidgetAdapter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = PDFObjectEditorMappedWidgetAdapter;
|
||||
|
||||
public:
|
||||
explicit PDFObjectEditorMappedCheckBoxAdapter(QLabel* label, QCheckBox* checkBox, PDFObjectEditorAbstractModel* model, size_t attribute, QObject* parent);
|
||||
|
||||
virtual PDFObject getValue() const override;
|
||||
virtual void setValue(PDFObject object) override;
|
||||
|
||||
private:
|
||||
QLabel* m_label;
|
||||
QCheckBox* m_checkBox;
|
||||
};
|
||||
|
||||
class PDFObjectEditorMappedColorAdapter : public PDFObjectEditorMappedWidgetAdapter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = PDFObjectEditorMappedWidgetAdapter;
|
||||
|
||||
public:
|
||||
explicit PDFObjectEditorMappedColorAdapter(QLabel* label, QPushButton* pushButton, PDFObjectEditorAbstractModel* model, size_t attribute, QObject* parent);
|
||||
|
||||
virtual PDFObject getValue() const override;
|
||||
virtual void setValue(PDFObject object) override;
|
||||
|
||||
private:
|
||||
QLabel* m_label;
|
||||
QPushButton* m_pushButton;
|
||||
QColor m_color;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
||||
#endif // PDFOBJECTEDITORWIDGET_IMPL_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user