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

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2011-05-23
0007  * Description : a tool to create panorama by fusion of several images.
0008  * Acknowledge : based on the expoblending tool
0009  *
0010  * SPDX-FileCopyrightText: 2011-2016 by Benjamin Girault <benjamin dot girault at gmail dot com>
0011  * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #include "panointropage.h"
0018 
0019 // Qt includes
0020 
0021 #include <QLabel>
0022 #include <QPixmap>
0023 #include <QCheckBox>
0024 #include <QRadioButton>
0025 #include <QGroupBox>
0026 #include <QButtonGroup>
0027 #include <QVBoxLayout>
0028 #include <QStandardPaths>
0029 
0030 // KDE includes
0031 
0032 #include <klocalizedstring.h>
0033 
0034 // Local includes
0035 
0036 #include "digikam_config.h"
0037 #include "digikam_globals.h"
0038 #include "dbinarysearch.h"
0039 #include "autooptimiserbinary.h"
0040 #include "cpcleanbinary.h"
0041 #include "cpfindbinary.h"
0042 #include "enblendbinary.h"
0043 #include "makebinary.h"
0044 #include "nonabinary.h"
0045 #include "panomodifybinary.h"
0046 #include "pto2mkbinary.h"
0047 #include "huginexecutorbinary.h"
0048 #include "dlayoutbox.h"
0049 
0050 namespace DigikamGenericPanoramaPlugin
0051 {
0052 
0053 class Q_DECL_HIDDEN PanoIntroPage::Private
0054 {
0055 public:
0056 
0057     explicit Private(PanoManager* const m)
0058         : mngr                    (m),
0059 /*
0060           addGPlusMetadataCheckBox(0),
0061 */
0062 /*
0063           // TODO HDR
0064           hdrCheckBox             (0),
0065 */
0066           formatGroupBox          (nullptr),
0067           settingsGroupBox        (nullptr),
0068           jpegRadioButton         (nullptr),
0069           tiffRadioButton         (nullptr),
0070           hdrRadioButton          (nullptr),
0071           binariesWidget          (nullptr)
0072     {
0073     }
0074 
0075     PanoManager*    mngr;
0076 /*
0077     QCheckBox*      addGPlusMetadataCheckBox;
0078 */
0079 /*
0080     // TODO HDR
0081     QCheckBox*      hdrCheckBox;
0082 */
0083     QGroupBox*      formatGroupBox;
0084     QGroupBox*      settingsGroupBox;
0085     QRadioButton*   jpegRadioButton;
0086     QRadioButton*   tiffRadioButton;
0087     QRadioButton*   hdrRadioButton;
0088     DBinarySearch*  binariesWidget;
0089 };
0090 
0091 PanoIntroPage::PanoIntroPage(PanoManager* const mngr, QWizard* const dlg)
0092     : DWizardPage(dlg, QString::fromLatin1("<b>%1</b>").arg(i18nc("@title: window", "Welcome to Panorama Tool"))),
0093       d          (new Private(mngr))
0094 {
0095     DVBox* const vbox   = new DVBox(this);
0096 
0097     QLabel* const title = new QLabel(vbox);
0098     title->setWordWrap(true);
0099     title->setOpenExternalLinks(true);
0100     title->setText(QString::fromUtf8("<qt>"
0101                                      "<p><h1><b>%1</b></h1></p>"
0102                                      "<p>%2</p>"
0103                                      "<p>%3</p>"
0104                                      "<p>%4</p>"
0105                                      "<p>%5 <a href='http://hugin.sourceforge.net/tutorials/overview/en.shtml'>%6</a></p>"      // krazy:exclude=insecurenet
0106                                      "</qt>")
0107                    .arg(i18nc("@info", "Welcome to Panorama Tool"))
0108                    .arg(i18nc("@info", "This tool stitches several images together to create a panorama, making the seam between images not visible."))
0109                    .arg(i18nc("@info", "This assistant will help you to configure how to import images before stitching them into a panorama."))
0110                    .arg(i18nc("@info", "Images must be taken from the same point of view."))
0111                    .arg(i18nc("@info", "For more information, please take a look at "))
0112                    .arg(i18nc("@info", "this page")));
0113 
0114     QGroupBox* const binaryBox        = new QGroupBox(vbox);
0115     QGridLayout* const binaryLayout   = new QGridLayout;
0116     binaryBox->setLayout(binaryLayout);
0117     binaryBox->setTitle(i18nc("@title: group", "Panorama Binaries"));
0118     d->binariesWidget = new DBinarySearch(binaryBox);
0119     d->binariesWidget->addBinary(d->mngr->autoOptimiserBinary());
0120     d->binariesWidget->addBinary(d->mngr->cpCleanBinary());
0121     d->binariesWidget->addBinary(d->mngr->cpFindBinary());
0122     d->binariesWidget->addBinary(d->mngr->enblendBinary());
0123     d->binariesWidget->addBinary(d->mngr->makeBinary());
0124     d->binariesWidget->addBinary(d->mngr->nonaBinary());
0125     d->binariesWidget->addBinary(d->mngr->panoModifyBinary());
0126 
0127     d->mngr->checkForHugin2015();
0128 
0129     if (d->mngr->hugin2015())
0130     {
0131         d->binariesWidget->addBinary(d->mngr->huginExecutorBinary());
0132     }
0133     else
0134     {
0135         d->binariesWidget->addBinary(d->mngr->pto2MkBinary());
0136     }
0137 
0138     d->mngr->checkBinaries();
0139 
0140 #ifdef Q_OS_MACOS
0141 
0142     // Hugin bundle PKG install
0143 
0144     d->binariesWidget->addDirectory(QLatin1String("/Applications/Hugin/HuginTools"));
0145     d->binariesWidget->addDirectory(QLatin1String("/Applications/Hugin/Hugin.app/Contents/MacOS"));
0146     d->binariesWidget->addDirectory(QLatin1String("/Applications/Hugin/tools_mac"));
0147 
0148     // Std Macports install
0149 
0150     d->binariesWidget->addDirectory(QLatin1String("/opt/local/bin"));
0151 
0152     // digiKam Bundle PKG install
0153 
0154     d->binariesWidget->addDirectory(macOSBundlePrefix() + QLatin1String("bin"));
0155 
0156 #endif
0157 
0158 #ifdef Q_OS_WIN
0159 
0160     d->binariesWidget->addDirectory(QLatin1String("C:/Program Files/Hugin/bin"));
0161     d->binariesWidget->addDirectory(QLatin1String("C:/Program Files (x86)/Hugin/bin"));
0162     d->binariesWidget->addDirectory(QLatin1String("C:/Program Files/GnuWin32/bin"));
0163     d->binariesWidget->addDirectory(QLatin1String("C:/Program Files (x86)/GnuWin32/bin"));
0164 
0165 #endif
0166 
0167 /*
0168     QVBoxLayout* const settingsVBox = new QVBoxLayout();
0169     d->settingsGroupBox             = new QGroupBox(i18nc("@title:group", "Panorama Settings"), this);
0170     d->settingsGroupBox->setLayout(settingsVBox);
0171 
0172     d->addGPlusMetadataCheckBox     = new QCheckBox(i18nc("@option:check", "Add Photosphere Metadata"), d->settingsGroupBox);
0173     d->addGPlusMetadataCheckBox->setToolTip(i18nc("@info:tooltip", "Add Exif metadata to the output panorama image for Google+ 3D viewer"));
0174     d->addGPlusMetadataCheckBox->setWhatsThis(i18nc("@info:whatsthis", "\"Add Photosphere Metadata\": Enabling this allows the program to add "
0175                                                     "metadata to the output image such that when uploaded to Google+, the "
0176                                                     "Google+ 3D viewer is activated and the panorama can be seen in 3D. Note "
0177                                                     "that this feature is most interesting for large panoramas."));
0178     settingsVBox->addWidget(d->addGPlusMetadataCheckBox);
0179     vbox->addWidget(d->settingsGroupBox);
0180 */
0181     QVBoxLayout* const formatVBox = new QVBoxLayout();
0182     d->formatGroupBox             = new QGroupBox(i18nc("@title: group", "File Format"), vbox);
0183     d->formatGroupBox->setLayout(formatVBox);
0184     QButtonGroup* const group     = new QButtonGroup();
0185 
0186     d->jpegRadioButton            = new QRadioButton(i18nc("@option: radio", "JPEG output"), d->formatGroupBox);
0187 
0188     // The following comment is to get the next string extracted for translation
0189 
0190     // xgettext: no-c-format
0191     d->jpegRadioButton->setToolTip(i18nc("@info: tooltip", "Selects a JPEG output with 90% compression rate "
0192                                          "(lossy compression, smaller size)."));
0193     d->jpegRadioButton->setWhatsThis(i18nc("@info:whatsthis", "\"JPEG output\": Using JPEG output, the panorama file will be smaller "
0194                                            "at the cost of information loss during compression. This is the easiest "
0195                                            "way to share the result, or print it online or in a shop."));
0196     formatVBox->addWidget(d->jpegRadioButton);
0197     group->addButton(d->jpegRadioButton);
0198 
0199     d->tiffRadioButton          = new QRadioButton(i18nc("@option: radio", "TIFF output"), d->formatGroupBox);
0200     d->tiffRadioButton->setToolTip(i18nc("@info: tooltip", "Selects a TIFF output compressed using the LZW algorithm "
0201                                          "(lossless compression, bigger size)."));
0202     d->tiffRadioButton->setWhatsThis(i18nc("@info: whatsthis", "\"TIFF output\": Using TIFF output, you get the same color depth than "
0203                                            "your original photos using RAW images at the cost of a bigger panorama file."));
0204     formatVBox->addWidget(d->tiffRadioButton);
0205     group->addButton(d->tiffRadioButton);
0206 
0207 /*
0208     // TODO HDR
0209     d->hdrRadioButton           = new QRadioButton(i18nc("@option: radio", "HDR output"), d->formatGroupBox);
0210     d->hdrRadioButton->setToolTip(i18nc("@info: tooltip", "Selects an High Dynamic Range (HDR) image, that can be processed further "
0211                                         "with a dedicated software."));
0212     d->hdrRadioButton->setWhatsThis(i18nc("@info: whatsthis", "\"HDR output\": Output in High Dynamic Range, meaning that every piece of "
0213                                           "information contained in the original photos are preserved. Note that you "
0214                                           "need another software to process the resulting panorama, like "
0215                                           "<a href=\"http://qtpfsgui.sourceforge.net/\">Luminance HDR</a>"));       // krazy:exclude=insecurenet
0216     formatVBox->addWidget(d->hdrRadioButton);
0217     group->addButton(d->hdrRadioButton);
0218 */
0219 
0220     switch (d->mngr->format())
0221     {
0222         case JPEG:
0223             d->jpegRadioButton->setChecked(true);
0224             break;
0225 
0226         case TIFF:
0227             d->tiffRadioButton->setChecked(true);
0228             break;
0229 
0230         case HDR:
0231 /*
0232             // TODO HDR
0233             d->hdrRadioButton->setChecked(true);
0234 */
0235             break;
0236     }
0237 
0238     setPageWidget(vbox);
0239 
0240     QPixmap leftPix(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/data/assistant-tripod.png")));
0241     setLeftBottomPix(leftPix.scaledToWidth(128, Qt::SmoothTransformation));
0242 
0243 /*
0244     connect(d->addGPlusMetadataCheckBox, SIGNAL(stateChanged(int)),
0245             this, SLOT(slotToggleGPano(int)));
0246 
0247     d->addGPlusMetadataCheckBox->setChecked(d->mngr->gPano());
0248 */
0249     slotToggleGPano(0);  // Disabled for the moment
0250 
0251     connect(group, SIGNAL(buttonClicked(QAbstractButton*)),
0252             this, SLOT(slotChangeFileFormat(QAbstractButton*)));
0253 
0254     connect(d->binariesWidget, SIGNAL(signalBinariesFound(bool)),
0255             this, SLOT(slotBinariesChanged(bool)));
0256 /*
0257     // TODO HDR
0258      d->hdrCheckBox->setChecked(d->mngr->hdr());
0259 */
0260 }
0261 
0262 PanoIntroPage::~PanoIntroPage()
0263 {
0264     delete d;
0265 }
0266 
0267 bool PanoIntroPage::binariesFound()
0268 {
0269     return d->binariesWidget->allBinariesFound();
0270 }
0271 
0272 void PanoIntroPage::slotToggleGPano(int state)
0273 {
0274     d->mngr->setGPano(state);
0275 }
0276 
0277 void PanoIntroPage::slotChangeFileFormat(QAbstractButton* button)
0278 {
0279     if      (button == d->jpegRadioButton)
0280     {
0281         d->mngr->setFileFormatJPEG();
0282     }
0283     else if (button == d->tiffRadioButton)
0284     {
0285         d->mngr->setFileFormatTIFF();
0286     }
0287     else if (button == d->hdrRadioButton)
0288     {
0289         d->mngr->setFileFormatHDR();
0290     }
0291 }
0292 
0293 void PanoIntroPage::slotBinariesChanged(bool found)
0294 {
0295     setComplete(found);
0296     Q_EMIT completeChanged();
0297 }
0298 
0299 /*
0300 // TODO HDR
0301 void PanoIntroPage::slotShowFileFormat(int state)
0302 {
0303     d->mngr->setHDR(state);
0304 
0305     if (state)
0306     {
0307         d->formatGroupBox->setEnabled(false);
0308     }
0309     else
0310     {
0311         d->formatGroupBox->setEnabled(true);
0312     }
0313 }
0314 */
0315 
0316 void PanoIntroPage::initializePage()
0317 {
0318     setComplete(d->binariesWidget->allBinariesFound());
0319     Q_EMIT completeChanged();
0320 }
0321 
0322 } // namespace DigikamGenericPanoramaPlugin
0323 
0324 #include "moc_panointropage.cpp"