File indexing completed on 2025-01-19 03:53:23

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-26-02
0007  * Description : a widget to select a physical album
0008  *
0009  * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2009-2010 by Johannes Wienke <languitar at semipol dot de>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "albumselectwidget.h"
0017 
0018 // Qt includes
0019 
0020 #include <QIcon>
0021 #include <QGridLayout>
0022 #include <QApplication>
0023 #include <QStyle>
0024 #include <QPushButton>
0025 #include <QAction>
0026 #include <QTimer>
0027 
0028 // KDE includes
0029 
0030 #include <kconfiggroup.h>
0031 #include <klocalizedstring.h>
0032 #include <ksharedconfig.h>
0033 
0034 // Local includes
0035 
0036 #include "digikam_debug.h"
0037 #include "album.h"
0038 #include "albummodificationhelper.h"
0039 #include "albumthumbnailloader.h"
0040 #include "collectionmanager.h"
0041 #include "contextmenuhelper.h"
0042 
0043 namespace Digikam
0044 {
0045 
0046 class Q_DECL_HIDDEN AlbumSelectTreeView::Private
0047 {
0048 public:
0049 
0050     explicit Private()
0051       : albumModificationHelper(nullptr),
0052         newAlbumAction         (nullptr)
0053     {
0054     }
0055 
0056     AlbumModificationHelper* albumModificationHelper;
0057     QAction*                 newAlbumAction;
0058 };
0059 
0060 AlbumSelectTreeView::AlbumSelectTreeView(AlbumModel* const model,
0061                                          AlbumModificationHelper* const albumModificationHelper,
0062                                          QWidget* const parent)
0063     : AlbumTreeView(parent),
0064       d            (new Private)
0065 {
0066     setAlbumModel(model);
0067     d->albumModificationHelper = albumModificationHelper;
0068     d->newAlbumAction          = new QAction(QIcon::fromTheme(QLatin1String("folder-new")),
0069                                              i18n("Create New Album"), this);
0070 }
0071 
0072 AlbumSelectTreeView::~AlbumSelectTreeView()
0073 {
0074     delete d;
0075 }
0076 
0077 void AlbumSelectTreeView::addCustomContextMenuActions(ContextMenuHelper& cmh, Album* album)
0078 {
0079     cmh.addAction(d->newAlbumAction);
0080     d->newAlbumAction->setEnabled(album);
0081 }
0082 
0083 void AlbumSelectTreeView::handleCustomContextMenuAction(QAction* action, const AlbumPointer<Album>& album)
0084 {
0085     Album* const a       = album;
0086     PAlbum* const palbum = dynamic_cast<PAlbum*>(a);
0087 
0088     if (palbum && (action == d->newAlbumAction))
0089     {
0090         d->albumModificationHelper->slotAlbumNew(palbum);
0091     }
0092 }
0093 
0094 void AlbumSelectTreeView::slotNewAlbum()
0095 {
0096     PAlbum* const palbum = currentAlbum();
0097 
0098     if (palbum)
0099     {
0100         PAlbum* const createdAlbum = d->albumModificationHelper->slotAlbumNew(palbum);
0101 
0102         if (createdAlbum)
0103         {
0104             setCurrentAlbums(QList<Album*>() << createdAlbum, false);
0105         }
0106     }
0107 }
0108 
0109 // --------------------------------------------------------------------------------------------------------
0110 
0111 class Q_DECL_HIDDEN AlbumSelectWidget::Private
0112 {
0113 public:
0114 
0115     explicit Private()
0116       : complAlbum             (nullptr),
0117         albumModel             (nullptr),
0118         albumTreeView          (nullptr),
0119         albumModificationHelper(nullptr),
0120         searchBar              (nullptr),
0121         newAlbumBtn            (nullptr)
0122     {
0123     }
0124 
0125     PAlbum*                  complAlbum;
0126     AlbumModel*              albumModel;
0127     AlbumSelectTreeView*     albumTreeView;
0128 
0129     AlbumModificationHelper* albumModificationHelper;
0130 
0131     SearchTextBarDb*         searchBar;
0132 
0133     QPushButton*             newAlbumBtn;
0134 };
0135 
0136 AlbumSelectWidget::AlbumSelectWidget(QWidget* const parent,
0137                                      PAlbum* const albumToSelect, bool completerSelect)
0138     : QWidget(parent),
0139       d      (new Private)
0140 {
0141     setObjectName(QLatin1String("AlbumSelectWidget"));
0142 
0143     d->albumModificationHelper = new AlbumModificationHelper(this, this);
0144 
0145     // TODO let this class implement StateSavingObject
0146 
0147     KConfigGroup group = KSharedConfig::openConfig()->group(objectName());
0148 
0149     QGridLayout* const grid = new QGridLayout(this);
0150     d->albumModel           = new AlbumModel(AbstractAlbumModel::IgnoreRootAlbum, this);
0151     d->albumTreeView        = new AlbumSelectTreeView(d->albumModel, d->albumModificationHelper, this);
0152     d->albumTreeView->setDragEnabled(false);
0153     d->albumTreeView->setRootIsDecorated(true);
0154     d->albumTreeView->setDropIndicatorShown(false);
0155     d->albumTreeView->setAcceptDrops(false);
0156     d->albumTreeView->setSelectAlbumOnClick(false);
0157     d->albumTreeView->setSelectOnContextMenu(false);
0158     d->albumTreeView->setEnableContextMenu(true);
0159     d->albumTreeView->setSortingEnabled(true);
0160     d->albumTreeView->setConfigGroup(group);
0161     d->albumTreeView->setEntryPrefix(QLatin1String("AlbumTreeView"));
0162 
0163     d->searchBar   = new SearchTextBarDb(this, QLatin1String("AlbumSelectWidgetSearchBar"));
0164     d->searchBar->setModel(d->albumModel, AbstractAlbumModel::AlbumIdRole, AbstractAlbumModel::AlbumTitleRole);
0165     d->searchBar->setFilterModel(d->albumTreeView->albumFilterModel());
0166     d->searchBar->setConfigGroup(group);
0167     d->albumTreeView->setEntryPrefix(QLatin1String("AlbumTreeView"));
0168 
0169     d->newAlbumBtn = new QPushButton(i18n("&New Album"), this);
0170     d->newAlbumBtn->setToolTip(i18n("Create new album"));
0171     d->newAlbumBtn->setIcon(QIcon::fromTheme(QLatin1String("folder-new")));
0172 
0173     grid->addWidget(d->albumTreeView, 0, 0, 1, 2);
0174     grid->addWidget(d->searchBar,     1, 0, 1, 1);
0175     grid->addWidget(d->newAlbumBtn,   1, 1, 1, 1);
0176     grid->setRowStretch(0, 10);
0177     grid->setContentsMargins(QMargins());
0178     grid->setSpacing(qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing),
0179                              QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing)));
0180 
0181     // ------------------------------------------------------------------------------------
0182 
0183     PAlbum* select = albumToSelect;
0184 
0185     if (!select)
0186     {
0187         select = AlbumManager::instance()->currentPAlbum();
0188     }
0189 
0190     d->albumTreeView->setCurrentAlbums(QList<Album*>() << select, false);
0191 
0192     bool enabled = !(!currentAlbum() || currentAlbum()->isRoot());
0193     d->newAlbumBtn->setEnabled(enabled);
0194 
0195     // ------------------------------------------------------------------------------------
0196 
0197     connect(d->albumTreeView, SIGNAL(currentAlbumChanged(Album*)),
0198             this, SLOT(slotSelectionChanged()));
0199 
0200     connect(AlbumManager::instance(), SIGNAL(signalAlbumRenamed(Album*)),
0201             this, SLOT(slotAlbumRenamed(Album*)));
0202 
0203     if (completerSelect)
0204     {
0205         connect(d->searchBar, SIGNAL(completerHighlighted(int)),
0206                 this, SLOT(slotCompleterHighlighted(int)));
0207 
0208         connect(d->searchBar, SIGNAL(completerActivated()),
0209                 this, SIGNAL(completerActivated()));
0210     }
0211 
0212     connect(d->newAlbumBtn, SIGNAL(clicked()),
0213             d->albumTreeView, SLOT(slotNewAlbum()));
0214 
0215     d->albumTreeView->loadState();
0216     d->searchBar->loadState();
0217 
0218     if (completerSelect)
0219     {
0220         d->searchBar->setFocus();
0221     }
0222 }
0223 
0224 AlbumSelectWidget::~AlbumSelectWidget()
0225 {
0226     d->albumTreeView->saveState();
0227     d->searchBar->saveState();
0228     delete d;
0229 }
0230 
0231 PAlbum* AlbumSelectWidget::currentAlbum() const
0232 {
0233     return d->albumTreeView->currentAlbum();
0234 }
0235 
0236 void AlbumSelectWidget::setCurrentAlbum(PAlbum* const albumToSelect)
0237 {
0238     d->albumTreeView->setCurrentAlbums(QList<Album*>() << albumToSelect);
0239 }
0240 
0241 QUrl AlbumSelectWidget::currentAlbumUrl() const
0242 {
0243     PAlbum* const palbum = d->albumTreeView->currentAlbum();
0244 
0245     if (palbum)
0246     {
0247         return palbum->fileUrl();
0248     }
0249 
0250     return QUrl();
0251 }
0252 
0253 void AlbumSelectWidget::setCurrentAlbumUrl(const QUrl& albumUrl)
0254 {
0255     PAlbum* const urlAlbum = AlbumManager::instance()->findPAlbum(albumUrl);
0256 
0257     if (urlAlbum)
0258     {
0259         d->albumTreeView->setCurrentAlbums(QList<Album*>() << urlAlbum);
0260     }
0261     else
0262     {
0263         qCDebug(DIGIKAM_GENERAL_LOG) << "Cannot find an album for " << albumUrl;
0264     }
0265 }
0266 
0267 void AlbumSelectWidget::slotAlbumRenamed(Album* album)
0268 {
0269     if (!album || (album->type() != Album::PHYSICAL))
0270     {
0271         return;
0272     }
0273 
0274     QModelIndex index = d->albumModel->indexForAlbum(album);
0275 
0276     if (index.isValid())
0277     {
0278         slotSelectionChanged();
0279     }
0280 }
0281 
0282 void AlbumSelectWidget::slotCompleterHighlighted(int albumId)
0283 {
0284     PAlbum* const album = AlbumManager::instance()->findPAlbum(albumId);
0285 
0286     if (album)
0287     {
0288         d->complAlbum = album;
0289         QTimer::singleShot(0, this, SLOT(slotCompleterTimer()));
0290     }
0291 }
0292 
0293 void AlbumSelectWidget::slotCompleterTimer()
0294 {
0295     if (d->complAlbum)
0296     {
0297         d->albumTreeView->setCurrentAlbums(QList<Album*>() << d->complAlbum);
0298     }
0299 }
0300 
0301 void AlbumSelectWidget::slotSelectionChanged()
0302 {
0303     bool enabled = !(!currentAlbum() || currentAlbum()->isRoot());
0304     d->newAlbumBtn->setEnabled(enabled);
0305 
0306     Q_EMIT itemSelectionChanged();
0307 }
0308 
0309 } // namespace Digikam
0310 
0311 #include "moc_albumselectwidget.cpp"