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"