mirror of https://github.com/JakubMelka/PDF4QT.git
Signature plugin: selection
This commit is contained in:
parent
f5881b897d
commit
5d8e2818a2
|
@ -19,6 +19,7 @@
|
|||
#include "ui_pdfpagecontenteditorwidget.h"
|
||||
#include "pdfwidgetutils.h"
|
||||
#include "pdfpagecontentelements.h"
|
||||
#include "pdfutils.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QToolButton>
|
||||
|
@ -26,10 +27,12 @@
|
|||
namespace pdf
|
||||
{
|
||||
|
||||
PDFPageContentEditorWidget::PDFPageContentEditorWidget(QWidget *parent) :
|
||||
PDFPageContentEditorWidget::PDFPageContentEditorWidget(QWidget* parent) :
|
||||
QDockWidget(parent),
|
||||
ui(new Ui::PDFPageContentEditorWidget),
|
||||
m_toolBoxColumnCount(6)
|
||||
m_toolBoxColumnCount(6),
|
||||
m_scene(nullptr),
|
||||
m_selectionChangeEnabled(true)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
@ -76,6 +79,7 @@ PDFPageContentEditorWidget::PDFPageContentEditorWidget(QWidget *parent) :
|
|||
|
||||
connect(&m_actionMapper, &QSignalMapper::mappedObject, this, &PDFPageContentEditorWidget::onActionTriggerRequest);
|
||||
connect(&m_operationMapper, &QSignalMapper::mappedInt, this, &PDFPageContentEditorWidget::operationTriggered);
|
||||
connect(ui->itemsListWidget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &PDFPageContentEditorWidget::onItemSelectionChanged);
|
||||
}
|
||||
|
||||
PDFPageContentEditorWidget::~PDFPageContentEditorWidget()
|
||||
|
@ -126,6 +130,56 @@ QToolButton* PDFPageContentEditorWidget::getToolButtonForOperation(int operation
|
|||
return qobject_cast<QToolButton*>(m_operationMapper.mapping(operation));
|
||||
}
|
||||
|
||||
void PDFPageContentEditorWidget::updateItemsInListWidget()
|
||||
{
|
||||
ui->itemsListWidget->setUpdatesEnabled(false);
|
||||
|
||||
if (m_scene)
|
||||
{
|
||||
std::set<PDFInteger> presentElementIds;
|
||||
std::set<PDFInteger> elementIds = m_scene->getElementIds();
|
||||
|
||||
// Remove items which are not here
|
||||
for (int i = 0; i < ui->itemsListWidget->count();)
|
||||
{
|
||||
QListWidgetItem* item = ui->itemsListWidget->item(i);
|
||||
const PDFInteger elementId = item->data(Qt::UserRole).toLongLong();
|
||||
if (!elementIds.count(elementId))
|
||||
{
|
||||
delete ui->itemsListWidget->takeItem(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
presentElementIds.insert(elementId);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
// Add items which are here
|
||||
for (PDFInteger elementId : elementIds)
|
||||
{
|
||||
if (presentElementIds.count(elementId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const PDFPageContentElement* element = m_scene->getElementById(elementId);
|
||||
Q_ASSERT(element);
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem(element->getDescription());
|
||||
item->setData(Qt::UserRole, elementId);
|
||||
|
||||
ui->itemsListWidget->addItem(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->itemsListWidget->clear();
|
||||
}
|
||||
|
||||
ui->itemsListWidget->setUpdatesEnabled(true);
|
||||
}
|
||||
|
||||
void PDFPageContentEditorWidget::onActionTriggerRequest(QObject* actionObject)
|
||||
{
|
||||
QAction* action = qobject_cast<QAction*>(actionObject);
|
||||
|
@ -146,4 +200,55 @@ void PDFPageContentEditorWidget::onActionChanged()
|
|||
button->setEnabled(action->isEnabled());
|
||||
}
|
||||
|
||||
void PDFPageContentEditorWidget::onItemSelectionChanged()
|
||||
{
|
||||
if (m_selectionChangeEnabled)
|
||||
{
|
||||
emit itemSelectionChangedByUser();
|
||||
}
|
||||
}
|
||||
|
||||
PDFPageContentScene* PDFPageContentEditorWidget::scene() const
|
||||
{
|
||||
return m_scene;
|
||||
}
|
||||
|
||||
void PDFPageContentEditorWidget::setScene(PDFPageContentScene* newScene)
|
||||
{
|
||||
if (m_scene != newScene)
|
||||
{
|
||||
m_scene = newScene;
|
||||
updateItemsInListWidget();
|
||||
}
|
||||
}
|
||||
|
||||
std::set<PDFInteger> PDFPageContentEditorWidget::getSelection() const
|
||||
{
|
||||
std::set<PDFInteger> result;
|
||||
|
||||
for (int i = 0; i < ui->itemsListWidget->count(); ++i)
|
||||
{
|
||||
QListWidgetItem* item = ui->itemsListWidget->item(i);
|
||||
if (item->isSelected())
|
||||
{
|
||||
const PDFInteger elementId = item->data(Qt::UserRole).toLongLong();
|
||||
result.insert(elementId);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PDFPageContentEditorWidget::setSelection(const std::set<PDFInteger>& selection)
|
||||
{
|
||||
pdf::PDFTemporaryValueChange guard(&m_selectionChangeEnabled, false);
|
||||
|
||||
for (int i = 0; i < ui->itemsListWidget->count(); ++i)
|
||||
{
|
||||
QListWidgetItem* item = ui->itemsListWidget->item(i);
|
||||
const PDFInteger elementId = item->data(Qt::UserRole).toLongLong();
|
||||
item->setSelected(selection.count(elementId));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include <QDockWidget>
|
||||
#include <QSignalMapper>
|
||||
|
||||
#include <set>
|
||||
|
||||
class QToolButton;
|
||||
|
||||
namespace Ui
|
||||
|
@ -32,6 +34,7 @@ class PDFPageContentEditorWidget;
|
|||
|
||||
namespace pdf
|
||||
{
|
||||
class PDFPageContentScene;
|
||||
|
||||
class PDF4QTLIBSHARED_EXPORT PDFPageContentEditorWidget : public QDockWidget
|
||||
{
|
||||
|
@ -46,18 +49,31 @@ public:
|
|||
|
||||
QToolButton* getToolButtonForOperation(int operation) const;
|
||||
|
||||
/// Update items in list widget
|
||||
void updateItemsInListWidget();
|
||||
|
||||
PDFPageContentScene* scene() const;
|
||||
void setScene(PDFPageContentScene* newScene);
|
||||
|
||||
std::set<PDFInteger> getSelection() const;
|
||||
void setSelection(const std::set<PDFInteger>& selection);
|
||||
|
||||
signals:
|
||||
void operationTriggered(int operation);
|
||||
void itemSelectionChangedByUser();
|
||||
|
||||
private:
|
||||
void onActionTriggerRequest(QObject* actionObject);
|
||||
void onActionChanged();
|
||||
void onItemSelectionChanged();
|
||||
|
||||
Ui::PDFPageContentEditorWidget* ui;
|
||||
QSignalMapper m_actionMapper;
|
||||
QSignalMapper m_operationMapper;
|
||||
int m_toolBoxColumnCount;
|
||||
QSize m_toolButtonIconSize;
|
||||
PDFPageContentScene* m_scene;
|
||||
bool m_selectionChangeEnabled;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
|
|
@ -170,7 +170,11 @@
|
|||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QListView" name="listView"/>
|
||||
<widget class="QListWidget" name="itemsListWidget">
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
|
|
@ -207,6 +207,11 @@ void PDFPageContentElement::performRectangleSetSize(QRectF& rectangle, QSizeF si
|
|||
rectangle.translate(0, offset);
|
||||
}
|
||||
|
||||
QString PDFPageContentElement::formatDescription(const QString& description) const
|
||||
{
|
||||
return PDFTranslationContext::tr("#%1: %2").arg(getElementId()).arg(description);
|
||||
}
|
||||
|
||||
const QPen& PDFPageContentStyledElement::getPen() const
|
||||
{
|
||||
return m_pen;
|
||||
|
@ -314,6 +319,11 @@ void PDFPageContentElementRectangle::setSize(QSizeF size)
|
|||
performRectangleSetSize(m_rectangle, size);
|
||||
}
|
||||
|
||||
QString PDFPageContentElementRectangle::getDescription() const
|
||||
{
|
||||
return formatDescription(isRounded() ? PDFTranslationContext::tr("Rounded rectangle") : PDFTranslationContext::tr("Rectangle"));
|
||||
}
|
||||
|
||||
PDFPageContentScene::PDFPageContentScene(QObject* parent) :
|
||||
QObject(parent),
|
||||
m_firstFreeId(1),
|
||||
|
@ -790,6 +800,7 @@ void PDFPageContentScene::updateMouseCursor(const MouseEventInfo& info, PDFReal
|
|||
void PDFPageContentScene::onSelectionChanged()
|
||||
{
|
||||
emit sceneChanged(true);
|
||||
emit selectionChanged();
|
||||
}
|
||||
|
||||
PDFWidget* PDFPageContentScene::widget() const
|
||||
|
@ -835,6 +846,26 @@ std::set<PDFInteger> PDFPageContentScene::getElementIds() const
|
|||
return result;
|
||||
}
|
||||
|
||||
std::set<PDFInteger> PDFPageContentScene::getSelectedElementIds() const
|
||||
{
|
||||
std::set<PDFInteger> result;
|
||||
|
||||
for (const auto& element : m_elements)
|
||||
{
|
||||
if (m_manipulator.isSelected(element->getElementId()))
|
||||
{
|
||||
result.insert(element->getElementId());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PDFPageContentScene::setSelectedElementIds(const std::set<PDFInteger>& selectedElementIds)
|
||||
{
|
||||
m_manipulator.selectNew(selectedElementIds);
|
||||
}
|
||||
|
||||
void PDFPageContentScene::removeElementsById(const std::vector<PDFInteger>& selection)
|
||||
{
|
||||
const size_t oldSize = m_elements.size();
|
||||
|
@ -1000,6 +1031,11 @@ void PDFPageContentElementLine::setSize(QSizeF size)
|
|||
m_line.setPoints(p1, p2);
|
||||
}
|
||||
|
||||
QString PDFPageContentElementLine::getDescription() const
|
||||
{
|
||||
return formatDescription(PDFTranslationContext::tr("Line"));
|
||||
}
|
||||
|
||||
PDFPageContentElementLine::LineGeometry PDFPageContentElementLine::getGeometry() const
|
||||
{
|
||||
return m_geometry;
|
||||
|
@ -1110,6 +1146,11 @@ void PDFPageContentSvgElement::setSize(QSizeF size)
|
|||
performRectangleSetSize(m_rectangle, size);
|
||||
}
|
||||
|
||||
QString PDFPageContentSvgElement::getDescription() const
|
||||
{
|
||||
return formatDescription(PDFTranslationContext::tr("SVG image"));
|
||||
}
|
||||
|
||||
const QByteArray& PDFPageContentSvgElement::getContent() const
|
||||
{
|
||||
return m_content;
|
||||
|
@ -1207,6 +1248,11 @@ void PDFPageContentElementDot::setSize(QSizeF size)
|
|||
Q_UNUSED(size);
|
||||
}
|
||||
|
||||
QString PDFPageContentElementDot::getDescription() const
|
||||
{
|
||||
return formatDescription(PDFTranslationContext::tr("Dot"));
|
||||
}
|
||||
|
||||
QPointF PDFPageContentElementDot::getPoint() const
|
||||
{
|
||||
return m_point;
|
||||
|
@ -1297,6 +1343,11 @@ void PDFPageContentElementFreehandCurve::setSize(QSizeF size)
|
|||
Q_UNUSED(size);
|
||||
}
|
||||
|
||||
QString PDFPageContentElementFreehandCurve::getDescription() const
|
||||
{
|
||||
return formatDescription(PDFTranslationContext::tr("Freehand curve"));
|
||||
}
|
||||
|
||||
QPainterPath PDFPageContentElementFreehandCurve::getCurve() const
|
||||
{
|
||||
return m_curve;
|
||||
|
@ -2304,6 +2355,11 @@ void PDFPageContentElementTextBox::setSize(QSizeF size)
|
|||
performRectangleSetSize(m_rectangle, size);
|
||||
}
|
||||
|
||||
QString PDFPageContentElementTextBox::getDescription() const
|
||||
{
|
||||
return formatDescription(PDFTranslationContext::tr("Text box '%1'").arg(getText()));
|
||||
}
|
||||
|
||||
const QString& PDFPageContentElementTextBox::getText() const
|
||||
{
|
||||
return m_text;
|
||||
|
|
|
@ -71,6 +71,9 @@ public:
|
|||
/// nothing for elements, which does not support it.
|
||||
virtual void setSize(QSizeF size) = 0;
|
||||
|
||||
/// Returns description of the element
|
||||
virtual QString getDescription() const = 0;
|
||||
|
||||
PDFInteger getPageIndex() const;
|
||||
void setPageIndex(PDFInteger newPageIndex);
|
||||
|
||||
|
@ -108,6 +111,8 @@ protected:
|
|||
|
||||
void performRectangleSetSize(QRectF& rectangle, QSizeF size);
|
||||
|
||||
QString formatDescription(const QString& description) const;
|
||||
|
||||
PDFInteger m_elementId = -1;
|
||||
PDFInteger m_pageIndex = -1;
|
||||
};
|
||||
|
@ -155,6 +160,7 @@ public:
|
|||
virtual void performManipulation(uint mode, const QPointF& offset) override;
|
||||
virtual QRectF getBoundingBox() const override;
|
||||
virtual void setSize(QSizeF size);
|
||||
virtual QString getDescription() const override;
|
||||
|
||||
private:
|
||||
bool m_rounded = false;
|
||||
|
@ -188,6 +194,7 @@ public:
|
|||
virtual void performManipulation(uint mode, const QPointF& offset) override;
|
||||
virtual QRectF getBoundingBox() const override;
|
||||
virtual void setSize(QSizeF size);
|
||||
virtual QString getDescription() const override;
|
||||
|
||||
LineGeometry getGeometry() const;
|
||||
void setGeometry(LineGeometry newGeometry);
|
||||
|
@ -220,6 +227,7 @@ public:
|
|||
virtual void performManipulation(uint mode, const QPointF& offset) override;
|
||||
virtual QRectF getBoundingBox() const override;
|
||||
virtual void setSize(QSizeF size);
|
||||
virtual QString getDescription() const override;
|
||||
|
||||
QPointF getPoint() const;
|
||||
void setPoint(QPointF newPoint);
|
||||
|
@ -248,6 +256,7 @@ public:
|
|||
virtual void performManipulation(uint mode, const QPointF& offset) override;
|
||||
virtual QRectF getBoundingBox() const override;
|
||||
virtual void setSize(QSizeF size);
|
||||
virtual QString getDescription() const override;
|
||||
|
||||
QPainterPath getCurve() const;
|
||||
void setCurve(QPainterPath newCurve);
|
||||
|
@ -282,6 +291,7 @@ public:
|
|||
virtual void performManipulation(uint mode, const QPointF& offset) override;
|
||||
virtual QRectF getBoundingBox() const override;
|
||||
virtual void setSize(QSizeF size);
|
||||
virtual QString getDescription() const override;
|
||||
|
||||
const QByteArray& getContent() const;
|
||||
void setContent(const QByteArray& newContent);
|
||||
|
@ -318,6 +328,7 @@ public:
|
|||
virtual void performManipulation(uint mode, const QPointF& offset) override;
|
||||
virtual QRectF getBoundingBox() const override;
|
||||
virtual void setSize(QSizeF size);
|
||||
virtual QString getDescription() const override;
|
||||
|
||||
const QString& getText() const;
|
||||
void setText(const QString& newText);
|
||||
|
@ -489,6 +500,12 @@ public:
|
|||
/// Returns set of all element ids
|
||||
std::set<PDFInteger> getElementIds() const;
|
||||
|
||||
/// Returns set of selected element ids
|
||||
std::set<PDFInteger> getSelectedElementIds() const;
|
||||
|
||||
/// Set selected items
|
||||
void setSelectedElementIds(const std::set<PDFInteger>& selectedElementIds);
|
||||
|
||||
/// Removes elements specified in selection
|
||||
/// \param selection Items to be removed
|
||||
void removeElementsById(const std::vector<PDFInteger>& selection);
|
||||
|
@ -528,6 +545,8 @@ signals:
|
|||
/// This signal is emitted when scene has changed (including graphics)
|
||||
void sceneChanged(bool graphicsOnly);
|
||||
|
||||
void selectionChanged();
|
||||
|
||||
private:
|
||||
|
||||
struct MouseEventInfo
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "signatureplugin.h"
|
||||
#include "pdfdrawwidget.h"
|
||||
#include "pdfutils.h"
|
||||
#include "pdfpagecontenteditorwidget.h"
|
||||
|
||||
#include <QAction>
|
||||
|
@ -31,7 +32,8 @@ SignaturePlugin::SignaturePlugin() :
|
|||
m_actions({ }),
|
||||
m_tools({ }),
|
||||
m_editorWidget(nullptr),
|
||||
m_scene(nullptr)
|
||||
m_scene(nullptr),
|
||||
m_sceneSelectionChangeEnabled(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -143,6 +145,7 @@ void SignaturePlugin::setWidget(pdf::PDFWidget* widget)
|
|||
m_widget->getDrawWidgetProxy()->registerDrawInterface(&m_scene);
|
||||
m_scene.setWidget(m_widget);
|
||||
connect(&m_scene, &pdf::PDFPageContentScene::sceneChanged, this, &SignaturePlugin::onSceneChanged);
|
||||
connect(&m_scene, &pdf::PDFPageContentScene::selectionChanged, this, &SignaturePlugin::onSceneSelectionChanged);
|
||||
connect(clearAction, &QAction::triggered, &m_scene, &pdf::PDFPageContentScene::clear);
|
||||
connect(activateAction, &QAction::triggered, this, &SignaturePlugin::setActive);
|
||||
|
||||
|
@ -179,9 +182,30 @@ void SignaturePlugin::onSceneChanged(bool graphicsOnly)
|
|||
updateActions();
|
||||
}
|
||||
|
||||
if (m_editorWidget)
|
||||
{
|
||||
m_editorWidget->updateItemsInListWidget();
|
||||
}
|
||||
|
||||
updateGraphics();
|
||||
}
|
||||
|
||||
void SignaturePlugin::onSceneSelectionChanged()
|
||||
{
|
||||
if (m_editorWidget && m_sceneSelectionChangeEnabled)
|
||||
{
|
||||
m_editorWidget->setSelection(m_scene.getSelectedElementIds());
|
||||
}
|
||||
}
|
||||
|
||||
void SignaturePlugin::onWidgetSelectionChanged()
|
||||
{
|
||||
Q_ASSERT(m_editorWidget);
|
||||
|
||||
pdf::PDFTemporaryValueChange guard(&m_sceneSelectionChangeEnabled, false);
|
||||
m_scene.setSelectedElementIds(m_editorWidget->getSelection());
|
||||
}
|
||||
|
||||
void SignaturePlugin::setActive(bool active)
|
||||
{
|
||||
if (m_scene.isActive() != active)
|
||||
|
@ -276,7 +300,9 @@ void SignaturePlugin::updateDockWidget()
|
|||
m_dataExchangeInterface->getMainWindow()->addDockWidget(Qt::RightDockWidgetArea, m_editorWidget, Qt::Vertical);
|
||||
m_editorWidget->setFloating(false);
|
||||
m_editorWidget->setWindowTitle(tr("Signature Toolbox"));
|
||||
m_editorWidget->setScene(&m_scene);
|
||||
connect(m_editorWidget, &pdf::PDFPageContentEditorWidget::operationTriggered, &m_scene, &pdf::PDFPageContentScene::performOperation);
|
||||
connect(m_editorWidget, &pdf::PDFPageContentEditorWidget::itemSelectionChangedByUser, this, &SignaturePlugin::onWidgetSelectionChanged);
|
||||
|
||||
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::AlignTop))->setIcon(QIcon(":/resources/pce-align-top.svg"));
|
||||
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::AlignCenterVertically))->setIcon(QIcon(":/resources/pce-align-v-center.svg"));
|
||||
|
|
|
@ -49,6 +49,8 @@ public:
|
|||
|
||||
private:
|
||||
void onSceneChanged(bool graphicsOnly);
|
||||
void onSceneSelectionChanged();
|
||||
void onWidgetSelectionChanged();
|
||||
|
||||
enum Action
|
||||
{
|
||||
|
@ -103,6 +105,7 @@ private:
|
|||
pdf::PDFPageContentEditorWidget* m_editorWidget;
|
||||
|
||||
pdf::PDFPageContentScene m_scene;
|
||||
bool m_sceneSelectionChangeEnabled;
|
||||
};
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
|
Loading…
Reference in New Issue