File indexing completed on 2025-01-05 03:53:14
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2017-05-25 0007 * Description : a tool to print images 0008 * 0009 * SPDX-FileCopyrightText: 2012-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "advprintfinalpage.h" 0016 0017 // Qt includes 0018 0019 #include <QImage> 0020 #include <QIcon> 0021 #include <QSpacerItem> 0022 #include <QVBoxLayout> 0023 #include <QUrl> 0024 #include <QApplication> 0025 #include <QStyle> 0026 #include <QTimer> 0027 #include <QDir> 0028 #include <QFile> 0029 #include <QMessageBox> 0030 #include <QDesktopServices> 0031 #include <QPrintDialog> 0032 0033 // KDE includes 0034 0035 #include <klocalizedstring.h> 0036 0037 // Local includes 0038 0039 #include "advprintthread.h" 0040 #include "advprintwizard.h" 0041 #include "advprintcaptionpage.h" 0042 #include "advprintphotopage.h" 0043 #include "dlayoutbox.h" 0044 #include "digikam_debug.h" 0045 #include "dprogresswdg.h" 0046 #include "dhistoryview.h" 0047 #include "dmetadata.h" 0048 #include "dfileoperations.h" 0049 #include "dimg.h" 0050 0051 namespace DigikamGenericPrintCreatorPlugin 0052 { 0053 0054 class Q_DECL_HIDDEN AdvPrintFinalPage::Private 0055 { 0056 public: 0057 0058 explicit Private(QWizard* const dialog) 0059 : FONT_HEIGHT_RATIO(0.8F), 0060 progressView (nullptr), 0061 progressBar (nullptr), 0062 wizard (nullptr), 0063 settings (nullptr), 0064 printThread (nullptr), 0065 photoPage (nullptr), 0066 iface (nullptr), 0067 complete (false) 0068 { 0069 wizard = dynamic_cast<AdvPrintWizard*>(dialog); 0070 0071 if (wizard) 0072 { 0073 settings = wizard->settings(); 0074 iface = wizard->iface(); 0075 } 0076 } 0077 0078 const float FONT_HEIGHT_RATIO; 0079 0080 DHistoryView* progressView; 0081 DProgressWdg* progressBar; 0082 AdvPrintWizard* wizard; 0083 AdvPrintSettings* settings; 0084 AdvPrintThread* printThread; 0085 AdvPrintPhotoPage* photoPage; 0086 DInfoInterface* iface; 0087 bool complete; 0088 }; 0089 0090 AdvPrintFinalPage::AdvPrintFinalPage(QWizard* const dialog, const QString& title) 0091 : DWizardPage(dialog, title), 0092 d (new Private(dialog)) 0093 { 0094 DVBox* const vbox = new DVBox(this); 0095 d->progressView = new DHistoryView(vbox); 0096 d->progressBar = new DProgressWdg(vbox); 0097 0098 vbox->setStretchFactor(d->progressBar, 10); 0099 vbox->setSpacing(qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0100 QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing))); 0101 vbox->setContentsMargins(QMargins()); 0102 0103 setPageWidget(vbox); 0104 setLeftBottomPix(QIcon::fromTheme(QLatin1String("system-run"))); 0105 } 0106 0107 AdvPrintFinalPage::~AdvPrintFinalPage() 0108 { 0109 if (d->printThread) 0110 { 0111 d->printThread->cancel(); 0112 } 0113 0114 delete d; 0115 } 0116 0117 void AdvPrintFinalPage::setPhotoPage(AdvPrintPhotoPage* const photoPage) 0118 { 0119 d->photoPage = photoPage; 0120 } 0121 0122 void AdvPrintFinalPage::initializePage() 0123 { 0124 d->complete = false; 0125 0126 Q_EMIT completeChanged(); 0127 0128 QTimer::singleShot(0, this, SLOT(slotProcess())); 0129 } 0130 0131 void AdvPrintFinalPage::slotProcess() 0132 { 0133 if (!d->wizard) 0134 { 0135 d->progressView->addEntry(i18n("Internal Error"), 0136 DHistoryView::ErrorEntry); 0137 return; 0138 } 0139 0140 if (d->settings->photos.isEmpty()) 0141 { 0142 d->progressView->addEntry(i18n("No page to print..."), 0143 DHistoryView::ErrorEntry); 0144 return; 0145 } 0146 0147 d->progressView->clear(); 0148 d->progressBar->reset(); 0149 0150 d->progressView->addEntry(i18n("Starting to pre-process files..."), 0151 DHistoryView::ProgressEntry); 0152 0153 d->progressView->addEntry(i18n("%1 items to process", d->settings->inputImages.count()), 0154 DHistoryView::ProgressEntry); 0155 0156 d->progressBar->setMinimum(0); 0157 d->progressBar->setMaximum(d->settings->photos.count()); 0158 0159 // set the default crop regions if not already set 0160 0161 int sizeIndex = d->photoPage->ui()->ListPhotoSizes->currentRow(); 0162 d->settings->outputLayouts = d->settings->photosizes.at(sizeIndex); 0163 d->printThread = new AdvPrintThread(this); 0164 0165 connect(d->printThread, SIGNAL(signalProgress(int)), 0166 d->progressBar, SLOT(setValue(int))); 0167 0168 connect(d->printThread, SIGNAL(signalMessage(QString,bool)), 0169 this, SLOT(slotMessage(QString,bool))); 0170 0171 connect(d->printThread, SIGNAL(signalDone(bool)), 0172 this, SLOT(slotPrint(bool))); 0173 0174 d->printThread->preparePrint(d->settings, sizeIndex); 0175 d->printThread->start(); 0176 } 0177 0178 void AdvPrintFinalPage::slotPrint(bool b) 0179 { 0180 if (!b) 0181 { 0182 slotDone(b); 0183 return; 0184 } 0185 0186 if (!print()) 0187 { 0188 d->progressView->addEntry(i18n("Printing process aborted..."), 0189 DHistoryView::ErrorEntry); 0190 return; 0191 } 0192 0193 disconnect(d->printThread, SIGNAL(signalDone(bool)), 0194 this, SLOT(slotPrint(bool))); 0195 0196 connect(d->printThread, SIGNAL(signalDone(bool)), 0197 this, SLOT(slotDone(bool))); 0198 0199 d->printThread->print(d->settings); 0200 d->printThread->start(); 0201 } 0202 0203 void AdvPrintFinalPage::cleanupPage() 0204 { 0205 if (d->printThread) 0206 { 0207 d->printThread->cancel(); 0208 } 0209 0210 if (d->settings->gimpFiles.count() > 0) 0211 { 0212 removeGimpFiles(); 0213 } 0214 } 0215 0216 void AdvPrintFinalPage::slotMessage(const QString& mess, bool err) 0217 { 0218 d->progressView->addEntry(mess, err ? DHistoryView::ErrorEntry 0219 : DHistoryView::ProgressEntry); 0220 } 0221 0222 void AdvPrintFinalPage::slotDone(bool completed) 0223 { 0224 d->progressBar->progressCompleted(); 0225 d->complete = completed; 0226 0227 if (!d->complete) 0228 { 0229 d->progressView->addEntry(i18n("Printing process is not completed"), 0230 DHistoryView::WarningEntry); 0231 } 0232 else 0233 { 0234 d->progressView->addEntry(i18n("Printing process completed."), 0235 DHistoryView::ProgressEntry); 0236 0237 if (d->settings->printerName == d->settings->outputName(AdvPrintSettings::FILES)) 0238 { 0239 if (d->settings->openInFileBrowser) 0240 { 0241 QDesktopServices::openUrl(d->settings->outputDir); 0242 d->progressView->addEntry(i18n("Open destination directory in file-browser."), 0243 DHistoryView::ProgressEntry); 0244 } 0245 } 0246 else if (d->settings->printerName == d->settings->outputName(AdvPrintSettings::GIMP)) 0247 { 0248 if (!d->settings->gimpFiles.isEmpty()) 0249 { 0250 QStringList args; 0251 QString prog = d->settings->gimpPath; 0252 0253 for (QStringList::ConstIterator it = d->settings->gimpFiles.constBegin() ; 0254 it != d->settings->gimpFiles.constEnd() ; ++it) 0255 { 0256 args << (*it); 0257 } 0258 0259 QProcess process; 0260 process.setProcessEnvironment(adjustedEnvironmentForAppImage()); 0261 0262 if (!process.startDetached(prog, args)) 0263 { 0264 d->progressView->addEntry(i18n("There was an error to launch the external " 0265 "Gimp program. Please make sure it is properly " 0266 "installed."), 0267 DHistoryView::WarningEntry); 0268 return; 0269 } 0270 } 0271 } 0272 } 0273 0274 Q_EMIT completeChanged(); 0275 } 0276 0277 bool AdvPrintFinalPage::isComplete() const 0278 { 0279 return d->complete; 0280 } 0281 0282 void AdvPrintFinalPage::removeGimpFiles() 0283 { 0284 for (QStringList::ConstIterator it = d->settings->gimpFiles.constBegin() ; 0285 it != d->settings->gimpFiles.constEnd() ; ++it) 0286 { 0287 if (QFile::exists(*it)) 0288 { 0289 if (QFile::remove(*it) == false) 0290 { 0291 QMessageBox::information(this, 0292 QString(), 0293 i18n("Could not remove the GIMP's temporary files.")); 0294 break; 0295 } 0296 } 0297 } 0298 } 0299 0300 bool AdvPrintFinalPage::checkTempPath(const QString& tempPath) const 0301 { 0302 // does the temp path exist? 0303 0304 if (!QDir(tempPath).exists()) 0305 { 0306 if (!QDir().mkpath(tempPath)) 0307 { 0308 d->progressView->addEntry(i18n("Unable to create a temporary folder. " 0309 "Please make sure you have proper permissions " 0310 "to this folder and try again."), 0311 DHistoryView::WarningEntry); 0312 0313 return false; 0314 } 0315 } 0316 0317 return true; 0318 } 0319 0320 bool AdvPrintFinalPage::print() 0321 { 0322 // Real printer to use. 0323 0324 if ((d->settings->printerName != d->settings->outputName(AdvPrintSettings::FILES)) && 0325 (d->settings->printerName != d->settings->outputName(AdvPrintSettings::GIMP))) 0326 { 0327 // tell him again! 0328 0329 d->photoPage->printer()->setFullPage(true); 0330 0331 qreal left, top, right, bottom; 0332 auto margins = d->photoPage->printer()->pageLayout().margins(QPageLayout::Millimeter); 0333 left = margins.left(); 0334 top = margins.top(); 0335 right = margins.right(); 0336 bottom = margins.bottom(); 0337 0338 qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Margins before print dialog: left " 0339 << left 0340 << " right " 0341 << right 0342 << " top " 0343 << top 0344 << " bottom " 0345 << bottom; 0346 0347 qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "(1) paper page " 0348 << d->photoPage->printer()->pageLayout().pageSize().id() 0349 << " size " 0350 << d->photoPage->printer()->pageLayout().pageSize().size(QPageSize::Millimeter); 0351 0352 auto pageSize = d->photoPage->printer()->pageLayout().pageSize().id(); 0353 QPrintDialog* const dialog = new QPrintDialog(d->photoPage->printer(), this); 0354 dialog->setWindowTitle(i18nc("@title:window", "Print Creator")); 0355 0356 qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "(2) paper page " 0357 << dialog->printer()->pageLayout().pageSize().id() 0358 << " size " 0359 << dialog->printer()->pageLayout().pageSize().size(QPageSize::Millimeter); 0360 0361 if (dialog->exec() != QDialog::Accepted) 0362 { 0363 return false; 0364 } 0365 0366 qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "(3) paper page " 0367 << dialog->printer()->pageLayout().pageSize().id() 0368 << " size " 0369 << dialog->printer()->pageLayout().pageSize().size(QPageSize::Millimeter); 0370 0371 // Why paperSize changes if printer properties is not pressed? 0372 0373 if (pageSize != d->photoPage->printer()->pageLayout().pageSize().id()) 0374 { 0375 d->photoPage->printer()->setPageSize(QPageSize(pageSize)); 0376 } 0377 0378 qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "(4) paper page " 0379 << dialog->printer()->pageLayout().pageSize().id() 0380 << " size " 0381 << dialog->printer()->pageLayout().pageSize().size(QPageSize::Millimeter); 0382 0383 margins = dialog->printer()->pageLayout().margins(QPageLayout::Millimeter); 0384 left = margins.left(); 0385 top = margins.top(); 0386 right = margins.right(); 0387 bottom = margins.bottom(); 0388 0389 qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Dialog exit, new margins: left " 0390 << left 0391 << " right " 0392 << right 0393 << " top " 0394 << top 0395 << " bottom " 0396 << bottom; 0397 0398 d->settings->outputPrinter = d->photoPage->printer(); 0399 0400 return true; 0401 } 0402 else if (d->settings->printerName == d->settings->outputName(AdvPrintSettings::GIMP)) 0403 { 0404 d->settings->imageFormat = AdvPrintSettings::JPEG; 0405 0406 if (!checkTempPath(d->settings->tempPath)) 0407 { 0408 return false; 0409 } 0410 0411 if (d->settings->gimpFiles.count() > 0) 0412 { 0413 removeGimpFiles(); 0414 } 0415 0416 d->settings->outputPath = d->settings->tempPath; 0417 0418 return true; 0419 } 0420 else if (d->settings->printerName == d->settings->outputName(AdvPrintSettings::FILES)) 0421 { 0422 d->settings->outputPath = d->settings->outputDir.toLocalFile(); 0423 0424 return true; 0425 } 0426 0427 return false; 0428 } 0429 0430 } // namespace DigikamGenericPrintCreatorPlugin 0431 0432 #include "moc_advprintfinalpage.cpp"