File indexing completed on 2024-05-12 04:19:47
0001 // vim: set tabstop=4 shiftwidth=4 expandtab: 0002 /* 0003 Gwenview: an image viewer 0004 Copyright 2007 Aurélien Gâteau <agateau@kde.org> 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public License 0008 as published by the Free Software Foundation; either version 2 0009 of the License, or (at your option) any later version. 0010 0011 This program is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 GNU General Public License for more details. 0015 0016 You should have received a copy of the GNU General Public License 0017 along with this program; if not, write to the Free Software 0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0019 0020 */ 0021 // Self 0022 #include "printhelper.h" 0023 0024 // STD 0025 #include <memory> 0026 0027 // Qt 0028 #include <QCheckBox> 0029 #include <QPainter> 0030 #include <QPrintDialog> 0031 #include <QPrintPreviewDialog> 0032 #include <QPrinter> 0033 #include <QUrl> 0034 0035 // KF 0036 #include <KLocalizedString> 0037 0038 // Local 0039 #include "printoptionspage.h" 0040 0041 namespace Gwenview 0042 { 0043 struct PrintHelperPrivate { 0044 QWidget *mParent = nullptr; 0045 0046 QSize adjustSize(PrintOptionsPage *optionsPage, Document::Ptr doc, int printerResolution, const QSize &viewportSize) 0047 { 0048 QSize size = doc->size(); 0049 PrintOptionsPage::ScaleMode scaleMode = optionsPage->scaleMode(); 0050 if (scaleMode == PrintOptionsPage::ScaleToPage) { 0051 bool imageBiggerThanPaper = size.width() > viewportSize.width() || size.height() > viewportSize.height(); 0052 0053 if (imageBiggerThanPaper || optionsPage->enlargeSmallerImages()) { 0054 size.scale(viewportSize, Qt::KeepAspectRatio); 0055 } 0056 0057 } else if (scaleMode == PrintOptionsPage::ScaleToCustomSize) { 0058 double wImg = optionsPage->scaleWidth(); 0059 double hImg = optionsPage->scaleHeight(); 0060 size.setWidth(int(wImg * printerResolution)); 0061 size.setHeight(int(hImg * printerResolution)); 0062 0063 } else { 0064 // No scale 0065 const double INCHES_PER_METER = 100. / 2.54; 0066 const int dpmX = doc->image().dotsPerMeterX(); 0067 const int dpmY = doc->image().dotsPerMeterY(); 0068 if (dpmX > 0 && dpmY > 0) { 0069 double wImg = double(size.width()) / double(dpmX) * INCHES_PER_METER; 0070 double hImg = double(size.height()) / double(dpmY) * INCHES_PER_METER; 0071 size.setWidth(int(wImg * printerResolution)); 0072 size.setHeight(int(hImg * printerResolution)); 0073 } 0074 } 0075 return size; 0076 } 0077 0078 QPoint adjustPosition(PrintOptionsPage *optionsPage, const QSize &imageSize, const QSize &viewportSize) 0079 { 0080 Qt::Alignment alignment = optionsPage->alignment(); 0081 int posX, posY; 0082 0083 if (alignment & Qt::AlignLeft) { 0084 posX = 0; 0085 } else if (alignment & Qt::AlignHCenter) { 0086 posX = (viewportSize.width() - imageSize.width()) / 2; 0087 } else { 0088 posX = viewportSize.width() - imageSize.width(); 0089 } 0090 0091 if (alignment & Qt::AlignTop) { 0092 posY = 0; 0093 } else if (alignment & Qt::AlignVCenter) { 0094 posY = (viewportSize.height() - imageSize.height()) / 2; 0095 } else { 0096 posY = viewportSize.height() - imageSize.height(); 0097 } 0098 0099 return QPoint(posX, posY); 0100 } 0101 0102 void setupPrinter(QPrinter *printer, Document::Ptr doc) 0103 { 0104 doc->waitUntilLoaded(); 0105 printer->setDocName(doc->url().fileName()); 0106 const auto docSize = doc->size(); 0107 printer->setPageOrientation(docSize.width() > docSize.height() ? QPageLayout::Landscape : QPageLayout::Portrait); 0108 } 0109 0110 void print(QPrinter *printer, Document::Ptr doc, bool showPrinterSetupDialog) 0111 { 0112 auto optionsPage = new PrintOptionsPage(doc->size()); 0113 optionsPage->loadConfig(); 0114 0115 QScopedPointer<QPrintDialog> dialog; 0116 if (showPrinterSetupDialog) { 0117 dialog.reset(new QPrintDialog(printer, mParent)); 0118 #if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) 0119 dialog->setOptionTabs(QList<QWidget *>() << optionsPage); 0120 #else 0121 optionsPage->setParent(dialog.data()); 0122 #endif 0123 0124 dialog->setWindowTitle(i18n("Print Image")); 0125 bool wantToPrint = dialog->exec(); 0126 0127 optionsPage->saveConfig(); 0128 if (!wantToPrint) { 0129 return; 0130 } 0131 } 0132 0133 QPainter painter(printer); 0134 const QRect rect = painter.viewport(); 0135 const QSize size = adjustSize(optionsPage, doc, printer->resolution(), rect.size()); 0136 const QPoint pos = adjustPosition(optionsPage, size, rect.size()); 0137 painter.setViewport(pos.x(), pos.y(), size.width(), size.height()); 0138 if (!dialog) { 0139 delete optionsPage; 0140 } 0141 0142 const QImage image = doc->image(); 0143 painter.setWindow(image.rect()); 0144 painter.drawImage(0, 0, image); 0145 } 0146 }; 0147 0148 PrintHelper::PrintHelper(QWidget *parent) 0149 : d(new PrintHelperPrivate) 0150 { 0151 d->mParent = parent; 0152 } 0153 0154 PrintHelper::~PrintHelper() 0155 { 0156 delete d; 0157 } 0158 0159 void PrintHelper::print(Document::Ptr doc) 0160 { 0161 QPrinter printer; 0162 d->setupPrinter(&printer, doc); 0163 d->print(&printer, doc, true); 0164 } 0165 0166 void PrintHelper::printPreview(Document::Ptr doc) 0167 { 0168 QPrinter printer; 0169 d->setupPrinter(&printer, doc); 0170 QPrintPreviewDialog dlg(&printer, d->mParent); 0171 QObject::connect(&dlg, &QPrintPreviewDialog::paintRequested, [this, doc](QPrinter *printer) { 0172 d->print(printer, doc, false); 0173 }); 0174 dlg.exec(); 0175 } 0176 0177 } // namespace