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