diff --git a/PdfForQtLib/PdfForQtLib.pro b/PdfForQtLib/PdfForQtLib.pro index 6f1da5f..bd46135 100644 --- a/PdfForQtLib/PdfForQtLib.pro +++ b/PdfForQtLib/PdfForQtLib.pro @@ -224,7 +224,8 @@ qt_libraries.files = $$[QT_INSTALL_BINS]/Qt?Widgets$${SUFFIX}.dll \ $$[QT_INSTALL_BINS]/Qt?Gui$${SUFFIX}.dll \ $$[QT_INSTALL_BINS]/Qt?Core$${SUFFIX}.dll \ $$[QT_INSTALL_BINS]/Qt?WinExtras$${SUFFIX}.dll \ - $$[QT_INSTALL_BINS]/Qt?Svg$${SUFFIX}.dll + $$[QT_INSTALL_BINS]/Qt?Svg$${SUFFIX}.dll \ + $$[QT_INSTALL_BINS]/Qt?PrintSupport$${SUFFIX}.dll qt_libraries.path = $$DESTDIR/install INSTALLS += qt_libraries @@ -235,3 +236,7 @@ INSTALLS += qt_plugin_platform qt_plugin_iconengine.files = $$[QT_INSTALL_PLUGINS]/iconengines/qsvgicon$${SUFFIX}.dll qt_plugin_iconengine.path = $$DESTDIR/install/iconengines INSTALLS += qt_plugin_iconengine + +qt_plugin_printsupport.files = $$[QT_INSTALL_PLUGINS]/printsupport/windowsprintersupport$${SUFFIX}.dll +qt_plugin_printsupport.path = $$DESTDIR/install/printsupport +INSTALLS += qt_plugin_printsupport diff --git a/PdfForQtLib/sources/pdfrenderer.h b/PdfForQtLib/sources/pdfrenderer.h index 556d045..034eb85 100644 --- a/PdfForQtLib/sources/pdfrenderer.h +++ b/PdfForQtLib/sources/pdfrenderer.h @@ -37,7 +37,7 @@ class PDFPrecompiledPage; class PDFOptionalContentActivity; /// Renders the PDF page on the painter, or onto an image. -class PDFRenderer +class PDFFORQTLIBSHARED_EXPORT PDFRenderer { public: diff --git a/PdfForQtViewer/PdfForQtViewer.pro b/PdfForQtViewer/PdfForQtViewer.pro index a30df1c..0e95fdf 100644 --- a/PdfForQtViewer/PdfForQtViewer.pro +++ b/PdfForQtViewer/PdfForQtViewer.pro @@ -4,7 +4,7 @@ # #------------------------------------------------- -QT += core gui winextras +QT += core gui winextras printsupport greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/PdfForQtViewer/pdfforqtviewer.qrc b/PdfForQtViewer/pdfforqtviewer.qrc index a1088ca..9d30a24 100644 --- a/PdfForQtViewer/pdfforqtviewer.qrc +++ b/PdfForQtViewer/pdfforqtviewer.qrc @@ -35,5 +35,6 @@ resources/ui.svg resources/rotate-left.svg resources/rotate-right.svg + resources/print.svg diff --git a/PdfForQtViewer/pdfviewermainwindow.cpp b/PdfForQtViewer/pdfviewermainwindow.cpp index 376a19d..664cd8d 100644 --- a/PdfForQtViewer/pdfviewermainwindow.cpp +++ b/PdfForQtViewer/pdfviewermainwindow.cpp @@ -37,6 +37,7 @@ #include "pdfexecutionpolicy.h" #include "pdfwidgetutils.h" +#include #include #include #include @@ -53,6 +54,8 @@ #include #include #include +#include +#include #include #ifdef Q_OS_WIN @@ -109,6 +112,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) : ui->actionCopyText->setShortcut(QKeySequence::Copy); ui->actionRotateRight->setShortcut(QKeySequence("Ctrl+Shift++")); ui->actionRotateLeft->setShortcut(QKeySequence("Ctrl+Shift+-")); + ui->actionPrint->setShortcut(QKeySequence::Print); for (QAction* action : m_recentFileManager->getActions()) { @@ -806,6 +810,14 @@ void PDFViewerMainWindow::updateActionsAvailability() const bool isBusy = m_futureWatcher.isRunning() || m_isBusy; const bool hasDocument = m_pdfDocument; const bool hasValidDocument = !isBusy && hasDocument; + bool canPrint = false; + if (m_pdfDocument) + { + const pdf::PDFObjectStorage& storage = m_pdfDocument->getStorage(); + const pdf::PDFSecurityHandler* securityHandler = storage.getSecurityHandler(); + canPrint = securityHandler->isAllowed(pdf::PDFSecurityHandler::Permission::PrintLowResolution) || + securityHandler->isAllowed(pdf::PDFSecurityHandler::Permission::PrintHighResolution); + } ui->actionOpen->setEnabled(!isBusy); ui->actionClose->setEnabled(hasValidDocument); @@ -817,6 +829,7 @@ void PDFViewerMainWindow::updateActionsAvailability() ui->actionFitHeight->setEnabled(hasValidDocument); ui->actionRendering_Errors->setEnabled(hasValidDocument); ui->actionFind->setEnabled(hasValidDocument); + ui->actionPrint->setEnabled(hasValidDocument && canPrint); setEnabled(!isBusy); } @@ -1158,4 +1171,109 @@ void PDFViewerMainWindow::on_actionRotateLeft_triggered() m_pdfWidget->getDrawWidgetProxy()->performOperation(pdf::PDFDrawWidgetProxy::RotateLeft); } +void PDFViewerMainWindow::on_actionPrint_triggered() +{ + // Are we allowed to print in high resolution? If yes, then print in high resolution, + // otherwise print in low resolution. If this action is triggered, then print operation + // should be allowed (at least print in low resolution). + const pdf::PDFObjectStorage& storage = m_pdfDocument->getStorage(); + const pdf::PDFSecurityHandler* securityHandler = storage.getSecurityHandler(); + QPrinter::PrinterMode printerMode = QPrinter::HighResolution; + if (!securityHandler->isAllowed(pdf::PDFSecurityHandler::Permission::PrintHighResolution)) + { + printerMode = QPrinter::ScreenResolution; + } + + // Run print dialog + QPrinter printer(printerMode); + QPrintDialog printDialog(&printer, this); + printDialog.setOptions(QPrintDialog::PrintPageRange | QPrintDialog::PrintShowPageSize | QPrintDialog::PrintCollateCopies | QPrintDialog::PrintSelection); + printDialog.setOption(QPrintDialog::PrintCurrentPage, m_pdfWidget->getDrawWidget()->getCurrentPages().size() == 1); + printDialog.setMinMax(1, int(m_pdfDocument->getCatalog()->getPageCount())); + if (printDialog.exec() == QPrintDialog::Accepted) + { + std::vector pageIndices; + switch (printDialog.printRange()) + { + case QAbstractPrintDialog::AllPages: + { + pageIndices.resize(m_pdfDocument->getCatalog()->getPageCount(), 0); + std::iota(pageIndices.begin(), pageIndices.end(), 0); + break; + } + + case QAbstractPrintDialog::Selection: + case QAbstractPrintDialog::CurrentPage: + { + pageIndices = m_pdfWidget->getDrawWidget()->getCurrentPages(); + break; + } + + case QAbstractPrintDialog::PageRange: + { + const pdf::PDFInteger fromPage = printDialog.fromPage(); + const pdf::PDFInteger toPage = printDialog.toPage(); + const pdf::PDFInteger pageCount = toPage - fromPage + 1; + if (pageCount > 0) + { + pageIndices.resize(pageCount, 0); + std::iota(pageIndices.begin(), pageIndices.end(), fromPage - 1); + } + break; + } + + default: + Q_ASSERT(false); + break; + } + + if (pageIndices.empty()) + { + // Nothing to be printed + return; + } + + pdf::ProgressStartupInfo info; + info.showDialog = true; + info.text = tr("Printing document"); + m_progress->start(pageIndices.size(), qMove(info)); + printer.setFullPage(true); + QPainter painter(&printer); + + const pdf::PDFCatalog* catalog = m_pdfDocument->getCatalog(); + pdf::PDFDrawWidgetProxy* proxy = m_pdfWidget->getDrawWidgetProxy(); + pdf::PDFOptionalContentActivity optionalContentActivity(m_pdfDocument.data(), pdf::OCUsage::Print, nullptr); + pdf::PDFCMSPointer cms = proxy->getCMSManager()->getCurrentCMS(); + pdf::PDFRenderer renderer(m_pdfDocument.get(), proxy->getFontCache(), cms.data(), &optionalContentActivity, proxy->getFeatures(), proxy->getMeshQualitySettings()); + + const pdf::PDFInteger lastPage = pageIndices.back(); + for (const pdf::PDFInteger pageIndex : pageIndices) + { + const pdf::PDFPage* page = catalog->getPage(pageIndex); + Q_ASSERT(page); + + QRectF mediaBox = page->getRotatedMediaBox(); + QRectF paperRect = printer.paperRect(); + QSizeF scaledSize = mediaBox.size().scaled(paperRect.size(), Qt::KeepAspectRatio); + mediaBox.setSize(scaledSize); + mediaBox.moveCenter(paperRect.center()); + + renderer.render(&painter, mediaBox, pageIndex); + m_progress->step(); + + if (pageIndex != lastPage) + { + if (!printer.newPage()) + { + break; + } + } + } + + painter.end(); + m_progress->finish(); + } +} + } // namespace pdfviewer + diff --git a/PdfForQtViewer/pdfviewermainwindow.h b/PdfForQtViewer/pdfviewermainwindow.h index 2b6c21e..838f111 100644 --- a/PdfForQtViewer/pdfviewermainwindow.h +++ b/PdfForQtViewer/pdfviewermainwindow.h @@ -96,6 +96,8 @@ private slots: void on_actionRotateLeft_triggered(); + void on_actionPrint_triggered(); + private: void onActionOpenTriggered(); void onActionCloseTriggered(); diff --git a/PdfForQtViewer/pdfviewermainwindow.ui b/PdfForQtViewer/pdfviewermainwindow.ui index 5fc6a17..73fef20 100644 --- a/PdfForQtViewer/pdfviewermainwindow.ui +++ b/PdfForQtViewer/pdfviewermainwindow.ui @@ -31,6 +31,7 @@ + @@ -440,6 +441,15 @@ Rotate Left + + + + :/resources/print.svg:/resources/print.svg + + + Print + + diff --git a/PdfForQtViewer/resources/print.svg b/PdfForQtViewer/resources/print.svg new file mode 100644 index 0000000..caa7fad --- /dev/null +++ b/PdfForQtViewer/resources/print.svg @@ -0,0 +1,114 @@ + + + + + + + + + + image/svg+xml + + + + + Jakub Melka + + + + + + + + + + + + + + + + + + + + + +