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

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2000-12-05
0007  * Description : helper class used to modify physical albums in views
0008  *
0009  * SPDX-FileCopyrightText: 2009-2011 by Johannes Wienke <languitar at semipol dot de>
0010  * SPDX-FileCopyrightText: 2014-2015 by Mohamed_Anwer <m_dot_anwer at gmx dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "albummodificationhelper.h"
0017 
0018 // Qt includes
0019 
0020 #include <QApplication>
0021 #include <QDirIterator>
0022 #include <QInputDialog>
0023 #include <QMessageBox>
0024 #include <QAction>
0025 #include <QUrl>
0026 
0027 // KDE includes
0028 
0029 #include <klocalizedstring.h>
0030 
0031 // Local includes
0032 
0033 #include "digikam_debug.h"
0034 #include "albummanager.h"
0035 #include "albumpropsedit.h"
0036 #include "albumpointer.h"
0037 #include "applicationsettings.h"
0038 #include "collectionmanager.h"
0039 #include "deletedialog.h"
0040 #include "dio.h"
0041 #include "itemiconview.h"
0042 #include "digikamapp.h"
0043 #include "coredb.h"
0044 #include "coredbaccess.h"
0045 
0046 namespace Digikam
0047 {
0048 
0049 class Q_DECL_HIDDEN AlbumModificationHelper::Private
0050 {
0051 public:
0052 
0053     explicit Private()
0054       : dialogParent(nullptr)
0055     {
0056     }
0057 
0058     QWidget*     dialogParent;
0059 };
0060 
0061 AlbumModificationHelper::AlbumModificationHelper(QObject* const parent, QWidget* const dialogParent)
0062     : QObject(parent),
0063       d(new Private)
0064 {
0065     d->dialogParent = dialogParent;
0066 }
0067 
0068 AlbumModificationHelper::~AlbumModificationHelper()
0069 {
0070     delete d;
0071 }
0072 
0073 void AlbumModificationHelper::bindAlbum(QAction* const action, PAlbum* const album) const
0074 {
0075     action->setData(QVariant::fromValue(AlbumPointer<PAlbum>(album)));
0076 }
0077 
0078 PAlbum* AlbumModificationHelper::boundAlbum(QObject* const sender) const
0079 {
0080     QAction* action = nullptr;
0081 
0082     if ((action = qobject_cast<QAction*>(sender)))
0083     {
0084         return action->data().value<AlbumPointer<PAlbum> >();
0085     }
0086 
0087     return nullptr;
0088 }
0089 
0090 PAlbum* AlbumModificationHelper::slotAlbumNew()
0091 {
0092     return slotAlbumNew(boundAlbum(sender()));
0093 }
0094 
0095 PAlbum* AlbumModificationHelper::slotAlbumNew(PAlbum* parent)
0096 {
0097     if (!parent)
0098     {
0099         qCWarning(DIGIKAM_GENERAL_LOG) << "No parent album given";
0100         return nullptr;
0101     }
0102 
0103     ApplicationSettings* settings = ApplicationSettings::instance();
0104 
0105     if (!settings)
0106     {
0107         qCWarning(DIGIKAM_GENERAL_LOG) << "could not get Album Settings";
0108         return nullptr;
0109     }
0110 
0111 /*
0112     QDir libraryDir(settings->getAlbumLibraryPath());
0113 
0114     if (!libraryDir.exists())
0115     {
0116         QMessageBox::critical(qApp->activeWindow(), qApp->applicationName(),
0117                               i18n("The album library has not been set correctly.\n"
0118                                    "Select \"Configure Digikam\" from the Settings "
0119                                    "menu and choose a folder to use for the album "
0120                                    "library."));
0121         return;
0122     }
0123 */
0124 
0125     // if we create an album under root, need to supply the album root path.
0126 
0127     QString albumRootPath;
0128 
0129     albumRootPath = CollectionManager::instance()->albumRootPath(parent->albumRootId());
0130 
0131     QString     title;
0132     QString     comments;
0133     QString     category;
0134     QDate       date;
0135     QStringList albumCategories;
0136     int         parentSelector;
0137 
0138     if (!AlbumPropsEdit::createNew(parent, title, comments, date, category,
0139                                    albumCategories, parentSelector))
0140     {
0141         return nullptr;
0142     }
0143 
0144     QStringList oldAlbumCategories(ApplicationSettings::instance()->getAlbumCategoryNames());
0145 
0146     if (albumCategories != oldAlbumCategories)
0147     {
0148         ApplicationSettings::instance()->setAlbumCategoryNames(albumCategories);
0149     }
0150 
0151     QString errMsg;
0152     PAlbum* album = nullptr;
0153 
0154     if (parent->isRoot() || (parentSelector == 1))
0155     {
0156         album = AlbumManager::instance()->createPAlbum(albumRootPath, title, comments,
0157                                                        date, category, errMsg);
0158     }
0159     else
0160     {
0161         album = AlbumManager::instance()->createPAlbum(parent, title, comments,
0162                                                        date, category, errMsg);
0163     }
0164 
0165     if (!album)
0166     {
0167         QMessageBox::critical(qApp->activeWindow(), qApp->applicationName(), errMsg);
0168 
0169         return nullptr;
0170     }
0171 
0172     return album;
0173 }
0174 
0175 void AlbumModificationHelper::slotAlbumDelete()
0176 {
0177     slotAlbumDelete(boundAlbum(sender()));
0178 }
0179 
0180 void AlbumModificationHelper::slotAlbumDelete(PAlbum* album)
0181 {
0182     if (!album || album->isRoot() || album->isAlbumRoot())
0183     {
0184         return;
0185     }
0186 
0187     // find subalbums
0188 
0189     QList<QUrl> childrenList;
0190     addAlbumChildrenToList(childrenList, album);
0191 
0192     DeleteDialog dialog(d->dialogParent);
0193 
0194     // All subalbums will be presented in the list as well
0195 
0196     if (!dialog.confirmDeleteList(childrenList,
0197                                   (childrenList.size() == 1) ? DeleteDialogMode::Albums
0198                                                              : DeleteDialogMode::Subalbums,
0199                                   DeleteDialogMode::UserPreference))
0200     {
0201         return;
0202     }
0203 
0204     bool useTrash = !dialog.shouldDelete();
0205     QFileInfo fileInfo(album->folderPath());
0206 
0207     // If the trash is used no check is necessary, as the trash lists all files
0208     // and only perform this check if the album is a directory
0209 
0210     if (!useTrash && fileInfo.isDir())
0211     {
0212         QStringList imageTypes, audioTypes, videoTypes, allTypes, foundTypes;
0213         QDirIterator it(fileInfo.path(), QDir::Files, QDirIterator::Subdirectories);
0214 
0215         CoreDbAccess().db()->getFilterSettings(&imageTypes, &videoTypes, &audioTypes);
0216         allTypes << imageTypes << audioTypes << videoTypes;
0217         bool notEmpty = false;
0218 
0219         while (it.hasNext())
0220         {
0221             it.next();
0222             QString ext = it.fileInfo().suffix().toLower();
0223 
0224             if      (!allTypes.contains(ext) && !foundTypes.contains(ext))
0225             {
0226                 foundTypes << ext;
0227             }
0228             else if (allTypes.contains(ext) && !notEmpty)
0229             {
0230                 notEmpty = true;
0231             }
0232         }
0233 
0234         if      (!foundTypes.isEmpty())
0235         {
0236             foundTypes.sort();
0237 
0238             QString found = foundTypes.join(QLatin1String(", "));
0239 
0240             int result    = QMessageBox::warning(qApp->activeWindow(), qApp->applicationName(),
0241                                                  i18n("<p>The album you want to delete contains files "
0242                                                       "(%1) which are not displayed in digiKam.</p>"
0243                                                       "<p>Do you want to continue?</p>", found),
0244                                                  QMessageBox::Yes | QMessageBox::No);
0245 
0246             if (result != QMessageBox::Yes)
0247             {
0248                 return;
0249             }
0250         }
0251         else if (notEmpty)
0252         {
0253             int result    = QMessageBox::warning(qApp->activeWindow(), qApp->applicationName(),
0254                                                  i18n("<p>The album you want to delete is not empty.</p>"
0255                                                       "<p>Do you want to continue?</p>"),
0256                                                  QMessageBox::Yes | QMessageBox::No);
0257 
0258             if (result != QMessageBox::Yes)
0259             {
0260                 return;
0261             }
0262         }
0263     }
0264 
0265     DIO::del(album, useTrash);
0266 }
0267 
0268 void AlbumModificationHelper::slotAlbumRename()
0269 {
0270     slotAlbumRename(boundAlbum(sender()));
0271 }
0272 
0273 void AlbumModificationHelper::slotAlbumRename(PAlbum* album)
0274 {
0275     if (!album)
0276     {
0277         return;
0278     }
0279 
0280     QString oldTitle(album->title());
0281 
0282     QPointer<QInputDialog> textDlg = new QInputDialog(d->dialogParent);
0283 
0284     if (!album->isAlbumRoot())
0285     {
0286         textDlg->setWindowTitle(i18nc("@title:window", "Rename Album (%1)", oldTitle));
0287     }
0288     else
0289     {
0290         textDlg->setWindowTitle(i18nc("@title:window", "Rename Album Root (%1)", oldTitle));
0291     }
0292 
0293     textDlg->setLabelText(i18n("Enter new album name:"));
0294     textDlg->resize(450, textDlg->sizeHint().height());
0295     textDlg->setInputMode(QInputDialog::TextInput);
0296     textDlg->setTextEchoMode(QLineEdit::Normal);
0297     textDlg->setTextValue(oldTitle);
0298 
0299     if (textDlg->exec() != QDialog::Accepted)
0300     {
0301         delete textDlg;
0302         return;
0303     }
0304 
0305     QString title = textDlg->textValue().trimmed();
0306     delete textDlg;
0307 
0308     if (title != oldTitle)
0309     {
0310         if (album->isAlbumRoot())
0311         {
0312             CollectionLocation location =
0313                 CollectionManager::instance()->
0314                     locationForAlbumRootId(album->albumRootId());
0315 
0316             if (!location.isNull())
0317             {
0318                 CollectionManager::instance()->setLabel(location, title);
0319             }
0320         }
0321         else
0322         {
0323             QString errMsg;
0324 
0325             if (!AlbumManager::instance()->renamePAlbum(album, title, errMsg))
0326             {
0327                 QMessageBox::critical(qApp->activeWindow(), qApp->applicationName(), errMsg);
0328             }
0329         }
0330     }
0331 }
0332 
0333 void AlbumModificationHelper::addAlbumChildrenToList(QList<QUrl>& list, Album* const album)
0334 {
0335     // simple recursive helper function
0336 
0337     if (album)
0338     {
0339         if (!list.contains(album->databaseUrl()))
0340         {
0341             list.append(album->databaseUrl());
0342         }
0343 
0344         AlbumIterator it(album);
0345 
0346         while (it.current())
0347         {
0348             addAlbumChildrenToList(list, *it);
0349             ++it;
0350         }
0351     }
0352 }
0353 
0354 void AlbumModificationHelper::slotAlbumEdit()
0355 {
0356     slotAlbumEdit(boundAlbum(sender()));
0357 }
0358 
0359 void AlbumModificationHelper::slotAlbumEdit(PAlbum* album)
0360 {
0361     if (!album || album->isRoot() || album->isAlbumRoot())
0362     {
0363         return;
0364     }
0365 
0366     QString     oldTitle(album->title());
0367     QString     oldComments(album->caption());
0368     QString     oldCategory(album->category());
0369     QDate       oldDate(album->date());
0370     QStringList oldAlbumCategories(ApplicationSettings::instance()->getAlbumCategoryNames());
0371 
0372     QString     title, comments, category;
0373     QDate       date;
0374     QStringList albumCategories;
0375 
0376     if (AlbumPropsEdit::editProps(album, title, comments, date,
0377                                   category, albumCategories))
0378     {
0379         if (comments != oldComments)
0380         {
0381             album->setCaption(comments);
0382         }
0383 
0384         if ((date != oldDate) && date.isValid())
0385         {
0386             album->setDate(date);
0387         }
0388 
0389         if (category != oldCategory)
0390         {
0391             album->setCategory(category);
0392         }
0393 
0394         ApplicationSettings::instance()->setAlbumCategoryNames(albumCategories);
0395 
0396         // Do this last : so that if anything else changed we can
0397         // successfully save to the db with the old name
0398 
0399         if (title != oldTitle)
0400         {
0401             QString errMsg;
0402 
0403             if (!AlbumManager::instance()->renamePAlbum(album, title, errMsg))
0404             {
0405                 QMessageBox::critical(d->dialogParent, qApp->applicationName(), errMsg);
0406             }
0407         }
0408 
0409         // Resorting the tree View after changing metadata
0410 
0411         DigikamApp::instance()->view()->slotSortAlbums(ApplicationSettings::instance()->getAlbumSortRole());
0412     }
0413 }
0414 
0415 void AlbumModificationHelper::slotAlbumResetIcon(PAlbum* album)
0416 {
0417     if (!album)
0418     {
0419         return;
0420     }
0421 
0422     QString err;
0423     AlbumManager::instance()->updatePAlbumIcon(album, 0, err);
0424 }
0425 
0426 void AlbumModificationHelper::slotAlbumResetIcon()
0427 {
0428     slotAlbumResetIcon(boundAlbum(sender()));
0429 }
0430 
0431 } // namespace Digikam
0432 
0433 #include "moc_albummodificationhelper.cpp"