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 "advprintcroppage.h"
0016 
0017 // Qt includes
0018 
0019 #include <QIcon>
0020 #include <QWidget>
0021 #include <QApplication>
0022 #include <QStyle>
0023 #include <QStandardPaths>
0024 
0025 // KDE includes
0026 
0027 #include <klocalizedstring.h>
0028 
0029 // Local includes
0030 
0031 #include "digikam_debug.h"
0032 #include "advprintwizard.h"
0033 #include "advprintphoto.h"
0034 
0035 namespace DigikamGenericPrintCreatorPlugin
0036 {
0037 
0038 class Q_DECL_HIDDEN AdvPrintCropPage::Private
0039 {
0040 public:
0041 
0042     template <class Ui_Class>
0043 
0044     class Q_DECL_HIDDEN WizardUI : public QWidget, public Ui_Class
0045     {
0046     public:
0047 
0048         explicit WizardUI(QWidget* const parent)
0049             : QWidget(parent)
0050         {
0051             this->setupUi(this);
0052         }
0053     };
0054 
0055     typedef WizardUI<Ui_AdvPrintCropPage> CropUI;
0056 
0057 public:
0058 
0059     explicit Private(QWizard* const dialog)
0060       : settings(nullptr),
0061         iface   (nullptr)
0062     {
0063         cropUi = new CropUI(dialog);
0064         wizard = dynamic_cast<AdvPrintWizard*>(dialog);
0065 
0066         if (wizard)
0067         {
0068             settings = wizard->settings();
0069             iface    = wizard->iface();
0070         }
0071     }
0072 
0073     CropUI*           cropUi;
0074     AdvPrintWizard*   wizard;
0075     AdvPrintSettings* settings;
0076     DInfoInterface*   iface;
0077 };
0078 
0079 AdvPrintCropPage::AdvPrintCropPage(QWizard* const wizard, const QString& title)
0080     : DWizardPage(wizard, title),
0081       d          (new Private(wizard))
0082 {
0083     d->cropUi->BtnCropRotateRight->setIcon(QIcon::fromTheme(QLatin1String("object-rotate-right"))
0084                                            .pixmap(16, 16));
0085     d->cropUi->BtnCropRotateLeft->setIcon(QIcon::fromTheme(QLatin1String("object-rotate-left"))
0086                                           .pixmap(16, 16));
0087 
0088     // -----------------------------------
0089 
0090     connect(d->cropUi->m_disableCrop, SIGNAL(stateChanged(int)),
0091             this, SLOT(slotCropSelection(int)));
0092 
0093     connect(d->cropUi->BtnCropPrev, SIGNAL(clicked()),
0094             this, SLOT(slotBtnCropPrevClicked()));
0095 
0096     connect(d->cropUi->BtnCropNext, SIGNAL(clicked()),
0097             this, SLOT(slotBtnCropNextClicked()));
0098 
0099     connect(d->cropUi->BtnCropRotateRight, SIGNAL(clicked()),
0100             this, SLOT(slotBtnCropRotateRightClicked()));
0101 
0102     connect(d->cropUi->BtnCropRotateLeft, SIGNAL(clicked()),
0103             this, SLOT(slotBtnCropRotateLeftClicked()));
0104 
0105     // -----------------------------------
0106 
0107     setPageWidget(d->cropUi);
0108     setLeftBottomPix(QIcon::fromTheme(QLatin1String("transform-crop")));
0109 }
0110 
0111 AdvPrintCropPage::~AdvPrintCropPage()
0112 {
0113     delete d;
0114 }
0115 
0116 Ui_AdvPrintCropPage* AdvPrintCropPage::ui() const
0117 {
0118     return d->cropUi;
0119 }
0120 
0121 void AdvPrintCropPage::slotCropSelection(int)
0122 {
0123     d->cropUi->cropFrame->drawCropRectangle(!d->cropUi->m_disableCrop->isChecked());
0124     d->cropUi->update();
0125 }
0126 
0127 void AdvPrintCropPage::initializePage()
0128 {
0129     d->settings->currentCropPhoto = 0;
0130 
0131     if (d->settings->photos.size())
0132     {
0133         AdvPrintPhoto* const photo = d->settings->photos[d->settings->currentCropPhoto];
0134         setBtnCropEnabled();
0135         d->cropUi->update();
0136         d->wizard->updateCropFrame(photo, d->settings->currentCropPhoto);
0137     }
0138 }
0139 
0140 bool AdvPrintCropPage::validatePage()
0141 {
0142     d->settings->disableCrop = d->cropUi->m_disableCrop->isChecked();
0143 
0144     return true;
0145 }
0146 
0147 void AdvPrintCropPage::slotBtnCropPrevClicked()
0148 {
0149     AdvPrintPhoto* const photo = d->settings->photos[--d->settings->currentCropPhoto];
0150 
0151     setBtnCropEnabled();
0152 
0153     if (!photo)
0154     {
0155         d->settings->currentCropPhoto = 0;
0156         return;
0157     }
0158 
0159     d->wizard->updateCropFrame(photo, d->settings->currentCropPhoto);
0160 }
0161 
0162 void AdvPrintCropPage::slotBtnCropNextClicked()
0163 {
0164     AdvPrintPhoto* const photo = d->settings->photos[++d->settings->currentCropPhoto];
0165     setBtnCropEnabled();
0166 
0167     if (!photo)
0168     {
0169         d->settings->currentCropPhoto = d->settings->photos.count() - 1;
0170         return;
0171     }
0172 
0173     d->wizard->updateCropFrame(photo, d->settings->currentCropPhoto);
0174 }
0175 
0176 void AdvPrintCropPage::setBtnCropEnabled()
0177 {
0178     if (d->settings->currentCropPhoto == 0)
0179     {
0180         d->cropUi->BtnCropPrev->setEnabled(false);
0181     }
0182     else
0183     {
0184         d->cropUi->BtnCropPrev->setEnabled(true);
0185     }
0186 
0187     if (d->settings->currentCropPhoto == (int)d->settings->photos.count() - 1)
0188     {
0189         d->cropUi->BtnCropNext->setEnabled(false);
0190     }
0191     else
0192     {
0193         d->cropUi->BtnCropNext->setEnabled(true);
0194     }
0195 }
0196 
0197 void AdvPrintCropPage::slotBtnCropRotateLeftClicked()
0198 {
0199     // by definition, the cropRegion should be set by now,
0200     // which means that after our rotation it will become invalid,
0201     // so we will initialize it to -2 in an awful hack (this
0202     // tells the cropFrame to reset the crop region, but don't
0203     // automatically rotate the image to fit.
0204 
0205     AdvPrintPhoto* const photo = d->settings->photos[d->settings->currentCropPhoto];
0206     photo->m_cropRegion        = QRect(-2, -2, -2, -2);
0207     photo->m_rotation          = (photo->m_rotation - 90) % 360;
0208 
0209     d->wizard->updateCropFrame(photo, d->settings->currentCropPhoto);
0210 }
0211 
0212 void AdvPrintCropPage::slotBtnCropRotateRightClicked()
0213 {
0214     // by definition, the cropRegion should be set by now,
0215     // which means that after our rotation it will become invalid,
0216     // so we will initialize it to -2 in an awful hack (this
0217     // tells the cropFrame to reset the crop region, but don't
0218     // automatically rotate the image to fit.
0219 
0220     AdvPrintPhoto* const photo = d->settings->photos[d->settings->currentCropPhoto];
0221     photo->m_cropRegion        = QRect(-2, -2, -2, -2);
0222     photo->m_rotation          = (photo->m_rotation + 90) % 360;
0223 
0224     d->wizard->updateCropFrame(photo, d->settings->currentCropPhoto);
0225 }
0226 
0227 } // namespace DigikamGenericPrintCreatorPlugin
0228 
0229 #include "moc_advprintcroppage.cpp"