File indexing completed on 2025-03-09 03:57:08

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2010-11-14
0007  * Description : process dialog for renaming files
0008  *
0009  * SPDX-FileCopyrightText: 2010-2012 by Andi Clemens <andi dot clemens at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "advancedrenameprocessdialog.h"
0016 
0017 // Qt includes
0018 
0019 #include <QDialogButtonBox>
0020 #include <QAbstractButton>
0021 #include <QCloseEvent>
0022 #include <QMessageBox>
0023 #include <QPixmap>
0024 #include <QPointer>
0025 #include <QTimer>
0026 #include <QDir>
0027 
0028 // KDE includes
0029 
0030 #include <klocalizedstring.h>
0031 
0032 // Local includes
0033 
0034 #include "dio.h"
0035 #include "thumbnailloadthread.h"
0036 
0037 namespace Digikam
0038 {
0039 
0040 class Q_DECL_HIDDEN AdvancedRenameProcessDialog::Private
0041 {
0042 public:
0043 
0044     explicit Private()
0045         : thumbLoadThread(nullptr),
0046           overwrite      (false),
0047           cancel         (false)
0048     {
0049     }
0050 
0051     ThumbnailLoadThread* thumbLoadThread;
0052 
0053     NewNameInfo          currentInfo;
0054     NewNamesList         newNameList;
0055     NewNamesList         failedList;
0056 
0057     bool                 overwrite;
0058     bool                 cancel;
0059 
0060     QPixmap              thumbPixmap;
0061     QString              thumbPath;
0062     QString              infoLabel;
0063 };
0064 
0065 AdvancedRenameProcessDialog::AdvancedRenameProcessDialog(const NewNamesList& list, QWidget* const parent)
0066     : DProgressDlg(parent),
0067       d           (new Private)
0068 {
0069     d->newNameList     = list;
0070     d->thumbLoadThread = new ThumbnailLoadThread;
0071     d->infoLabel       = i18n("<b>Renaming images. Please wait...</b>");
0072 
0073     connect(d->thumbLoadThread, SIGNAL(signalThumbnailLoaded(LoadingDescription,QPixmap)),
0074             this, SLOT(slotGotThumbnail(LoadingDescription,QPixmap)));
0075 
0076     connect(DIO::instance(), SIGNAL(signalRenameFailed(QUrl)),
0077             this, SLOT(slotRenameFailed(QUrl)));
0078 
0079     connect(DIO::instance(), SIGNAL(signalRenameFinished()),
0080             this, SLOT(slotRenameFinished()));
0081 
0082     setValue(0);
0083     setModal(true);
0084     setLabel(d->infoLabel);
0085     setButtonText(i18nc("@action:button", "&Abort"));
0086     setTitle(i18n("Processing..."));
0087     setWindowTitle(i18nc("@title:window", "Renaming Images"));
0088 
0089     getNextThumbnail();
0090     setMaximum(d->newNameList.count());
0091     QTimer::singleShot(500, this, SLOT(slotRenameImages()));
0092 }
0093 
0094 AdvancedRenameProcessDialog::~AdvancedRenameProcessDialog()
0095 {
0096     delete d->thumbLoadThread;
0097     delete d;
0098 }
0099 
0100 void AdvancedRenameProcessDialog::slotRenameImages()
0101 {
0102     if (d->newNameList.isEmpty())
0103     {
0104         slotCancel();
0105         return;
0106     }
0107 
0108     processOne();
0109 }
0110 
0111 void AdvancedRenameProcessDialog::processOne()
0112 {
0113     if (d->cancel || d->newNameList.isEmpty())
0114     {
0115         return;
0116     }
0117 
0118     d->currentInfo = d->newNameList.takeFirst();
0119 
0120     addedAction(d->thumbPixmap,
0121                 QDir::toNativeSeparators(d->thumbPath));
0122 
0123     DIO::rename(d->currentInfo.first,
0124                 d->currentInfo.second, d->overwrite);
0125 
0126     getNextThumbnail();
0127 }
0128 
0129 void AdvancedRenameProcessDialog::complete()
0130 {
0131     done(QDialogButtonBox::Cancel);
0132 }
0133 
0134 void AdvancedRenameProcessDialog::slotGotThumbnail(const LoadingDescription& desc, const QPixmap& pix)
0135 {
0136     d->thumbPixmap = pix;
0137     d->thumbPath   = desc.filePath;
0138 }
0139 
0140 void AdvancedRenameProcessDialog::slotCancel()
0141 {
0142     abort();
0143     done(QDialogButtonBox::Cancel);
0144 }
0145 
0146 void AdvancedRenameProcessDialog::slotRenameFinished()
0147 {
0148     if (d->cancel)
0149     {
0150         return;
0151     }
0152 
0153     advance(1);
0154 
0155     if (d->newNameList.isEmpty())
0156     {
0157         if (!d->failedList.isEmpty())
0158         {
0159             QPointer<QMessageBox> msgBox = new QMessageBox(QMessageBox::Warning,
0160                      i18nc("@title:window", "Renaming Images"),
0161                      i18np("An error occurred while renaming %1 image.\n"
0162                            "Do you want to rename this image again or "
0163                            "rename this image by overwriting?",
0164                            "An error occurred while renaming %1 images.\n"
0165                            "Do you want to rename these images again or "
0166                            "rename these images by overwriting?",
0167                            d->failedList.count()),
0168                      QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, this);
0169 
0170             msgBox->button(QMessageBox::Yes)->setText(i18nc("@action:button", "Rename Again"));
0171             msgBox->button(QMessageBox::Yes)->setIcon(QIcon::fromTheme(QLatin1String("document-edit")));
0172             msgBox->button(QMessageBox::No)->setText(i18nc("@action:button", "Overwrite"));
0173             msgBox->button(QMessageBox::No)->setIcon(QIcon::fromTheme(QLatin1String("edit-copy")));
0174 
0175             int result = msgBox->exec();
0176             delete msgBox;
0177 
0178             if      (result == QMessageBox::Cancel)
0179             {
0180                 d->failedList.clear();
0181                 complete();
0182             }
0183             else if (result == QMessageBox::No)
0184             {
0185                 d->newNameList = d->failedList;
0186                 d->failedList.clear();
0187                 d->overwrite   = true;
0188 
0189                 setValue(0);
0190                 getNextThumbnail();
0191                 setLabel(d->infoLabel);
0192                 setMaximum(d->newNameList.count());
0193                 QTimer::singleShot(500, this, SLOT(slotRenameImages()));
0194             }
0195             else
0196             {
0197                 complete();
0198             }
0199         }
0200         else
0201         {
0202             complete();
0203         }
0204     }
0205     else
0206     {
0207         processOne();
0208     }
0209 }
0210 
0211 void AdvancedRenameProcessDialog::slotRenameFailed(const QUrl& url)
0212 {
0213     if (d->cancel || (d->currentInfo.first != url))
0214     {
0215         return;
0216     }
0217 
0218     d->failedList << d->currentInfo;
0219 
0220     setLabel(i18n("<b>Renaming images. Errors: %1</b>",
0221                   d->failedList.count()));
0222 }
0223 
0224 void AdvancedRenameProcessDialog::closeEvent(QCloseEvent* e)
0225 {
0226     abort();
0227     e->accept();
0228 }
0229 
0230 void AdvancedRenameProcessDialog::abort()
0231 {
0232     d->cancel = true;
0233     d->failedList.clear();
0234 }
0235 
0236 QList<QUrl> AdvancedRenameProcessDialog::failedUrls() const
0237 {
0238     QList<QUrl> failedUrls;
0239 
0240     Q_FOREACH (const NewNameInfo& info, d->failedList)
0241     {
0242         failedUrls << info.first;
0243     }
0244 
0245     return failedUrls;
0246 }
0247 
0248 void AdvancedRenameProcessDialog::getNextThumbnail()
0249 {
0250     if (!d->newNameList.isEmpty())
0251     {
0252         QString path = d->newNameList.first().first.toLocalFile();
0253         d->thumbLoadThread->find(ThumbnailIdentifier(path));
0254     }
0255 }
0256 
0257 } // namespace Digikam
0258 
0259 #include "moc_advancedrenameprocessdialog.cpp"