File indexing completed on 2025-01-05 03:53:08
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 * 0009 * SPDX-FileCopyrightText: 2011-2016 by Benjamin Girault <benjamin dot girault at gmail dot com> 0010 * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "panomanager.h" 0017 0018 // Qt includes 0019 0020 #include <QFile> 0021 #include <QSharedPointer> 0022 0023 // KDE includes 0024 0025 #include <ksharedconfig.h> 0026 #include <kconfiggroup.h> 0027 0028 // Local includes 0029 0030 #include "digikam_debug.h" 0031 #include "panowizard.h" 0032 #include "panoactionthread.h" 0033 #include "autooptimiserbinary.h" 0034 #include "cpcleanbinary.h" 0035 #include "cpfindbinary.h" 0036 #include "enblendbinary.h" 0037 #include "makebinary.h" 0038 #include "nonabinary.h" 0039 #include "panomodifybinary.h" 0040 #include "pto2mkbinary.h" 0041 #include "huginexecutorbinary.h" 0042 #include "ptofile.h" 0043 0044 namespace DigikamGenericPanoramaPlugin 0045 { 0046 0047 class Q_DECL_HIDDEN PanoManager::Private 0048 { 0049 public: 0050 0051 explicit Private() 0052 : basePtoData (nullptr), 0053 cpFindPtoData (nullptr), 0054 cpCleanPtoData (nullptr), 0055 autoOptimisePtoData (nullptr), 0056 viewAndCropOptimisePtoData (nullptr), 0057 previewPtoData (nullptr), 0058 panoPtoData (nullptr), 0059 hugin2015 (false), 0060 thread (nullptr), 0061 plugin (nullptr), 0062 wizard (nullptr), 0063 config (KSharedConfig::openConfig()), 0064 group (config->group(QLatin1String("Panorama Settings"))) 0065 { 0066 gPano = group.readEntry("GPano", false); 0067 /* 0068 hdr = group.readEntry("HDR", false); 0069 */ 0070 fileType = (PanoramaFileType) group.readEntry("File Type", (int) JPEG); 0071 } 0072 0073 ~Private() 0074 { 0075 /* 0076 group.writeEntry("HDR", hdr); 0077 */ 0078 group.writeEntry("GPano", gPano); 0079 group.writeEntry("File Type", (int) fileType); 0080 config->sync(); 0081 } 0082 0083 QList<QUrl> inputUrls; 0084 0085 QUrl basePtoUrl; 0086 QSharedPointer<PTOType> basePtoData; 0087 QUrl cpFindPtoUrl; 0088 QSharedPointer<PTOType> cpFindPtoData; 0089 QUrl cpCleanPtoUrl; 0090 QSharedPointer<PTOType> cpCleanPtoData; 0091 QUrl autoOptimisePtoUrl; 0092 QSharedPointer<PTOType> autoOptimisePtoData; 0093 QUrl viewAndCropOptimisePtoUrl; 0094 QSharedPointer<PTOType> viewAndCropOptimisePtoData; 0095 QUrl previewPtoUrl; 0096 QSharedPointer<PTOType> previewPtoData; 0097 QUrl panoPtoUrl; 0098 QSharedPointer<PTOType> panoPtoData; 0099 0100 QUrl previewMkUrl; 0101 QUrl previewUrl; 0102 QUrl mkUrl; 0103 QUrl panoUrl; 0104 0105 bool hugin2015; 0106 bool gPano; 0107 /* 0108 bool hdr; 0109 */ 0110 0111 PanoramaFileType fileType; 0112 0113 PanoramaItemUrlsMap preProcessedUrlsMap; 0114 0115 PanoActionThread* thread; 0116 0117 DPlugin* plugin; 0118 0119 AutoOptimiserBinary autoOptimiserBinary; 0120 CPCleanBinary cpCleanBinary; 0121 CPFindBinary cpFindBinary; 0122 EnblendBinary enblendBinary; 0123 MakeBinary makeBinary; 0124 NonaBinary nonaBinary; 0125 PanoModifyBinary panoModifyBinary; 0126 Pto2MkBinary pto2MkBinary; 0127 HuginExecutorBinary huginExecutorBinary; 0128 0129 PanoWizard* wizard; 0130 0131 private: 0132 0133 KSharedConfigPtr config; 0134 KConfigGroup group; 0135 }; 0136 0137 QPointer<PanoManager> PanoManager::internalPtr = QPointer<PanoManager>(); 0138 0139 PanoManager::PanoManager(QObject* const parent) 0140 : QObject(parent), 0141 d (new Private) 0142 { 0143 d->thread = new PanoActionThread(this); 0144 } 0145 0146 PanoManager::~PanoManager() 0147 { 0148 delete d->thread; 0149 delete d->wizard; 0150 delete d; 0151 } 0152 0153 PanoManager* PanoManager::instance() 0154 { 0155 if (PanoManager::internalPtr.isNull()) 0156 { 0157 PanoManager::internalPtr = new PanoManager(); 0158 } 0159 0160 return PanoManager::internalPtr; 0161 } 0162 0163 bool PanoManager::isCreated() 0164 { 0165 return (!internalPtr.isNull()); 0166 } 0167 0168 void PanoManager::checkForHugin2015() 0169 { 0170 if (d->autoOptimiserBinary.recheckDirectories()) 0171 { 0172 d->hugin2015 = d->autoOptimiserBinary.versionIsRight(2015.0); 0173 } 0174 0175 qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Hugin >= 2015.0 : " << d->hugin2015; 0176 } 0177 0178 bool PanoManager::checkBinaries() 0179 { 0180 bool result = d->autoOptimiserBinary.recheckDirectories() && 0181 d->cpCleanBinary.recheckDirectories() && 0182 d->cpFindBinary.recheckDirectories() && 0183 d->enblendBinary.recheckDirectories() && 0184 d->makeBinary.recheckDirectories() && 0185 d->nonaBinary.recheckDirectories(); 0186 0187 if (result) 0188 { 0189 if (d->hugin2015) 0190 { 0191 qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Check for Hugin Executor"; 0192 result = d->huginExecutorBinary.recheckDirectories(); 0193 } 0194 else 0195 { 0196 qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Check for Hugin Pto2Mk"; 0197 result = d->pto2MkBinary.recheckDirectories(); 0198 } 0199 } 0200 0201 return result; 0202 } 0203 0204 bool PanoManager::hugin2015() const 0205 { 0206 return d->hugin2015; 0207 } 0208 0209 void PanoManager::setGPano(bool gPano) 0210 { 0211 d->gPano = gPano; 0212 } 0213 0214 bool PanoManager::gPano() const 0215 { 0216 return d->gPano; 0217 } 0218 0219 /* 0220 void PanoManager::setHDR(bool hdr) 0221 { 0222 d->hdr = hdr; 0223 } 0224 0225 bool PanoManager::hdr() const 0226 { 0227 return d->hdr; 0228 } 0229 */ 0230 0231 void PanoManager::setFileFormatJPEG() 0232 { 0233 d->fileType = JPEG; 0234 } 0235 0236 void PanoManager::setFileFormatTIFF() 0237 { 0238 d->fileType = TIFF; 0239 } 0240 0241 void PanoManager::setFileFormatHDR() 0242 { 0243 d->fileType = HDR; 0244 } 0245 0246 PanoramaFileType PanoManager::format() const 0247 { 0248 return d->fileType; 0249 } 0250 0251 AutoOptimiserBinary& PanoManager::autoOptimiserBinary() const 0252 { 0253 return d->autoOptimiserBinary; 0254 } 0255 0256 CPCleanBinary& PanoManager::cpCleanBinary() const 0257 { 0258 return d->cpCleanBinary; 0259 } 0260 0261 CPFindBinary& PanoManager::cpFindBinary() const 0262 { 0263 return d->cpFindBinary; 0264 } 0265 0266 EnblendBinary& PanoManager::enblendBinary() const 0267 { 0268 return d->enblendBinary; 0269 } 0270 0271 MakeBinary& PanoManager::makeBinary() const 0272 { 0273 return d->makeBinary; 0274 } 0275 0276 NonaBinary& PanoManager::nonaBinary() const 0277 { 0278 return d->nonaBinary; 0279 } 0280 0281 PanoModifyBinary& PanoManager::panoModifyBinary() const 0282 { 0283 return d->panoModifyBinary; 0284 } 0285 0286 Pto2MkBinary& PanoManager::pto2MkBinary() const 0287 { 0288 return d->pto2MkBinary; 0289 } 0290 0291 HuginExecutorBinary& PanoManager::huginExecutorBinary() const 0292 { 0293 return d->huginExecutorBinary; 0294 } 0295 0296 QUrl& PanoManager::basePtoUrl() const 0297 { 0298 return d->basePtoUrl; 0299 } 0300 0301 QSharedPointer<PTOType> PanoManager::basePtoData() 0302 { 0303 if (d->basePtoData.isNull()) 0304 { 0305 PTOFile file(cpFindBinary().version()); 0306 file.openFile(d->basePtoUrl.toLocalFile()); 0307 d->basePtoData = QSharedPointer<PTOType>(file.getPTO()); 0308 0309 if (d->basePtoData.isNull()) 0310 { 0311 d->basePtoData = QSharedPointer<PTOType>(new PTOType(cpFindBinary().version())); 0312 } 0313 } 0314 0315 return d->basePtoData; 0316 } 0317 0318 void PanoManager::resetBasePto() 0319 { 0320 d->basePtoData.clear(); 0321 0322 QFile pto(d->basePtoUrl.toLocalFile()); 0323 0324 if (pto.exists()) 0325 { 0326 pto.remove(); 0327 } 0328 0329 d->basePtoUrl.clear(); 0330 } 0331 0332 QUrl& PanoManager::cpFindPtoUrl() const 0333 { 0334 return d->cpFindPtoUrl; 0335 } 0336 0337 QSharedPointer<PTOType> PanoManager::cpFindPtoData() 0338 { 0339 if (d->cpFindPtoData.isNull()) 0340 { 0341 PTOFile file(cpFindBinary().version()); 0342 file.openFile(d->cpFindPtoUrl.toLocalFile()); 0343 d->cpFindPtoData = QSharedPointer<PTOType>(file.getPTO()); 0344 0345 if (d->cpFindPtoData.isNull()) 0346 { 0347 d->cpFindPtoData = QSharedPointer<PTOType>(new PTOType(cpFindBinary().version())); 0348 } 0349 } 0350 0351 return d->cpFindPtoData; 0352 } 0353 0354 void PanoManager::resetCpFindPto() 0355 { 0356 d->cpFindPtoData.clear(); 0357 0358 QFile pto(d->cpFindPtoUrl.toLocalFile()); 0359 0360 if (pto.exists()) 0361 { 0362 pto.remove(); 0363 } 0364 0365 d->cpFindPtoUrl.clear(); 0366 } 0367 0368 QUrl& PanoManager::cpCleanPtoUrl() const 0369 { 0370 return d->cpCleanPtoUrl; 0371 } 0372 0373 QSharedPointer<PTOType> PanoManager::cpCleanPtoData() 0374 { 0375 if (d->cpCleanPtoData.isNull()) 0376 { 0377 PTOFile file(cpFindBinary().version()); 0378 file.openFile(d->cpCleanPtoUrl.toLocalFile()); 0379 d->cpCleanPtoData = QSharedPointer<PTOType>(file.getPTO()); 0380 0381 if (d->cpCleanPtoData.isNull()) 0382 { 0383 d->cpCleanPtoData = QSharedPointer<PTOType>(new PTOType(cpFindBinary().version())); 0384 } 0385 } 0386 0387 return d->cpCleanPtoData; 0388 } 0389 0390 void PanoManager::resetCpCleanPto() 0391 { 0392 d->cpCleanPtoData.clear(); 0393 0394 QFile pto(d->cpCleanPtoUrl.toLocalFile()); 0395 0396 if (pto.exists()) 0397 { 0398 pto.remove(); 0399 } 0400 0401 d->cpCleanPtoUrl.clear(); 0402 } 0403 0404 QUrl& PanoManager::autoOptimisePtoUrl() const 0405 { 0406 return d->autoOptimisePtoUrl; 0407 } 0408 0409 QSharedPointer<PTOType> PanoManager::autoOptimisePtoData() 0410 { 0411 if (d->autoOptimisePtoData.isNull()) 0412 { 0413 PTOFile file(cpFindBinary().version()); 0414 file.openFile(d->autoOptimisePtoUrl.toLocalFile()); 0415 d->autoOptimisePtoData = QSharedPointer<PTOType>(file.getPTO()); 0416 0417 if (d->autoOptimisePtoData.isNull()) 0418 { 0419 d->autoOptimisePtoData = QSharedPointer<PTOType>(new PTOType(cpFindBinary().version())); 0420 } 0421 } 0422 0423 return d->autoOptimisePtoData; 0424 } 0425 0426 void PanoManager::resetAutoOptimisePto() 0427 { 0428 d->autoOptimisePtoData.clear(); 0429 0430 QFile pto(d->autoOptimisePtoUrl.toLocalFile()); 0431 0432 if (pto.exists()) 0433 { 0434 pto.remove(); 0435 } 0436 0437 d->autoOptimisePtoUrl.clear(); 0438 } 0439 0440 QUrl& PanoManager::viewAndCropOptimisePtoUrl() const 0441 { 0442 return d->viewAndCropOptimisePtoUrl; 0443 } 0444 0445 QSharedPointer<PTOType> PanoManager::viewAndCropOptimisePtoData() 0446 { 0447 if (d->viewAndCropOptimisePtoData.isNull()) 0448 { 0449 PTOFile file(cpFindBinary().version()); 0450 file.openFile(d->viewAndCropOptimisePtoUrl.toLocalFile()); 0451 d->viewAndCropOptimisePtoData = QSharedPointer<PTOType>(file.getPTO()); 0452 0453 if (d->viewAndCropOptimisePtoData.isNull()) 0454 { 0455 d->viewAndCropOptimisePtoData = QSharedPointer<PTOType>(new PTOType(cpFindBinary().version())); 0456 } 0457 } 0458 0459 return d->viewAndCropOptimisePtoData; 0460 } 0461 0462 void PanoManager::resetViewAndCropOptimisePto() 0463 { 0464 d->viewAndCropOptimisePtoData.clear(); 0465 0466 QFile pto(d->viewAndCropOptimisePtoUrl.toLocalFile()); 0467 0468 if (pto.exists()) 0469 { 0470 pto.remove(); 0471 } 0472 0473 d->viewAndCropOptimisePtoUrl.clear(); 0474 } 0475 0476 QUrl& PanoManager::previewPtoUrl() const 0477 { 0478 return d->previewPtoUrl; 0479 } 0480 0481 QSharedPointer<PTOType> PanoManager::previewPtoData() 0482 { 0483 if (d->previewPtoData.isNull()) 0484 { 0485 PTOFile file(cpFindBinary().version()); 0486 file.openFile(d->previewPtoUrl.toLocalFile()); 0487 d->previewPtoData = QSharedPointer<PTOType>(file.getPTO()); 0488 0489 if (d->previewPtoData.isNull()) 0490 { 0491 d->previewPtoData = QSharedPointer<PTOType>(new PTOType(cpFindBinary().version())); 0492 } 0493 } 0494 0495 return d->previewPtoData; 0496 } 0497 0498 void PanoManager::resetPreviewPto() 0499 { 0500 d->previewPtoData.clear(); 0501 0502 QFile pto(d->previewPtoUrl.toLocalFile()); 0503 0504 if (pto.exists()) 0505 { 0506 pto.remove(); 0507 } 0508 0509 d->previewPtoUrl.clear(); 0510 } 0511 0512 QUrl& PanoManager::panoPtoUrl() const 0513 { 0514 return d->panoPtoUrl; 0515 } 0516 0517 QSharedPointer<PTOType> PanoManager::panoPtoData() 0518 { 0519 if (d->panoPtoData.isNull()) 0520 { 0521 PTOFile file(cpFindBinary().version()); 0522 file.openFile(d->panoPtoUrl.toLocalFile()); 0523 d->panoPtoData = QSharedPointer<PTOType>(file.getPTO()); 0524 0525 if (d->panoPtoData.isNull()) 0526 { 0527 d->panoPtoData = QSharedPointer<PTOType>(new PTOType(cpFindBinary().version())); 0528 } 0529 } 0530 0531 return d->panoPtoData; 0532 } 0533 0534 void PanoManager::resetPanoPto() 0535 { 0536 d->panoPtoData.clear(); 0537 0538 QFile pto(d->panoPtoUrl.toLocalFile()); 0539 0540 if (pto.exists()) 0541 { 0542 pto.remove(); 0543 } 0544 0545 d->panoPtoUrl.clear(); 0546 } 0547 0548 QUrl& PanoManager::previewMkUrl() const 0549 { 0550 return d->previewMkUrl; 0551 } 0552 0553 void PanoManager::resetPreviewMkUrl() 0554 { 0555 QFile pto(d->previewMkUrl.toLocalFile()); 0556 0557 if (pto.exists()) 0558 { 0559 pto.remove(); 0560 } 0561 0562 d->previewMkUrl.clear(); 0563 } 0564 0565 QUrl& PanoManager::previewUrl() const 0566 { 0567 return d->previewUrl; 0568 } 0569 0570 void PanoManager::resetPreviewUrl() 0571 { 0572 QFile pto(d->previewUrl.toLocalFile()); 0573 0574 if (pto.exists()) 0575 { 0576 pto.remove(); 0577 } 0578 0579 d->previewUrl.clear(); 0580 } 0581 0582 QUrl& PanoManager::mkUrl() const 0583 { 0584 return d->mkUrl; 0585 } 0586 0587 void PanoManager::resetMkUrl() 0588 { 0589 QFile pto(d->mkUrl.toLocalFile()); 0590 0591 if (pto.exists()) 0592 { 0593 pto.remove(); 0594 } 0595 0596 d->mkUrl.clear(); 0597 } 0598 0599 QUrl& PanoManager::panoUrl() const 0600 { 0601 return d->panoUrl; 0602 } 0603 0604 void PanoManager::resetPanoUrl() 0605 { 0606 QFile pto(d->panoUrl.toLocalFile()); 0607 0608 if (pto.exists()) 0609 { 0610 pto.remove(); 0611 } 0612 0613 d->panoUrl.clear(); 0614 } 0615 0616 void PanoManager::setItemsList(const QList<QUrl>& urls) 0617 { 0618 d->inputUrls = urls; 0619 } 0620 0621 QList<QUrl>& PanoManager::itemsList() const 0622 { 0623 return d->inputUrls; 0624 } 0625 0626 void PanoManager::setPlugin(DPlugin* const plugin) 0627 { 0628 d->plugin = plugin; 0629 } 0630 0631 void PanoManager::setPreProcessedMap(const PanoramaItemUrlsMap& urls) 0632 { 0633 d->preProcessedUrlsMap = urls; 0634 } 0635 0636 PanoramaItemUrlsMap& PanoManager::preProcessedMap() const 0637 { 0638 return d->preProcessedUrlsMap; 0639 } 0640 0641 PanoActionThread* PanoManager::thread() const 0642 { 0643 return d->thread; 0644 } 0645 0646 void PanoManager::run() 0647 { 0648 startWizard(); 0649 } 0650 0651 void PanoManager::startWizard() 0652 { 0653 if (d->wizard && (d->wizard->isMinimized() || !d->wizard->isHidden())) 0654 { 0655 d->wizard->showNormal(); // krazy:exclude=qmethods 0656 d->wizard->activateWindow(); 0657 d->wizard->raise(); 0658 } 0659 else 0660 { 0661 delete d->wizard; 0662 0663 d->wizard = new PanoWizard(this); 0664 d->wizard->setPlugin(d->plugin); 0665 d->wizard->show(); 0666 } 0667 } 0668 0669 } // namespace DigikamGenericPanoramaPlugin 0670 0671 #include "moc_panomanager.cpp"