mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Use LF instead of CRLF
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"Name" : "Dimensions",
|
||||
"Author" : "Jakub Melka",
|
||||
"Version" : "1.0.0",
|
||||
"License" : "LGPL v3",
|
||||
"Description" : "Measure distances, area, perimeter in a document page."
|
||||
}
|
||||
{
|
||||
"Name" : "Dimensions",
|
||||
"Author" : "Jakub Melka",
|
||||
"Version" : "1.0.0",
|
||||
"License" : "LGPL v3",
|
||||
"Description" : "Measure distances, area, perimeter in a document page."
|
||||
}
|
||||
|
@@ -1,54 +1,54 @@
|
||||
# Copyright (C) 2020-2021 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/>.
|
||||
|
||||
TEMPLATE = lib
|
||||
DEFINES += DIMENSIONPLUGIN_LIBRARY
|
||||
|
||||
QT += gui widgets
|
||||
|
||||
LIBS += -L$$OUT_PWD/../..
|
||||
|
||||
LIBS += -lPdf4QtLib
|
||||
|
||||
QMAKE_CXXFLAGS += /std:c++latest /utf-8
|
||||
|
||||
INCLUDEPATH += $$PWD/../../Pdf4QtLib/Sources
|
||||
|
||||
DESTDIR = $$OUT_PWD/../../pdfplugins
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
SOURCES += \
|
||||
dimensionsplugin.cpp \
|
||||
dimensiontool.cpp \
|
||||
settingsdialog.cpp
|
||||
|
||||
HEADERS += \
|
||||
dimensionsplugin.h \
|
||||
dimensiontool.h \
|
||||
settingsdialog.h
|
||||
|
||||
CONFIG += force_debug_info
|
||||
|
||||
DISTFILES += \
|
||||
DimensionsPlugin.json
|
||||
|
||||
RESOURCES += \
|
||||
icons.qrc
|
||||
|
||||
FORMS += \
|
||||
settingsdialog.ui
|
||||
# Copyright (C) 2020-2021 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/>.
|
||||
|
||||
TEMPLATE = lib
|
||||
DEFINES += DIMENSIONPLUGIN_LIBRARY
|
||||
|
||||
QT += gui widgets
|
||||
|
||||
LIBS += -L$$OUT_PWD/../..
|
||||
|
||||
LIBS += -lPdf4QtLib
|
||||
|
||||
QMAKE_CXXFLAGS += /std:c++latest /utf-8
|
||||
|
||||
INCLUDEPATH += $$PWD/../../Pdf4QtLib/Sources
|
||||
|
||||
DESTDIR = $$OUT_PWD/../../pdfplugins
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
SOURCES += \
|
||||
dimensionsplugin.cpp \
|
||||
dimensiontool.cpp \
|
||||
settingsdialog.cpp
|
||||
|
||||
HEADERS += \
|
||||
dimensionsplugin.h \
|
||||
dimensiontool.h \
|
||||
settingsdialog.h
|
||||
|
||||
CONFIG += force_debug_info
|
||||
|
||||
DISTFILES += \
|
||||
DimensionsPlugin.json
|
||||
|
||||
RESOURCES += \
|
||||
icons.qrc
|
||||
|
||||
FORMS += \
|
||||
settingsdialog.ui
|
||||
|
@@ -1,374 +1,374 @@
|
||||
// Copyright (C) 2020-2021 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 "dimensionsplugin.h"
|
||||
#include "pdfdrawwidget.h"
|
||||
#include "pdfwidgetutils.h"
|
||||
#include "settingsdialog.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QFontMetricsF>
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
DimensionsPlugin::DimensionsPlugin() :
|
||||
pdf::PDFPlugin(nullptr),
|
||||
m_dimensionTools(),
|
||||
m_showDimensionsAction(nullptr),
|
||||
m_clearDimensionsAction(nullptr),
|
||||
m_settingsAction(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DimensionsPlugin::setWidget(pdf::PDFWidget* widget)
|
||||
{
|
||||
Q_ASSERT(!m_widget);
|
||||
|
||||
BaseClass::setWidget(widget);
|
||||
|
||||
QAction* horizontalDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/linear-horizontal.svg"), tr("Horizontal Dimension"), this);
|
||||
QAction* verticalDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/linear-vertical.svg"), tr("Vertical Dimension"), this);
|
||||
QAction* linearDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/linear.svg"), tr("Linear Dimension"), this);
|
||||
QAction* perimeterDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/perimeter.svg"), tr("Perimeter"), this);
|
||||
QAction* rectanglePerimeterDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/rectangle-perimeter.svg"), tr("Rectangle Perimeter"), this);
|
||||
QAction* areaDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/area.svg"), tr("Area"), this);
|
||||
QAction* rectangleAreaDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/rectangle-area.svg"), tr("Rectangle Area"), this);
|
||||
QAction* angleAction = new QAction(QIcon(":/pdfplugins/dimensiontool/angle.svg"), tr("Angle"), this);
|
||||
|
||||
horizontalDimensionAction->setObjectName("dimensiontool_LinearHorizontalAction");
|
||||
verticalDimensionAction->setObjectName("dimensiontool_LinearVerticalAction");
|
||||
linearDimensionAction->setObjectName("dimensiontool_LinearAction");
|
||||
perimeterDimensionAction->setObjectName("dimensiontool_PerimeterAction");
|
||||
rectanglePerimeterDimensionAction->setObjectName("dimensiontool_RectanglePerimeterAction");
|
||||
areaDimensionAction->setObjectName("dimensiontool_AreaAction");
|
||||
rectangleAreaDimensionAction->setObjectName("dimensiontool_RectangleAreaAction");
|
||||
angleAction->setObjectName("dimensiontool_AngleAction");
|
||||
|
||||
horizontalDimensionAction->setCheckable(true);
|
||||
verticalDimensionAction->setCheckable(true);
|
||||
linearDimensionAction->setCheckable(true);
|
||||
perimeterDimensionAction->setCheckable(true);
|
||||
rectanglePerimeterDimensionAction->setCheckable(true);
|
||||
areaDimensionAction->setCheckable(true);
|
||||
rectangleAreaDimensionAction->setCheckable(true);
|
||||
angleAction->setCheckable(true);
|
||||
|
||||
m_dimensionTools[DimensionTool::LinearHorizontal] = new DimensionTool(DimensionTool::LinearHorizontal, widget->getDrawWidgetProxy(), horizontalDimensionAction, this);
|
||||
m_dimensionTools[DimensionTool::LinearVertical] = new DimensionTool(DimensionTool::LinearVertical, widget->getDrawWidgetProxy(), verticalDimensionAction, this);
|
||||
m_dimensionTools[DimensionTool::Linear] = new DimensionTool(DimensionTool::Linear, widget->getDrawWidgetProxy(), linearDimensionAction, this);
|
||||
m_dimensionTools[DimensionTool::Perimeter] = new DimensionTool(DimensionTool::Perimeter, widget->getDrawWidgetProxy(), perimeterDimensionAction, this);
|
||||
m_dimensionTools[DimensionTool::RectanglePerimeter] = new DimensionTool(DimensionTool::RectanglePerimeter, widget->getDrawWidgetProxy(), rectanglePerimeterDimensionAction, this);
|
||||
m_dimensionTools[DimensionTool::Area] = new DimensionTool(DimensionTool::Area, widget->getDrawWidgetProxy(), areaDimensionAction, this);
|
||||
m_dimensionTools[DimensionTool::RectangleArea] = new DimensionTool(DimensionTool::RectangleArea, widget->getDrawWidgetProxy(), rectangleAreaDimensionAction, this);
|
||||
m_dimensionTools[DimensionTool::Angle] = new DimensionTool(DimensionTool::Angle, widget->getDrawWidgetProxy(), angleAction, this);
|
||||
|
||||
pdf::PDFToolManager* toolManager = widget->getToolManager();
|
||||
for (DimensionTool* tool : m_dimensionTools)
|
||||
{
|
||||
toolManager->addTool(tool);
|
||||
connect(tool, &DimensionTool::dimensionCreated, this, &DimensionsPlugin::onDimensionCreated);
|
||||
}
|
||||
|
||||
m_showDimensionsAction = new QAction(QIcon(":/pdfplugins/dimensiontool/show-dimensions.svg"), tr("Show Dimensions"), this);
|
||||
m_clearDimensionsAction = new QAction(QIcon(":/pdfplugins/dimensiontool/clear-dimensions.svg"), tr("Clear Dimensions"), this);
|
||||
m_settingsAction = new QAction(QIcon(":/pdfplugins/dimensiontool/settings.svg"), tr("Settings"), this);
|
||||
|
||||
m_showDimensionsAction->setCheckable(true);
|
||||
m_showDimensionsAction->setChecked(true);
|
||||
|
||||
connect(m_showDimensionsAction, &QAction::triggered, this, &DimensionsPlugin::onShowDimensionsTriggered);
|
||||
connect(m_clearDimensionsAction, &QAction::triggered, this, &DimensionsPlugin::onClearDimensionsTriggered);
|
||||
connect(m_settingsAction, &QAction::triggered, this, &DimensionsPlugin::onSettingsTriggered);
|
||||
|
||||
m_lengthUnit = DimensionUnit::getLengthUnits().front();
|
||||
m_areaUnit = DimensionUnit::getAreaUnits().front();
|
||||
m_angleUnit = DimensionUnit::getAngleUnits().front();
|
||||
|
||||
m_widget->getDrawWidgetProxy()->registerDrawInterface(this);
|
||||
|
||||
updateActions();
|
||||
}
|
||||
|
||||
void DimensionsPlugin::setDocument(const pdf::PDFModifiedDocument& document)
|
||||
{
|
||||
BaseClass::setDocument(document);
|
||||
|
||||
if (document.hasReset())
|
||||
{
|
||||
m_dimensions.clear();
|
||||
updateActions();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<QAction*> DimensionsPlugin::getActions() const
|
||||
{
|
||||
std::vector<QAction*> result;
|
||||
|
||||
for (DimensionTool* tool : m_dimensionTools)
|
||||
{
|
||||
if (tool)
|
||||
{
|
||||
result.push_back(tool->getAction());
|
||||
}
|
||||
}
|
||||
|
||||
if (!result.empty())
|
||||
{
|
||||
result.push_back(nullptr);
|
||||
result.push_back(m_showDimensionsAction);
|
||||
result.push_back(m_clearDimensionsAction);
|
||||
result.push_back(m_settingsAction);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void DimensionsPlugin::drawPage(QPainter* painter,
|
||||
pdf::PDFInteger pageIndex,
|
||||
const pdf::PDFPrecompiledPage* compiledPage,
|
||||
pdf::PDFTextLayoutGetter& layoutGetter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
QList<pdf::PDFRenderError>& errors) const
|
||||
{
|
||||
Q_UNUSED(compiledPage);
|
||||
Q_UNUSED(layoutGetter);
|
||||
Q_UNUSED(errors);
|
||||
|
||||
if (!m_showDimensionsAction || !m_showDimensionsAction->isChecked() || m_dimensions.empty())
|
||||
{
|
||||
// Nothing to draw
|
||||
return;
|
||||
}
|
||||
|
||||
QLocale locale;
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
|
||||
for (const Dimension& dimension : m_dimensions)
|
||||
{
|
||||
if (pageIndex != dimension.getPageIndex())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (dimension.getType())
|
||||
{
|
||||
case Dimension::Linear:
|
||||
{
|
||||
QPointF p1 = pagePointToDevicePointMatrix.map(dimension.getPolygon().front());
|
||||
QPointF p2 = pagePointToDevicePointMatrix.map(dimension.getPolygon().back());
|
||||
|
||||
// Swap so p1 is to the left of the page, before p2 (for correct determination of angle)
|
||||
if (p1.x() > p2.x())
|
||||
{
|
||||
qSwap(p1, p2);
|
||||
}
|
||||
|
||||
QLineF line(p1, p2);
|
||||
|
||||
if (qFuzzyIsNull(line.length()))
|
||||
{
|
||||
// If we have zero line, then do nothing
|
||||
continue;
|
||||
}
|
||||
|
||||
QLineF unitVectorLine = line.normalVector().unitVector();
|
||||
QPointF unitVector = unitVectorLine.p2() - unitVectorLine.p1();
|
||||
qreal extensionLineSize = pdf::PDFWidgetUtils::scaleDPI_y(painter->device(), 5);
|
||||
|
||||
painter->setPen(Qt::black);
|
||||
painter->drawLine(line);
|
||||
|
||||
QLineF extensionLineLeft(p1 - unitVector * extensionLineSize, p1 + unitVector * extensionLineSize);
|
||||
QLineF extensionLineRight(p2 - unitVector * extensionLineSize, p2 + unitVector * extensionLineSize);
|
||||
|
||||
painter->drawLine(extensionLineLeft);
|
||||
painter->drawLine(extensionLineRight);
|
||||
|
||||
QPointF textPoint = line.center();
|
||||
qreal angle = line.angle();
|
||||
QFontMetricsF fontMetrics(painter->font());
|
||||
QRectF textRect(-line.length() * 0.5, -fontMetrics.lineSpacing(), line.length(), fontMetrics.lineSpacing());
|
||||
|
||||
QString text = QString("%1 %2").arg(locale.toString(dimension.getMeasuredValue() * m_lengthUnit.scale, 'f', 2), m_lengthUnit.symbol);
|
||||
|
||||
painter->save();
|
||||
painter->translate(textPoint);
|
||||
painter->rotate(-angle);
|
||||
painter->drawText(textRect, Qt::AlignCenter | Qt::TextDontClip, text);
|
||||
painter->restore();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Dimension::Perimeter:
|
||||
case Dimension::Area:
|
||||
{
|
||||
const bool isArea = dimension.getType() == Dimension::Type::Area;
|
||||
const std::vector<QPointF>& polygon = dimension.getPolygon();
|
||||
|
||||
qreal lineSize = pdf::PDFWidgetUtils::scaleDPI_x(painter->device(), 1);
|
||||
qreal pointSize = pdf::PDFWidgetUtils::scaleDPI_x(painter->device(), 5);
|
||||
|
||||
painter->save();
|
||||
QPen pen(Qt::black);
|
||||
pen.setWidthF(lineSize);
|
||||
pen.setCosmetic(true);
|
||||
|
||||
QColor brushColor = Qt::black;
|
||||
brushColor.setAlphaF(0.1);
|
||||
painter->setPen(qMove(pen));
|
||||
painter->setBrush(QBrush(brushColor, isArea ? Qt::SolidPattern : Qt::DiagCrossPattern));
|
||||
|
||||
painter->setMatrix(pagePointToDevicePointMatrix, true);
|
||||
painter->drawPolygon(polygon.data(), int(polygon.size()), Qt::OddEvenFill);
|
||||
painter->restore();
|
||||
|
||||
QPen penPoint(Qt::black);
|
||||
penPoint.setCapStyle(Qt::RoundCap);
|
||||
penPoint.setWidthF(pointSize);
|
||||
painter->setPen(penPoint);
|
||||
|
||||
QPointF centerPoint(0, 0);
|
||||
for (const QPointF& point : polygon)
|
||||
{
|
||||
QPointF mappedPoint = pagePointToDevicePointMatrix.map(point);
|
||||
centerPoint += mappedPoint;
|
||||
painter->drawPoint(mappedPoint);
|
||||
}
|
||||
|
||||
centerPoint *= 1.0 / qreal(polygon.size());
|
||||
|
||||
QString text;
|
||||
|
||||
if (isArea)
|
||||
{
|
||||
text = tr("A = %1 %2").arg(locale.toString(dimension.getMeasuredValue() * m_areaUnit.scale, 'f', 2), m_areaUnit.symbol);
|
||||
}
|
||||
else
|
||||
{
|
||||
text = tr("p = %1 %2").arg(locale.toString(dimension.getMeasuredValue() * m_lengthUnit.scale, 'f', 2), m_lengthUnit.symbol);
|
||||
}
|
||||
painter->drawText(centerPoint, text);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Dimension::Angular:
|
||||
{
|
||||
const std::vector<QPointF>& polygon = dimension.getPolygon();
|
||||
QLineF line1(pagePointToDevicePointMatrix.map(polygon[1]), pagePointToDevicePointMatrix.map(polygon.front()));
|
||||
QLineF line2(pagePointToDevicePointMatrix.map(polygon[1]), pagePointToDevicePointMatrix.map(polygon.back()));
|
||||
|
||||
qreal lineSize = pdf::PDFWidgetUtils::scaleDPI_x(painter->device(), 1);
|
||||
qreal pointSize = pdf::PDFWidgetUtils::scaleDPI_x(painter->device(), 5);
|
||||
|
||||
qreal maxLength = qMax(line1.length(), line2.length());
|
||||
line1.setLength(maxLength);
|
||||
line2.setLength(maxLength);
|
||||
|
||||
QPen pen(Qt::black);
|
||||
pen.setWidthF(lineSize);
|
||||
painter->setPen(qMove(pen));
|
||||
|
||||
painter->drawLine(line1);
|
||||
painter->drawLine(line2);
|
||||
|
||||
qreal startAngle = line1.angle() * 16;
|
||||
qreal angleLength = dimension.getMeasuredValue() * 16;
|
||||
|
||||
QRectF rect(-maxLength * 0.5, -maxLength * 0.5, maxLength, maxLength);
|
||||
rect.translate(line1.p1());
|
||||
painter->drawArc(rect, startAngle - angleLength, angleLength);
|
||||
|
||||
QPen penPoint(Qt::black);
|
||||
penPoint.setCapStyle(Qt::RoundCap);
|
||||
penPoint.setWidthF(pointSize);
|
||||
painter->setPen(penPoint);
|
||||
|
||||
painter->drawPoint(line1.p1());
|
||||
painter->drawPoint(line1.p2());
|
||||
painter->drawPoint(line2.p2());
|
||||
|
||||
QMatrix textMatrix;
|
||||
textMatrix.translate(line1.x1(), line1.y1());
|
||||
textMatrix.rotate(-line1.angle() + dimension.getMeasuredValue() * 0.5);
|
||||
|
||||
QPointF textPoint = textMatrix.map(QPointF(maxLength * 0.25, 0.0));
|
||||
QString text = QString("%1 %2").arg(locale.toString(dimension.getMeasuredValue() * m_angleUnit.scale, 'f', 2), m_angleUnit.symbol);
|
||||
painter->drawText(textPoint, text);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DimensionsPlugin::onShowDimensionsTriggered()
|
||||
{
|
||||
updateGraphics();
|
||||
}
|
||||
|
||||
void DimensionsPlugin::onClearDimensionsTriggered()
|
||||
{
|
||||
m_dimensions.clear();
|
||||
updateActions();
|
||||
updateGraphics();
|
||||
}
|
||||
|
||||
void DimensionsPlugin::onSettingsTriggered()
|
||||
{
|
||||
SettingsDialog dialog(m_widget, m_lengthUnit, m_areaUnit, m_angleUnit);
|
||||
dialog.exec();
|
||||
|
||||
updateGraphics();
|
||||
}
|
||||
|
||||
void DimensionsPlugin::onDimensionCreated(Dimension dimension)
|
||||
{
|
||||
m_dimensions.emplace_back(qMove(dimension));
|
||||
updateActions();
|
||||
updateGraphics();
|
||||
}
|
||||
|
||||
void DimensionsPlugin::updateActions()
|
||||
{
|
||||
if (m_showDimensionsAction)
|
||||
{
|
||||
m_showDimensionsAction->setEnabled(!m_dimensions.empty());
|
||||
}
|
||||
if (m_clearDimensionsAction)
|
||||
{
|
||||
m_clearDimensionsAction->setEnabled(!m_dimensions.empty());
|
||||
}
|
||||
}
|
||||
|
||||
void DimensionsPlugin::updateGraphics()
|
||||
{
|
||||
if (m_widget)
|
||||
{
|
||||
m_widget->getDrawWidget()->getWidget()->update();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Copyright (C) 2020-2021 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 "dimensionsplugin.h"
|
||||
#include "pdfdrawwidget.h"
|
||||
#include "pdfwidgetutils.h"
|
||||
#include "settingsdialog.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QFontMetricsF>
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
DimensionsPlugin::DimensionsPlugin() :
|
||||
pdf::PDFPlugin(nullptr),
|
||||
m_dimensionTools(),
|
||||
m_showDimensionsAction(nullptr),
|
||||
m_clearDimensionsAction(nullptr),
|
||||
m_settingsAction(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DimensionsPlugin::setWidget(pdf::PDFWidget* widget)
|
||||
{
|
||||
Q_ASSERT(!m_widget);
|
||||
|
||||
BaseClass::setWidget(widget);
|
||||
|
||||
QAction* horizontalDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/linear-horizontal.svg"), tr("Horizontal Dimension"), this);
|
||||
QAction* verticalDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/linear-vertical.svg"), tr("Vertical Dimension"), this);
|
||||
QAction* linearDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/linear.svg"), tr("Linear Dimension"), this);
|
||||
QAction* perimeterDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/perimeter.svg"), tr("Perimeter"), this);
|
||||
QAction* rectanglePerimeterDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/rectangle-perimeter.svg"), tr("Rectangle Perimeter"), this);
|
||||
QAction* areaDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/area.svg"), tr("Area"), this);
|
||||
QAction* rectangleAreaDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/rectangle-area.svg"), tr("Rectangle Area"), this);
|
||||
QAction* angleAction = new QAction(QIcon(":/pdfplugins/dimensiontool/angle.svg"), tr("Angle"), this);
|
||||
|
||||
horizontalDimensionAction->setObjectName("dimensiontool_LinearHorizontalAction");
|
||||
verticalDimensionAction->setObjectName("dimensiontool_LinearVerticalAction");
|
||||
linearDimensionAction->setObjectName("dimensiontool_LinearAction");
|
||||
perimeterDimensionAction->setObjectName("dimensiontool_PerimeterAction");
|
||||
rectanglePerimeterDimensionAction->setObjectName("dimensiontool_RectanglePerimeterAction");
|
||||
areaDimensionAction->setObjectName("dimensiontool_AreaAction");
|
||||
rectangleAreaDimensionAction->setObjectName("dimensiontool_RectangleAreaAction");
|
||||
angleAction->setObjectName("dimensiontool_AngleAction");
|
||||
|
||||
horizontalDimensionAction->setCheckable(true);
|
||||
verticalDimensionAction->setCheckable(true);
|
||||
linearDimensionAction->setCheckable(true);
|
||||
perimeterDimensionAction->setCheckable(true);
|
||||
rectanglePerimeterDimensionAction->setCheckable(true);
|
||||
areaDimensionAction->setCheckable(true);
|
||||
rectangleAreaDimensionAction->setCheckable(true);
|
||||
angleAction->setCheckable(true);
|
||||
|
||||
m_dimensionTools[DimensionTool::LinearHorizontal] = new DimensionTool(DimensionTool::LinearHorizontal, widget->getDrawWidgetProxy(), horizontalDimensionAction, this);
|
||||
m_dimensionTools[DimensionTool::LinearVertical] = new DimensionTool(DimensionTool::LinearVertical, widget->getDrawWidgetProxy(), verticalDimensionAction, this);
|
||||
m_dimensionTools[DimensionTool::Linear] = new DimensionTool(DimensionTool::Linear, widget->getDrawWidgetProxy(), linearDimensionAction, this);
|
||||
m_dimensionTools[DimensionTool::Perimeter] = new DimensionTool(DimensionTool::Perimeter, widget->getDrawWidgetProxy(), perimeterDimensionAction, this);
|
||||
m_dimensionTools[DimensionTool::RectanglePerimeter] = new DimensionTool(DimensionTool::RectanglePerimeter, widget->getDrawWidgetProxy(), rectanglePerimeterDimensionAction, this);
|
||||
m_dimensionTools[DimensionTool::Area] = new DimensionTool(DimensionTool::Area, widget->getDrawWidgetProxy(), areaDimensionAction, this);
|
||||
m_dimensionTools[DimensionTool::RectangleArea] = new DimensionTool(DimensionTool::RectangleArea, widget->getDrawWidgetProxy(), rectangleAreaDimensionAction, this);
|
||||
m_dimensionTools[DimensionTool::Angle] = new DimensionTool(DimensionTool::Angle, widget->getDrawWidgetProxy(), angleAction, this);
|
||||
|
||||
pdf::PDFToolManager* toolManager = widget->getToolManager();
|
||||
for (DimensionTool* tool : m_dimensionTools)
|
||||
{
|
||||
toolManager->addTool(tool);
|
||||
connect(tool, &DimensionTool::dimensionCreated, this, &DimensionsPlugin::onDimensionCreated);
|
||||
}
|
||||
|
||||
m_showDimensionsAction = new QAction(QIcon(":/pdfplugins/dimensiontool/show-dimensions.svg"), tr("Show Dimensions"), this);
|
||||
m_clearDimensionsAction = new QAction(QIcon(":/pdfplugins/dimensiontool/clear-dimensions.svg"), tr("Clear Dimensions"), this);
|
||||
m_settingsAction = new QAction(QIcon(":/pdfplugins/dimensiontool/settings.svg"), tr("Settings"), this);
|
||||
|
||||
m_showDimensionsAction->setCheckable(true);
|
||||
m_showDimensionsAction->setChecked(true);
|
||||
|
||||
connect(m_showDimensionsAction, &QAction::triggered, this, &DimensionsPlugin::onShowDimensionsTriggered);
|
||||
connect(m_clearDimensionsAction, &QAction::triggered, this, &DimensionsPlugin::onClearDimensionsTriggered);
|
||||
connect(m_settingsAction, &QAction::triggered, this, &DimensionsPlugin::onSettingsTriggered);
|
||||
|
||||
m_lengthUnit = DimensionUnit::getLengthUnits().front();
|
||||
m_areaUnit = DimensionUnit::getAreaUnits().front();
|
||||
m_angleUnit = DimensionUnit::getAngleUnits().front();
|
||||
|
||||
m_widget->getDrawWidgetProxy()->registerDrawInterface(this);
|
||||
|
||||
updateActions();
|
||||
}
|
||||
|
||||
void DimensionsPlugin::setDocument(const pdf::PDFModifiedDocument& document)
|
||||
{
|
||||
BaseClass::setDocument(document);
|
||||
|
||||
if (document.hasReset())
|
||||
{
|
||||
m_dimensions.clear();
|
||||
updateActions();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<QAction*> DimensionsPlugin::getActions() const
|
||||
{
|
||||
std::vector<QAction*> result;
|
||||
|
||||
for (DimensionTool* tool : m_dimensionTools)
|
||||
{
|
||||
if (tool)
|
||||
{
|
||||
result.push_back(tool->getAction());
|
||||
}
|
||||
}
|
||||
|
||||
if (!result.empty())
|
||||
{
|
||||
result.push_back(nullptr);
|
||||
result.push_back(m_showDimensionsAction);
|
||||
result.push_back(m_clearDimensionsAction);
|
||||
result.push_back(m_settingsAction);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void DimensionsPlugin::drawPage(QPainter* painter,
|
||||
pdf::PDFInteger pageIndex,
|
||||
const pdf::PDFPrecompiledPage* compiledPage,
|
||||
pdf::PDFTextLayoutGetter& layoutGetter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
QList<pdf::PDFRenderError>& errors) const
|
||||
{
|
||||
Q_UNUSED(compiledPage);
|
||||
Q_UNUSED(layoutGetter);
|
||||
Q_UNUSED(errors);
|
||||
|
||||
if (!m_showDimensionsAction || !m_showDimensionsAction->isChecked() || m_dimensions.empty())
|
||||
{
|
||||
// Nothing to draw
|
||||
return;
|
||||
}
|
||||
|
||||
QLocale locale;
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
|
||||
for (const Dimension& dimension : m_dimensions)
|
||||
{
|
||||
if (pageIndex != dimension.getPageIndex())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (dimension.getType())
|
||||
{
|
||||
case Dimension::Linear:
|
||||
{
|
||||
QPointF p1 = pagePointToDevicePointMatrix.map(dimension.getPolygon().front());
|
||||
QPointF p2 = pagePointToDevicePointMatrix.map(dimension.getPolygon().back());
|
||||
|
||||
// Swap so p1 is to the left of the page, before p2 (for correct determination of angle)
|
||||
if (p1.x() > p2.x())
|
||||
{
|
||||
qSwap(p1, p2);
|
||||
}
|
||||
|
||||
QLineF line(p1, p2);
|
||||
|
||||
if (qFuzzyIsNull(line.length()))
|
||||
{
|
||||
// If we have zero line, then do nothing
|
||||
continue;
|
||||
}
|
||||
|
||||
QLineF unitVectorLine = line.normalVector().unitVector();
|
||||
QPointF unitVector = unitVectorLine.p2() - unitVectorLine.p1();
|
||||
qreal extensionLineSize = pdf::PDFWidgetUtils::scaleDPI_y(painter->device(), 5);
|
||||
|
||||
painter->setPen(Qt::black);
|
||||
painter->drawLine(line);
|
||||
|
||||
QLineF extensionLineLeft(p1 - unitVector * extensionLineSize, p1 + unitVector * extensionLineSize);
|
||||
QLineF extensionLineRight(p2 - unitVector * extensionLineSize, p2 + unitVector * extensionLineSize);
|
||||
|
||||
painter->drawLine(extensionLineLeft);
|
||||
painter->drawLine(extensionLineRight);
|
||||
|
||||
QPointF textPoint = line.center();
|
||||
qreal angle = line.angle();
|
||||
QFontMetricsF fontMetrics(painter->font());
|
||||
QRectF textRect(-line.length() * 0.5, -fontMetrics.lineSpacing(), line.length(), fontMetrics.lineSpacing());
|
||||
|
||||
QString text = QString("%1 %2").arg(locale.toString(dimension.getMeasuredValue() * m_lengthUnit.scale, 'f', 2), m_lengthUnit.symbol);
|
||||
|
||||
painter->save();
|
||||
painter->translate(textPoint);
|
||||
painter->rotate(-angle);
|
||||
painter->drawText(textRect, Qt::AlignCenter | Qt::TextDontClip, text);
|
||||
painter->restore();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Dimension::Perimeter:
|
||||
case Dimension::Area:
|
||||
{
|
||||
const bool isArea = dimension.getType() == Dimension::Type::Area;
|
||||
const std::vector<QPointF>& polygon = dimension.getPolygon();
|
||||
|
||||
qreal lineSize = pdf::PDFWidgetUtils::scaleDPI_x(painter->device(), 1);
|
||||
qreal pointSize = pdf::PDFWidgetUtils::scaleDPI_x(painter->device(), 5);
|
||||
|
||||
painter->save();
|
||||
QPen pen(Qt::black);
|
||||
pen.setWidthF(lineSize);
|
||||
pen.setCosmetic(true);
|
||||
|
||||
QColor brushColor = Qt::black;
|
||||
brushColor.setAlphaF(0.1);
|
||||
painter->setPen(qMove(pen));
|
||||
painter->setBrush(QBrush(brushColor, isArea ? Qt::SolidPattern : Qt::DiagCrossPattern));
|
||||
|
||||
painter->setMatrix(pagePointToDevicePointMatrix, true);
|
||||
painter->drawPolygon(polygon.data(), int(polygon.size()), Qt::OddEvenFill);
|
||||
painter->restore();
|
||||
|
||||
QPen penPoint(Qt::black);
|
||||
penPoint.setCapStyle(Qt::RoundCap);
|
||||
penPoint.setWidthF(pointSize);
|
||||
painter->setPen(penPoint);
|
||||
|
||||
QPointF centerPoint(0, 0);
|
||||
for (const QPointF& point : polygon)
|
||||
{
|
||||
QPointF mappedPoint = pagePointToDevicePointMatrix.map(point);
|
||||
centerPoint += mappedPoint;
|
||||
painter->drawPoint(mappedPoint);
|
||||
}
|
||||
|
||||
centerPoint *= 1.0 / qreal(polygon.size());
|
||||
|
||||
QString text;
|
||||
|
||||
if (isArea)
|
||||
{
|
||||
text = tr("A = %1 %2").arg(locale.toString(dimension.getMeasuredValue() * m_areaUnit.scale, 'f', 2), m_areaUnit.symbol);
|
||||
}
|
||||
else
|
||||
{
|
||||
text = tr("p = %1 %2").arg(locale.toString(dimension.getMeasuredValue() * m_lengthUnit.scale, 'f', 2), m_lengthUnit.symbol);
|
||||
}
|
||||
painter->drawText(centerPoint, text);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Dimension::Angular:
|
||||
{
|
||||
const std::vector<QPointF>& polygon = dimension.getPolygon();
|
||||
QLineF line1(pagePointToDevicePointMatrix.map(polygon[1]), pagePointToDevicePointMatrix.map(polygon.front()));
|
||||
QLineF line2(pagePointToDevicePointMatrix.map(polygon[1]), pagePointToDevicePointMatrix.map(polygon.back()));
|
||||
|
||||
qreal lineSize = pdf::PDFWidgetUtils::scaleDPI_x(painter->device(), 1);
|
||||
qreal pointSize = pdf::PDFWidgetUtils::scaleDPI_x(painter->device(), 5);
|
||||
|
||||
qreal maxLength = qMax(line1.length(), line2.length());
|
||||
line1.setLength(maxLength);
|
||||
line2.setLength(maxLength);
|
||||
|
||||
QPen pen(Qt::black);
|
||||
pen.setWidthF(lineSize);
|
||||
painter->setPen(qMove(pen));
|
||||
|
||||
painter->drawLine(line1);
|
||||
painter->drawLine(line2);
|
||||
|
||||
qreal startAngle = line1.angle() * 16;
|
||||
qreal angleLength = dimension.getMeasuredValue() * 16;
|
||||
|
||||
QRectF rect(-maxLength * 0.5, -maxLength * 0.5, maxLength, maxLength);
|
||||
rect.translate(line1.p1());
|
||||
painter->drawArc(rect, startAngle - angleLength, angleLength);
|
||||
|
||||
QPen penPoint(Qt::black);
|
||||
penPoint.setCapStyle(Qt::RoundCap);
|
||||
penPoint.setWidthF(pointSize);
|
||||
painter->setPen(penPoint);
|
||||
|
||||
painter->drawPoint(line1.p1());
|
||||
painter->drawPoint(line1.p2());
|
||||
painter->drawPoint(line2.p2());
|
||||
|
||||
QMatrix textMatrix;
|
||||
textMatrix.translate(line1.x1(), line1.y1());
|
||||
textMatrix.rotate(-line1.angle() + dimension.getMeasuredValue() * 0.5);
|
||||
|
||||
QPointF textPoint = textMatrix.map(QPointF(maxLength * 0.25, 0.0));
|
||||
QString text = QString("%1 %2").arg(locale.toString(dimension.getMeasuredValue() * m_angleUnit.scale, 'f', 2), m_angleUnit.symbol);
|
||||
painter->drawText(textPoint, text);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DimensionsPlugin::onShowDimensionsTriggered()
|
||||
{
|
||||
updateGraphics();
|
||||
}
|
||||
|
||||
void DimensionsPlugin::onClearDimensionsTriggered()
|
||||
{
|
||||
m_dimensions.clear();
|
||||
updateActions();
|
||||
updateGraphics();
|
||||
}
|
||||
|
||||
void DimensionsPlugin::onSettingsTriggered()
|
||||
{
|
||||
SettingsDialog dialog(m_widget, m_lengthUnit, m_areaUnit, m_angleUnit);
|
||||
dialog.exec();
|
||||
|
||||
updateGraphics();
|
||||
}
|
||||
|
||||
void DimensionsPlugin::onDimensionCreated(Dimension dimension)
|
||||
{
|
||||
m_dimensions.emplace_back(qMove(dimension));
|
||||
updateActions();
|
||||
updateGraphics();
|
||||
}
|
||||
|
||||
void DimensionsPlugin::updateActions()
|
||||
{
|
||||
if (m_showDimensionsAction)
|
||||
{
|
||||
m_showDimensionsAction->setEnabled(!m_dimensions.empty());
|
||||
}
|
||||
if (m_clearDimensionsAction)
|
||||
{
|
||||
m_clearDimensionsAction->setEnabled(!m_dimensions.empty());
|
||||
}
|
||||
}
|
||||
|
||||
void DimensionsPlugin::updateGraphics()
|
||||
{
|
||||
if (m_widget)
|
||||
{
|
||||
m_widget->getDrawWidget()->getWidget()->update();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,73 +1,73 @@
|
||||
// Copyright (C) 2020-2021 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/>.
|
||||
|
||||
#ifndef DIMENSIONSPLUGIN_H
|
||||
#define DIMENSIONSPLUGIN_H
|
||||
|
||||
#include "pdfplugin.h"
|
||||
#include "dimensiontool.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
class DimensionsPlugin : public pdf::PDFPlugin, public pdf::IDocumentDrawInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "PDF4QT.DimensionsPlugin" FILE "DimensionsPlugin.json")
|
||||
|
||||
private:
|
||||
using BaseClass = pdf::PDFPlugin;
|
||||
|
||||
public:
|
||||
DimensionsPlugin();
|
||||
|
||||
virtual void setWidget(pdf::PDFWidget* widget) override;
|
||||
virtual void setDocument(const pdf::PDFModifiedDocument& document) override;
|
||||
virtual std::vector<QAction*> getActions() const override;
|
||||
|
||||
virtual void drawPage(QPainter* painter,
|
||||
pdf::PDFInteger pageIndex,
|
||||
const pdf::PDFPrecompiledPage* compiledPage,
|
||||
pdf::PDFTextLayoutGetter& layoutGetter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
QList<pdf::PDFRenderError>& errors) const override;
|
||||
|
||||
private:
|
||||
void onShowDimensionsTriggered();
|
||||
void onClearDimensionsTriggered();
|
||||
void onSettingsTriggered();
|
||||
void onDimensionCreated(Dimension dimension);
|
||||
void updateActions();
|
||||
void updateGraphics();
|
||||
|
||||
std::array<DimensionTool*, DimensionTool::LastStyle> m_dimensionTools;
|
||||
std::vector<Dimension> m_dimensions;
|
||||
|
||||
QAction* m_showDimensionsAction;
|
||||
QAction* m_clearDimensionsAction;
|
||||
QAction* m_settingsAction;
|
||||
|
||||
DimensionUnit m_lengthUnit;
|
||||
DimensionUnit m_areaUnit;
|
||||
DimensionUnit m_angleUnit;
|
||||
};
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
||||
#endif // DIMENSIONSPLUGIN_H
|
||||
// Copyright (C) 2020-2021 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/>.
|
||||
|
||||
#ifndef DIMENSIONSPLUGIN_H
|
||||
#define DIMENSIONSPLUGIN_H
|
||||
|
||||
#include "pdfplugin.h"
|
||||
#include "dimensiontool.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace pdfplugin
|
||||
{
|
||||
|
||||
class DimensionsPlugin : public pdf::PDFPlugin, public pdf::IDocumentDrawInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "PDF4QT.DimensionsPlugin" FILE "DimensionsPlugin.json")
|
||||
|
||||
private:
|
||||
using BaseClass = pdf::PDFPlugin;
|
||||
|
||||
public:
|
||||
DimensionsPlugin();
|
||||
|
||||
virtual void setWidget(pdf::PDFWidget* widget) override;
|
||||
virtual void setDocument(const pdf::PDFModifiedDocument& document) override;
|
||||
virtual std::vector<QAction*> getActions() const override;
|
||||
|
||||
virtual void drawPage(QPainter* painter,
|
||||
pdf::PDFInteger pageIndex,
|
||||
const pdf::PDFPrecompiledPage* compiledPage,
|
||||
pdf::PDFTextLayoutGetter& layoutGetter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
QList<pdf::PDFRenderError>& errors) const override;
|
||||
|
||||
private:
|
||||
void onShowDimensionsTriggered();
|
||||
void onClearDimensionsTriggered();
|
||||
void onSettingsTriggered();
|
||||
void onDimensionCreated(Dimension dimension);
|
||||
void updateActions();
|
||||
void updateGraphics();
|
||||
|
||||
std::array<DimensionTool*, DimensionTool::LastStyle> m_dimensionTools;
|
||||
std::vector<Dimension> m_dimensions;
|
||||
|
||||
QAction* m_showDimensionsAction;
|
||||
QAction* m_clearDimensionsAction;
|
||||
QAction* m_settingsAction;
|
||||
|
||||
DimensionUnit m_lengthUnit;
|
||||
DimensionUnit m_areaUnit;
|
||||
DimensionUnit m_angleUnit;
|
||||
};
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
||||
#endif // DIMENSIONSPLUGIN_H
|
||||
|
@@ -1,309 +1,309 @@
|
||||
// Copyright (C) 2020-2021 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 "dimensiontool.h"
|
||||
#include "pdfwidgetutils.h"
|
||||
#include "pdfdrawwidget.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
DimensionTool::DimensionTool(Style style, pdf::PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent) :
|
||||
BaseClass(proxy, action, parent),
|
||||
m_style(style),
|
||||
m_previewPointPixelSize(0),
|
||||
m_pickTool(nullptr)
|
||||
{
|
||||
const bool isRectanglePicking = style == RectanglePerimeter || style == RectangleArea;
|
||||
const pdf::PDFPickTool::Mode pickingMode = isRectanglePicking ? pdf::PDFPickTool::Mode::Rectangles : pdf::PDFPickTool::Mode::Points;
|
||||
m_pickTool = new pdf::PDFPickTool(proxy, pickingMode, this);
|
||||
addTool(m_pickTool);
|
||||
connect(m_pickTool, &pdf::PDFPickTool::pointPicked, this, &DimensionTool::onPointPicked);
|
||||
connect(m_pickTool, &pdf::PDFPickTool::rectanglePicked, this, &DimensionTool::onRectanglePicked);
|
||||
m_previewPointPixelSize = pdf::PDFWidgetUtils::scaleDPI_x(proxy->getWidget(), 5);
|
||||
}
|
||||
|
||||
void DimensionTool::drawPage(QPainter* painter,
|
||||
pdf::PDFInteger pageIndex,
|
||||
const pdf::PDFPrecompiledPage* compiledPage,
|
||||
pdf::PDFTextLayoutGetter& layoutGetter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
QList<pdf::PDFRenderError>& errors) const
|
||||
{
|
||||
Q_UNUSED(compiledPage);
|
||||
Q_UNUSED(layoutGetter);
|
||||
Q_UNUSED(errors);
|
||||
|
||||
if (m_pickTool->getPageIndex() != pageIndex)
|
||||
{
|
||||
// Other page, nothing to draw
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_style == RectanglePerimeter || m_style == RectangleArea)
|
||||
{
|
||||
// Nothing to draw, picking tool is already drawing picked rectangle
|
||||
return;
|
||||
}
|
||||
|
||||
painter->setPen(Qt::black);
|
||||
const std::vector<QPointF>& points = m_pickTool->getPickedPoints();
|
||||
for (size_t i = 1; i < points.size(); ++i)
|
||||
{
|
||||
painter->drawLine(pagePointToDevicePointMatrix.map(points[i - 1]), pagePointToDevicePointMatrix.map(points[i]));
|
||||
}
|
||||
|
||||
if (!points.empty())
|
||||
{
|
||||
QMatrix inverted = pagePointToDevicePointMatrix.inverted();
|
||||
QPointF adjustedPoint = adjustPagePoint(inverted.map(m_pickTool->getSnappedPoint()));
|
||||
painter->drawLine(pagePointToDevicePointMatrix.map(points.back()), pagePointToDevicePointMatrix.map(adjustedPoint));
|
||||
}
|
||||
|
||||
QPen pen = painter->pen();
|
||||
pen.setWidth(m_previewPointPixelSize);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
painter->setPen(pen);
|
||||
|
||||
for (size_t i = 0; i < points.size(); ++i)
|
||||
{
|
||||
painter->drawPoint(pagePointToDevicePointMatrix.map(points[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void DimensionTool::onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint)
|
||||
{
|
||||
Q_UNUSED(pagePoint);
|
||||
|
||||
if (Dimension::isComplete(getDimensionType(), m_pickTool->getPickedPoints()))
|
||||
{
|
||||
// Create a new dimension...
|
||||
std::vector<QPointF> points = m_pickTool->getPickedPoints();
|
||||
for (QPointF& point : points)
|
||||
{
|
||||
point = adjustPagePoint(point);
|
||||
}
|
||||
|
||||
pdf::PDFReal measuredValue = getMeasuredValue(pageIndex, points);
|
||||
emit dimensionCreated(Dimension(getDimensionType(), pageIndex, measuredValue, qMove(points)));
|
||||
m_pickTool->resetTool();
|
||||
}
|
||||
|
||||
if ((m_style == Perimeter || m_style == Area) && m_pickTool->getPickedPoints().size() == 1)
|
||||
{
|
||||
m_pickTool->setCustomSnapPoints(pageIndex, m_pickTool->getPickedPoints());
|
||||
}
|
||||
}
|
||||
|
||||
void DimensionTool::onRectanglePicked(pdf::PDFInteger pageIndex, QRectF pageRectangle)
|
||||
{
|
||||
if (pageRectangle.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<QPointF> points = { pageRectangle.topLeft(), pageRectangle.topRight(), pageRectangle.bottomRight(), pageRectangle.bottomLeft(), pageRectangle.topLeft() };
|
||||
Q_ASSERT(Dimension::isComplete(getDimensionType(), points));
|
||||
pdf::PDFReal measuredValue = getMeasuredValue(pageIndex, points);
|
||||
emit dimensionCreated(Dimension(getDimensionType(), pageIndex, measuredValue, qMove(points)));
|
||||
}
|
||||
|
||||
QPointF DimensionTool::adjustPagePoint(QPointF pagePoint) const
|
||||
{
|
||||
switch (m_style)
|
||||
{
|
||||
case Style::LinearHorizontal:
|
||||
{
|
||||
const std::vector<QPointF>& pickedPoints = m_pickTool->getPickedPoints();
|
||||
if (!pickedPoints.empty())
|
||||
{
|
||||
const pdf::PDFPage* page = getDocument()->getCatalog()->getPage(m_pickTool->getPageIndex());
|
||||
const bool rotated = page->getPageRotation() == pdf::PageRotation::Rotate90 || page->getPageRotation() == pdf::PageRotation::Rotate270;
|
||||
|
||||
if (rotated)
|
||||
{
|
||||
pagePoint.setX(pickedPoints.front().x());
|
||||
}
|
||||
else
|
||||
{
|
||||
pagePoint.setY(pickedPoints.front().y());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Style::LinearVertical:
|
||||
{
|
||||
const std::vector<QPointF>& pickedPoints = m_pickTool->getPickedPoints();
|
||||
if (!pickedPoints.empty())
|
||||
{
|
||||
const pdf::PDFPage* page = getDocument()->getCatalog()->getPage(m_pickTool->getPageIndex());
|
||||
const bool rotated = page->getPageRotation() == pdf::PageRotation::Rotate90 || page->getPageRotation() == pdf::PageRotation::Rotate270;
|
||||
|
||||
if (!rotated)
|
||||
{
|
||||
pagePoint.setX(pickedPoints.front().x());
|
||||
}
|
||||
else
|
||||
{
|
||||
pagePoint.setY(pickedPoints.front().y());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return pagePoint;
|
||||
}
|
||||
|
||||
Dimension::Type DimensionTool::getDimensionType() const
|
||||
{
|
||||
switch (m_style)
|
||||
{
|
||||
case DimensionTool::LinearHorizontal:
|
||||
case DimensionTool::LinearVertical:
|
||||
case DimensionTool::Linear:
|
||||
return Dimension::Type::Linear;
|
||||
|
||||
case DimensionTool::Perimeter:
|
||||
case DimensionTool::RectanglePerimeter:
|
||||
return Dimension::Type::Perimeter;
|
||||
|
||||
case DimensionTool::Area:
|
||||
case DimensionTool::RectangleArea:
|
||||
return Dimension::Type::Area;
|
||||
|
||||
case DimensionTool::Angle:
|
||||
return Dimension::Type::Angular;
|
||||
}
|
||||
|
||||
Q_ASSERT(false);
|
||||
return Dimension::Type::Linear;
|
||||
}
|
||||
|
||||
pdf::PDFReal DimensionTool::getMeasuredValue(pdf::PDFInteger pageIndex, const std::vector<QPointF>& pickedPoints) const
|
||||
{
|
||||
const pdf::PDFPage* page = getDocument()->getCatalog()->getPage(pageIndex);
|
||||
Q_ASSERT(page);
|
||||
|
||||
switch (getDimensionType())
|
||||
{
|
||||
case Dimension::Linear:
|
||||
case Dimension::Perimeter:
|
||||
{
|
||||
pdf::PDFReal length = 0.0;
|
||||
|
||||
for (size_t i = 1; i < pickedPoints.size(); ++i)
|
||||
{
|
||||
QPointF vector = pickedPoints[i] - pickedPoints[i - 1];
|
||||
length += qSqrt(QPointF::dotProduct(vector, vector));
|
||||
}
|
||||
|
||||
return length * page->getUserUnit();
|
||||
}
|
||||
|
||||
case Dimension::Area:
|
||||
{
|
||||
pdf::PDFReal area = 0.0;
|
||||
|
||||
// We calculate the area using standard formula for polygons.
|
||||
// We determine integral over perimeter (for each edge of the polygon).
|
||||
for (size_t i = 1; i < pickedPoints.size(); ++i)
|
||||
{
|
||||
const QPointF& p1 = pickedPoints[i - 1];
|
||||
const QPointF& p2 = pickedPoints[i];
|
||||
|
||||
area += p1.x() * p2.y() - p1.y() * p2.x();
|
||||
}
|
||||
|
||||
area = qAbs(area) * 0.5;
|
||||
return area * page->getUserUnit() * page->getUserUnit();
|
||||
}
|
||||
|
||||
case Dimension::Angular:
|
||||
{
|
||||
Q_ASSERT(pickedPoints.size() == 3);
|
||||
QLineF line1(pickedPoints[1], pickedPoints.front());
|
||||
QLineF line2(pickedPoints[1], pickedPoints.back());
|
||||
return line1.angleTo(line2);
|
||||
}
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
bool Dimension::isComplete(Type type, const std::vector<QPointF>& polygon)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Dimension::Linear:
|
||||
return polygon.size() == 2;
|
||||
|
||||
case Dimension::Perimeter:
|
||||
case Dimension::Area:
|
||||
return polygon.size() > 2 && polygon.front() == polygon.back();
|
||||
|
||||
case Dimension::Angular:
|
||||
return polygon.size() == 3;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DimensionUnits DimensionUnit::getLengthUnits()
|
||||
{
|
||||
DimensionUnits units;
|
||||
|
||||
units.emplace_back(1.0, DimensionTool::tr("pt"));
|
||||
units.emplace_back(pdf::PDF_POINT_TO_INCH, DimensionTool::tr("in"));
|
||||
units.emplace_back(pdf::PDF_POINT_TO_MM, DimensionTool::tr("mm"));
|
||||
units.emplace_back(pdf::PDF_POINT_TO_MM * 0.1, DimensionTool::tr("cm"));
|
||||
|
||||
return units;
|
||||
}
|
||||
|
||||
DimensionUnits DimensionUnit::getAreaUnits()
|
||||
{
|
||||
DimensionUnits units;
|
||||
|
||||
units.emplace_back(1.0, DimensionTool::tr("sq. pt"));
|
||||
units.emplace_back(pdf::PDF_POINT_TO_INCH * pdf::PDF_POINT_TO_INCH, DimensionTool::tr("sq. in"));
|
||||
units.emplace_back(pdf::PDF_POINT_TO_MM * pdf::PDF_POINT_TO_MM, DimensionTool::tr("sq. mm"));
|
||||
units.emplace_back(pdf::PDF_POINT_TO_MM * 0.1 * pdf::PDF_POINT_TO_MM * 0.1, DimensionTool::tr("sq. cm"));
|
||||
|
||||
return units;
|
||||
}
|
||||
|
||||
DimensionUnits DimensionUnit::getAngleUnits()
|
||||
{
|
||||
DimensionUnits units;
|
||||
|
||||
units.emplace_back(1.0, DimensionTool::tr("°"));
|
||||
units.emplace_back(qDegreesToRadians(1.0), DimensionTool::tr("rad"));
|
||||
|
||||
return units;
|
||||
}
|
||||
// Copyright (C) 2020-2021 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 "dimensiontool.h"
|
||||
#include "pdfwidgetutils.h"
|
||||
#include "pdfdrawwidget.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
DimensionTool::DimensionTool(Style style, pdf::PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent) :
|
||||
BaseClass(proxy, action, parent),
|
||||
m_style(style),
|
||||
m_previewPointPixelSize(0),
|
||||
m_pickTool(nullptr)
|
||||
{
|
||||
const bool isRectanglePicking = style == RectanglePerimeter || style == RectangleArea;
|
||||
const pdf::PDFPickTool::Mode pickingMode = isRectanglePicking ? pdf::PDFPickTool::Mode::Rectangles : pdf::PDFPickTool::Mode::Points;
|
||||
m_pickTool = new pdf::PDFPickTool(proxy, pickingMode, this);
|
||||
addTool(m_pickTool);
|
||||
connect(m_pickTool, &pdf::PDFPickTool::pointPicked, this, &DimensionTool::onPointPicked);
|
||||
connect(m_pickTool, &pdf::PDFPickTool::rectanglePicked, this, &DimensionTool::onRectanglePicked);
|
||||
m_previewPointPixelSize = pdf::PDFWidgetUtils::scaleDPI_x(proxy->getWidget(), 5);
|
||||
}
|
||||
|
||||
void DimensionTool::drawPage(QPainter* painter,
|
||||
pdf::PDFInteger pageIndex,
|
||||
const pdf::PDFPrecompiledPage* compiledPage,
|
||||
pdf::PDFTextLayoutGetter& layoutGetter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
QList<pdf::PDFRenderError>& errors) const
|
||||
{
|
||||
Q_UNUSED(compiledPage);
|
||||
Q_UNUSED(layoutGetter);
|
||||
Q_UNUSED(errors);
|
||||
|
||||
if (m_pickTool->getPageIndex() != pageIndex)
|
||||
{
|
||||
// Other page, nothing to draw
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_style == RectanglePerimeter || m_style == RectangleArea)
|
||||
{
|
||||
// Nothing to draw, picking tool is already drawing picked rectangle
|
||||
return;
|
||||
}
|
||||
|
||||
painter->setPen(Qt::black);
|
||||
const std::vector<QPointF>& points = m_pickTool->getPickedPoints();
|
||||
for (size_t i = 1; i < points.size(); ++i)
|
||||
{
|
||||
painter->drawLine(pagePointToDevicePointMatrix.map(points[i - 1]), pagePointToDevicePointMatrix.map(points[i]));
|
||||
}
|
||||
|
||||
if (!points.empty())
|
||||
{
|
||||
QMatrix inverted = pagePointToDevicePointMatrix.inverted();
|
||||
QPointF adjustedPoint = adjustPagePoint(inverted.map(m_pickTool->getSnappedPoint()));
|
||||
painter->drawLine(pagePointToDevicePointMatrix.map(points.back()), pagePointToDevicePointMatrix.map(adjustedPoint));
|
||||
}
|
||||
|
||||
QPen pen = painter->pen();
|
||||
pen.setWidth(m_previewPointPixelSize);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
painter->setPen(pen);
|
||||
|
||||
for (size_t i = 0; i < points.size(); ++i)
|
||||
{
|
||||
painter->drawPoint(pagePointToDevicePointMatrix.map(points[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void DimensionTool::onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint)
|
||||
{
|
||||
Q_UNUSED(pagePoint);
|
||||
|
||||
if (Dimension::isComplete(getDimensionType(), m_pickTool->getPickedPoints()))
|
||||
{
|
||||
// Create a new dimension...
|
||||
std::vector<QPointF> points = m_pickTool->getPickedPoints();
|
||||
for (QPointF& point : points)
|
||||
{
|
||||
point = adjustPagePoint(point);
|
||||
}
|
||||
|
||||
pdf::PDFReal measuredValue = getMeasuredValue(pageIndex, points);
|
||||
emit dimensionCreated(Dimension(getDimensionType(), pageIndex, measuredValue, qMove(points)));
|
||||
m_pickTool->resetTool();
|
||||
}
|
||||
|
||||
if ((m_style == Perimeter || m_style == Area) && m_pickTool->getPickedPoints().size() == 1)
|
||||
{
|
||||
m_pickTool->setCustomSnapPoints(pageIndex, m_pickTool->getPickedPoints());
|
||||
}
|
||||
}
|
||||
|
||||
void DimensionTool::onRectanglePicked(pdf::PDFInteger pageIndex, QRectF pageRectangle)
|
||||
{
|
||||
if (pageRectangle.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<QPointF> points = { pageRectangle.topLeft(), pageRectangle.topRight(), pageRectangle.bottomRight(), pageRectangle.bottomLeft(), pageRectangle.topLeft() };
|
||||
Q_ASSERT(Dimension::isComplete(getDimensionType(), points));
|
||||
pdf::PDFReal measuredValue = getMeasuredValue(pageIndex, points);
|
||||
emit dimensionCreated(Dimension(getDimensionType(), pageIndex, measuredValue, qMove(points)));
|
||||
}
|
||||
|
||||
QPointF DimensionTool::adjustPagePoint(QPointF pagePoint) const
|
||||
{
|
||||
switch (m_style)
|
||||
{
|
||||
case Style::LinearHorizontal:
|
||||
{
|
||||
const std::vector<QPointF>& pickedPoints = m_pickTool->getPickedPoints();
|
||||
if (!pickedPoints.empty())
|
||||
{
|
||||
const pdf::PDFPage* page = getDocument()->getCatalog()->getPage(m_pickTool->getPageIndex());
|
||||
const bool rotated = page->getPageRotation() == pdf::PageRotation::Rotate90 || page->getPageRotation() == pdf::PageRotation::Rotate270;
|
||||
|
||||
if (rotated)
|
||||
{
|
||||
pagePoint.setX(pickedPoints.front().x());
|
||||
}
|
||||
else
|
||||
{
|
||||
pagePoint.setY(pickedPoints.front().y());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Style::LinearVertical:
|
||||
{
|
||||
const std::vector<QPointF>& pickedPoints = m_pickTool->getPickedPoints();
|
||||
if (!pickedPoints.empty())
|
||||
{
|
||||
const pdf::PDFPage* page = getDocument()->getCatalog()->getPage(m_pickTool->getPageIndex());
|
||||
const bool rotated = page->getPageRotation() == pdf::PageRotation::Rotate90 || page->getPageRotation() == pdf::PageRotation::Rotate270;
|
||||
|
||||
if (!rotated)
|
||||
{
|
||||
pagePoint.setX(pickedPoints.front().x());
|
||||
}
|
||||
else
|
||||
{
|
||||
pagePoint.setY(pickedPoints.front().y());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return pagePoint;
|
||||
}
|
||||
|
||||
Dimension::Type DimensionTool::getDimensionType() const
|
||||
{
|
||||
switch (m_style)
|
||||
{
|
||||
case DimensionTool::LinearHorizontal:
|
||||
case DimensionTool::LinearVertical:
|
||||
case DimensionTool::Linear:
|
||||
return Dimension::Type::Linear;
|
||||
|
||||
case DimensionTool::Perimeter:
|
||||
case DimensionTool::RectanglePerimeter:
|
||||
return Dimension::Type::Perimeter;
|
||||
|
||||
case DimensionTool::Area:
|
||||
case DimensionTool::RectangleArea:
|
||||
return Dimension::Type::Area;
|
||||
|
||||
case DimensionTool::Angle:
|
||||
return Dimension::Type::Angular;
|
||||
}
|
||||
|
||||
Q_ASSERT(false);
|
||||
return Dimension::Type::Linear;
|
||||
}
|
||||
|
||||
pdf::PDFReal DimensionTool::getMeasuredValue(pdf::PDFInteger pageIndex, const std::vector<QPointF>& pickedPoints) const
|
||||
{
|
||||
const pdf::PDFPage* page = getDocument()->getCatalog()->getPage(pageIndex);
|
||||
Q_ASSERT(page);
|
||||
|
||||
switch (getDimensionType())
|
||||
{
|
||||
case Dimension::Linear:
|
||||
case Dimension::Perimeter:
|
||||
{
|
||||
pdf::PDFReal length = 0.0;
|
||||
|
||||
for (size_t i = 1; i < pickedPoints.size(); ++i)
|
||||
{
|
||||
QPointF vector = pickedPoints[i] - pickedPoints[i - 1];
|
||||
length += qSqrt(QPointF::dotProduct(vector, vector));
|
||||
}
|
||||
|
||||
return length * page->getUserUnit();
|
||||
}
|
||||
|
||||
case Dimension::Area:
|
||||
{
|
||||
pdf::PDFReal area = 0.0;
|
||||
|
||||
// We calculate the area using standard formula for polygons.
|
||||
// We determine integral over perimeter (for each edge of the polygon).
|
||||
for (size_t i = 1; i < pickedPoints.size(); ++i)
|
||||
{
|
||||
const QPointF& p1 = pickedPoints[i - 1];
|
||||
const QPointF& p2 = pickedPoints[i];
|
||||
|
||||
area += p1.x() * p2.y() - p1.y() * p2.x();
|
||||
}
|
||||
|
||||
area = qAbs(area) * 0.5;
|
||||
return area * page->getUserUnit() * page->getUserUnit();
|
||||
}
|
||||
|
||||
case Dimension::Angular:
|
||||
{
|
||||
Q_ASSERT(pickedPoints.size() == 3);
|
||||
QLineF line1(pickedPoints[1], pickedPoints.front());
|
||||
QLineF line2(pickedPoints[1], pickedPoints.back());
|
||||
return line1.angleTo(line2);
|
||||
}
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
bool Dimension::isComplete(Type type, const std::vector<QPointF>& polygon)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Dimension::Linear:
|
||||
return polygon.size() == 2;
|
||||
|
||||
case Dimension::Perimeter:
|
||||
case Dimension::Area:
|
||||
return polygon.size() > 2 && polygon.front() == polygon.back();
|
||||
|
||||
case Dimension::Angular:
|
||||
return polygon.size() == 3;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DimensionUnits DimensionUnit::getLengthUnits()
|
||||
{
|
||||
DimensionUnits units;
|
||||
|
||||
units.emplace_back(1.0, DimensionTool::tr("pt"));
|
||||
units.emplace_back(pdf::PDF_POINT_TO_INCH, DimensionTool::tr("in"));
|
||||
units.emplace_back(pdf::PDF_POINT_TO_MM, DimensionTool::tr("mm"));
|
||||
units.emplace_back(pdf::PDF_POINT_TO_MM * 0.1, DimensionTool::tr("cm"));
|
||||
|
||||
return units;
|
||||
}
|
||||
|
||||
DimensionUnits DimensionUnit::getAreaUnits()
|
||||
{
|
||||
DimensionUnits units;
|
||||
|
||||
units.emplace_back(1.0, DimensionTool::tr("sq. pt"));
|
||||
units.emplace_back(pdf::PDF_POINT_TO_INCH * pdf::PDF_POINT_TO_INCH, DimensionTool::tr("sq. in"));
|
||||
units.emplace_back(pdf::PDF_POINT_TO_MM * pdf::PDF_POINT_TO_MM, DimensionTool::tr("sq. mm"));
|
||||
units.emplace_back(pdf::PDF_POINT_TO_MM * 0.1 * pdf::PDF_POINT_TO_MM * 0.1, DimensionTool::tr("sq. cm"));
|
||||
|
||||
return units;
|
||||
}
|
||||
|
||||
DimensionUnits DimensionUnit::getAngleUnits()
|
||||
{
|
||||
DimensionUnits units;
|
||||
|
||||
units.emplace_back(1.0, DimensionTool::tr("°"));
|
||||
units.emplace_back(qDegreesToRadians(1.0), DimensionTool::tr("rad"));
|
||||
|
||||
return units;
|
||||
}
|
||||
|
@@ -1,132 +1,132 @@
|
||||
// Copyright (C) 2020-2021 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/>.
|
||||
|
||||
#ifndef DIMENSIONTOOL_H
|
||||
#define DIMENSIONTOOL_H
|
||||
|
||||
#include "pdfwidgettool.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QPolygonF>
|
||||
|
||||
struct DimensionUnit;
|
||||
using DimensionUnits = std::vector<DimensionUnit>;
|
||||
|
||||
struct DimensionUnit
|
||||
{
|
||||
explicit inline DimensionUnit() = default;
|
||||
explicit inline DimensionUnit(pdf::PDFReal scale, QString symbol) :
|
||||
scale(scale),
|
||||
symbol(qMove(symbol))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pdf::PDFReal scale = 1.0;
|
||||
QString symbol;
|
||||
|
||||
static DimensionUnits getLengthUnits();
|
||||
static DimensionUnits getAreaUnits();
|
||||
static DimensionUnits getAngleUnits();
|
||||
};
|
||||
|
||||
class Dimension
|
||||
{
|
||||
public:
|
||||
|
||||
enum Type
|
||||
{
|
||||
Linear,
|
||||
Perimeter,
|
||||
Area,
|
||||
Angular
|
||||
};
|
||||
|
||||
inline explicit Dimension() = default;
|
||||
inline explicit Dimension(Type type, pdf::PDFInteger pageIndex, pdf::PDFReal measuredValue, std::vector<QPointF> polygon) :
|
||||
m_type(type),
|
||||
m_pageIndex(pageIndex),
|
||||
m_measuredValue(measuredValue),
|
||||
m_polygon(qMove(polygon))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Type getType() const { return m_type; }
|
||||
pdf::PDFInteger getPageIndex() const { return m_pageIndex; }
|
||||
pdf::PDFReal getMeasuredValue() const { return m_measuredValue; }
|
||||
const std::vector<QPointF>& getPolygon() const { return m_polygon; }
|
||||
|
||||
/// Returns true, if definition fo given type is complete
|
||||
static bool isComplete(Type type, const std::vector<QPointF>& polygon);
|
||||
|
||||
private:
|
||||
Type m_type = Linear;
|
||||
pdf::PDFInteger m_pageIndex = -1;
|
||||
pdf::PDFReal m_measuredValue = 0.0;
|
||||
std::vector<QPointF> m_polygon;
|
||||
};
|
||||
|
||||
class DimensionTool : public pdf::PDFWidgetTool
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = pdf::PDFWidgetTool;
|
||||
|
||||
public:
|
||||
|
||||
enum Style
|
||||
{
|
||||
LinearHorizontal,
|
||||
LinearVertical,
|
||||
Linear,
|
||||
Perimeter,
|
||||
RectanglePerimeter,
|
||||
Area,
|
||||
RectangleArea,
|
||||
Angle,
|
||||
LastStyle
|
||||
};
|
||||
|
||||
|
||||
explicit DimensionTool(Style style, pdf::PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent);
|
||||
|
||||
void drawPage(QPainter* painter,
|
||||
pdf::PDFInteger pageIndex,
|
||||
const pdf::PDFPrecompiledPage* compiledPage,
|
||||
pdf::PDFTextLayoutGetter& layoutGetter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
QList<pdf::PDFRenderError>& errors) const override;
|
||||
|
||||
signals:
|
||||
void dimensionCreated(Dimension dimension);
|
||||
|
||||
private:
|
||||
void onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint);
|
||||
void onRectanglePicked(pdf::PDFInteger pageIndex, QRectF pageRectangle);
|
||||
|
||||
QPointF adjustPagePoint(QPointF pagePoint) const;
|
||||
Dimension::Type getDimensionType() const;
|
||||
pdf::PDFReal getMeasuredValue(pdf::PDFInteger pageIndex, const std::vector<QPointF>& pickedPoints) const;
|
||||
|
||||
Style m_style;
|
||||
int m_previewPointPixelSize;
|
||||
pdf::PDFPickTool* m_pickTool;
|
||||
};
|
||||
|
||||
#endif // DIMENSIONTOOL_H
|
||||
// Copyright (C) 2020-2021 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/>.
|
||||
|
||||
#ifndef DIMENSIONTOOL_H
|
||||
#define DIMENSIONTOOL_H
|
||||
|
||||
#include "pdfwidgettool.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QPolygonF>
|
||||
|
||||
struct DimensionUnit;
|
||||
using DimensionUnits = std::vector<DimensionUnit>;
|
||||
|
||||
struct DimensionUnit
|
||||
{
|
||||
explicit inline DimensionUnit() = default;
|
||||
explicit inline DimensionUnit(pdf::PDFReal scale, QString symbol) :
|
||||
scale(scale),
|
||||
symbol(qMove(symbol))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pdf::PDFReal scale = 1.0;
|
||||
QString symbol;
|
||||
|
||||
static DimensionUnits getLengthUnits();
|
||||
static DimensionUnits getAreaUnits();
|
||||
static DimensionUnits getAngleUnits();
|
||||
};
|
||||
|
||||
class Dimension
|
||||
{
|
||||
public:
|
||||
|
||||
enum Type
|
||||
{
|
||||
Linear,
|
||||
Perimeter,
|
||||
Area,
|
||||
Angular
|
||||
};
|
||||
|
||||
inline explicit Dimension() = default;
|
||||
inline explicit Dimension(Type type, pdf::PDFInteger pageIndex, pdf::PDFReal measuredValue, std::vector<QPointF> polygon) :
|
||||
m_type(type),
|
||||
m_pageIndex(pageIndex),
|
||||
m_measuredValue(measuredValue),
|
||||
m_polygon(qMove(polygon))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Type getType() const { return m_type; }
|
||||
pdf::PDFInteger getPageIndex() const { return m_pageIndex; }
|
||||
pdf::PDFReal getMeasuredValue() const { return m_measuredValue; }
|
||||
const std::vector<QPointF>& getPolygon() const { return m_polygon; }
|
||||
|
||||
/// Returns true, if definition fo given type is complete
|
||||
static bool isComplete(Type type, const std::vector<QPointF>& polygon);
|
||||
|
||||
private:
|
||||
Type m_type = Linear;
|
||||
pdf::PDFInteger m_pageIndex = -1;
|
||||
pdf::PDFReal m_measuredValue = 0.0;
|
||||
std::vector<QPointF> m_polygon;
|
||||
};
|
||||
|
||||
class DimensionTool : public pdf::PDFWidgetTool
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = pdf::PDFWidgetTool;
|
||||
|
||||
public:
|
||||
|
||||
enum Style
|
||||
{
|
||||
LinearHorizontal,
|
||||
LinearVertical,
|
||||
Linear,
|
||||
Perimeter,
|
||||
RectanglePerimeter,
|
||||
Area,
|
||||
RectangleArea,
|
||||
Angle,
|
||||
LastStyle
|
||||
};
|
||||
|
||||
|
||||
explicit DimensionTool(Style style, pdf::PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent);
|
||||
|
||||
void drawPage(QPainter* painter,
|
||||
pdf::PDFInteger pageIndex,
|
||||
const pdf::PDFPrecompiledPage* compiledPage,
|
||||
pdf::PDFTextLayoutGetter& layoutGetter,
|
||||
const QMatrix& pagePointToDevicePointMatrix,
|
||||
QList<pdf::PDFRenderError>& errors) const override;
|
||||
|
||||
signals:
|
||||
void dimensionCreated(Dimension dimension);
|
||||
|
||||
private:
|
||||
void onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint);
|
||||
void onRectanglePicked(pdf::PDFInteger pageIndex, QRectF pageRectangle);
|
||||
|
||||
QPointF adjustPagePoint(QPointF pagePoint) const;
|
||||
Dimension::Type getDimensionType() const;
|
||||
pdf::PDFReal getMeasuredValue(pdf::PDFInteger pageIndex, const std::vector<QPointF>& pickedPoints) const;
|
||||
|
||||
Style m_style;
|
||||
int m_previewPointPixelSize;
|
||||
pdf::PDFPickTool* m_pickTool;
|
||||
};
|
||||
|
||||
#endif // DIMENSIONTOOL_H
|
||||
|
@@ -1,15 +1,15 @@
|
||||
<RCC>
|
||||
<qresource prefix="/pdfplugins/dimensiontool">
|
||||
<file>area.svg</file>
|
||||
<file>linear.svg</file>
|
||||
<file>linear-horizontal.svg</file>
|
||||
<file>linear-vertical.svg</file>
|
||||
<file>perimeter.svg</file>
|
||||
<file>clear-dimensions.svg</file>
|
||||
<file>settings.svg</file>
|
||||
<file>show-dimensions.svg</file>
|
||||
<file>angle.svg</file>
|
||||
<file>rectangle-area.svg</file>
|
||||
<file>rectangle-perimeter.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
<RCC>
|
||||
<qresource prefix="/pdfplugins/dimensiontool">
|
||||
<file>area.svg</file>
|
||||
<file>linear.svg</file>
|
||||
<file>linear-horizontal.svg</file>
|
||||
<file>linear-vertical.svg</file>
|
||||
<file>perimeter.svg</file>
|
||||
<file>clear-dimensions.svg</file>
|
||||
<file>settings.svg</file>
|
||||
<file>show-dimensions.svg</file>
|
||||
<file>angle.svg</file>
|
||||
<file>rectangle-area.svg</file>
|
||||
<file>rectangle-perimeter.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -1,66 +1,66 @@
|
||||
// Copyright (C) 2020-2021 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 "settingsdialog.h"
|
||||
#include "ui_settingsdialog.h"
|
||||
|
||||
#include "pdfwidgetutils.h"
|
||||
|
||||
SettingsDialog::SettingsDialog(QWidget* parent, DimensionUnit& lengthUnit, DimensionUnit& areaUnit, DimensionUnit& angleUnit) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::SettingsDialog),
|
||||
m_lengthUnit(lengthUnit),
|
||||
m_areaUnit(areaUnit),
|
||||
m_angleUnit(angleUnit)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_lengthUnits = DimensionUnit::getLengthUnits();
|
||||
m_areaUnits = DimensionUnit::getAreaUnits();
|
||||
m_angleUnits = DimensionUnit::getAngleUnits();
|
||||
|
||||
initComboBox(m_lengthUnits, m_lengthUnit, ui->lengthsComboBox);
|
||||
initComboBox(m_areaUnits, m_areaUnit, ui->areasComboBox);
|
||||
initComboBox(m_angleUnits, m_angleUnit, ui->anglesComboBox);
|
||||
|
||||
setMinimumSize(pdf::PDFWidgetUtils::scaleDPI(this, QSize(320, 160)));
|
||||
pdf::PDFWidgetUtils::style(this);
|
||||
}
|
||||
|
||||
SettingsDialog::~SettingsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void SettingsDialog::initComboBox(const DimensionUnits& units, const DimensionUnit& currentUnit, QComboBox* comboBox)
|
||||
{
|
||||
for (const DimensionUnit& unit : units)
|
||||
{
|
||||
comboBox->addItem(unit.symbol, unit.symbol);
|
||||
}
|
||||
|
||||
comboBox->setCurrentIndex(comboBox->findText(currentUnit.symbol));
|
||||
}
|
||||
|
||||
void SettingsDialog::accept()
|
||||
{
|
||||
m_lengthUnit = m_lengthUnits[ui->lengthsComboBox->currentIndex()];
|
||||
m_areaUnit = m_areaUnits[ui->areasComboBox->currentIndex()];
|
||||
m_angleUnit = m_angleUnits[ui->anglesComboBox->currentIndex()];
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
// Copyright (C) 2020-2021 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 "settingsdialog.h"
|
||||
#include "ui_settingsdialog.h"
|
||||
|
||||
#include "pdfwidgetutils.h"
|
||||
|
||||
SettingsDialog::SettingsDialog(QWidget* parent, DimensionUnit& lengthUnit, DimensionUnit& areaUnit, DimensionUnit& angleUnit) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::SettingsDialog),
|
||||
m_lengthUnit(lengthUnit),
|
||||
m_areaUnit(areaUnit),
|
||||
m_angleUnit(angleUnit)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_lengthUnits = DimensionUnit::getLengthUnits();
|
||||
m_areaUnits = DimensionUnit::getAreaUnits();
|
||||
m_angleUnits = DimensionUnit::getAngleUnits();
|
||||
|
||||
initComboBox(m_lengthUnits, m_lengthUnit, ui->lengthsComboBox);
|
||||
initComboBox(m_areaUnits, m_areaUnit, ui->areasComboBox);
|
||||
initComboBox(m_angleUnits, m_angleUnit, ui->anglesComboBox);
|
||||
|
||||
setMinimumSize(pdf::PDFWidgetUtils::scaleDPI(this, QSize(320, 160)));
|
||||
pdf::PDFWidgetUtils::style(this);
|
||||
}
|
||||
|
||||
SettingsDialog::~SettingsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void SettingsDialog::initComboBox(const DimensionUnits& units, const DimensionUnit& currentUnit, QComboBox* comboBox)
|
||||
{
|
||||
for (const DimensionUnit& unit : units)
|
||||
{
|
||||
comboBox->addItem(unit.symbol, unit.symbol);
|
||||
}
|
||||
|
||||
comboBox->setCurrentIndex(comboBox->findText(currentUnit.symbol));
|
||||
}
|
||||
|
||||
void SettingsDialog::accept()
|
||||
{
|
||||
m_lengthUnit = m_lengthUnits[ui->lengthsComboBox->currentIndex()];
|
||||
m_areaUnit = m_areaUnits[ui->areasComboBox->currentIndex()];
|
||||
m_angleUnit = m_angleUnits[ui->anglesComboBox->currentIndex()];
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
@@ -1,58 +1,58 @@
|
||||
// Copyright (C) 2020-2021 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/>.
|
||||
|
||||
#ifndef SETTINGSDIALOG_H
|
||||
#define SETTINGSDIALOG_H
|
||||
|
||||
#include "dimensiontool.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QComboBox;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class SettingsDialog;
|
||||
}
|
||||
|
||||
class SettingsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SettingsDialog(QWidget* parent,
|
||||
DimensionUnit& lengthUnit,
|
||||
DimensionUnit& areaUnit,
|
||||
DimensionUnit& angleUnit);
|
||||
virtual ~SettingsDialog() override;
|
||||
|
||||
virtual void accept() override;
|
||||
|
||||
private:
|
||||
Ui::SettingsDialog* ui;
|
||||
|
||||
void initComboBox(const DimensionUnits& units, const DimensionUnit& currentUnit, QComboBox* comboBox);
|
||||
|
||||
DimensionUnits m_lengthUnits;
|
||||
DimensionUnits m_areaUnits;
|
||||
DimensionUnits m_angleUnits;
|
||||
DimensionUnit& m_lengthUnit;
|
||||
DimensionUnit& m_areaUnit;
|
||||
DimensionUnit& m_angleUnit;
|
||||
};
|
||||
|
||||
#endif // SETTINGSDIALOG_H
|
||||
// Copyright (C) 2020-2021 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/>.
|
||||
|
||||
#ifndef SETTINGSDIALOG_H
|
||||
#define SETTINGSDIALOG_H
|
||||
|
||||
#include "dimensiontool.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QComboBox;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class SettingsDialog;
|
||||
}
|
||||
|
||||
class SettingsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SettingsDialog(QWidget* parent,
|
||||
DimensionUnit& lengthUnit,
|
||||
DimensionUnit& areaUnit,
|
||||
DimensionUnit& angleUnit);
|
||||
virtual ~SettingsDialog() override;
|
||||
|
||||
virtual void accept() override;
|
||||
|
||||
private:
|
||||
Ui::SettingsDialog* ui;
|
||||
|
||||
void initComboBox(const DimensionUnits& units, const DimensionUnit& currentUnit, QComboBox* comboBox);
|
||||
|
||||
DimensionUnits m_lengthUnits;
|
||||
DimensionUnits m_areaUnits;
|
||||
DimensionUnits m_angleUnits;
|
||||
DimensionUnit& m_lengthUnit;
|
||||
DimensionUnit& m_areaUnit;
|
||||
DimensionUnit& m_angleUnit;
|
||||
};
|
||||
|
||||
#endif // SETTINGSDIALOG_H
|
||||
|
@@ -1,103 +1,103 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SettingsDialog</class>
|
||||
<widget class="QDialog" name="SettingsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>254</width>
|
||||
<height>165</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Unit Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="unitsGroupBox">
|
||||
<property name="title">
|
||||
<string>Units</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lengthsLabel">
|
||||
<property name="text">
|
||||
<string>Lengths</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="lengthsComboBox"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="areasLabel">
|
||||
<property name="text">
|
||||
<string>Areas</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="areasComboBox"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="anglesLabel">
|
||||
<property name="text">
|
||||
<string>Angles</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="anglesComboBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>SettingsDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>SettingsDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SettingsDialog</class>
|
||||
<widget class="QDialog" name="SettingsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>254</width>
|
||||
<height>165</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Unit Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="unitsGroupBox">
|
||||
<property name="title">
|
||||
<string>Units</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lengthsLabel">
|
||||
<property name="text">
|
||||
<string>Lengths</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="lengthsComboBox"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="areasLabel">
|
||||
<property name="text">
|
||||
<string>Areas</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="areasComboBox"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="anglesLabel">
|
||||
<property name="text">
|
||||
<string>Angles</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="anglesComboBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>SettingsDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>SettingsDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
Reference in New Issue
Block a user