File indexing completed on 2025-03-09 03:58:43

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2012-20-07
0007  * Description : Thumbnail bar for import tool
0008  *
0009  * SPDX-FileCopyrightText: 2012      by Islam Wazery <wazery at ubuntu dot com>
0010  * SPDX-FileCopyrightText: 2012-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 "importthumbnailbar.h"
0017 
0018 // Local includes
0019 
0020 #include "digikam_debug.h"
0021 #include "applicationsettings.h"
0022 #include "importsettings.h"
0023 #include "importdelegate.h"
0024 #include "importfiltermodel.h"
0025 #include "importoverlays.h"
0026 
0027 namespace Digikam
0028 {
0029 
0030 class Q_DECL_HIDDEN ImportThumbnailBar::Private
0031 {
0032 public:
0033 
0034     explicit Private()
0035       : scrollPolicy(Qt::ScrollBarAlwaysOn),
0036         duplicatesFilter(nullptr)
0037     {
0038     }
0039 
0040     Qt::ScrollBarPolicy            scrollPolicy;
0041     NoDuplicatesImportFilterModel* duplicatesFilter;
0042 };
0043 
0044 ImportThumbnailBar::ImportThumbnailBar(QWidget* const parent)
0045     : ImportCategorizedView(parent),
0046       d(new Private())
0047 {
0048     setItemDelegate(new ImportThumbnailDelegate(this));
0049     setSpacing(3);
0050     setUsePointingHandCursor(false);
0051     setScrollStepGranularity(5);
0052     setScrollBarPolicy(Qt::ScrollBarAlwaysOn);
0053 
0054     setDragEnabled(true);
0055     setAcceptDrops(true);
0056     setDropIndicatorShown(false);
0057 
0058     // Disable QListView::Batched optimization
0059     // for the thumbnail bar, see bug #468593
0060 
0061     setLayoutMode(QListView::SinglePass);
0062 
0063     setScrollCurrentToCenter(ApplicationSettings::instance()->getScrollItemToCenter());
0064     setToolTipEnabled(ImportSettings::instance()->showToolTipsIsValid());
0065 
0066     // --- NOTE: use dynamic binding as slotSetupChanged() is a virtual method which can be re-implemented in derived classes.
0067 
0068     connect(ImportSettings::instance(), &ImportSettings::setupChanged,
0069             this, &ImportThumbnailBar::slotSetupChanged);
0070 
0071     this->slotSetupChanged();
0072 
0073     // ---
0074 
0075     setFlow(LeftToRight);
0076 }
0077 
0078 ImportThumbnailBar::~ImportThumbnailBar()
0079 {
0080     delete d;
0081 }
0082 
0083 void ImportThumbnailBar::setModelsFiltered(ImportItemModel* model, ImportSortFilterModel* filterModel)
0084 {
0085     if (!d->duplicatesFilter)
0086     {
0087         d->duplicatesFilter = new NoDuplicatesImportFilterModel(this);
0088     }
0089 
0090     d->duplicatesFilter->setSourceFilterModel(filterModel);
0091     ImportCategorizedView::setModels(model, d->duplicatesFilter);
0092 }
0093 
0094 void ImportThumbnailBar::installOverlays()
0095 {
0096     ImportRatingOverlay* const ratingOverlay = new ImportRatingOverlay(this);
0097     addOverlay(ratingOverlay);
0098 
0099     connect(ratingOverlay, SIGNAL(ratingEdited(QList<QModelIndex>,int)),
0100             this, SLOT(assignRating(QList<QModelIndex>,int)));
0101 
0102     addOverlay(new ImportLockOverlay(this));
0103     addOverlay(new ImportDownloadOverlay(this));
0104     addOverlay(new ImportCoordinatesOverlay(this));
0105 }
0106 
0107 void ImportThumbnailBar::slotDockLocationChanged(Qt::DockWidgetArea area)
0108 {
0109     if ((area == Qt::LeftDockWidgetArea) || (area == Qt::RightDockWidgetArea))
0110     {
0111         setFlow(TopToBottom);
0112     }
0113     else
0114     {
0115         setFlow(LeftToRight);
0116     }
0117 
0118     scrollTo(currentIndex());
0119 }
0120 
0121 void ImportThumbnailBar::setScrollBarPolicy(Qt::ScrollBarPolicy policy)
0122 {
0123     if (policy == Qt::ScrollBarAsNeeded)
0124     {
0125         // Delegate resizing will cause endless relayouting, see bug #228807
0126 
0127         qCDebug(DIGIKAM_IMPORTUI_LOG) << "The Qt::ScrollBarAsNeeded policy is not supported by ImportThumbnailBar";
0128     }
0129 
0130     d->scrollPolicy = policy;
0131 
0132     if (flow() == TopToBottom)
0133     {
0134         setVerticalScrollBarPolicy(d->scrollPolicy);
0135         setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0136     }
0137     else
0138     {
0139         setHorizontalScrollBarPolicy(d->scrollPolicy);
0140         setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0141     }
0142 }
0143 
0144 void ImportThumbnailBar::setFlow(QListView::Flow flow)
0145 {
0146     setWrapping(false);
0147 
0148     ImportCategorizedView::setFlow(flow);
0149 
0150     ImportThumbnailDelegate* del = static_cast<ImportThumbnailDelegate*>(delegate());
0151     del->setFlow(flow);
0152 
0153     // Reset the minimum and maximum sizes.
0154 
0155     setMinimumSize(QSize(0, 0));
0156     setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
0157 
0158     // Adjust minimum and maximum width to thumbnail sizes.
0159 
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 ImportThumbnailBar::slotSetupChanged()
0177 {
0178     setScrollCurrentToCenter(ApplicationSettings::instance()->getScrollItemToCenter());
0179     setToolTipEnabled(ImportSettings::instance()->showToolTipsIsValid());
0180     setFont(ImportSettings::instance()->getIconViewFont());
0181 
0182     ImportCategorizedView::slotSetupChanged();
0183 }
0184 
0185 void ImportThumbnailBar::assignRating(const QList<QModelIndex>& indexes, int rating)
0186 {
0187    QList<QModelIndex> mappedIndexes = importSortFilterModel()->mapListToSource(indexes);
0188 
0189    Q_FOREACH (const QModelIndex& index, mappedIndexes)
0190    {
0191        if (index.isValid())
0192        {
0193             importItemModel()->camItemInfoRef(index).rating = rating;
0194        }
0195    }
0196 }
0197 
0198 bool ImportThumbnailBar::event(QEvent* e)
0199 {
0200     // reset widget max/min sizes
0201 
0202     if ((e->type() == QEvent::StyleChange) || (e->type() == QEvent::Show))
0203     {
0204         setFlow(flow());
0205     }
0206 
0207     return ImportCategorizedView::event(e);
0208 }
0209 
0210 QModelIndex ImportThumbnailBar::nextIndex(const QModelIndex& index) const
0211 {
0212     return importFilterModel()->index(index.row() + 1, 0);
0213 }
0214 
0215 QModelIndex ImportThumbnailBar::previousIndex(const QModelIndex& index) const
0216 {
0217     return importFilterModel()->index(index.row() - 1, 0);
0218 }
0219 
0220 QModelIndex ImportThumbnailBar::firstIndex() const
0221 {
0222     return importFilterModel()->index(0, 0);
0223 }
0224 
0225 QModelIndex ImportThumbnailBar::lastIndex() const
0226 {
0227     return importFilterModel()->index(importFilterModel()->rowCount() - 1, 0);
0228 }
0229 
0230 } // namespace Digikam
0231 
0232 #include "moc_importthumbnailbar.cpp"