mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-03-03 19:08:51 +01:00
Signature plugin: manipulation operations
This commit is contained in:
parent
2b7d5939bd
commit
5163bd1c80
@ -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()
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user