diff --git a/PdfForQtLib/PdfForQtLib.pro b/PdfForQtLib/PdfForQtLib.pro index bf7658a..571ddcc 100644 --- a/PdfForQtLib/PdfForQtLib.pro +++ b/PdfForQtLib/PdfForQtLib.pro @@ -56,9 +56,11 @@ SOURCES += \ sources/pdfpattern.cpp \ sources/pdfprogress.cpp \ sources/pdfsecurityhandler.cpp \ + sources/pdfsnapper.cpp \ sources/pdftextlayout.cpp \ sources/pdfutils.cpp \ sources/pdfwidgettool.cpp \ + sources/pdfwidgetutils.cpp \ sources/pdfxreftable.cpp \ sources/pdfvisitor.cpp \ sources/pdfencoding.cpp \ @@ -102,8 +104,10 @@ HEADERS += \ sources/pdfpattern.h \ sources/pdfprogress.h \ sources/pdfsecurityhandler.h \ + sources/pdfsnapper.h \ sources/pdftextlayout.h \ sources/pdfwidgettool.h \ + sources/pdfwidgetutils.h \ sources/pdfxreftable.h \ sources/pdfflatmap.h \ sources/pdfvisitor.h \ diff --git a/PdfForQtLib/sources/pdfpainter.cpp b/PdfForQtLib/sources/pdfpainter.cpp index f151b51..407abc8 100644 --- a/PdfForQtLib/sources/pdfpainter.cpp +++ b/PdfForQtLib/sources/pdfpainter.cpp @@ -402,6 +402,7 @@ PDFPrecompiledPageGenerator::PDFPrecompiledPageGenerator(PDFPrecompiledPage* pre m_precompiledPage(precompiledPage) { m_precompiledPage->setPaperColor(cms->getPaperColor()); + m_precompiledPage->getSnapInfo()->addPageMediaBox(page->getRotatedMediaBox()); } void PDFPrecompiledPageGenerator::performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule) @@ -428,6 +429,17 @@ void PDFPrecompiledPageGenerator::performImagePainting(const QImage& image) return; } + // Add snap info for image to the snapper + QMatrix matrix = getCurrentWorldMatrix(); + PDFSnapInfo* snapInfo = m_precompiledPage->getSnapInfo(); + snapInfo->addImage({ + matrix.map(QPointF(0.0, 0.0)), + matrix.map(QPointF(1.0, 0.0)), + matrix.map(QPointF(1.0, 1.0)), + matrix.map(QPointF(0.0, 1.0)), + matrix.map(QPointF(0.5, 0.5)), + }); + if (isTransparencyGroupActive()) { PDFReal alpha = getEffectiveFillingAlpha(); diff --git a/PdfForQtLib/sources/pdfpainter.h b/PdfForQtLib/sources/pdfpainter.h index f70c316..9460d84 100644 --- a/PdfForQtLib/sources/pdfpainter.h +++ b/PdfForQtLib/sources/pdfpainter.h @@ -23,6 +23,7 @@ #include "pdfrenderer.h" #include "pdfpagecontentprocessor.h" #include "pdftextlayout.h" +#include "pdfsnapper.h" #include #include @@ -223,6 +224,9 @@ public: QColor getPaperColor() const { return m_paperColor; } void setPaperColor(QColor paperColor) { m_paperColor = paperColor; } + PDFSnapInfo* getSnapInfo() { return &m_snapInfo; } + const PDFSnapInfo* getSnapInfo() const { return &m_snapInfo; } + private: struct PathPaintData { @@ -291,6 +295,7 @@ private: std::vector m_matrices; std::vector m_compositionModes; QList m_errors; + PDFSnapInfo m_snapInfo; }; /// Processor, which processes PDF's page commands and writes them to the precompiled page. diff --git a/PdfForQtLib/sources/pdfsnapper.cpp b/PdfForQtLib/sources/pdfsnapper.cpp new file mode 100644 index 0000000..5d74457 --- /dev/null +++ b/PdfForQtLib/sources/pdfsnapper.cpp @@ -0,0 +1,129 @@ +// Copyright (C) 2020 Jakub Melka +// +// This file is part of PdfForQt. +// +// PdfForQt 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 +// (at your option) any later version. +// +// PdfForQt 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 PDFForQt. If not, see . + +#include "pdfsnapper.h" +#include "pdfcompiler.h" +#include "pdfwidgetutils.h" + +#include + +namespace pdf +{ + +void PDFSnapInfo::addPageMediaBox(const QRectF& mediaBox) +{ + QPointF tl = mediaBox.topLeft(); + QPointF tr = mediaBox.topRight(); + QPointF bl = mediaBox.bottomLeft(); + QPointF br = mediaBox.bottomRight(); + QPointF center = mediaBox.center(); + + m_snapPoints.insert(m_snapPoints.cend(), { + SnapPoint(SnapType::PageCorner, tl ), + SnapPoint(SnapType::PageCorner, tr ), + SnapPoint(SnapType::PageCorner, bl ), + SnapPoint(SnapType::PageCorner, br ), + SnapPoint(SnapType::PageCenter, center) + }); + + addLine(tl, tr); + addLine(tr, br); + addLine(br, bl); + addLine(tl, bl); +} + +void PDFSnapInfo::addImage(const std::array& points) +{ + m_snapPoints.insert(m_snapPoints.cend(), { + SnapPoint(SnapType::ImageCorner, points[0]), + SnapPoint(SnapType::ImageCorner, points[1]), + SnapPoint(SnapType::ImageCorner, points[2]), + SnapPoint(SnapType::ImageCorner, points[3]), + SnapPoint(SnapType::ImageCenter, points[4]) + }); + + for (size_t i = 0; i < 4; ++i) + { + addLine(points[i], points[(i + 1) % 4]); + } +} + +void PDFSnapInfo::addLine(const QPointF& start, const QPointF& end) +{ + QLineF line(start, end); + m_snapPoints.emplace_back(SnapType::LineCenter, line.center()); + m_snapLines.emplace_back(line); +} + +PDFSnapper::PDFSnapper() +{ + +} + +void PDFSnapper::drawSnapPoints(QPainter* painter, PDFInteger pageIndex, const PDFPrecompiledPage* compiledPage, const QMatrix& pagePointToDevicePointMatrix) const +{ + if (m_currentPage != -1 && m_currentPage != pageIndex) + { + // We are drawing only snap points, which are on current page + return; + } + + Q_ASSERT(painter); + Q_ASSERT(compiledPage); + + const PDFSnapInfo* snapInfo = (m_currentPage != pageIndex) ? compiledPage->getSnapInfo() : &m_currentPageSnapInfo; + + painter->save(); + painter->setRenderHint(QPainter::Antialiasing, true); + + QPen pen = painter->pen(); + pen.setCapStyle(Qt::RoundCap); + pen.setWidth(PDFWidgetUtils::scaleDPI_x(painter->device(), 10)); + + for (const PDFSnapInfo::SnapPoint& snapPoint : snapInfo->getSnapPoints()) + { + QColor color = pen.color(); + QColor newColor = color; + switch (snapPoint.type) + { + case SnapType::PageCorner: + newColor = Qt::blue; + break; + + case SnapType::GeneratedLineProjection: + newColor = Qt::green; + break; + + default: + newColor = Qt::red; + break; + } + + if (color != newColor) + { + pen.setColor(newColor); + painter->setPen(pen); + } + + QPoint point = pagePointToDevicePointMatrix.map(snapPoint.point).toPoint(); + painter->drawPoint(point); + } + + painter->restore(); +} + +} // namespace pdf diff --git a/PdfForQtLib/sources/pdfsnapper.h b/PdfForQtLib/sources/pdfsnapper.h new file mode 100644 index 0000000..0e51f47 --- /dev/null +++ b/PdfForQtLib/sources/pdfsnapper.h @@ -0,0 +1,110 @@ +// Copyright (C) 2020 Jakub Melka +// +// This file is part of PdfForQt. +// +// PdfForQt 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 +// (at your option) any later version. +// +// PdfForQt 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 PDFForQt. If not, see . + +#ifndef PDFSNAPPER_H +#define PDFSNAPPER_H + +#include "pdfglobal.h" + +#include + +class QPainter; + +namespace pdf +{ +class PDFPrecompiledPage; + +enum class SnapType +{ + Invalid, + PageCorner, ///< Corner of the page media box + ImageCorner, ///< Corner of image + PageCenter, ///< Center of page media box + ImageCenter, ///< Center of image + LineCenter, ///< Center of line + GeneratedLineProjection ///< Generated point to line projections +}; + +/// Contain informations for snap points in the pdf page. Snap points +/// can be for example image centers, rectangle corners, line start/end +/// points, page boundary boxes etc. All coordinates are in page coordinates. +class PDFSnapInfo +{ +public: + explicit inline PDFSnapInfo() = default; + + struct SnapPoint + { + explicit inline constexpr SnapPoint() = default; + explicit inline constexpr SnapPoint(SnapType type, QPointF point) : + type(type), + point(point) + { + + } + + SnapType type = SnapType::Invalid; + QPointF point; + }; + + /// Adds page media box. Media box must be in page coordinates. + /// \param mediaBox Media box + void addPageMediaBox(const QRectF& mediaBox); + + /// Adds image box. Because it is not guaranteed, that it will be rectangle, five + /// points are defined - four corners and center. + /// \param points Four corner points in clockwise order, fifth point is center, + /// all in page coordinates. + void addImage(const std::array& points); + + /// Adds line and line center points + /// \param start Start point of line, in page coordinates + /// \param end End point of line, in page coordinates + void addLine(const QPointF& start, const QPointF& end); + + /// Returns snap points + const std::vector& getSnapPoints() const { return m_snapPoints; } + +private: + std::vector m_snapPoints; + std::vector m_snapLines; +}; + +/// Snap engine, which handles snapping of points on the page. +class PDFSnapper +{ +public: + PDFSnapper(); + + /// Draws snapping points onto the page + /// \param painter Painter + /// \param pageIndex Page index + /// \param compiledPage Compiled page + /// \param pagePointToDevicePointMatrix Matrix mapping page space to device point space + void drawSnapPoints(QPainter* painter, + pdf::PDFInteger pageIndex, + const PDFPrecompiledPage* compiledPage, + const QMatrix& pagePointToDevicePointMatrix) const; + +private: + PDFSnapInfo m_currentPageSnapInfo; + PDFInteger m_currentPage = -1; +}; + +} // namespace pdf + +#endif // PDFSNAPPER_H diff --git a/PdfForQtLib/sources/pdfwidgettool.cpp b/PdfForQtLib/sources/pdfwidgettool.cpp index f06c73f..cfc1851 100644 --- a/PdfForQtLib/sources/pdfwidgettool.cpp +++ b/PdfForQtLib/sources/pdfwidgettool.cpp @@ -59,18 +59,6 @@ PDFWidgetTool::~PDFWidgetTool() } -void PDFWidgetTool::drawPage(QPainter* painter, - PDFInteger pageIndex, - const PDFPrecompiledPage* compiledPage, - PDFTextLayoutGetter& layoutGetter, - const QMatrix& pagePointToDevicePointMatrix) const -{ - for (PDFWidgetTool* tool : m_toolStack) - { - tool->drawPage(painter, pageIndex, compiledPage, layoutGetter, pagePointToDevicePointMatrix); - } -} - void PDFWidgetTool::setDocument(const PDFDocument* document) { if (m_document != document) @@ -78,6 +66,12 @@ void PDFWidgetTool::setDocument(const PDFDocument* document) // We must turn off the tool, if we are changing the document setActive(false); m_document = document; + + for (PDFWidgetTool* tool : m_toolStack) + { + tool->setDocument(document); + } + updateActions(); } } @@ -107,37 +101,61 @@ void PDFWidgetTool::setActive(bool active) void PDFWidgetTool::keyPressEvent(QWidget* widget, QKeyEvent* event) { - Q_UNUSED(widget); - Q_UNUSED(event); + if (PDFWidgetTool* tool = getTopToolstackTool()) + { + tool->keyPressEvent(widget, event); + } } void PDFWidgetTool::mousePressEvent(QWidget* widget, QMouseEvent* event) { - Q_UNUSED(widget); - Q_UNUSED(event); + if (PDFWidgetTool* tool = getTopToolstackTool()) + { + tool->mousePressEvent(widget, event); + } } void PDFWidgetTool::mouseReleaseEvent(QWidget* widget, QMouseEvent* event) { - Q_UNUSED(widget); - Q_UNUSED(event); + if (PDFWidgetTool* tool = getTopToolstackTool()) + { + tool->mouseReleaseEvent(widget, event); + } } void PDFWidgetTool::mouseMoveEvent(QWidget* widget, QMouseEvent* event) { - Q_UNUSED(widget); - Q_UNUSED(event); + if (PDFWidgetTool* tool = getTopToolstackTool()) + { + tool->mouseMoveEvent(widget, event); + } } void PDFWidgetTool::wheelEvent(QWidget* widget, QWheelEvent* event) { - Q_UNUSED(widget); - Q_UNUSED(event); + if (PDFWidgetTool* tool = getTopToolstackTool()) + { + tool->wheelEvent(widget, event); + } +} + +const std::optional& PDFWidgetTool::getCursor() const +{ + // If we have active subtool, return its mouse cursor + if (PDFWidgetTool* tool = getTopToolstackTool()) + { + return tool->getCursor(); + } + + return m_cursor; } void PDFWidgetTool::setActiveImpl(bool active) { - Q_UNUSED(active); + for (PDFWidgetTool* tool : m_toolStack) + { + tool->setActive(active); + } } void PDFWidgetTool::updateActions() @@ -149,6 +167,26 @@ void PDFWidgetTool::updateActions() } } +PDFWidgetTool* PDFWidgetTool::getTopToolstackTool() const +{ + if (!m_toolStack.empty()) + { + return m_toolStack.back(); + } + + return nullptr; +} + +void PDFWidgetTool::addTool(PDFWidgetTool* tool) +{ + m_toolStack.push_back(tool); +} + +void PDFWidgetTool::removeTool() +{ + m_toolStack.pop_back(); +} + PDFFindTextTool::PDFFindTextTool(PDFDrawWidgetProxy* proxy, QAction* prevAction, QAction* nextAction, QObject* parent, QWidget* parentDialog) : BaseClass(proxy, parent), m_prevAction(prevAction), @@ -192,6 +230,8 @@ void PDFFindTextTool::clearResults() void PDFFindTextTool::setActiveImpl(bool active) { + BaseClass::setActiveImpl(active); + if (active) { Q_ASSERT(!m_dialog); @@ -561,6 +601,8 @@ void PDFSelectTextTool::mouseMoveEvent(QWidget* widget, QMouseEvent* event) void PDFSelectTextTool::setActiveImpl(bool active) { + BaseClass::setActiveImpl(active); + if (active) { pdf::PDFAsynchronousTextLayoutCompiler* compiler = getProxy()->getTextLayoutCompiler(); @@ -665,6 +707,7 @@ PDFToolManager::PDFToolManager(PDFDrawWidgetProxy* proxy, Actions actions, QObje m_predefinedTools[FindTextTool] = new PDFFindTextTool(proxy, actions.findPrevAction, actions.findNextAction, this, parentDialog); m_predefinedTools[SelectTextTool] = new PDFSelectTextTool(proxy, actions.selectTextToolAction, actions.copyTextAction, actions.selectAllAction, actions.deselectAction, this); m_predefinedTools[MagnifierTool] = new PDFMagnifierTool(proxy, actions.magnifierAction, this); + m_predefinedTools[ScreenshotTool] = new PDFScreenshotTool(proxy, actions.screenshotToolAction, this); for (PDFWidgetTool* tool : m_predefinedTools) { @@ -903,4 +946,71 @@ void PDFMagnifierTool::setMagnifierSize(int magnifierSize) m_magnifierSize = magnifierSize; } +PDFPickTool::PDFPickTool(PDFDrawWidgetProxy* proxy, PDFPickTool::Mode mode, QObject* parent) : + BaseClass(proxy, parent), + m_mode(mode) +{ + setCursor(Qt::BlankCursor); +} + +void PDFPickTool::drawPage(QPainter* painter, + PDFInteger pageIndex, + const PDFPrecompiledPage* compiledPage, + PDFTextLayoutGetter& layoutGetter, + const QMatrix& pagePointToDevicePointMatrix) const +{ + Q_UNUSED(layoutGetter); + + m_snapper.drawSnapPoints(painter, pageIndex, compiledPage, pagePointToDevicePointMatrix); +} + +void PDFPickTool::drawPostRendering(QPainter* painter, QRect rect) const +{ + QPoint hleft = m_mousePosition; + QPoint hright = m_mousePosition; + QPoint vtop = m_mousePosition; + QPoint vbottom = m_mousePosition; + + hleft.setX(0); + hright.setX(rect.width()); + vtop.setY(0); + vbottom.setY(rect.height()); + + painter->setPen(Qt::black); + painter->drawLine(hleft, hright); + painter->drawLine(vtop, vbottom); +} + +void PDFPickTool::mousePressEvent(QWidget* widget, QMouseEvent* event) +{ + Q_UNUSED(widget); + event->accept(); +} + +void PDFPickTool::mouseReleaseEvent(QWidget* widget, QMouseEvent* event) +{ + Q_UNUSED(widget); + event->accept(); +} + +void PDFPickTool::mouseMoveEvent(QWidget* widget, QMouseEvent* event) +{ + Q_UNUSED(widget); + event->accept(); + QPoint mousePos = event->pos(); + if (m_mousePosition != mousePos) + { + m_mousePosition = mousePos; + getProxy()->repaintNeeded(); + } +} + +PDFScreenshotTool::PDFScreenshotTool(PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent) : + BaseClass(proxy, action, parent), + m_pickTool(nullptr) +{ + m_pickTool = new PDFPickTool(proxy, PDFPickTool::Mode::Rectangles, this); + addTool(m_pickTool); +} + } // namespace pdf diff --git a/PdfForQtLib/sources/pdfwidgettool.h b/PdfForQtLib/sources/pdfwidgettool.h index 77864bf..93ee518 100644 --- a/PdfForQtLib/sources/pdfwidgettool.h +++ b/PdfForQtLib/sources/pdfwidgettool.h @@ -20,6 +20,7 @@ #include "pdfdrawspacecontroller.h" #include "pdftextlayout.h" +#include "pdfsnapper.h" #include #include @@ -44,12 +45,6 @@ public: explicit PDFWidgetTool(PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent); virtual ~PDFWidgetTool(); - virtual void drawPage(QPainter* painter, - PDFInteger pageIndex, - const PDFPrecompiledPage* compiledPage, - PDFTextLayoutGetter& layoutGetter, - const QMatrix& pagePointToDevicePointMatrix) const override; - /// Sets document, shuts down the tool, if it is active, and document /// is changing. /// \param document Document @@ -93,7 +88,7 @@ public: /// Returns actual cursor defined by the tool. Cursor can be undefined, /// in this case, optional will be set to nullopt. - const std::optional& getCursor() const { return m_cursor; } + const std::optional& getCursor() const; signals: void toolActivityChanged(bool active); @@ -102,12 +97,19 @@ protected: virtual void setActiveImpl(bool active); virtual void updateActions(); + /// Returns currently active tool from toolstack, + /// or nullptr, if no active tool from toolstack exists. + PDFWidgetTool* getTopToolstackTool() const; + const PDFDocument* getDocument() const { return m_document; } PDFDrawWidgetProxy* getProxy() const { return m_proxy; } inline void setCursor(QCursor cursor) { m_cursor = qMove(cursor); } inline void unsetCursor() { m_cursor = std::nullopt; } + void addTool(PDFWidgetTool* tool); + void removeTool(); + private: bool m_active; const PDFDocument* m_document; @@ -271,6 +273,60 @@ private: PDFReal m_magnifierZoom; }; +/// Tools for picking various items on page - points, rectangles, images etc. +class PDFFORQTLIBSHARED_EXPORT PDFPickTool : public PDFWidgetTool +{ + Q_OBJECT + +private: + using BaseClass = PDFWidgetTool; + +public: + + enum class Mode + { + Points, ///< Pick points + Rectangles, ///< Pick rectangles + Images ///< Pick images + }; + + /// Constructs new picking tool + /// \param proxy Draw widget proxy + /// \param mode Picking mode + /// \param parent Parent object + explicit PDFPickTool(PDFDrawWidgetProxy* proxy, Mode mode, QObject* parent); + + virtual void drawPage(QPainter* painter, PDFInteger pageIndex, const PDFPrecompiledPage* compiledPage, PDFTextLayoutGetter& layoutGetter, const QMatrix& pagePointToDevicePointMatrix) const override; + virtual void drawPostRendering(QPainter* painter, QRect rect) const override; + virtual void mousePressEvent(QWidget* widget, QMouseEvent* event) override; + virtual void mouseReleaseEvent(QWidget* widget, QMouseEvent* event) override; + virtual void mouseMoveEvent(QWidget* widget, QMouseEvent* event) override; + +private: + Mode m_mode; + PDFSnapper m_snapper; + QPoint m_mousePosition; +}; + +/// Tool that makes screenshot of page area and copies it to the clipboard +class PDFFORQTLIBSHARED_EXPORT PDFScreenshotTool : public PDFWidgetTool +{ + Q_OBJECT + +private: + using BaseClass = PDFWidgetTool; + +public: + /// Constructs new screenshot tool + /// \param proxy Draw widget proxy + /// \param action Tool activation action + /// \param parent Parent object + explicit PDFScreenshotTool(PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent); + +private: + PDFPickTool* m_pickTool; +}; + /// Manager used for managing tools, their activity, availability /// and other settings. It also defines a predefined set of tools, /// available for various purposes (text searching, magnifier tool etc.) @@ -291,6 +347,7 @@ public: QAction* deselectAction = nullptr; QAction* copyTextAction = nullptr; QAction* magnifierAction = nullptr; + QAction* screenshotToolAction = nullptr; }; /// Construct new text search tool @@ -309,6 +366,7 @@ public: FindTextTool, SelectTextTool, MagnifierTool, + ScreenshotTool, ToolEnd }; diff --git a/PdfForQtViewer/pdfwidgetutils.cpp b/PdfForQtLib/sources/pdfwidgetutils.cpp similarity index 76% rename from PdfForQtViewer/pdfwidgetutils.cpp rename to PdfForQtLib/sources/pdfwidgetutils.cpp index 5e90a91..faef5e3 100644 --- a/PdfForQtViewer/pdfwidgetutils.cpp +++ b/PdfForQtLib/sources/pdfwidgetutils.cpp @@ -25,27 +25,27 @@ int qt_default_dpi_x() { return 96; } int qt_default_dpi_y() { return 96; } #endif -namespace pdfviewer +namespace pdf { -int PDFWidgetUtils::getPixelSize(QWidget* widget, pdf::PDFReal sizeMM) +int PDFWidgetUtils::getPixelSize(QPaintDevice* device, pdf::PDFReal sizeMM) { - const int width = widget->width(); - const int height = widget->height(); + const int width = device->width(); + const int height = device->height(); if (width > height) { - return pdf::PDFReal(width) * sizeMM / pdf::PDFReal(widget->widthMM()); + return PDFReal(width) * sizeMM / PDFReal(device->widthMM()); } else { - return pdf::PDFReal(height) * sizeMM / pdf::PDFReal(widget->heightMM()); + return PDFReal(height) * sizeMM / PDFReal(device->heightMM()); } } -int PDFWidgetUtils::scaleDPI_x(QWidget* widget, int unscaledSize) +int PDFWidgetUtils::scaleDPI_x(QPaintDevice* device, int unscaledSize) { - const double logicalDPI_x = widget->logicalDpiX(); + const double logicalDPI_x = device->logicalDpiX(); const double defaultDPI_x = qt_default_dpi_x(); return (logicalDPI_x / defaultDPI_x) * unscaledSize; } @@ -63,7 +63,7 @@ void PDFWidgetUtils::scaleWidget(QWidget* widget, QSize unscaledSize) widget->resize(width, height); } -QSize PDFWidgetUtils::scaleDPI(QWidget* widget, QSize unscaledSize) +QSize PDFWidgetUtils::scaleDPI(QPaintDevice* widget, QSize unscaledSize) { const double logicalDPI_x = widget->logicalDpiX(); const double logicalDPI_y = widget->logicalDpiY(); @@ -76,4 +76,4 @@ QSize PDFWidgetUtils::scaleDPI(QWidget* widget, QSize unscaledSize) return QSize(width, height); } -} // namespace pdfviewer +} // namespace pdf diff --git a/PdfForQtViewer/pdfwidgetutils.h b/PdfForQtLib/sources/pdfwidgetutils.h similarity index 73% rename from PdfForQtViewer/pdfwidgetutils.h rename to PdfForQtLib/sources/pdfwidgetutils.h index b413e16..72bf3d2 100644 --- a/PdfForQtViewer/pdfwidgetutils.h +++ b/PdfForQtLib/sources/pdfwidgetutils.h @@ -22,19 +22,20 @@ #include -namespace pdfviewer +namespace pdf { -class PDFWidgetUtils +class PDFFORQTLIBSHARED_EXPORT PDFWidgetUtils { public: PDFWidgetUtils() = delete; /// Converts size in MM to pixel size - static int getPixelSize(QWidget* widget, pdf::PDFReal sizeMM); + static int getPixelSize(QPaintDevice* device, pdf::PDFReal sizeMM); /// Scale horizontal DPI value - static int scaleDPI_x(QWidget* widget, int unscaledSize); + /// \param device Paint device to obtain logical DPI for scaling + static int scaleDPI_x(QPaintDevice* device, int unscaledSize); /// Scales widget based on DPI /// \param widget Widget to be scaled @@ -42,11 +43,11 @@ public: static void scaleWidget(QWidget* widget, QSize unscaledSize); /// Scales size based on DPI - /// \param widget Widget, from which we get DPI + /// \param device Paint device to obtain logical DPI for scaling /// \param unscaledSize Unscaled size - static QSize scaleDPI(QWidget* widget, QSize unscaledSize); + static QSize scaleDPI(QPaintDevice* widget, QSize unscaledSize); }; -} // namespace pdfviewer +} // namespace pdf #endif // PDFWIDGETUTILS_H diff --git a/PdfForQtViewer/PdfForQtViewer.pro b/PdfForQtViewer/PdfForQtViewer.pro index fecc47f..f2641f5 100644 --- a/PdfForQtViewer/PdfForQtViewer.pro +++ b/PdfForQtViewer/PdfForQtViewer.pro @@ -44,8 +44,7 @@ SOURCES += \ pdftexttospeech.cpp \ pdfviewermainwindow.cpp \ pdfviewersettings.cpp \ - pdfviewersettingsdialog.cpp \ - pdfwidgetutils.cpp + pdfviewersettingsdialog.cpp HEADERS += \ pdfaboutdialog.h \ @@ -58,8 +57,7 @@ HEADERS += \ pdftexttospeech.h \ pdfviewermainwindow.h \ pdfviewersettings.h \ - pdfviewersettingsdialog.h \ - pdfwidgetutils.h + pdfviewersettingsdialog.h FORMS += \ pdfaboutdialog.ui \ diff --git a/PdfForQtViewer/pdfaboutdialog.cpp b/PdfForQtViewer/pdfaboutdialog.cpp index 0ac8b0a..501169a 100644 --- a/PdfForQtViewer/pdfaboutdialog.cpp +++ b/PdfForQtViewer/pdfaboutdialog.cpp @@ -48,7 +48,7 @@ PDFAboutDialog::PDFAboutDialog(QWidget* parent) : ui->tableWidget->setItem(i, 3, new QTableWidgetItem(info.url)); } - PDFWidgetUtils::scaleWidget(this, QSize(750, 600)); + pdf::PDFWidgetUtils::scaleWidget(this, QSize(750, 600)); } PDFAboutDialog::~PDFAboutDialog() diff --git a/PdfForQtViewer/pdfdocumentpropertiesdialog.cpp b/PdfForQtViewer/pdfdocumentpropertiesdialog.cpp index 84d2542..322b849 100644 --- a/PdfForQtViewer/pdfdocumentpropertiesdialog.cpp +++ b/PdfForQtViewer/pdfdocumentpropertiesdialog.cpp @@ -48,13 +48,13 @@ PDFDocumentPropertiesDialog::PDFDocumentPropertiesDialog(const pdf::PDFDocument* initializeFonts(document); initializeDisplayAndPrintSettings(document); - const int minimumSectionSize = PDFWidgetUtils::scaleDPI_x(this, 300); + const int minimumSectionSize = pdf::PDFWidgetUtils::scaleDPI_x(this, 300); for (QTreeWidget* widget : findChildren(QString(), Qt::FindChildrenRecursively)) { widget->header()->setMinimumSectionSize(minimumSectionSize); } - PDFWidgetUtils::scaleWidget(this, QSize(750, 600)); + pdf::PDFWidgetUtils::scaleWidget(this, QSize(750, 600)); } PDFDocumentPropertiesDialog::~PDFDocumentPropertiesDialog() diff --git a/PdfForQtViewer/pdfforqtviewer.qrc b/PdfForQtViewer/pdfforqtviewer.qrc index 5ccd23e..809024c 100644 --- a/PdfForQtViewer/pdfforqtviewer.qrc +++ b/PdfForQtViewer/pdfforqtviewer.qrc @@ -41,5 +41,6 @@ resources/play.svg resources/stop.svg resources/magnifier.svg + resources/screenshot-tool.svg diff --git a/PdfForQtViewer/pdfrendertoimagesdialog.cpp b/PdfForQtViewer/pdfrendertoimagesdialog.cpp index 13236bf..f9c1e49 100644 --- a/PdfForQtViewer/pdfrendertoimagesdialog.cpp +++ b/PdfForQtViewer/pdfrendertoimagesdialog.cpp @@ -80,7 +80,7 @@ PDFRenderToImagesDialog::PDFRenderToImagesDialog(const pdf::PDFDocument* documen loadImageWriterSettings(); loadImageExportSettings(); - PDFWidgetUtils::scaleWidget(this, QSize(1000, 600)); + pdf::PDFWidgetUtils::scaleWidget(this, QSize(1000, 600)); } PDFRenderToImagesDialog::~PDFRenderToImagesDialog() diff --git a/PdfForQtViewer/pdfsidebarwidget.cpp b/PdfForQtViewer/pdfsidebarwidget.cpp index 231ddfa..aace4af 100644 --- a/PdfForQtViewer/pdfsidebarwidget.cpp +++ b/PdfForQtViewer/pdfsidebarwidget.cpp @@ -356,7 +356,7 @@ void PDFSidebarWidget::onOutlineItemClicked(const QModelIndex& index) void PDFSidebarWidget::onThumbnailsSizeChanged(int size) { - const int thumbnailsSize = PDFWidgetUtils::getPixelSize(this, size * 10.0); + const int thumbnailsSize = pdf::PDFWidgetUtils::getPixelSize(this, size * 10.0); Q_ASSERT(thumbnailsSize > 0); m_thumbnailsModel->setThumbnailsSize(thumbnailsSize); } diff --git a/PdfForQtViewer/pdfviewermainwindow.cpp b/PdfForQtViewer/pdfviewermainwindow.cpp index cb6cc38..0eb0cd6 100644 --- a/PdfForQtViewer/pdfviewermainwindow.cpp +++ b/PdfForQtViewer/pdfviewermainwindow.cpp @@ -94,7 +94,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) : ui->setupUi(this); // Initialize toolbar icon size - QSize iconSize = PDFWidgetUtils::scaleDPI(this, QSize(24, 24)); + QSize iconSize = pdf::PDFWidgetUtils::scaleDPI(this, QSize(24, 24)); ui->mainToolBar->setIconSize(iconSize); // Initialize task bar progress @@ -190,6 +190,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) : // Tools ui->mainToolBar->addAction(ui->actionSelectText); ui->mainToolBar->addAction(ui->actionMagnifier); + ui->mainToolBar->addAction(ui->actionScreenshot); connect(ui->actionZoom_In, &QAction::triggered, this, [this] { m_pdfWidget->getDrawWidgetProxy()->performOperation(pdf::PDFDrawWidgetProxy::ZoomIn); }); connect(ui->actionZoom_Out, &QAction::triggered, this, [this] { m_pdfWidget->getDrawWidgetProxy()->performOperation(pdf::PDFDrawWidgetProxy::ZoomOut); }); @@ -253,6 +254,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) : actions.deselectAction = ui->actionDeselectText; actions.copyTextAction = ui->actionCopyText; actions.magnifierAction = ui->actionMagnifier; + actions.screenshotToolAction = ui->actionScreenshot; m_toolManager = new pdf::PDFToolManager(m_pdfWidget->getDrawWidgetProxy(), actions, this, this); m_pdfWidget->setToolManager(m_toolManager); updateMagnifierToolSettings(); @@ -1129,7 +1131,7 @@ void PDFViewerMainWindow::on_actionRendering_Errors_triggered() void PDFViewerMainWindow::updateMagnifierToolSettings() { pdf::PDFMagnifierTool* magnifierTool = m_toolManager->getMagnifierTool(); - magnifierTool->setMagnifierSize(PDFWidgetUtils::scaleDPI_x(this, m_settings->getSettings().m_magnifierSize)); + magnifierTool->setMagnifierSize(pdf::PDFWidgetUtils::scaleDPI_x(this, m_settings->getSettings().m_magnifierSize)); magnifierTool->setMagnifierZoom(m_settings->getSettings().m_magnifierZoom); } diff --git a/PdfForQtViewer/pdfviewermainwindow.ui b/PdfForQtViewer/pdfviewermainwindow.ui index 16794fe..93fb3b2 100644 --- a/PdfForQtViewer/pdfviewermainwindow.ui +++ b/PdfForQtViewer/pdfviewermainwindow.ui @@ -87,6 +87,7 @@ Tools + @@ -473,6 +474,18 @@ Magnifier Tool + + + true + + + + :/resources/screenshot-tool.svg:/resources/screenshot-tool.svg + + + Screenshot + + diff --git a/PdfForQtViewer/resources/screenshot-tool.svg b/PdfForQtViewer/resources/screenshot-tool.svg new file mode 100644 index 0000000..a4ed576 --- /dev/null +++ b/PdfForQtViewer/resources/screenshot-tool.svg @@ -0,0 +1,135 @@ + + + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + +