File indexing completed on 2025-01-05 03:51:11

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2010-02-06
0007  * Description : Thumbnail bar for items
0008  *
0009  * SPDX-FileCopyrightText: 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
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 "itemthumbnailbar.h"
0017 
0018 // Qt includes
0019 
0020 #include <QEvent>
0021 
0022 // Local includes
0023 
0024 #include "digikam_debug.h"
0025 #include "applicationsettings.h"
0026 #include "itemalbumfiltermodel.h"
0027 #include "itemalbummodel.h"
0028 #include "itemdragdrop.h"
0029 #include "itemratingoverlay.h"
0030 #include "itemcoordinatesoverlay.h"
0031 #include "itemthumbnaildelegate.h"
0032 #include "fileactionmngr.h"
0033 
0034 namespace Digikam
0035 {
0036 
0037 class Q_DECL_HIDDEN ItemThumbnailBar::Private
0038 {
0039 public:
0040 
0041     explicit Private()
0042       : scrollPolicy    (Qt::ScrollBarAlwaysOn),
0043         duplicatesFilter(nullptr)
0044     {
0045     }
0046 
0047     Qt::ScrollBarPolicy          scrollPolicy;
0048     NoDuplicatesItemFilterModel* duplicatesFilter;
0049 };
0050 
0051 ItemThumbnailBar::ItemThumbnailBar(QWidget* const parent)
0052     : ItemCategorizedView(parent),
0053       d                  (new Private())
0054 {
0055     setItemDelegate(new ItemThumbnailDelegate(this));
0056     setSpacing(3);
0057     setUsePointingHandCursor(false);
0058     setScrollStepGranularity(5);
0059     setScrollBarPolicy(Qt::ScrollBarAlwaysOn);
0060 
0061     setDragEnabled(true);
0062     setAcceptDrops(true);
0063     setDropIndicatorShown(false);
0064 
0065     // Disable QListView::Batched optimization
0066     // for the thumbnail bar, see bug #468593
0067 
0068     setLayoutMode(QListView::SinglePass);
0069 
0070     setScrollCurrentToCenter(ApplicationSettings::instance()->getScrollItemToCenter());
0071     setToolTipEnabled(ApplicationSettings::instance()->showToolTipsIsValid());
0072 
0073     // --- NOTE: use dynamic binding as slotSetupChanged() is a virtual slot which can be re-implemented in derived classes.
0074     connect(ApplicationSettings::instance(), &ApplicationSettings::setupChanged,
0075             this, &ItemThumbnailBar::slotSetupChanged);
0076 
0077     this->slotSetupChanged();
0078     // ---
0079 
0080     setFlow(LeftToRight);
0081 }
0082 
0083 ItemThumbnailBar::~ItemThumbnailBar()
0084 {
0085     delete d;
0086 }
0087 
0088 void ItemThumbnailBar::setModelsFiltered(ItemModel* model, ImageSortFilterModel* filterModel)
0089 {
0090     if (!d->duplicatesFilter)
0091     {
0092         d->duplicatesFilter = new NoDuplicatesItemFilterModel(this);
0093     }
0094 
0095     d->duplicatesFilter->setSourceFilterModel(filterModel);
0096     ItemCategorizedView::setModels(model, d->duplicatesFilter);
0097 }
0098 
0099 void ItemThumbnailBar::installOverlays()
0100 {
0101     ItemRatingOverlay* const ratingOverlay = new ItemRatingOverlay(this);
0102     addOverlay(ratingOverlay);
0103 
0104     connect(ratingOverlay, SIGNAL(ratingEdited(QList<QModelIndex>,int)),
0105             this, SLOT(assignRating(QList<QModelIndex>,int)));
0106 
0107     addOverlay(new ItemCoordinatesOverlay(this));
0108 }
0109 
0110 void ItemThumbnailBar::slotDockLocationChanged(Qt::DockWidgetArea area)
0111 {
0112     if (area == Qt::LeftDockWidgetArea || area == Qt::RightDockWidgetArea)
0113     {
0114         setFlow(TopToBottom);
0115     }
0116     else
0117     {
0118         setFlow(LeftToRight);
0119     }
0120 
0121     scrollTo(currentIndex());
0122 }
0123 
0124 void ItemThumbnailBar::setScrollBarPolicy(Qt::ScrollBarPolicy policy)
0125 {
0126     if (policy == Qt::ScrollBarAsNeeded)
0127     {
0128         // Delegate resizing will cause endless relayouting, see bug #228807
0129         qCDebug(DIGIKAM_GENERAL_LOG) << "The Qt::ScrollBarAsNeeded policy is not supported by ItemThumbnailBar";
0130     }
0131 
0132     d->scrollPolicy = policy;
0133 
0134     if (flow() == TopToBottom)
0135     {
0136         setVerticalScrollBarPolicy(d->scrollPolicy);
0137         setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0138     }
0139     else
0140     {
0141         setHorizontalScrollBarPolicy(d->scrollPolicy);
0142         setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0143     }
0144 }
0145 
0146 void ItemThumbnailBar::setFlow(QListView::Flow flow)
0147 {
0148     setWrapping(false);
0149 
0150     ItemCategorizedView::setFlow(flow);
0151 
0152     ItemThumbnailDelegate* const del = static_cast<ItemThumbnailDelegate*>(delegate());
0153     del->setFlow(flow);
0154 
0155     // Reset the minimum and maximum sizes.
0156     setMinimumSize(QSize(0, 0));
0157     setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
0158 
0159     // Adjust minimum and maximum width to thumbnail sizes.
0160     if (flow == TopToBottom)
0161     {
0162         int viewportFullWidgetOffset = size().width() - viewport()->size().width();
0163         setMinimumWidth(del->minimumSize() + viewportFullWidgetOffset);
0164         setMaximumWidth(del->maximumSize() + viewportFullWidgetOffset);
0165     }
0166     else
0167     {
0168         int viewportFullWidgetOffset = size().height() - viewport()->size().height();
0169         setMinimumHeight(del->minimumSize() + viewportFullWidgetOffset);
0170         setMaximumHeight(del->maximumSize() + viewportFullWidgetOffset);
0171     }
0172 
0173     setScrollBarPolicy(d->scrollPolicy);
0174 }
0175 
0176 void ItemThumbnailBar::slotSetupChanged()
0177 {
0178     setScrollCurrentToCenter(ApplicationSettings::instance()->getScrollItemToCenter());
0179     setToolTipEnabled(ApplicationSettings::instance()->showToolTipsIsValid());
0180     setFont(ApplicationSettings::instance()->getIconViewFont());
0181 
0182     ItemCategorizedView::slotSetupChanged();
0183 }
0184 
0185 void ItemThumbnailBar::assignRating(const QList<QModelIndex>& indexes, int rating)
0186 {
0187     ItemInfoList infos(imageSortFilterModel()->imageInfos(indexes));
0188 
0189     if (needGroupResolving(ApplicationSettings::Metadata, infos))
0190     {
0191         infos = resolveGrouping(infos);
0192     }
0193 
0194     FileActionMngr::instance()->assignRating(infos, rating);
0195 }
0196 
0197 bool ItemThumbnailBar::event(QEvent* e)
0198 {
0199     // reset widget max/min sizes
0200     if (e->type() == QEvent::StyleChange || e->type() == QEvent::Show)
0201     {
0202         setFlow(flow());
0203     }
0204 
0205     return ItemCategorizedView::event(e);
0206 }
0207 
0208 QModelIndex ItemThumbnailBar::nextIndex(const QModelIndex& index) const
0209 {
0210     return imageFilterModel()->index(index.row() + 1, 0);
0211 }
0212 
0213 QModelIndex ItemThumbnailBar::previousIndex(const QModelIndex& index) const
0214 {
0215     return imageFilterModel()->index(index.row() - 1, 0);
0216 }
0217 
0218 QModelIndex ItemThumbnailBar::firstIndex() const
0219 {
0220     return imageFilterModel()->index(0, 0);
0221 }
0222 
0223 QModelIndex ItemThumbnailBar::lastIndex() const
0224 {
0225     return imageFilterModel()->index(imageFilterModel()->rowCount() - 1, 0);
0226 }
0227 
0228 bool ItemThumbnailBar::hasHiddenGroupedImages(const ItemInfo& info) const
0229 {
0230     return (info.hasGroupedImages()                &&
0231             !imageFilterModel()->isAllGroupsOpen() &&
0232             !imageFilterModel()->isGroupOpen(info.id()));
0233 }
0234 
0235 } // namespace Digikam
0236 
0237 #include "moc_itemthumbnailbar.cpp"