"Fossies" - the Fresh Open Source Software Archive

Member "digikam-6.3.0/core/dplugins/generic/tools/panorama/wizard/panolastpage.cpp" (4 Sep 2019, 12365 Bytes) of package /linux/misc/digikam-6.3.0.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "panolastpage.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 6.2.0_vs_6.3.0.

    1 /* ============================================================
    2  *
    3  * This file is a part of digiKam project
    4  * https://www.digikam.org
    5  *
    6  * Date        : 2011-05-23
    7  * Description : a tool to create panorama by fusion of several images.
    8  * Acknowledge : based on the expoblending tool
    9  *
   10  * Copyright (C) 2011-2016 by Benjamin Girault <benjamin dot girault at gmail dot com>
   11  * Copyright (C) 2009-2019 by Gilles Caulier <caulier dot gilles at gmail dot com>
   12  *
   13  * This program is free software; you can redistribute it
   14  * and/or modify it under the terms of the GNU General
   15  * Public License as published by the Free Software Foundation;
   16  * either version 2, or (at your option) any later version.
   17  *
   18  * This program is distributed in the hope that it will be useful,
   19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21  * GNU General Public License for more details.
   22  *
   23  * ============================================================ */
   24 
   25 #include "panolastpage.h"
   26 
   27 // Qt includes
   28 
   29 #include <QUrl>
   30 #include <QFile>
   31 #include <QDir>
   32 #include <QLabel>
   33 #include <QPixmap>
   34 #include <QGroupBox>
   35 #include <QVBoxLayout>
   36 #include <QCheckBox>
   37 #include <QStandardPaths>
   38 #include <QLineEdit>
   39 
   40 // KDE includes
   41 
   42 #include <klocalizedstring.h>
   43 #include <kconfiggroup.h>
   44 #include <kconfig.h>
   45 
   46 // Local includes
   47 
   48 #include "digikam_debug.h"
   49 #include "panomanager.h"
   50 #include "panoactionthread.h"
   51 #include "dlayoutbox.h"
   52 
   53 namespace DigikamGenericPanoramaPlugin
   54 {
   55 
   56 class Q_DECL_HIDDEN PanoLastPage::Private
   57 {
   58 public:
   59 
   60     explicit Private()
   61       : copyDone(false),
   62         title(nullptr),
   63         saveSettingsGroupBox(nullptr),
   64         fileTemplateQLineEdit(nullptr),
   65         savePtoCheckBox(nullptr),
   66         warningLabel(nullptr),
   67         errorLabel(nullptr),
   68         mngr(nullptr)
   69     {
   70     }
   71 
   72     bool         copyDone;
   73 
   74     QLabel*      title;
   75 
   76     QGroupBox*   saveSettingsGroupBox;
   77     QLineEdit*   fileTemplateQLineEdit;
   78     QCheckBox*   savePtoCheckBox;
   79     QLabel*      warningLabel;
   80     QLabel*      errorLabel;
   81 
   82     PanoManager* mngr;
   83 };
   84 
   85 PanoLastPage::PanoLastPage(PanoManager* const mngr, QWizard* const dlg)
   86      : DWizardPage(dlg, i18nc("@title:window", "<b>Panorama Stitched</b>")),
   87        d(new Private)
   88 {
   89     KConfig config;
   90     KConfigGroup group        = config.group("Panorama Settings");
   91 
   92     d->mngr                   = mngr;
   93 
   94     DVBox* const vbox         = new DVBox(this);
   95 
   96     d->title                  = new QLabel(vbox);
   97     d->title->setOpenExternalLinks(true);
   98     d->title->setWordWrap(true);
   99 
  100     QVBoxLayout* const formatVBox = new QVBoxLayout();
  101 
  102     d->saveSettingsGroupBox   = new QGroupBox(i18nc("@title:group", "Save Settings"), vbox);
  103     d->saveSettingsGroupBox->setLayout(formatVBox);
  104     formatVBox->addStretch(1);
  105 
  106     QLabel* const fileTemplateLabel = new QLabel(i18nc("@label:textbox", "File name template:"), d->saveSettingsGroupBox);
  107     formatVBox->addWidget(fileTemplateLabel);
  108 
  109     d->fileTemplateQLineEdit  = new QLineEdit(QLatin1String("panorama"), d->saveSettingsGroupBox);
  110     d->fileTemplateQLineEdit->setToolTip(i18nc("@info:tooltip", "Name of the panorama file (without its extension)."));
  111     d->fileTemplateQLineEdit->setWhatsThis(i18nc("@info:whatsthis", "<b>File name template</b>: Set here the base name of the files that "
  112                                                 "will be saved. For example, if your template is <i>panorama</i> and if "
  113                                                 "you chose a JPEG output, then your panorama will be saved with the "
  114                                                 "name <i>panorama.jpg</i>. If you choose to save also the project file, "
  115                                                 "it will have the name <i>panorama.pto</i>."));
  116     formatVBox->addWidget(d->fileTemplateQLineEdit);
  117 
  118     d->savePtoCheckBox        = new QCheckBox(i18nc("@option:check", "Save project file"), d->saveSettingsGroupBox);
  119     d->savePtoCheckBox->setChecked(group.readEntry("Save PTO", false));
  120     d->savePtoCheckBox->setToolTip(i18nc("@info:tooltip", "Save the project file for further processing within Hugin GUI."));
  121     d->savePtoCheckBox->setWhatsThis(i18nc("@info:whatsthis", "<b>Save project file</b>: You can keep the project file generated to stitch "
  122                                           "your panorama for further tweaking within "
  123                                           "<a href=\"http://hugin.sourceforge.net/\">Hugin</a> by checking this. "
  124                                           "This is useful if you want a different projection, modify the horizon or "
  125                                           "the center of the panorama, or modify the control points to get better results."));
  126     formatVBox->addWidget(d->savePtoCheckBox);
  127 
  128     d->warningLabel = new QLabel(d->saveSettingsGroupBox);
  129     d->warningLabel->hide();
  130     formatVBox->addWidget(d->warningLabel);
  131 
  132     d->errorLabel = new QLabel(d->saveSettingsGroupBox);
  133     d->errorLabel->hide();
  134     formatVBox->addWidget(d->errorLabel);
  135 
  136     vbox->setStretchFactor(new QWidget(vbox), 2);
  137 
  138     setPageWidget(vbox);
  139 
  140     QPixmap leftPix(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/data/assistant-hugin.png")));
  141     setLeftBottomPix(leftPix.scaledToWidth(128, Qt::SmoothTransformation));
  142 
  143     connect(d->fileTemplateQLineEdit, SIGNAL(textChanged(QString)),
  144             this, SLOT(slotTemplateChanged(QString)));
  145 
  146     connect(d->savePtoCheckBox, SIGNAL(stateChanged(int)),
  147             this, SLOT(slotPtoCheckBoxChanged(int)));
  148 }
  149 
  150 PanoLastPage::~PanoLastPage()
  151 {
  152     KConfig config;
  153     KConfigGroup group = config.group("Panorama Settings");
  154     group.writeEntry("Save PTO", d->savePtoCheckBox->isChecked());
  155     config.sync();
  156 
  157     delete d;
  158 }
  159 
  160 void PanoLastPage::copyFiles()
  161 {
  162     connect(d->mngr->thread(), SIGNAL(jobCollectionFinished(DigikamGenericPanoramaPlugin::PanoActionData)),
  163             this, SLOT(slotPanoAction(DigikamGenericPanoramaPlugin::PanoActionData)));
  164 
  165     QUrl panoUrl = d->mngr->preProcessedMap().begin().key().adjusted(QUrl::RemoveFilename);
  166     panoUrl.setPath(panoUrl.path() + panoFileName(d->fileTemplateQLineEdit->text()));
  167 
  168     d->mngr->thread()->copyFiles(d->mngr->panoPtoUrl(),
  169                                  d->mngr->panoUrl(),
  170                                  panoUrl,
  171                                  d->mngr->preProcessedMap(),
  172                                  d->savePtoCheckBox->isChecked(),
  173                                  d->mngr->gPano()
  174                                 );
  175 }
  176 
  177 QString PanoLastPage::panoFileName(const QString& fileTemplate) const
  178 {
  179     switch (d->mngr->format())
  180     {
  181         default:
  182         case JPEG:
  183             return fileTemplate + QLatin1String(".jpg");
  184         case TIFF:
  185             return fileTemplate + QLatin1String(".tif");
  186     }
  187 }
  188 
  189 void PanoLastPage::checkFiles()
  190 {
  191     QString dir = d->mngr->preProcessedMap().begin().key().toString(QUrl::RemoveFilename);
  192     QUrl panoUrl(dir + panoFileName(d->fileTemplateQLineEdit->text()));
  193     QUrl ptoUrl(dir + d->fileTemplateQLineEdit->text() + QLatin1String(".pto"));
  194     QFile panoFile(panoUrl.toString(QUrl::PreferLocalFile));
  195     QFile ptoFile(ptoUrl.toString(QUrl::PreferLocalFile));
  196 
  197     bool rawsOk = true;
  198 
  199     if (d->savePtoCheckBox->isChecked())
  200     {
  201         for (auto& input : d->mngr->preProcessedMap().keys())
  202         {
  203             if (input != d->mngr->preProcessedMap()[input].preprocessedUrl)
  204             {
  205                 QString dir2 = input.toString(QUrl::RemoveFilename);
  206                 QUrl derawUrl(dir2 + d->mngr->preProcessedMap()[input].preprocessedUrl.fileName());
  207                 QFile derawFile(derawUrl.toString(QUrl::PreferLocalFile));
  208                 rawsOk &= !derawFile.exists();
  209             }
  210         }
  211     }
  212 
  213     if (panoFile.exists() || (d->savePtoCheckBox->isChecked() && ptoFile.exists()))
  214     {
  215         setComplete(false);
  216         emit completeChanged();
  217         d->warningLabel->setText(i18n("<qt><p><font color=\"red\"><b>Warning:</b> "
  218                                       "This file already exists.</font></p></qt>"));
  219         d->warningLabel->show();
  220     }
  221     else if (!rawsOk)
  222     {
  223         setComplete(true);
  224         emit completeChanged();
  225         d->warningLabel->setText(i18n("<qt><p><font color=\"orange\"><b>Warning:</b> "
  226                                       "One or more converted raw files already exists (they will be skipped during the copying process).</font></p></qt>"));
  227         d->warningLabel->show();
  228     }
  229     else
  230     {
  231         setComplete(true);
  232         emit completeChanged();
  233         d->warningLabel->hide();
  234     }
  235 }
  236 
  237 void PanoLastPage::initializePage()
  238 {
  239     QString first = d->mngr->itemsList().first().fileName();
  240     QString last  = d->mngr->itemsList().last().fileName();
  241     QString file  = QString::fromLatin1("%1-%2")
  242         .arg(first.left(first.lastIndexOf(QLatin1Char('.'))))
  243         .arg(last.left(last.lastIndexOf(QLatin1Char('.'))));
  244     d->fileTemplateQLineEdit->setText(file);
  245 
  246     checkFiles();
  247 }
  248 
  249 bool PanoLastPage::validatePage()
  250 {
  251     if (d->copyDone)
  252         return true;
  253 
  254     setComplete(false);
  255     copyFiles();
  256 
  257     return false;
  258 }
  259 
  260 void PanoLastPage::slotTemplateChanged(const QString&)
  261 {
  262     d->title->setText(i18n("<qt>"
  263                            "<p><h1><b>Panorama Stitching is Done</b></h1></p>"
  264                            "<p>Congratulations. Your images are stitched into a panorama.</p>"
  265                            "<p>Your panorama will be created to the directory:<br />"
  266                            "<b>%1</b><br />"
  267                            "once you press the <i>Finish</i> button, with the name set below.</p>"
  268                            "<p>If you choose to save the project file, and "
  269                            "if your images were raw images then the converted images used during "
  270                            "the stitching process will be copied at the same time (those are "
  271                            "TIFF files that can be big).</p>"
  272                            "</qt>",
  273                            QDir::toNativeSeparators(d->mngr->preProcessedMap().begin().key().toString(QUrl::RemoveFilename | QUrl::PreferLocalFile))
  274                           ));
  275     checkFiles();
  276 }
  277 
  278 void PanoLastPage::slotPtoCheckBoxChanged(int)
  279 {
  280     checkFiles();
  281 }
  282 
  283 void PanoLastPage::slotPanoAction(const DigikamGenericPanoramaPlugin::PanoActionData& ad)
  284 {
  285     qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "SlotPanoAction (lastPage)";
  286     qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "starting, success, action:" << ad.starting << ad.success << ad.action;
  287 
  288     if (!ad.starting)           // Something is complete...
  289     {
  290         if (!ad.success)        // Something is failed...
  291         {
  292             switch (ad.action)
  293             {
  294                 case PANO_COPY:
  295                 {
  296                     disconnect(d->mngr->thread(), SIGNAL(jobCollectionFinished(DigikamGenericPanoramaPlugin::PanoActionData)),
  297                                this, SLOT(slotPanoAction(DigikamGenericPanoramaPlugin::PanoActionData)));
  298 
  299                     d->errorLabel->setText(i18n("<qt><p><font color=\"red\"><b>Error:</b> "
  300                                                  "%1</font></p></qt>", ad.message));
  301                     d->errorLabel->show();
  302                     break;
  303                 }
  304                 default:
  305                 {
  306                     qCWarning(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Unknown action (last) " << ad.action;
  307                     break;
  308                 }
  309             }
  310         }
  311         else                    // Something is done...
  312         {
  313             switch (ad.action)
  314             {
  315                 case PANO_COPY:
  316                 {
  317                     disconnect(d->mngr->thread(), SIGNAL(jobCollectionFinished(DigikamGenericPanoramaPlugin::PanoActionData)),
  318                                this, SLOT(slotPanoAction(DigikamGenericPanoramaPlugin::PanoActionData)));
  319 
  320                     d->copyDone = true;
  321                     emit signalCopyFinished();
  322                     break;
  323                 }
  324                 default:
  325                 {
  326                     qCWarning(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Unknown action (last) " << ad.action;
  327                     break;
  328                 }
  329             }
  330         }
  331     }
  332 }
  333 
  334 } // namespace DigikamGenericPanoramaPlugin