Signature plugin: manipulation operations

This commit is contained in:
Jakub Melka 2022-03-13 19:37:36 +01:00
parent 2b7d5939bd
commit 5163bd1c80
6 changed files with 433 additions and 47 deletions

View File

@ -18,6 +18,7 @@
#include "pdfpagecontenteditorwidget.h"
#include "ui_pdfpagecontenteditorwidget.h"
#include "pdfwidgetutils.h"
#include "pdfpagecontentelements.h"
#include <QAction>
#include <QToolButton>
@ -39,7 +40,42 @@ PDFPageContentEditorWidget::PDFPageContentEditorWidget(QWidget *parent) :
button->setIconSize(m_toolButtonIconSize);
}
m_operationMapper.setMapping(ui->alignVertTopButton, static_cast<int>(PDFPageContentElementManipulator::Operation::AlignTop));
m_operationMapper.setMapping(ui->alignVertMiddleButton, static_cast<int>(PDFPageContentElementManipulator::Operation::AlignCenterVertically));
m_operationMapper.setMapping(ui->alignVertBottomButton, static_cast<int>(PDFPageContentElementManipulator::Operation::AlignBottom));
m_operationMapper.setMapping(ui->alignHorLeftButton, static_cast<int>(PDFPageContentElementManipulator::Operation::AlignLeft));
m_operationMapper.setMapping(ui->alignHorMiddleButton, static_cast<int>(PDFPageContentElementManipulator::Operation::AlignCenterHorizontally));
m_operationMapper.setMapping(ui->alignHorRightButton, static_cast<int>(PDFPageContentElementManipulator::Operation::AlignRight));
m_operationMapper.setMapping(ui->setSameWidthButton, static_cast<int>(PDFPageContentElementManipulator::Operation::SetSameWidth));
m_operationMapper.setMapping(ui->setSameHeightButton, static_cast<int>(PDFPageContentElementManipulator::Operation::SetSameHeight));
m_operationMapper.setMapping(ui->setSameSizeButton, static_cast<int>(PDFPageContentElementManipulator::Operation::SetSameSize));
m_operationMapper.setMapping(ui->centerHorizontallyButton, static_cast<int>(PDFPageContentElementManipulator::Operation::CenterHorizontally));
m_operationMapper.setMapping(ui->centerVerticallyButton, static_cast<int>(PDFPageContentElementManipulator::Operation::CenterVertically));
m_operationMapper.setMapping(ui->centerRectButton, static_cast<int>(PDFPageContentElementManipulator::Operation::CenterHorAndVert));
m_operationMapper.setMapping(ui->layoutHorizontallyButton, static_cast<int>(PDFPageContentElementManipulator::Operation::LayoutHorizontally));
m_operationMapper.setMapping(ui->layoutVerticallyButton, static_cast<int>(PDFPageContentElementManipulator::Operation::LayoutVertically));
m_operationMapper.setMapping(ui->layoutFormButton, static_cast<int>(PDFPageContentElementManipulator::Operation::LayoutForm));
m_operationMapper.setMapping(ui->layoutGridButton, static_cast<int>(PDFPageContentElementManipulator::Operation::LayoutGrid));
connect(ui->alignVertTopButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->alignVertMiddleButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->alignVertBottomButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->alignHorLeftButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->alignHorMiddleButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->alignHorRightButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->setSameWidthButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->setSameHeightButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->setSameSizeButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->centerHorizontallyButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->centerVerticallyButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->centerRectButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->layoutHorizontallyButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->layoutVerticallyButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->layoutFormButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(ui->layoutGridButton, &QToolButton::clicked, &m_operationMapper, QOverload<>::of(&QSignalMapper::map));
connect(&m_actionMapper, &QSignalMapper::mappedObject, this, &PDFPageContentEditorWidget::onActionTriggerRequest);
connect(&m_operationMapper, &QSignalMapper::mappedInt, this, &PDFPageContentEditorWidget::operationTriggered);
}
PDFPageContentEditorWidget::~PDFPageContentEditorWidget()

View File

@ -42,12 +42,16 @@ public:
/// Adds external action to the tool box
void addAction(QAction* action);
signals:
void operationTriggered(int operation);
private:
void onActionTriggerRequest(QObject* actionObject);
void onActionChanged();
Ui::PDFPageContentEditorWidget* ui;
QSignalMapper m_actionMapper;
QSignalMapper m_operationMapper;
int m_toolBoxColumnCount;
QSize m_toolButtonIconSize;
};

View File

@ -34,85 +34,85 @@
<layout class="QGridLayout" name="geometryToolsGroupBoxLayout">
<item row="0" column="0">
<widget class="QToolButton" name="alignVertTopButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Align to Top</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="alignVertMiddleButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Align to Vertical Center</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="alignVertBottomButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Align to Bottom</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QToolButton" name="setSameWidthButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Set Same Width</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QToolButton" name="setSameHeightButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Set Same Height</string>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QToolButton" name="setSameSizeButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Set Same Size</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QToolButton" name="alignHorLeftButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Align to Left</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QToolButton" name="alignHorMiddleButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Align to Horizontal Center</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QToolButton" name="alignHorRightButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Align to Right</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QToolButton" name="centerHorizontallyButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Center Horizontally</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QToolButton" name="centerVerticallyButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Center Vertically</string>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QToolButton" name="centerRectButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Center to Page Media Box</string>
</property>
</widget>
</item>
@ -127,29 +127,29 @@
<layout class="QHBoxLayout" name="layoutToolBoxLayout">
<item>
<widget class="QToolButton" name="layoutHorizontallyButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Make Horizontal Layout</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="layoutVerticallyButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Make Vertical Layout</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="layoutFormButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Make Form Layout</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="layoutGridButton">
<property name="text">
<string>...</string>
<property name="toolTip">
<string>Make Grid Layout</string>
</property>
</widget>
</item>

View File

@ -199,6 +199,13 @@ void PDFPageContentElement::performRectangleManipulation(QRectF& rectangle,
}
}
void PDFPageContentElement::performRectangleSetSize(QRectF& rectangle, QSizeF size)
{
const qreal offset = rectangle.size().height() - size.height();
rectangle.setSize(size);
rectangle.translate(0, offset);
}
const QPen& PDFPageContentStyledElement::getPen() const
{
return m_pen;
@ -301,6 +308,11 @@ QRectF PDFPageContentElementRectangle::getBoundingBox() const
return getRectangle();
}
void PDFPageContentElementRectangle::setSize(QSizeF size)
{
performRectangleSetSize(m_rectangle, size);
}
PDFPageContentScene::PDFPageContentScene(QObject* parent) :
QObject(parent),
m_firstFreeId(1),
@ -353,6 +365,7 @@ void PDFPageContentScene::clear()
{
if (!m_elements.empty())
{
m_manipulator.reset();
m_elements.clear();
emit sceneChanged(false);
}
@ -821,10 +834,10 @@ std::set<PDFInteger> PDFPageContentScene::getElementIds() const
return result;
}
void PDFPageContentScene::removeElementsById(const std::set<PDFInteger>& selection)
void PDFPageContentScene::removeElementsById(const std::vector<PDFInteger>& selection)
{
const size_t oldSize = m_elements.size();
m_elements.erase(std::remove_if(m_elements.begin(), m_elements.end(), [&selection](const auto& element){ return selection.count(element->getElementId()); }), m_elements.end());
m_elements.erase(std::remove_if(m_elements.begin(), m_elements.end(), [&selection](const auto& element){ return std::find(selection.cbegin(), selection.cend(), element->getElementId()) != selection.cend(); }), m_elements.end());
const size_t newSize = m_elements.size();
if (newSize < oldSize)
@ -833,6 +846,21 @@ void PDFPageContentScene::removeElementsById(const std::set<PDFInteger>& selecti
}
}
void PDFPageContentScene::performOperation(int operation)
{
m_manipulator.performOperation(static_cast<PDFPageContentElementManipulator::Operation>(operation));
}
const PDFDocument* PDFPageContentScene::getDocument() const
{
if (m_widget)
{
return m_widget->getDrawWidgetProxy()->getDocument();
}
return nullptr;
}
PDFPageContentElementLine* PDFPageContentElementLine::clone() const
{
PDFPageContentElementLine* copy = new PDFPageContentElementLine();
@ -945,6 +973,32 @@ QRectF PDFPageContentElementLine::getBoundingBox() const
return QRectF();
}
void PDFPageContentElementLine::setSize(QSizeF size)
{
QPointF p1 = m_line.p1();
QPointF p2 = m_line.p2();
if (p1.x() < p2.x())
{
p2.setX(p1.x() + size.width());
}
else
{
p1.setX(p2.x() + size.width());
}
if (p1.y() < p2.y())
{
p1.setY(p2.y() - size.height());
}
else
{
p2.setY(p1.y() - size.height());
}
m_line.setPoints(p1, p2);
}
PDFPageContentElementLine::LineGeometry PDFPageContentElementLine::getGeometry() const
{
return m_geometry;
@ -1050,6 +1104,11 @@ QRectF PDFPageContentSvgElement::getBoundingBox() const
return getRectangle();
}
void PDFPageContentSvgElement::setSize(QSizeF size)
{
performRectangleSetSize(m_rectangle, size);
}
const QByteArray& PDFPageContentSvgElement::getContent() const
{
return m_content;
@ -1142,6 +1201,11 @@ QRectF PDFPageContentElementDot::getBoundingBox() const
return QRectF(m_point, QSizeF(0.001, 0.001));
}
void PDFPageContentElementDot::setSize(QSizeF size)
{
Q_UNUSED(size);
}
QPointF PDFPageContentElementDot::getPoint() const
{
return m_point;
@ -1227,6 +1291,11 @@ QRectF PDFPageContentElementFreehandCurve::getBoundingBox() const
return m_curve.controlPointRect();
}
void PDFPageContentElementFreehandCurve::setSize(QSizeF size)
{
Q_UNUSED(size);
}
QPainterPath PDFPageContentElementFreehandCurve::getCurve() const
{
return m_curve;
@ -1261,6 +1330,11 @@ PDFPageContentElementManipulator::PDFPageContentElementManipulator(PDFPageConten
}
bool PDFPageContentElementManipulator::isSelected(PDFInteger id) const
{
return std::find(m_selection.cbegin(), m_selection.cend(), id) != m_selection.cend();
}
void PDFPageContentElementManipulator::reset()
{
cancelManipulation();
@ -1285,7 +1359,7 @@ void PDFPageContentElementManipulator::update(PDFInteger id, SelectionModes mode
if (!isSelected(id))
{
modified = true;
m_selection.insert(id);
m_selection.push_back(id);
}
}
@ -1294,7 +1368,7 @@ void PDFPageContentElementManipulator::update(PDFInteger id, SelectionModes mode
if (isSelected(id))
{
modified = true;
m_selection.erase(id);
eraseSelectedElementById(id);
}
}
@ -1302,11 +1376,11 @@ void PDFPageContentElementManipulator::update(PDFInteger id, SelectionModes mode
{
if (isSelected(id))
{
m_selection.erase(id);
eraseSelectedElementById(id);
}
else
{
m_selection.insert(id);
m_selection.push_back(id);
}
// When toggle is performed, selection is always changed
@ -1340,7 +1414,7 @@ void PDFPageContentElementManipulator::update(const std::set<PDFInteger>& ids, S
if (!isSelected(id))
{
modified = true;
m_selection.insert(id);
m_selection.push_back(id);
}
}
}
@ -1352,7 +1426,7 @@ void PDFPageContentElementManipulator::update(const std::set<PDFInteger>& ids, S
if (isSelected(id))
{
modified = true;
m_selection.erase(id);
eraseSelectedElementById(id);
}
}
}
@ -1363,11 +1437,11 @@ void PDFPageContentElementManipulator::update(const std::set<PDFInteger>& ids, S
{
if (isSelected(id))
{
m_selection.erase(id);
eraseSelectedElementById(id);
}
else
{
m_selection.insert(id);
m_selection.push_back(id);
}
// When toggle is performed, selection is always changed
@ -1439,6 +1513,185 @@ bool PDFPageContentElementManipulator::isManipulationAllowed(PDFInteger pageInde
return false;
}
void PDFPageContentElementManipulator::performOperation(Operation operation)
{
if (isSelectionEmpty())
{
// Jakub Melka: nothing selected
return;
}
QRectF representativeRect = getSelectionBoundingRect();
std::vector<PDFPageContentElement*> manipulatedElements;
for (const PDFInteger id : m_selection)
{
const PDFPageContentElement* element = m_scene->getElementById(id);
manipulatedElements.push_back(element->clone());
}
switch (operation)
{
case Operation::AlignTop:
{
for (PDFPageContentElement* element : manipulatedElements)
{
QRectF boundingBox = element->getBoundingBox();
const qreal offset = representativeRect.bottom() - boundingBox.bottom();
element->performManipulation(PDFPageContentElement::Translate, QPointF(0.0, offset));
}
break;
}
case Operation::AlignCenterVertically:
{
for (PDFPageContentElement* element : manipulatedElements)
{
QRectF boundingBox = element->getBoundingBox();
const qreal offset = representativeRect.center().y() - boundingBox.center().y();
element->performManipulation(PDFPageContentElement::Translate, QPointF(0.0, offset));
}
break;
}
case Operation::AlignBottom:
{
for (PDFPageContentElement* element : manipulatedElements)
{
QRectF boundingBox = element->getBoundingBox();
const qreal offset = representativeRect.top() - boundingBox.top();
element->performManipulation(PDFPageContentElement::Translate, QPointF(0.0, offset));
}
break;
}
case Operation::AlignLeft:
{
for (PDFPageContentElement* element : manipulatedElements)
{
QRectF boundingBox = element->getBoundingBox();
const qreal offset = representativeRect.left() - boundingBox.left();
element->performManipulation(PDFPageContentElement::Translate, QPointF(offset, 0.0));
}
break;
}
case Operation::AlignCenterHorizontally:
{
for (PDFPageContentElement* element : manipulatedElements)
{
QRectF boundingBox = element->getBoundingBox();
const qreal offset = representativeRect.center().x() - boundingBox.center().x();
element->performManipulation(PDFPageContentElement::Translate, QPointF(offset, 0.0));
}
break;
}
case Operation::AlignRight:
{
for (PDFPageContentElement* element : manipulatedElements)
{
QRectF boundingBox = element->getBoundingBox();
const qreal offset = representativeRect.right() - boundingBox.right();
element->performManipulation(PDFPageContentElement::Translate, QPointF(offset, 0.0));
}
break;
}
case Operation::SetSameHeight:
{
QSizeF size = manipulatedElements.front()->getBoundingBox().size();
for (PDFPageContentElement* element : manipulatedElements)
{
size.setWidth(element->getBoundingBox().width());
element->setSize(size);
}
break;
}
case Operation::SetSameWidth:
{
QSizeF size = manipulatedElements.front()->getBoundingBox().size();
for (PDFPageContentElement* element : manipulatedElements)
{
size.setHeight(element->getBoundingBox().height());
element->setSize(size);
}
break;
}
case Operation::SetSameSize:
{
QSizeF size = manipulatedElements.front()->getBoundingBox().size();
for (PDFPageContentElement* element : manipulatedElements)
{
element->setSize(size);
}
break;
}
case Operation::CenterHorizontally:
{
const PDFInteger pageIndex = manipulatedElements.front()->getPageIndex();
QRectF pageMediaBox = getPageMediaBox(pageIndex);
const qreal offset = pageMediaBox.center().x() - representativeRect.center().x();
for (PDFPageContentElement* element : manipulatedElements)
{
element->performManipulation(PDFPageContentElement::Translate, QPointF(offset, 0.0));
}
break;
}
case Operation::CenterVertically:
{
const PDFInteger pageIndex = manipulatedElements.front()->getPageIndex();
QRectF pageMediaBox = getPageMediaBox(pageIndex);
const qreal offset = pageMediaBox.center().y() - representativeRect.center().y();
for (PDFPageContentElement* element : manipulatedElements)
{
element->performManipulation(PDFPageContentElement::Translate, QPointF(0.0, offset));
}
break;
}
case Operation::CenterHorAndVert:
{
const PDFInteger pageIndex = manipulatedElements.front()->getPageIndex();
QRectF pageMediaBox = getPageMediaBox(pageIndex);
const qreal offsetX = pageMediaBox.center().x() - representativeRect.center().x();
const qreal offsetY = pageMediaBox.center().y() - representativeRect.center().y();
QPointF offset(offsetX, offsetY);
for (PDFPageContentElement* element : manipulatedElements)
{
element->performManipulation(PDFPageContentElement::Translate, offset);
}
break;
}
case Operation::LayoutVertically:
break;
case Operation::LayoutHorizontally:
break;
case Operation::LayoutForm:
break;
case Operation::LayoutGrid:
break;
}
for (PDFPageContentElement* element : manipulatedElements)
{
m_scene->replaceElement(element);
}
}
void PDFPageContentElementManipulator::performDeleteSelection()
{
cancelManipulation();
@ -1593,4 +1846,48 @@ void PDFPageContentElementManipulator::drawPage(QPainter* painter,
}
}
QRectF PDFPageContentElementManipulator::getSelectionBoundingRect() const
{
QRectF rect;
for (const PDFInteger elementId : m_selection)
{
if (const PDFPageContentElement* element = m_scene->getElementById(elementId))
{
rect = rect.united(element->getBoundingBox());
}
}
return rect;
}
QRectF PDFPageContentElementManipulator::getPageMediaBox(PDFInteger pageIndex) const
{
if (pageIndex < 0)
{
return QRectF();
}
if (const PDFDocument* document = m_scene->getDocument())
{
size_t pageCount = document->getCatalog()->getPageCount();
if (size_t(pageIndex) < pageCount)
{
const PDFPage* page = document->getCatalog()->getPage(pageIndex);
return page->getMediaBox();
}
}
return QRectF();
}
void PDFPageContentElementManipulator::eraseSelectedElementById(PDFInteger id)
{
auto it = std::find(m_selection.begin(), m_selection.end(), id);
if (it != m_selection.end())
{
m_selection.erase(it);
}
}
} // namespace pdf

View File

@ -32,6 +32,7 @@ class QSvgRenderer;
namespace pdf
{
class PDFWidget;
class PDFDocument;
class PDFPageContentScene;
class PDF4QTLIBSHARED_EXPORT PDFPageContentElement
@ -65,6 +66,10 @@ public:
/// Returns bounding box of the element
virtual QRectF getBoundingBox() const = 0;
/// Sets size to the elements that supports it. Does
/// nothing for elements, which does not support it.
virtual void setSize(QSizeF size) = 0;
PDFInteger getPageIndex() const;
void setPageIndex(PDFInteger newPageIndex);
@ -75,8 +80,6 @@ public:
/// \param mode Manipulation mode
static Qt::CursorShape getCursorShapeForManipulationMode(uint mode);
protected:
enum ManipulationModes : uint
{
None = 0,
@ -93,6 +96,7 @@ protected:
Pt2
};
protected:
uint getRectangleManipulationMode(const QRectF& rectangle,
const QPointF& point,
PDFReal snapPointDistanceThreshold) const;
@ -101,6 +105,8 @@ protected:
uint mode,
const QPointF& offset);
void performRectangleSetSize(QRectF& rectangle, QSizeF size);
PDFInteger m_elementId = -1;
PDFInteger m_pageIndex = -1;
};
@ -147,6 +153,7 @@ public:
virtual void performManipulation(uint mode, const QPointF& offset) override;
virtual QRectF getBoundingBox() const override;
virtual void setSize(QSizeF size);
private:
bool m_rounded = false;
@ -179,6 +186,7 @@ public:
virtual void performManipulation(uint mode, const QPointF& offset) override;
virtual QRectF getBoundingBox() const override;
virtual void setSize(QSizeF size);
LineGeometry getGeometry() const;
void setGeometry(LineGeometry newGeometry);
@ -210,6 +218,7 @@ public:
virtual void performManipulation(uint mode, const QPointF& offset) override;
virtual QRectF getBoundingBox() const override;
virtual void setSize(QSizeF size);
QPointF getPoint() const;
void setPoint(QPointF newPoint);
@ -237,6 +246,7 @@ public:
virtual void performManipulation(uint mode, const QPointF& offset) override;
virtual QRectF getBoundingBox() const override;
virtual void setSize(QSizeF size);
QPainterPath getCurve() const;
void setCurve(QPainterPath newCurve);
@ -270,6 +280,7 @@ public:
virtual void performManipulation(uint mode, const QPointF& offset) override;
virtual QRectF getBoundingBox() const override;
virtual void setSize(QSizeF size);
const QByteArray& getContent() const;
void setContent(const QByteArray& newContent);
@ -290,6 +301,26 @@ class PDF4QTLIBSHARED_EXPORT PDFPageContentElementManipulator : public QObject
public:
PDFPageContentElementManipulator(PDFPageContentScene* scene, QObject* parent);
enum class Operation
{
AlignTop,
AlignCenterVertically,
AlignBottom,
AlignLeft,
AlignCenterHorizontally,
AlignRight,
SetSameHeight,
SetSameWidth,
SetSameSize,
CenterHorizontally,
CenterVertically,
CenterHorAndVert,
LayoutVertically,
LayoutHorizontally,
LayoutForm,
LayoutGrid
};
enum SelectionMode
{
NoUpdate = 0x0000,
@ -302,7 +333,7 @@ public:
/// Returns true, if element with given id is selected
/// \param id Element id
bool isSelected(PDFInteger id) const { return m_selection.count(id); }
bool isSelected(PDFInteger id) const;
/// Returns true, if selection is empty
bool isSelectionEmpty() const { return m_selection.empty(); }
@ -324,6 +355,7 @@ public:
bool isManipulationAllowed(PDFInteger pageIndex) const;
bool isManipulationInProgress() const { return m_isManipulationInProgress; }
void performOperation(Operation operation);
void performDeleteSelection();
void startManipulation(PDFInteger pageIndex,
@ -349,13 +381,21 @@ public:
const QMatrix& pagePointToDevicePointMatrix,
QList<PDFRenderError>& errors) const;
/// Returns bounding box of whole selection
QRectF getSelectionBoundingRect() const;
/// Returns page rectangle for the page
QRectF getPageMediaBox(PDFInteger pageIndex) const;
signals:
void selectionChanged();
void stateChanged();
private:
void eraseSelectedElementById(PDFInteger id);
PDFPageContentScene* m_scene;
std::set<PDFInteger> m_selection;
std::vector<PDFInteger> m_selection;
bool m_isManipulationInProgress;
std::vector<std::unique_ptr<PDFPageContentElement>> m_manipulatedElements;
std::map<PDFInteger, uint> m_manipulationModes;
@ -372,6 +412,8 @@ public:
explicit PDFPageContentScene(QObject* parent);
virtual ~PDFPageContentScene();
static constexpr PDFInteger INVALID_ELEMENT_ID = 0;
/// Add new element to page content scene, scene
/// takes ownership over the element.
/// \param element Element
@ -400,7 +442,13 @@ public:
/// Removes elements specified in selection
/// \param selection Items to be removed
void removeElementsById(const std::set<PDFInteger>& selection);
void removeElementsById(const std::vector<PDFInteger>& selection);
/// Performs manipulation of selected elements with manipulator
void performOperation(int operation);
/// Returns document (or nullptr)
const PDFDocument* getDocument() const;
// IDrawWidgetInputInterface interface
public:

View File

@ -274,6 +274,7 @@ void SignaturePlugin::updateDockWidget()
m_dataExchangeInterface->getMainWindow()->addDockWidget(Qt::RightDockWidgetArea, m_editorWidget, Qt::Vertical);
m_editorWidget->setFloating(false);
m_editorWidget->setWindowTitle(tr("Signature Toolbox"));
connect(m_editorWidget, &pdf::PDFPageContentEditorWidget::operationTriggered, &m_scene, &pdf::PDFPageContentScene::performOperation);
for (QAction* action : m_actions)
{