2022-02-11 19:15:57 +01:00
|
|
|
// Copyright (C) 2022 Jakub Melka
|
|
|
|
//
|
|
|
|
// This file is part of PDF4QT.
|
|
|
|
//
|
|
|
|
// PDF4QT is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// with the written consent of the copyright owner, any later version.
|
|
|
|
//
|
|
|
|
// PDF4QT is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
#include "pdfpagecontenteditortools.h"
|
|
|
|
#include "pdfpagecontentelements.h"
|
2022-02-19 19:30:52 +01:00
|
|
|
#include "pdfpainterutils.h"
|
2022-03-26 19:26:32 +01:00
|
|
|
#include "pdftexteditpseudowidget.h"
|
2022-02-11 19:15:57 +01:00
|
|
|
|
|
|
|
#include <QPen>
|
2022-02-19 19:30:52 +01:00
|
|
|
#include <QPainter>
|
2022-02-27 19:59:53 +01:00
|
|
|
#include <QMouseEvent>
|
2022-03-26 19:26:32 +01:00
|
|
|
#include <QGuiApplication>
|
2022-02-11 19:15:57 +01:00
|
|
|
|
|
|
|
namespace pdf
|
|
|
|
{
|
|
|
|
|
|
|
|
PDFCreatePCElementTool::PDFCreatePCElementTool(PDFDrawWidgetProxy* proxy,
|
|
|
|
PDFPageContentScene* scene,
|
|
|
|
QAction* action,
|
|
|
|
QObject* parent) :
|
|
|
|
PDFWidgetTool(proxy, action, parent),
|
|
|
|
m_scene(scene)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-02-19 19:30:52 +01:00
|
|
|
QRectF PDFCreatePCElementTool::getRectangleFromPickTool(PDFPickTool* pickTool,
|
|
|
|
const QMatrix& pagePointToDevicePointMatrix)
|
|
|
|
{
|
|
|
|
const std::vector<QPointF>& points = pickTool->getPickedPoints();
|
|
|
|
if (points.empty())
|
|
|
|
{
|
|
|
|
return QRectF();
|
|
|
|
}
|
|
|
|
|
|
|
|
QPointF mousePoint = pagePointToDevicePointMatrix.inverted().map(pickTool->getSnappedPoint());
|
|
|
|
QPointF point = points.front();
|
|
|
|
qreal xMin = qMin(point.x(), mousePoint.x());
|
|
|
|
qreal xMax = qMax(point.x(), mousePoint.x());
|
|
|
|
qreal yMin = qMin(point.y(), mousePoint.y());
|
|
|
|
qreal yMax = qMax(point.y(), mousePoint.y());
|
|
|
|
qreal width = xMax - xMin;
|
|
|
|
qreal height = yMax - yMin;
|
|
|
|
|
|
|
|
if (!qFuzzyIsNull(width) && !qFuzzyIsNull(height))
|
|
|
|
{
|
|
|
|
return QRectF(xMin, yMin, width, height);
|
|
|
|
}
|
|
|
|
|
|
|
|
return QRectF();
|
|
|
|
}
|
|
|
|
|
2022-02-11 19:15:57 +01:00
|
|
|
PDFCreatePCElementRectangleTool::PDFCreatePCElementRectangleTool(PDFDrawWidgetProxy* proxy,
|
|
|
|
PDFPageContentScene* scene,
|
|
|
|
QAction* action,
|
|
|
|
bool isRounded,
|
|
|
|
QObject* parent) :
|
|
|
|
BaseClass(proxy, scene, action, parent),
|
|
|
|
m_pickTool(nullptr),
|
|
|
|
m_element(nullptr)
|
|
|
|
{
|
|
|
|
m_pickTool = new PDFPickTool(proxy, PDFPickTool::Mode::Rectangles, this);
|
|
|
|
m_pickTool->setDrawSelectionRectangle(false);
|
|
|
|
addTool(m_pickTool);
|
|
|
|
connect(m_pickTool, &PDFPickTool::rectanglePicked, this, &PDFCreatePCElementRectangleTool::onRectanglePicked);
|
|
|
|
|
|
|
|
QPen pen(Qt::SolidLine);
|
|
|
|
pen.setWidthF(1.0);
|
|
|
|
|
|
|
|
m_element = new PDFPageContentElementRectangle();
|
|
|
|
m_element->setBrush(Qt::NoBrush);
|
|
|
|
m_element->setPen(std::move(pen));
|
|
|
|
m_element->setRounded(isRounded);
|
|
|
|
|
|
|
|
updateActions();
|
|
|
|
}
|
|
|
|
|
|
|
|
PDFCreatePCElementRectangleTool::~PDFCreatePCElementRectangleTool()
|
|
|
|
{
|
|
|
|
delete m_element;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementRectangleTool::drawPage(QPainter* painter,
|
|
|
|
PDFInteger pageIndex,
|
|
|
|
const PDFPrecompiledPage* compiledPage,
|
|
|
|
PDFTextLayoutGetter& layoutGetter,
|
|
|
|
const QMatrix& pagePointToDevicePointMatrix,
|
|
|
|
QList<PDFRenderError>& errors) const
|
|
|
|
{
|
|
|
|
BaseClass::drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
|
|
|
|
|
|
|
|
if (pageIndex != m_pickTool->getPageIndex())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-19 19:30:52 +01:00
|
|
|
QRectF rectangle = getRectangleFromPickTool(m_pickTool, pagePointToDevicePointMatrix);
|
|
|
|
if (!rectangle.isValid())
|
2022-02-11 19:15:57 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_element->setPageIndex(pageIndex);
|
2022-02-19 19:30:52 +01:00
|
|
|
m_element->setRectangle(rectangle);
|
2022-02-11 19:15:57 +01:00
|
|
|
|
|
|
|
m_element->drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementRectangleTool::onRectanglePicked(PDFInteger pageIndex, QRectF pageRectangle)
|
|
|
|
{
|
|
|
|
if (pageRectangle.isEmpty())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_element->setPageIndex(pageIndex);
|
|
|
|
m_element->setRectangle(pageRectangle);
|
|
|
|
m_scene->addElement(m_element->clone());
|
|
|
|
|
|
|
|
setActive(false);
|
|
|
|
}
|
|
|
|
|
2022-02-13 19:46:09 +01:00
|
|
|
PDFCreatePCElementLineTool::PDFCreatePCElementLineTool(PDFDrawWidgetProxy* proxy,
|
|
|
|
PDFPageContentScene* scene,
|
|
|
|
QAction* action,
|
|
|
|
bool isHorizontal,
|
|
|
|
bool isVertical,
|
|
|
|
QObject* parent) :
|
|
|
|
BaseClass(proxy, scene, action, parent),
|
|
|
|
m_pickTool(nullptr),
|
|
|
|
m_element(nullptr)
|
|
|
|
{
|
|
|
|
m_pickTool = new PDFPickTool(proxy, PDFPickTool::Mode::Points, this);
|
|
|
|
m_pickTool->setDrawSelectionRectangle(false);
|
|
|
|
addTool(m_pickTool);
|
|
|
|
connect(m_pickTool, &PDFPickTool::pointPicked, this, &PDFCreatePCElementLineTool::onPointPicked);
|
|
|
|
|
|
|
|
QPen pen(Qt::SolidLine);
|
|
|
|
pen.setWidthF(2.0);
|
|
|
|
pen.setCapStyle(Qt::RoundCap);
|
|
|
|
|
|
|
|
PDFPageContentElementLine::LineGeometry geometry = PDFPageContentElementLine::LineGeometry::General;
|
|
|
|
|
|
|
|
if (isHorizontal)
|
|
|
|
{
|
|
|
|
geometry = PDFPageContentElementLine::LineGeometry::Horizontal;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isVertical)
|
|
|
|
{
|
|
|
|
geometry = PDFPageContentElementLine::LineGeometry::Vertical;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_element = new PDFPageContentElementLine();
|
|
|
|
m_element->setBrush(Qt::NoBrush);
|
|
|
|
m_element->setPen(std::move(pen));
|
|
|
|
m_element->setGeometry(geometry);
|
|
|
|
|
|
|
|
updateActions();
|
|
|
|
}
|
|
|
|
|
|
|
|
PDFCreatePCElementLineTool::~PDFCreatePCElementLineTool()
|
|
|
|
{
|
|
|
|
delete m_element;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementLineTool::drawPage(QPainter* painter,
|
|
|
|
PDFInteger pageIndex,
|
|
|
|
const PDFPrecompiledPage* compiledPage,
|
|
|
|
PDFTextLayoutGetter& layoutGetter,
|
|
|
|
const QMatrix& pagePointToDevicePointMatrix,
|
|
|
|
QList<PDFRenderError>& errors) const
|
|
|
|
{
|
|
|
|
BaseClass::drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
|
|
|
|
|
|
|
|
if (pageIndex != m_pickTool->getPageIndex() || !m_startPoint)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_element->setPageIndex(pageIndex);
|
|
|
|
|
|
|
|
QPointF startPoint = *m_startPoint;
|
|
|
|
QPointF endPoint = pagePointToDevicePointMatrix.inverted().map(m_pickTool->getSnappedPoint());
|
|
|
|
QLineF line(startPoint, endPoint);
|
|
|
|
|
|
|
|
if (!qFuzzyIsNull(line.length()))
|
|
|
|
{
|
|
|
|
m_element->setLine(line);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_element->drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementLineTool::clear()
|
|
|
|
{
|
|
|
|
m_startPoint = std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementLineTool::onPointPicked(PDFInteger pageIndex, QPointF pagePoint)
|
|
|
|
{
|
|
|
|
if (!m_startPoint || m_element->getPageIndex() != pageIndex)
|
|
|
|
{
|
|
|
|
m_startPoint = pagePoint;
|
|
|
|
m_element->setPageIndex(pageIndex);
|
|
|
|
m_element->setLine(QLineF(pagePoint, pagePoint));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qFuzzyCompare(m_startPoint.value().x(), pagePoint.x()) &&
|
|
|
|
qFuzzyCompare(m_startPoint.value().y(), pagePoint.y()))
|
|
|
|
{
|
|
|
|
// Jakub Melka: Point is same as the start point
|
|
|
|
clear();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QLineF line = m_element->getLine();
|
|
|
|
line.setP2(pagePoint);
|
|
|
|
m_element->setLine(line);
|
|
|
|
m_scene->addElement(m_element->clone());
|
|
|
|
clear();
|
|
|
|
|
|
|
|
setActive(false);
|
|
|
|
}
|
|
|
|
|
2022-02-19 19:30:52 +01:00
|
|
|
PDFCreatePCElementSvgTool::PDFCreatePCElementSvgTool(PDFDrawWidgetProxy* proxy,
|
|
|
|
PDFPageContentScene* scene,
|
|
|
|
QAction* action,
|
|
|
|
QByteArray content,
|
|
|
|
QObject* parent) :
|
|
|
|
BaseClass(proxy, scene, action, parent),
|
|
|
|
m_pickTool(nullptr),
|
|
|
|
m_element(nullptr)
|
|
|
|
{
|
|
|
|
m_pickTool = new PDFPickTool(proxy, PDFPickTool::Mode::Rectangles, this);
|
|
|
|
m_pickTool->setDrawSelectionRectangle(false);
|
|
|
|
addTool(m_pickTool);
|
|
|
|
connect(m_pickTool, &PDFPickTool::rectanglePicked, this, &PDFCreatePCElementSvgTool::onRectanglePicked);
|
|
|
|
|
|
|
|
m_element = new PDFPageContentSvgElement();
|
|
|
|
m_element->setContent(content);
|
|
|
|
|
|
|
|
updateActions();
|
|
|
|
}
|
|
|
|
|
|
|
|
PDFCreatePCElementSvgTool::~PDFCreatePCElementSvgTool()
|
|
|
|
{
|
|
|
|
delete m_element;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementSvgTool::drawPage(QPainter* painter,
|
|
|
|
PDFInteger pageIndex,
|
|
|
|
const PDFPrecompiledPage* compiledPage,
|
|
|
|
PDFTextLayoutGetter& layoutGetter,
|
|
|
|
const QMatrix& pagePointToDevicePointMatrix,
|
|
|
|
QList<PDFRenderError>& errors) const
|
|
|
|
{
|
|
|
|
BaseClass::drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
|
|
|
|
|
|
|
|
if (pageIndex != m_pickTool->getPageIndex())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QRectF rectangle = getRectangleFromPickTool(m_pickTool, pagePointToDevicePointMatrix);
|
|
|
|
if (!rectangle.isValid())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_element->setPageIndex(pageIndex);
|
|
|
|
m_element->setRectangle(rectangle);
|
|
|
|
|
|
|
|
{
|
|
|
|
PDFPainterStateGuard guard(painter);
|
|
|
|
painter->setWorldMatrix(pagePointToDevicePointMatrix, true);
|
|
|
|
painter->setRenderHint(QPainter::Antialiasing);
|
|
|
|
painter->setPen(Qt::DotLine);
|
|
|
|
painter->setBrush(Qt::NoBrush);
|
|
|
|
painter->drawRect(rectangle);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_element->drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementSvgTool::onRectanglePicked(PDFInteger pageIndex, QRectF pageRectangle)
|
|
|
|
{
|
|
|
|
if (pageRectangle.isEmpty())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_element->setPageIndex(pageIndex);
|
|
|
|
m_element->setRectangle(pageRectangle);
|
|
|
|
m_scene->addElement(m_element->clone());
|
|
|
|
|
|
|
|
setActive(false);
|
|
|
|
}
|
|
|
|
|
2022-02-27 17:08:24 +01:00
|
|
|
PDFCreatePCElementDotTool::PDFCreatePCElementDotTool(PDFDrawWidgetProxy* proxy,
|
|
|
|
PDFPageContentScene* scene,
|
|
|
|
QAction* action,
|
|
|
|
QObject* parent) :
|
|
|
|
BaseClass(proxy, scene, action, parent),
|
|
|
|
m_pickTool(nullptr),
|
|
|
|
m_element(nullptr)
|
|
|
|
{
|
|
|
|
m_pickTool = new PDFPickTool(proxy, PDFPickTool::Mode::Points, this);
|
|
|
|
m_pickTool->setDrawSelectionRectangle(false);
|
|
|
|
addTool(m_pickTool);
|
|
|
|
connect(m_pickTool, &PDFPickTool::pointPicked, this, &PDFCreatePCElementDotTool::onPointPicked);
|
|
|
|
|
|
|
|
QPen pen(Qt::SolidLine);
|
|
|
|
pen.setWidthF(5.0);
|
|
|
|
pen.setCapStyle(Qt::RoundCap);
|
|
|
|
|
|
|
|
m_element = new PDFPageContentElementDot();
|
|
|
|
m_element->setBrush(Qt::NoBrush);
|
|
|
|
m_element->setPen(std::move(pen));
|
|
|
|
|
|
|
|
updateActions();
|
|
|
|
}
|
|
|
|
|
|
|
|
PDFCreatePCElementDotTool::~PDFCreatePCElementDotTool()
|
|
|
|
{
|
|
|
|
delete m_element;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementDotTool::drawPage(QPainter* painter,
|
|
|
|
PDFInteger pageIndex,
|
|
|
|
const PDFPrecompiledPage* compiledPage,
|
|
|
|
PDFTextLayoutGetter& layoutGetter,
|
|
|
|
const QMatrix& pagePointToDevicePointMatrix,
|
|
|
|
QList<PDFRenderError>& errors) const
|
|
|
|
{
|
|
|
|
BaseClass::drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
|
|
|
|
|
|
|
|
QPointF point = pagePointToDevicePointMatrix.inverted().map(m_pickTool->getSnappedPoint());
|
|
|
|
|
|
|
|
PDFPainterStateGuard guard(painter);
|
|
|
|
painter->setWorldMatrix(pagePointToDevicePointMatrix, true);
|
|
|
|
painter->setRenderHint(QPainter::Antialiasing);
|
|
|
|
painter->setPen(m_element->getPen());
|
|
|
|
painter->setBrush(m_element->getBrush());
|
|
|
|
painter->drawPoint(point);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementDotTool::onPointPicked(PDFInteger pageIndex, QPointF pagePoint)
|
|
|
|
{
|
|
|
|
m_element->setPageIndex(pageIndex);
|
|
|
|
m_element->setPoint(pagePoint);
|
|
|
|
|
|
|
|
m_scene->addElement(m_element->clone());
|
|
|
|
m_element->setPageIndex(-1);
|
|
|
|
|
|
|
|
setActive(false);
|
|
|
|
}
|
|
|
|
|
2022-02-27 19:59:53 +01:00
|
|
|
PDFCreatePCElementFreehandCurveTool::PDFCreatePCElementFreehandCurveTool(PDFDrawWidgetProxy* proxy,
|
|
|
|
PDFPageContentScene* scene,
|
|
|
|
QAction* action,
|
|
|
|
QObject* parent) :
|
|
|
|
BaseClass(proxy, scene, action, parent),
|
|
|
|
m_element(nullptr)
|
|
|
|
{
|
|
|
|
QPen pen(Qt::SolidLine);
|
|
|
|
pen.setWidthF(2.0);
|
|
|
|
pen.setCapStyle(Qt::RoundCap);
|
|
|
|
|
|
|
|
m_element = new PDFPageContentElementFreehandCurve();
|
|
|
|
m_element->setBrush(Qt::NoBrush);
|
|
|
|
m_element->setPen(std::move(pen));
|
|
|
|
}
|
|
|
|
|
|
|
|
PDFCreatePCElementFreehandCurveTool::~PDFCreatePCElementFreehandCurveTool()
|
|
|
|
{
|
|
|
|
delete m_element;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementFreehandCurveTool::drawPage(QPainter* painter,
|
|
|
|
PDFInteger pageIndex,
|
|
|
|
const PDFPrecompiledPage* compiledPage,
|
|
|
|
PDFTextLayoutGetter& layoutGetter,
|
|
|
|
const QMatrix& pagePointToDevicePointMatrix,
|
|
|
|
QList<PDFRenderError>& errors) const
|
|
|
|
{
|
|
|
|
BaseClass::drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
|
|
|
|
|
|
|
|
if (pageIndex != m_element->getPageIndex() || m_element->isEmpty())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_element->drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementFreehandCurveTool::mousePressEvent(QWidget* widget, QMouseEvent* event)
|
|
|
|
{
|
|
|
|
Q_UNUSED(widget);
|
|
|
|
event->accept();
|
|
|
|
|
|
|
|
if (event->button() == Qt::LeftButton)
|
|
|
|
{
|
|
|
|
// Try to perform pick point
|
|
|
|
QPointF pagePoint;
|
|
|
|
PDFInteger pageIndex = getProxy()->getPageUnderPoint(event->pos(), &pagePoint);
|
|
|
|
if (pageIndex != -1 && // We have picked some point on page
|
|
|
|
(m_element->getPageIndex() == -1 || m_element->getPageIndex() == pageIndex)) // We are under current page
|
|
|
|
{
|
|
|
|
m_element->setPageIndex(pageIndex);
|
|
|
|
m_element->addStartPoint(pagePoint);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (event->button() == Qt::RightButton)
|
|
|
|
{
|
|
|
|
resetTool();
|
|
|
|
}
|
|
|
|
|
|
|
|
emit getProxy()->repaintNeeded();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementFreehandCurveTool::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
|
|
|
|
{
|
|
|
|
Q_UNUSED(widget);
|
|
|
|
event->accept();
|
|
|
|
|
|
|
|
if (event->button() == Qt::LeftButton)
|
|
|
|
{
|
|
|
|
// Try to perform pick point
|
|
|
|
QPointF pagePoint;
|
|
|
|
PDFInteger pageIndex = getProxy()->getPageUnderPoint(event->pos(), &pagePoint);
|
|
|
|
if (pageIndex != -1 && // We have picked some point on page
|
|
|
|
(m_element->getPageIndex() == pageIndex)) // We are under current page
|
|
|
|
{
|
|
|
|
m_element->setPageIndex(pageIndex);
|
|
|
|
m_element->addPoint(pagePoint);
|
|
|
|
|
|
|
|
if (!m_element->isEmpty())
|
|
|
|
{
|
|
|
|
m_scene->addElement(m_element->clone());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
resetTool();
|
|
|
|
}
|
|
|
|
|
|
|
|
emit getProxy()->repaintNeeded();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementFreehandCurveTool::mouseMoveEvent(QWidget* widget, QMouseEvent* event)
|
|
|
|
{
|
|
|
|
Q_UNUSED(widget);
|
|
|
|
event->accept();
|
|
|
|
|
|
|
|
if (event->buttons() & Qt::LeftButton && m_element->getPageIndex() != -1)
|
|
|
|
{
|
|
|
|
// Try to add point to the path
|
|
|
|
QPointF pagePoint;
|
|
|
|
PDFInteger pageIndex = getProxy()->getPageUnderPoint(event->pos(), &pagePoint);
|
|
|
|
if (pageIndex == m_element->getPageIndex())
|
|
|
|
{
|
|
|
|
m_element->addPoint(pagePoint);
|
|
|
|
}
|
|
|
|
|
|
|
|
emit getProxy()->repaintNeeded();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementFreehandCurveTool::setActiveImpl(bool active)
|
|
|
|
{
|
|
|
|
BaseClass::setActiveImpl(active);
|
|
|
|
|
|
|
|
if (!active)
|
|
|
|
{
|
|
|
|
resetTool();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementFreehandCurveTool::resetTool()
|
|
|
|
{
|
|
|
|
m_element->clear();
|
|
|
|
}
|
|
|
|
|
2022-03-26 19:26:32 +01:00
|
|
|
PDFCreatePCElementTextTool::PDFCreatePCElementTextTool(PDFDrawWidgetProxy* proxy,
|
|
|
|
PDFPageContentScene* scene,
|
|
|
|
QAction* action,
|
|
|
|
QObject* parent) :
|
|
|
|
BaseClass(proxy, scene, action, parent),
|
|
|
|
m_pickTool(nullptr),
|
|
|
|
m_element(nullptr),
|
|
|
|
m_textEditWidget(nullptr)
|
|
|
|
{
|
|
|
|
m_pickTool = new PDFPickTool(proxy, PDFPickTool::Mode::Rectangles, this);
|
|
|
|
m_pickTool->setDrawSelectionRectangle(true);
|
|
|
|
connect(m_pickTool, &PDFPickTool::rectanglePicked, this, &PDFCreatePCElementTextTool::onRectanglePicked);
|
|
|
|
|
|
|
|
QFont font = QGuiApplication::font();
|
|
|
|
font.setPixelSize(16.0);
|
|
|
|
|
|
|
|
m_element = new PDFPageContentElementTextBox();
|
|
|
|
m_element->setBrush(Qt::NoBrush);
|
|
|
|
m_element->setPen(QPen(Qt::SolidLine));
|
|
|
|
m_element->setFont(font);
|
|
|
|
|
2022-03-27 19:53:08 +02:00
|
|
|
m_textEditWidget = new PDFTextEditPseudowidget(PDFFormField::Multiline);
|
2022-03-26 19:26:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
PDFCreatePCElementTextTool::~PDFCreatePCElementTextTool()
|
|
|
|
{
|
|
|
|
delete m_textEditWidget;
|
|
|
|
delete m_element;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementTextTool::drawPage(QPainter* painter,
|
|
|
|
PDFInteger pageIndex,
|
|
|
|
const PDFPrecompiledPage* compiledPage,
|
|
|
|
PDFTextLayoutGetter& layoutGetter,
|
|
|
|
const QMatrix& pagePointToDevicePointMatrix,
|
|
|
|
QList<PDFRenderError>& errors) const
|
|
|
|
{
|
|
|
|
BaseClass::drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix, errors);
|
|
|
|
|
|
|
|
if (pageIndex != m_element->getPageIndex())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isEditing())
|
|
|
|
{
|
|
|
|
PDFPainterStateGuard guard(painter);
|
|
|
|
AnnotationDrawParameters parameters;
|
|
|
|
parameters.painter = painter;
|
|
|
|
parameters.boundingRectangle = m_element->getRectangle();
|
|
|
|
parameters.key.first = PDFAppeareanceStreams::Appearance::Normal;
|
|
|
|
parameters.invertColors = getProxy()->getFeatures().testFlag(PDFRenderer::InvertColors);
|
|
|
|
|
|
|
|
painter->setWorldMatrix(pagePointToDevicePointMatrix, true);
|
|
|
|
m_textEditWidget->draw(parameters, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-27 19:53:08 +02:00
|
|
|
void PDFCreatePCElementTextTool::resetTool()
|
|
|
|
{
|
|
|
|
m_textEditWidget->setText(QString());
|
|
|
|
m_element->setText(QString());
|
|
|
|
m_element->setPageIndex(-1);
|
|
|
|
|
|
|
|
if (getTopToolstackTool())
|
|
|
|
{
|
|
|
|
removeTool();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-26 19:26:32 +01:00
|
|
|
void PDFCreatePCElementTextTool::setActiveImpl(bool active)
|
|
|
|
{
|
|
|
|
BaseClass::setActiveImpl(active);
|
|
|
|
|
|
|
|
if (active)
|
|
|
|
{
|
|
|
|
Q_ASSERT(!getTopToolstackTool());
|
|
|
|
addTool(m_pickTool);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-03-27 19:53:08 +02:00
|
|
|
resetTool();
|
2022-03-26 19:26:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
m_pickTool->setActive(active);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementTextTool::onRectanglePicked(PDFInteger pageIndex, QRectF pageRectangle)
|
|
|
|
{
|
|
|
|
if (pageRectangle.isEmpty())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_element->setPageIndex(pageIndex);
|
|
|
|
m_element->setRectangle(pageRectangle);
|
|
|
|
|
|
|
|
m_textEditWidget->setAppearance(m_element->getFont(),
|
|
|
|
m_element->getAlignment(),
|
|
|
|
m_element->getRectangle(),
|
|
|
|
std::numeric_limits<int>::max(),
|
|
|
|
m_element->getPen().color());
|
|
|
|
|
|
|
|
removeTool();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementTextTool::finishEditing()
|
|
|
|
{
|
2022-03-27 19:53:08 +02:00
|
|
|
m_element->setText(m_textEditWidget->getText());
|
|
|
|
|
|
|
|
if (!m_element->getText().isEmpty())
|
|
|
|
{
|
|
|
|
m_scene->addElement(m_element->clone());
|
|
|
|
}
|
|
|
|
|
|
|
|
resetTool();
|
2022-03-26 19:26:32 +01:00
|
|
|
setActive(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<QPointF> PDFCreatePCElementTextTool::getPagePointUnderMouse(QMouseEvent* event) const
|
|
|
|
{
|
|
|
|
QPointF pagePoint;
|
|
|
|
PDFInteger pageIndex = getProxy()->getPageUnderPoint(event->pos(), &pagePoint);
|
|
|
|
if (pageIndex == m_element->getPageIndex() &&
|
|
|
|
m_element->getRectangle().contains(pagePoint))
|
|
|
|
{
|
|
|
|
return pagePoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PDFCreatePCElementTextTool::isEditing() const
|
|
|
|
{
|
|
|
|
return isActive() && !getTopToolstackTool();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementTextTool::shortcutOverrideEvent(QWidget* widget, QKeyEvent* event)
|
|
|
|
{
|
|
|
|
Q_UNUSED(widget);
|
|
|
|
|
|
|
|
if (isEditing())
|
|
|
|
{
|
|
|
|
m_textEditWidget->shortcutOverrideEvent(widget, event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementTextTool::keyPressEvent(QWidget* widget, QKeyEvent* event)
|
|
|
|
{
|
|
|
|
event->ignore();
|
|
|
|
|
|
|
|
if (!isEditing())
|
|
|
|
{
|
|
|
|
BaseClass::keyPressEvent(widget, event);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event->key() == Qt::Key_Escape)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!m_textEditWidget->isMultiline() && (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return))
|
|
|
|
{
|
|
|
|
// Commit the editor and create element
|
|
|
|
finishEditing();
|
|
|
|
event->accept();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_textEditWidget->keyPressEvent(widget, event);
|
|
|
|
|
|
|
|
if (event->isAccepted())
|
|
|
|
{
|
|
|
|
widget->update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementTextTool::mousePressEvent(QWidget* widget, QMouseEvent* event)
|
|
|
|
{
|
|
|
|
if (isEditing())
|
|
|
|
{
|
|
|
|
if (event->button() == Qt::LeftButton)
|
|
|
|
{
|
|
|
|
std::optional<QPointF> pagePoint = getPagePointUnderMouse(event);
|
|
|
|
if (pagePoint)
|
|
|
|
{
|
|
|
|
const int cursorPosition = m_textEditWidget->getCursorPositionFromWidgetPosition(pagePoint.value(), true);
|
|
|
|
m_textEditWidget->setCursorPosition(cursorPosition, event->modifiers() & Qt::ShiftModifier);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
finishEditing();
|
|
|
|
}
|
|
|
|
|
|
|
|
event->accept();
|
|
|
|
widget->update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
BaseClass::mousePressEvent(widget, event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementTextTool::mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event)
|
|
|
|
{
|
|
|
|
if (isEditing())
|
|
|
|
{
|
|
|
|
if (event->button() == Qt::LeftButton)
|
|
|
|
{
|
|
|
|
std::optional<QPointF> pagePoint = getPagePointUnderMouse(event);
|
|
|
|
if (pagePoint)
|
|
|
|
{
|
|
|
|
const int cursorPosition = m_textEditWidget->getCursorPositionFromWidgetPosition(pagePoint.value(), true);
|
|
|
|
m_textEditWidget->setCursorPosition(cursorPosition, false);
|
|
|
|
m_textEditWidget->setCursorPosition(m_textEditWidget->getCursorWordBackward(), false);
|
|
|
|
m_textEditWidget->setCursorPosition(m_textEditWidget->getCursorWordForward(), true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
finishEditing();
|
|
|
|
}
|
|
|
|
|
|
|
|
event->accept();
|
|
|
|
widget->update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
BaseClass::mousePressEvent(widget, event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementTextTool::mouseMoveEvent(QWidget* widget, QMouseEvent* event)
|
|
|
|
{
|
|
|
|
if (isEditing())
|
|
|
|
{
|
|
|
|
std::optional<QPointF> pagePoint = getPagePointUnderMouse(event);
|
|
|
|
if (pagePoint)
|
|
|
|
{
|
|
|
|
// We must test, if left mouse button is pressed while
|
|
|
|
// we are moving the mouse - if yes, then select the text.
|
|
|
|
if (event->buttons() & Qt::LeftButton)
|
|
|
|
{
|
|
|
|
const int cursorPosition = m_textEditWidget->getCursorPositionFromWidgetPosition(pagePoint.value(), true);
|
|
|
|
m_textEditWidget->setCursorPosition(cursorPosition, true);
|
|
|
|
|
|
|
|
event->accept();
|
|
|
|
widget->update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
BaseClass::mouseMoveEvent(widget, event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PDFCreatePCElementTextTool::wheelEvent(QWidget* widget, QWheelEvent* event)
|
|
|
|
{
|
|
|
|
if (isEditing())
|
|
|
|
{
|
2022-03-27 19:53:08 +02:00
|
|
|
event->ignore();
|
2022-03-26 19:26:32 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
BaseClass::wheelEvent(widget, event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-11 19:15:57 +01:00
|
|
|
} // namespace pdf
|