File indexing completed on 2025-01-19 03:51:10
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2009-02-06 0007 * Description : image editor printing interface. 0008 * 0009 * SPDX-FileCopyrightText: 2009 by Angelo Naselli <anaselli at linux dot it> 0010 * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "printhelper.h" 0017 0018 // C++ includes 0019 0020 #include <memory> 0021 0022 // Qt includes 0023 0024 #include <QWidget> 0025 #include <QCheckBox> 0026 #include <QPainter> 0027 #include <QPrinter> 0028 #include <QPrinterInfo> 0029 #include <QPrintDialog> 0030 #include <QMessageBox> 0031 0032 // KDE includes 0033 0034 #include <klocalizedstring.h> 0035 0036 // Local includes 0037 0038 #include "printoptionspage.h" 0039 #include "iccmanager.h" 0040 0041 namespace DigikamEditorPrintToolPlugin 0042 { 0043 0044 class Q_DECL_HIDDEN PrintHelper::Private 0045 { 0046 0047 public: 0048 0049 explicit Private() 0050 : parent(nullptr) 0051 { 0052 } 0053 0054 QWidget* parent; 0055 0056 public: 0057 0058 QSize adjustSize(PrintOptionsPage* const optionsPage, 0059 const DImg& doc, 0060 int printerResolution, 0061 const QSize& viewportSize) 0062 { 0063 QSize size = doc.size(); 0064 PrintOptionsPage::ScaleMode scaleMode = optionsPage->scaleMode(); 0065 0066 if (scaleMode == PrintOptionsPage::ScaleToPage) 0067 { 0068 bool imageBiggerThanPaper = (size.width() > viewportSize.width()) || 0069 (size.height() > viewportSize.height()); 0070 0071 if (imageBiggerThanPaper || optionsPage->enlargeSmallerImages()) 0072 { 0073 size.scale(viewportSize, Qt::KeepAspectRatio); 0074 } 0075 0076 } 0077 else if (scaleMode == PrintOptionsPage::ScaleToCustomSize) 0078 { 0079 double wImg = optionsPage->scaleWidth(); 0080 double hImg = optionsPage->scaleHeight(); 0081 size.setWidth(int (wImg * printerResolution)); 0082 size.setHeight(int (hImg * printerResolution)); 0083 } 0084 else 0085 { 0086 // No scale 0087 0088 const double INCHES_PER_METER = 100. / 2.54; 0089 QImage img = doc.copyQImage(); 0090 int dpmX = img.dotsPerMeterX(); 0091 int dpmY = img.dotsPerMeterY(); 0092 0093 if ((dpmX > 0) && (dpmY > 0)) 0094 { 0095 double wImg = double(size.width()) / double(dpmX) * INCHES_PER_METER; 0096 double hImg = double(size.height()) / double(dpmY) * INCHES_PER_METER; 0097 size.setWidth(int (wImg * printerResolution)); 0098 size.setHeight(int (hImg * printerResolution)); 0099 } 0100 } 0101 0102 return size; 0103 } 0104 0105 QPoint adjustPosition(PrintOptionsPage* const optionsPage, 0106 const QSize& imageSize, 0107 const QSize& viewportSize) 0108 { 0109 Qt::Alignment alignment = optionsPage->alignment(); 0110 int posX; 0111 int posY; 0112 0113 if (alignment & Qt::AlignLeft) 0114 { 0115 posX = 0; 0116 } 0117 else if (alignment & Qt::AlignHCenter) 0118 { 0119 posX = (viewportSize.width() - imageSize.width()) / 2; 0120 } 0121 else 0122 { 0123 posX = viewportSize.width() - imageSize.width(); 0124 } 0125 0126 if (alignment & Qt::AlignTop) 0127 { 0128 posY = 0; 0129 } 0130 else if (alignment & Qt::AlignVCenter) 0131 { 0132 posY = (viewportSize.height() - imageSize.height()) / 2; 0133 } 0134 else 0135 { 0136 posY = viewportSize.height() - imageSize.height(); 0137 } 0138 0139 return QPoint(posX, posY); 0140 } 0141 0142 void adjustImage(PrintOptionsPage* const optionsPage, 0143 const DImg& img) 0144 { 0145 if (optionsPage->colorManaged()) 0146 { 0147 IccManager manager(img); 0148 manager.transformForOutput(optionsPage->outputProfile()); 0149 } 0150 } 0151 }; 0152 0153 // ------------------------------------------------------------------------------ 0154 0155 PrintHelper::PrintHelper(QWidget* const parent) 0156 : d(new Private) 0157 { 0158 d->parent = parent; 0159 } 0160 0161 PrintHelper::~PrintHelper() 0162 { 0163 delete d; 0164 } 0165 0166 void PrintHelper::print(DImg& doc) 0167 { 0168 0169 #ifdef Q_OS_WIN 0170 0171 // NOTE: Under Windows if no printer is installed, QPrintDialog do nothing. 0172 0173 QList<QPrinterInfo> list = QPrinterInfo::availablePrinters(); 0174 0175 if (list.isEmpty()) 0176 { 0177 QMessageBox::warning(d->parent, i18nc("@title:window", "No Printer Available"), 0178 i18nc("@info", "No printer is installed on your system. Please install one at least.")); 0179 0180 return; 0181 } 0182 0183 #endif 0184 0185 QPrinter printer; 0186 0187 QPrintDialog* const dialog = new QPrintDialog(&printer, d->parent); 0188 dialog->setWindowTitle(i18nc("@title:window", "Print Image")); 0189 PrintOptionsPage* const optionsPage = new PrintOptionsPage(d->parent, doc.size()); 0190 optionsPage->loadConfig(); 0191 dialog->setOptionTabs(QList<QWidget*>() << optionsPage); 0192 0193 bool wantToPrint = (dialog->exec() == QDialog::Accepted); 0194 0195 optionsPage->saveConfig(); 0196 0197 if (!wantToPrint) 0198 { 0199 return; 0200 } 0201 0202 if (optionsPage->autoRotation()) 0203 { 0204 printer.setPageOrientation(doc.size().width() <= doc.size().height() ? QPageLayout::Portrait 0205 : QPageLayout::Landscape); 0206 } 0207 0208 QPainter painter(&printer); 0209 QRect rect = painter.viewport(); 0210 QSize size = d->adjustSize(optionsPage, doc, printer.resolution(), rect.size()); 0211 QPoint pos = d->adjustPosition(optionsPage, size, rect.size()); 0212 d->adjustImage(optionsPage, doc); 0213 painter.setViewport(pos.x(), pos.y(), size.width(), size.height()); 0214 0215 QImage image = doc.copyQImage(); 0216 painter.setWindow(image.rect()); 0217 painter.drawImage(0, 0, image); 0218 } 0219 0220 } // namespace DigikamEditorPrintToolPlugin