File indexing completed on 2025-01-05 03:53:13

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: 2017-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 "advprintcaptionpage.h"
0016 
0017 // Qt includes
0018 
0019 #include <QIcon>
0020 #include <QPrinterInfo>
0021 #include <QWidget>
0022 #include <QApplication>
0023 #include <QStyle>
0024 #include <QFileInfo>
0025 #include <QScopedPointer>
0026 
0027 // KDE includes
0028 
0029 #include <klocalizedstring.h>
0030 
0031 // Local includes
0032 
0033 #include "digikam_debug.h"
0034 #include "dmetadata.h"
0035 #include "advprintwizard.h"
0036 #include "advprintphoto.h"
0037 
0038 namespace DigikamGenericPrintCreatorPlugin
0039 {
0040 
0041 class Q_DECL_HIDDEN AdvPrintCaptionPage::Private
0042 {
0043 public:
0044 
0045     template <class Ui_Class>
0046 
0047     class Q_DECL_HIDDEN WizardUI : public QWidget, public Ui_Class
0048     {
0049     public:
0050 
0051         explicit WizardUI(QWidget* const parent)
0052             : QWidget(parent)
0053         {
0054             this->setupUi(this);
0055         }
0056     };
0057 
0058     typedef WizardUI<Ui_AdvPrintCaptionPage> CaptionUI;
0059 
0060 public:
0061 
0062     explicit Private(QWizard* const dialog)
0063       : settings(nullptr),
0064         iface   (nullptr)
0065     {
0066         captionUi = new CaptionUI(dialog);
0067         wizard    = dynamic_cast<AdvPrintWizard*>(dialog);
0068 
0069         if (wizard)
0070         {
0071             settings = wizard->settings();
0072             iface    = wizard->iface();
0073         }
0074     }
0075 
0076     CaptionUI*        captionUi;
0077     AdvPrintWizard*   wizard;
0078     AdvPrintSettings* settings;
0079     DInfoInterface*   iface;
0080 };
0081 
0082 AdvPrintCaptionPage::AdvPrintCaptionPage(QWizard* const wizard, const QString& title)
0083     : DWizardPage(wizard, title),
0084       d          (new Private(wizard))
0085 {
0086     QMap<AdvPrintSettings::CaptionType, QString> map                = AdvPrintSettings::captionTypeNames();
0087     QMap<AdvPrintSettings::CaptionType, QString>::const_iterator it = map.constBegin();
0088 
0089     while (it != map.constEnd())
0090     {
0091         d->captionUi->m_captionType->addItem(it.value(), (int)it.key());
0092         ++it;
0093     }
0094 
0095     d->captionUi->m_FreeCaptionFormat->setLinesVisible(1);
0096 
0097     // ----------------------------------------------------------------------
0098 
0099     connect(d->captionUi->m_captionType, SIGNAL(activated(int)),
0100             this, SLOT(slotCaptionChanged(int)));
0101 
0102     connect(d->captionUi->m_FreeCaptionFormat, SIGNAL(editingFinished()),
0103             this, SLOT(slotUpdateCaptions()));
0104 
0105     connect(d->captionUi->m_font_name, SIGNAL(currentFontChanged(QFont)),
0106             this, SLOT(slotUpdateCaptions()));
0107 
0108     connect(d->captionUi->m_font_size, SIGNAL(valueChanged(int)),
0109             this, SLOT(slotUpdateCaptions()));
0110 
0111     connect(d->captionUi->m_font_color, SIGNAL(signalColorSelected(QColor)),
0112             this, SLOT(slotUpdateCaptions()));
0113 
0114     connect(d->captionUi->mPrintList, SIGNAL(signalImageListChanged()),
0115             this, SLOT(slotUpdateCaptions()));
0116 
0117     // -----------------------------------
0118 
0119     d->captionUi->mPrintList->setIface(d->iface);
0120     d->captionUi->mPrintList->setAllowDuplicate(true);
0121     d->captionUi->mPrintList->setControlButtonsPlacement(DItemsList::NoControlButtons);
0122     d->captionUi->mPrintList->listView()->setColumn(DItemsListView::User1,
0123                                                     i18nc("@title: column", "Caption"),
0124                                                     true);
0125 
0126     // -----------------------------------
0127 
0128     setPageWidget(d->captionUi);
0129     setLeftBottomPix(QIcon::fromTheme(QLatin1String("imagecomment")));
0130 }
0131 
0132 AdvPrintCaptionPage::~AdvPrintCaptionPage()
0133 {
0134     delete d;
0135 }
0136 
0137 DItemsList* AdvPrintCaptionPage::imagesList() const
0138 {
0139     return d->captionUi->mPrintList;
0140 }
0141 
0142 void AdvPrintCaptionPage::initializePage()
0143 {
0144     d->captionUi->m_captionType->setCurrentIndex(d->settings->captionType);
0145     enableCaptionGroup(d->captionUi->m_captionType->currentIndex());
0146     d->captionUi->m_font_color->setColor(d->settings->captionColor);
0147     d->captionUi->m_font_name->setCurrentFont(d->settings->captionFont.family());
0148     d->captionUi->m_font_size->setValue(d->settings->captionSize);
0149     d->captionUi->m_FreeCaptionFormat->setText(d->settings->captionTxt);
0150     slotCaptionChanged(d->captionUi->m_captionType->currentIndex());
0151     slotUpdateImagesList();
0152     slotUpdateCaptions();
0153 }
0154 
0155 bool AdvPrintCaptionPage::validatePage()
0156 {
0157     d->settings->captionType  = (AdvPrintSettings::CaptionType)d->captionUi->m_captionType->currentIndex();
0158     d->settings->captionColor = d->captionUi->m_font_color->color();
0159     d->settings->captionFont  = QFont(d->captionUi->m_font_name->currentFont());
0160     d->settings->captionSize  = d->captionUi->m_font_size->value();
0161     d->settings->captionTxt   = d->captionUi->m_FreeCaptionFormat->text();
0162 
0163     return true;
0164 }
0165 
0166 void AdvPrintCaptionPage::slotUpdateImagesList()
0167 {
0168     d->captionUi->mPrintList->listView()->clear();
0169     d->captionUi->mPrintList->slotAddImages(d->wizard->itemsList());
0170 }
0171 
0172 void AdvPrintCaptionPage::blockCaptionButtons(bool block)
0173 {
0174     d->captionUi->m_captionType->blockSignals(block);
0175     d->captionUi->m_free_label->blockSignals(block);
0176     d->captionUi->m_font_name->blockSignals(block);
0177     d->captionUi->m_font_size->blockSignals(block);
0178     d->captionUi->m_font_color->blockSignals(block);
0179 }
0180 
0181 void AdvPrintCaptionPage::enableCaptionGroup(int index)
0182 {
0183     bool fontSettingsEnabled;
0184 
0185     if      (index == AdvPrintSettings::NONE)
0186     {
0187         fontSettingsEnabled = false;
0188         d->captionUi->m_customCaptionGB->setEnabled(false);
0189     }
0190     else if (index == AdvPrintSettings::CUSTOM)
0191     {
0192         fontSettingsEnabled = true;
0193         d->captionUi->m_customCaptionGB->setEnabled(true);
0194     }
0195     else
0196     {
0197         fontSettingsEnabled = true;
0198         d->captionUi->m_customCaptionGB->setEnabled(false);
0199     }
0200 
0201     d->captionUi->m_font_name->setEnabled(fontSettingsEnabled);
0202     d->captionUi->m_font_size->setEnabled(fontSettingsEnabled);
0203     d->captionUi->m_font_color->setEnabled(fontSettingsEnabled);
0204 }
0205 
0206 void AdvPrintCaptionPage::slotCaptionChanged(int index)
0207 {
0208     enableCaptionGroup(index);
0209     slotUpdateCaptions();
0210 }
0211 
0212 void AdvPrintCaptionPage::updateCaption(AdvPrintPhoto* const pPhoto)
0213 {
0214     if (pPhoto)
0215     {
0216         if      (!pPhoto->m_pAdvPrintCaptionInfo &&
0217                  (d->captionUi->m_captionType->currentIndex() != AdvPrintSettings::NONE))
0218         {
0219             pPhoto->m_pAdvPrintCaptionInfo = new AdvPrintCaptionInfo();
0220         }
0221         else if (pPhoto->m_pAdvPrintCaptionInfo &&
0222                  (d->captionUi->m_captionType->currentIndex() == AdvPrintSettings::NONE))
0223         {
0224             delete pPhoto->m_pAdvPrintCaptionInfo;
0225             pPhoto->m_pAdvPrintCaptionInfo = nullptr;
0226         }
0227 
0228         if (pPhoto->m_pAdvPrintCaptionInfo)
0229         {
0230             pPhoto->m_pAdvPrintCaptionInfo->m_captionColor =
0231                 d->captionUi->m_font_color->color();
0232             pPhoto->m_pAdvPrintCaptionInfo->m_captionSize  =
0233                 d->captionUi->m_font_size->value();
0234             pPhoto->m_pAdvPrintCaptionInfo->m_captionFont  =
0235                 d->captionUi->m_font_name->currentFont();
0236             pPhoto->m_pAdvPrintCaptionInfo->m_captionType  =
0237                 (AdvPrintSettings::CaptionType)d->captionUi->m_captionType->currentIndex();
0238             pPhoto->m_pAdvPrintCaptionInfo->m_captionText  =
0239                 d->captionUi->m_FreeCaptionFormat->text();
0240 
0241             qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Update caption properties for"
0242                                                  << pPhoto->m_url;
0243         }
0244     }
0245 }
0246 
0247 void AdvPrintCaptionPage::slotUpdateCaptions()
0248 {
0249     if (d->settings->photos.size())
0250     {
0251         Q_FOREACH (AdvPrintPhoto* const pPhoto, d->settings->photos)
0252         {
0253             updateCaption(pPhoto);
0254 
0255             if (pPhoto && pPhoto->m_pAdvPrintCaptionInfo)
0256             {
0257                 DItemsListViewItem* const lvItem = d->captionUi->mPrintList->listView()->findItem(pPhoto->m_url);
0258 
0259                 if (lvItem)
0260                 {
0261                     QString cap;
0262 
0263                     if (pPhoto->m_pAdvPrintCaptionInfo->m_captionType != AdvPrintSettings::NONE)
0264                     {
0265                         cap = captionFormatter(pPhoto);
0266                     }
0267 
0268                     qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << cap;
0269 
0270                     lvItem->setText(DItemsListView::User1, cap);
0271                 }
0272             }
0273         }
0274     }
0275 
0276     // create our photo sizes list
0277 
0278     d->wizard->previewPhotos();
0279 }
0280 
0281 QString AdvPrintCaptionPage::captionFormatter(AdvPrintPhoto* const photo)
0282 {
0283     if (!photo->m_pAdvPrintCaptionInfo)
0284     {
0285         qCWarning(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Internal caption info container is NULL for"
0286                                                << photo->m_url;
0287         return QString();
0288     }
0289 
0290     QString resolution;
0291     QSize   imageSize;
0292     QString format;
0293 
0294     // %f filename
0295     // %c comment
0296     // %d date-time
0297     // %t exposure time
0298     // %i iso
0299     // %r resolution
0300     // %a aperture
0301     // %l focal length
0302 
0303     switch (photo->m_pAdvPrintCaptionInfo->m_captionType)
0304     {
0305         case AdvPrintSettings::FILENAME:
0306         {
0307             format = QLatin1String("%f");
0308             break;
0309         }
0310 
0311         case AdvPrintSettings::DATETIME:
0312         {
0313             format = QLatin1String("%d");
0314             break;
0315         }
0316 
0317         case AdvPrintSettings::COMMENT:
0318         {
0319             format = QLatin1String("%c");
0320             break;
0321         }
0322 
0323         case AdvPrintSettings::CUSTOM:
0324         {
0325             format = photo->m_pAdvPrintCaptionInfo->m_captionText;
0326             break;
0327         }
0328 
0329         default:
0330         {
0331             qCWarning(DIGIKAM_DPLUGIN_GENERIC_LOG) << "UNKNOWN caption type "
0332                                                    << photo->m_pAdvPrintCaptionInfo->m_captionType;
0333             break;
0334         }
0335     }
0336 
0337     format.replace(QLatin1String("\\n"), QLatin1String("\n"));
0338 
0339     if (photo->m_iface)
0340     {
0341         DItemInfo info(photo->m_iface->itemInfo(photo->m_url));
0342         imageSize = info.dimensions();
0343 
0344         format.replace(QString::fromUtf8("%c"), info.comment());
0345         format.replace(QString::fromUtf8("%d"), QLocale().toString(info.dateTime(),
0346                                                 QLocale::ShortFormat));
0347         format.replace(QString::fromUtf8("%f"), info.name());
0348         format.replace(QString::fromUtf8("%t"), info.exposureTime());
0349         format.replace(QString::fromUtf8("%i"), info.sensitivity());
0350         format.replace(QString::fromUtf8("%a"), info.aperture());
0351         format.replace(QString::fromUtf8("%l"), info.focalLength());
0352     }
0353     else
0354     {
0355         QFileInfo fi(photo->m_url.toLocalFile());
0356         QScopedPointer<DMetadata> meta(new DMetadata(photo->m_url.toLocalFile()));
0357         imageSize                    = meta->getItemDimensions();
0358 
0359         format.replace(QString::fromUtf8("%c"), meta->getItemComments()[QLatin1String("x-default")].caption);
0360         format.replace(QString::fromUtf8("%d"), QLocale().toString(meta->getItemDateTime(), QLocale::ShortFormat));
0361         format.replace(QString::fromUtf8("%f"), fi.fileName());
0362 
0363         PhotoInfoContainer photoInfo = meta->getPhotographInformation();
0364         format.replace(QString::fromUtf8("%t"), photoInfo.exposureTime);
0365         format.replace(QString::fromUtf8("%i"), photoInfo.sensitivity);
0366         format.replace(QString::fromUtf8("%a"), photoInfo.aperture);
0367         format.replace(QString::fromUtf8("%l"), photoInfo.focalLength);
0368     }
0369 
0370     if (imageSize.isValid())
0371     {
0372         resolution = QString::fromUtf8("%1x%2").arg(imageSize.width()).arg(imageSize.height());
0373     }
0374 
0375     format.replace(QString::fromUtf8("%r"), resolution);
0376 
0377     qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Caption for"
0378                                          << photo->m_url
0379                                          << ":" << format;
0380     return format;
0381 }
0382 
0383 } // namespace DigikamGenericPrintCreatorPlugin
0384 
0385 #include "moc_advprintcaptionpage.cpp"