Object editation bugfixing and finishing

This commit is contained in:
Jakub Melka 2020-12-23 17:46:25 +01:00
parent 96ae91b36d
commit 5c7c0a5898
5 changed files with 211 additions and 2 deletions

View File

@ -1969,11 +1969,25 @@ void PDFWidgetAnnotationManager::updateFromMouseEvent(QMouseEvent* event)
void PDFWidgetAnnotationManager::onEditAnnotation()
{
PDFEditObjectDialog dialog(EditObjectType::Annotation, m_proxy->getWidget());
dialog.setObject(m_document->getObjectByReference(m_editableAnnotation));
PDFObject originalObject = m_document->getObjectByReference(m_editableAnnotation);
dialog.setObject(originalObject);
if (dialog.exec() == PDFEditObjectDialog::Accepted)
{
PDFObject object = dialog.getObject();
if (object != originalObject)
{
PDFDocumentModifier modifier(m_document);
modifier.markAnnotationsChanged();
modifier.getBuilder()->setObject(m_editableAnnotation, object);
modifier.getBuilder()->updateAnnotationAppearanceStreams(m_editableAnnotation);
if (modifier.finalize())
{
emit documentModified(PDFModifiedDocument(modifier.getDocument(), nullptr, modifier.getFlags()));
}
}
}
}

View File

@ -197,6 +197,7 @@ void PDFObjectEditorAbstractModel::setEditedObject(PDFObject object)
if (m_editedObject != object)
{
m_editedObject = qMove(object);
updateSelectorValues();
emit editedObjectChanged();
}
}
@ -240,6 +241,34 @@ QVariant PDFObjectEditorAbstractModel::getMaximumValue(size_t index) const
return m_attributes.at(index).maxValue;
}
void PDFObjectEditorAbstractModel::updateSelectorValues()
{
// Turn on selectors, which have some dependent attribute,
// which have value in the persisted object.
for (size_t index = 0; index < getAttributeCount(); ++index)
{
if (!queryAttribute(index, Question::IsSelector))
{
continue;
}
bool hasPersistedAttribute = false;
for (size_t dependentAttribute : getSelectorDependentAttributes(index))
{
if (!getValue(dependentAttribute).isNull())
{
hasPersistedAttribute = true;
break;
}
}
if (hasPersistedAttribute)
{
setSelectorValue(index, true);
}
}
}
size_t PDFObjectEditorAbstractModel::createAttribute(ObjectEditorAttributeType type,
QByteArray attributeName,
QString category,

View File

@ -172,6 +172,8 @@ signals:
void editedObjectChanged();
protected:
void updateSelectorValues();
size_t createAttribute(ObjectEditorAttributeType type,
QByteArray attributeName,
QString category,

View File

@ -78,6 +78,7 @@ PDFObject PDFObjectEditorWidget::getObject()
PDFObjectEditorWidgetMapper::PDFObjectEditorWidgetMapper(PDFObjectEditorAbstractModel* model, QObject* parent) :
BaseClass(parent),
m_model(model),
m_tabWidget(nullptr),
m_isCommitingDisabled(false)
{
connect(model, &PDFObjectEditorAbstractModel::editedObjectChanged, this, &PDFObjectEditorWidgetMapper::onEditedObjectChanged);
@ -130,6 +131,8 @@ void PDFObjectEditorWidgetMapper::initialize(QTabWidget* tabWidget)
QSpacerItem* spacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);
category.page->layout()->addItem(spacer);
}
m_tabWidget = tabWidget;
}
void PDFObjectEditorWidgetMapper::setObject(PDFObject object)
@ -163,6 +166,47 @@ void PDFObjectEditorWidgetMapper::loadWidgets()
}
adapter->setValue(object);
}
adapter->update();
}
std::vector<const Category*> insertedCategories;
insertedCategories.reserve(m_categories.size());
for (const Category& category : m_categories)
{
const bool isVisible = isCategoryVisible(category);
if (!isVisible)
{
m_tabWidget->removeTab(m_tabWidget->indexOf(category.page));
}
else
{
insertedCategories.push_back(&category);
}
}
for (auto it = insertedCategories.cbegin(); it != insertedCategories.cend(); ++it)
{
const Category* category = *it;
if (m_tabWidget->indexOf(category->page) != -1)
{
// Jakub Melka: category is present already in the tab widget
continue;
}
// Find index onto which we will insert the tab page. We want to preserve
// the order of categories, so we must insert tabs carefully.
int insertPosition = -1;
for (auto it2 = std::next(it); it2 != insertedCategories.cend(); ++it2)
{
insertPosition = m_tabWidget->indexOf((*it2)->page);
if (insertPosition != -1)
{
break;
}
}
m_tabWidget->insertTab(insertPosition, category->page, category->name);
}
}
@ -440,6 +484,22 @@ PDFObjectEditorWidgetMapper::Category* PDFObjectEditorWidgetMapper::getOrCreateC
return &m_categories.back();
}
bool PDFObjectEditorWidgetMapper::isCategoryVisible(const Category& category) const
{
for (const Subcategory& subcategory : category.subcategories)
{
for (size_t attribute : subcategory.attributes)
{
if (m_model->queryAttribute(attribute, PDFObjectEditorAbstractModel::Question::HasAttribute))
{
return true;
}
}
}
return false;
}
PDFObjectEditorWidgetMapper::Subcategory* PDFObjectEditorWidgetMapper::Category::getOrCreateSubcategory(QString subcategoryName)
{
auto subcategoryIt = std::find_if(subcategories.begin(), subcategories.end(), [&subcategoryName](const auto& subcategory) { return subcategory.name == subcategoryName; });
@ -521,6 +581,14 @@ void PDFObjectEditorMappedComboBoxAdapter::setValue(PDFObject object)
m_comboBox->setCurrentIndex(-1);
}
void PDFObjectEditorMappedComboBoxAdapter::update()
{
const bool enabled = m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::HasAttribute);
const bool readonly = !m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::IsAttributeEditable);
m_comboBox->setEnabled(enabled && !readonly);
}
PDFObjectEditorMappedLineEditAdapter::PDFObjectEditorMappedLineEditAdapter(QLabel* label,
QLineEdit* lineEdit,
PDFObjectEditorAbstractModel* model,
@ -549,6 +617,14 @@ void PDFObjectEditorMappedLineEditAdapter::setValue(PDFObject object)
m_lineEdit->setText(loader.readTextString(object, QString()));
}
void PDFObjectEditorMappedLineEditAdapter::update()
{
const bool enabled = m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::HasAttribute);
const bool readonly = !m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::IsAttributeEditable);
m_lineEdit->setEnabled(enabled);
m_lineEdit->setReadOnly(readonly);
}
PDFObjectEditorMappedTextBrowserAdapter::PDFObjectEditorMappedTextBrowserAdapter(QLabel* label,
QTextBrowser* textBrowser,
@ -576,7 +652,20 @@ PDFObject PDFObjectEditorMappedTextBrowserAdapter::getValue() const
void PDFObjectEditorMappedTextBrowserAdapter::setValue(PDFObject object)
{
PDFDocumentDataLoaderDecorator loader(m_model->getStorage());
m_textBrowser->setText(loader.readTextString(object, QString()));
QString text = loader.readTextString(object, QString());
if (text != m_textBrowser->toPlainText())
{
m_textBrowser->setText(text);
}
}
void PDFObjectEditorMappedTextBrowserAdapter::update()
{
const bool enabled = m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::HasAttribute);
const bool readonly = !m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::IsAttributeEditable);
m_textBrowser->setEnabled(enabled);
m_textBrowser->setReadOnly(readonly);
}
PDFObjectEditorMappedRectangleAdapter::PDFObjectEditorMappedRectangleAdapter(QLabel* label,
@ -601,6 +690,14 @@ void PDFObjectEditorMappedRectangleAdapter::setValue(PDFObject object)
m_rectangle = qMove(object);
}
void PDFObjectEditorMappedRectangleAdapter::update()
{
const bool enabled = m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::HasAttribute);
const bool readonly = !m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::IsAttributeEditable);
m_pushButton->setEnabled(enabled && !readonly);
}
PDFObjectEditorMappedDateTimeAdapter::PDFObjectEditorMappedDateTimeAdapter(QLabel* label,
QDateTimeEdit* dateTimeEdit,
PDFObjectEditorAbstractModel* model,
@ -636,6 +733,15 @@ void PDFObjectEditorMappedDateTimeAdapter::setValue(PDFObject object)
m_dateTimeEdit->setDateTime(dateTime);
}
void PDFObjectEditorMappedDateTimeAdapter::update()
{
const bool enabled = m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::HasAttribute);
const bool readonly = !m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::IsAttributeEditable);
m_dateTimeEdit->setEnabled(enabled);
m_dateTimeEdit->setReadOnly(readonly);
}
PDFObjectEditorMappedFlagsAdapter::PDFObjectEditorMappedFlagsAdapter(std::vector<std::pair<uint32_t, QCheckBox*>> flagCheckBoxes,
PDFObjectEditorAbstractModel* model,
size_t attribute,
@ -677,6 +783,18 @@ void PDFObjectEditorMappedFlagsAdapter::setValue(PDFObject object)
}
}
void PDFObjectEditorMappedFlagsAdapter::update()
{
const bool enabled = m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::HasAttribute);
const bool readonly = !m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::IsAttributeEditable);
const bool enableCheckbox = enabled && !readonly;
for (const auto& item : m_flagCheckBoxes)
{
item.second->setEnabled(enableCheckbox);
}
}
PDFObjectEditorMappedCheckBoxAdapter::PDFObjectEditorMappedCheckBoxAdapter(QLabel* label,
QCheckBox* checkBox,
PDFObjectEditorAbstractModel* model,
@ -701,6 +819,14 @@ void PDFObjectEditorMappedCheckBoxAdapter::setValue(PDFObject object)
m_checkBox->setChecked(loader.readBoolean(object, false));
}
void PDFObjectEditorMappedCheckBoxAdapter::update()
{
const bool enabled = m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::HasAttribute);
const bool readonly = !m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::IsAttributeEditable);
m_checkBox->setEnabled(enabled && !readonly);
}
PDFObjectEditorMappedDoubleAdapter::PDFObjectEditorMappedDoubleAdapter(QLabel* label,
QDoubleSpinBox* spinBox,
PDFObjectEditorAbstractModel* model,
@ -711,6 +837,8 @@ PDFObjectEditorMappedDoubleAdapter::PDFObjectEditorMappedDoubleAdapter(QLabel* l
m_spinBox(spinBox)
{
initLabel(label);
connect(spinBox, &QDoubleSpinBox::editingFinished, this, [this, attribute](){ emit commitRequested(attribute); });
}
PDFObject PDFObjectEditorMappedDoubleAdapter::getValue() const
@ -725,6 +853,15 @@ void PDFObjectEditorMappedDoubleAdapter::setValue(PDFObject object)
m_spinBox->setValue(value);
}
void PDFObjectEditorMappedDoubleAdapter::update()
{
const bool enabled = m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::HasAttribute);
const bool readonly = !m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::IsAttributeEditable);
m_spinBox->setEnabled(enabled);
m_spinBox->setReadOnly(readonly);
}
PDFObjectEditorMappedColorAdapter::PDFObjectEditorMappedColorAdapter(QLabel* label,
QPushButton* pushButton,
PDFObjectEditorAbstractModel* model,
@ -761,6 +898,14 @@ void PDFObjectEditorMappedColorAdapter::setValue(PDFObject object)
}
}
void PDFObjectEditorMappedColorAdapter::update()
{
const bool enabled = m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::HasAttribute);
const bool readonly = !m_model->queryAttribute(m_attribute, PDFObjectEditorAbstractModel::Question::IsAttributeEditable);
m_pushButton->setEnabled(enabled && !readonly);
}
PDFEditObjectDialog::PDFEditObjectDialog(EditObjectType type, QWidget* parent) :
BaseClass(parent),
m_widget(nullptr),

View File

@ -47,10 +47,15 @@ public:
/// Returns PDFObject value currently present in the widget
virtual PDFObject getValue() const = 0;
/// Sets PDFObject value to the widget. If data are incompatible,
/// then no data are set to the widget.
/// \param object Value to be set to the widget
virtual void setValue(PDFObject object) = 0;
/// Updates widget state (for example, visibility, enabledness and readonly mode)
virtual void update() = 0;
signals:
void commitRequested(size_t attribute);
@ -99,7 +104,12 @@ private:
void createMappedAdapter(QGroupBox* groupBox, QGridLayout* layout, size_t attribute);
Category* getOrCreateCategory(QString categoryName);
/// Returns true, if category is visible
/// \param category Category
bool isCategoryVisible(const Category& category) const;
PDFObjectEditorAbstractModel* m_model;
QTabWidget* m_tabWidget;
std::vector<Category> m_categories;
std::map<size_t, PDFObjectEditorMappedWidgetAdapter*> m_adapters;
bool m_isCommitingDisabled;
@ -117,6 +127,7 @@ public:
virtual PDFObject getValue() const override;
virtual void setValue(PDFObject object) override;
virtual void update() override;
private:
QLabel* m_label;
@ -135,6 +146,7 @@ public:
virtual PDFObject getValue() const override;
virtual void setValue(PDFObject object) override;
virtual void update() override;
private:
QLabel* m_label;
@ -153,6 +165,7 @@ public:
virtual PDFObject getValue() const override;
virtual void setValue(PDFObject object) override;
virtual void update() override;
private:
QLabel* m_label;
@ -171,6 +184,7 @@ public:
virtual PDFObject getValue() const override;
virtual void setValue(PDFObject object) override;
virtual void update() override;
private:
QLabel* m_label;
@ -190,6 +204,7 @@ public:
virtual PDFObject getValue() const override;
virtual void setValue(PDFObject object) override;
virtual void update() override;
private:
QLabel* m_label;
@ -211,6 +226,7 @@ public:
virtual PDFObject getValue() const override;
virtual void setValue(PDFObject object) override;
virtual void update() override;
private:
std::vector<std::pair<uint32_t, QCheckBox*>> m_flagCheckBoxes;
@ -228,6 +244,7 @@ public:
virtual PDFObject getValue() const override;
virtual void setValue(PDFObject object) override;
virtual void update() override;
private:
QLabel* m_label;
@ -246,6 +263,7 @@ public:
virtual PDFObject getValue() const override;
virtual void setValue(PDFObject object) override;
virtual void update() override;
private:
QLabel* m_label;
@ -265,6 +283,7 @@ public:
virtual PDFObject getValue() const override;
virtual void setValue(PDFObject object) override;
virtual void update() override;
private:
QLabel* m_label;