1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2012-20-07
7 * Description : Thumbnail bar for import tool
8 *
9 * Copyright (C) 2012 by Islam Wazery <wazery at ubuntu dot com>
10 * Copyright (C) 2012-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
11 *
12 * This program is free software you can redistribute it
13 * and/or modify it under the terms of the GNU General
14 * Public License as published by the Free Software Foundation
15 * either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * ============================================================ */
24
25 #include "importthumbnailbar.h"
26
27 // Local includes
28
29 #include "digikam_debug.h"
30 #include "applicationsettings.h"
31 #include "importsettings.h"
32 #include "importdelegate.h"
33 #include "importfiltermodel.h"
34 #include "importoverlays.h"
35
36 namespace Digikam
37 {
38
39 class Q_DECL_HIDDEN ImportThumbnailBar::Private
40 {
41 public:
42
Private()43 explicit Private()
44 : scrollPolicy(Qt::ScrollBarAlwaysOn),
45 duplicatesFilter(nullptr)
46 {
47 }
48
49 Qt::ScrollBarPolicy scrollPolicy;
50 NoDuplicatesImportFilterModel* duplicatesFilter;
51 };
52
ImportThumbnailBar(QWidget * const parent)53 ImportThumbnailBar::ImportThumbnailBar(QWidget* const parent)
54 : ImportCategorizedView(parent),
55 d(new Private())
56 {
57 setItemDelegate(new ImportThumbnailDelegate(this));
58 setSpacing(3);
59 setUsePointingHandCursor(false);
60 setScrollStepGranularity(5);
61 setScrollBarPolicy(Qt::ScrollBarAlwaysOn);
62
63 setDragEnabled(true);
64 setAcceptDrops(true);
65 setDropIndicatorShown(false);
66
67 setScrollCurrentToCenter(ApplicationSettings::instance()->getScrollItemToCenter());
68 setToolTipEnabled(ImportSettings::instance()->showToolTipsIsValid());
69
70 // --- NOTE: use dynamic binding as slotSetupChanged() is a virtual method which can be re-implemented in derived classes.
71
72 connect(ImportSettings::instance(), &ImportSettings::setupChanged,
73 this, &ImportThumbnailBar::slotSetupChanged);
74
75 this->slotSetupChanged();
76
77 // ---
78
79 setFlow(LeftToRight);
80 }
81
~ImportThumbnailBar()82 ImportThumbnailBar::~ImportThumbnailBar()
83 {
84 delete d;
85 }
86
setModelsFiltered(ImportItemModel * model,ImportSortFilterModel * filterModel)87 void ImportThumbnailBar::setModelsFiltered(ImportItemModel* model, ImportSortFilterModel* filterModel)
88 {
89 if (!d->duplicatesFilter)
90 {
91 d->duplicatesFilter = new NoDuplicatesImportFilterModel(this);
92 }
93
94 d->duplicatesFilter->setSourceFilterModel(filterModel);
95 ImportCategorizedView::setModels(model, d->duplicatesFilter);
96 }
97
installOverlays()98 void ImportThumbnailBar::installOverlays()
99 {
100 ImportRatingOverlay* const ratingOverlay = new ImportRatingOverlay(this);
101 addOverlay(ratingOverlay);
102
103 connect(ratingOverlay, SIGNAL(ratingEdited(QList<QModelIndex>,int)),
104 this, SLOT(assignRating(QList<QModelIndex>,int)));
105
106 addOverlay(new ImportLockOverlay(this));
107 addOverlay(new ImportDownloadOverlay(this));
108 addOverlay(new ImportCoordinatesOverlay(this));
109 }
110
slotDockLocationChanged(Qt::DockWidgetArea area)111 void ImportThumbnailBar::slotDockLocationChanged(Qt::DockWidgetArea area)
112 {
113 if ((area == Qt::LeftDockWidgetArea) || (area == Qt::RightDockWidgetArea))
114 {
115 setFlow(TopToBottom);
116 }
117 else
118 {
119 setFlow(LeftToRight);
120 }
121
122 scrollTo(currentIndex());
123 }
124
setScrollBarPolicy(Qt::ScrollBarPolicy policy)125 void ImportThumbnailBar::setScrollBarPolicy(Qt::ScrollBarPolicy policy)
126 {
127 if (policy == Qt::ScrollBarAsNeeded)
128 {
129 // Delegate resizing will cause endless relayouting, see bug #228807
130
131 qCDebug(DIGIKAM_IMPORTUI_LOG) << "The Qt::ScrollBarAsNeeded policy is not supported by ImportThumbnailBar";
132 }
133
134 d->scrollPolicy = policy;
135
136 if (flow() == TopToBottom)
137 {
138 setVerticalScrollBarPolicy(d->scrollPolicy);
139 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
140 }
141 else
142 {
143 setHorizontalScrollBarPolicy(d->scrollPolicy);
144 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
145 }
146 }
147
setFlow(QListView::Flow flow)148 void ImportThumbnailBar::setFlow(QListView::Flow flow)
149 {
150 setWrapping(false);
151
152 ImportCategorizedView::setFlow(flow);
153
154 ImportThumbnailDelegate* del = static_cast<ImportThumbnailDelegate*>(delegate());
155 del->setFlow(flow);
156
157 // Reset the minimum and maximum sizes.
158
159 setMinimumSize(QSize(0, 0));
160 setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
161
162 // Adjust minimum and maximum width to thumbnail sizes.
163
164 if (flow == TopToBottom)
165 {
166 int viewportFullWidgetOffset = size().width() - viewport()->size().width();
167 setMinimumWidth(del->minimumSize() + viewportFullWidgetOffset);
168 setMaximumWidth(del->maximumSize() + viewportFullWidgetOffset);
169 }
170 else
171 {
172 int viewportFullWidgetOffset = size().height() - viewport()->size().height();
173 setMinimumHeight(del->minimumSize() + viewportFullWidgetOffset);
174 setMaximumHeight(del->maximumSize() + viewportFullWidgetOffset);
175 }
176
177 setScrollBarPolicy(d->scrollPolicy);
178 }
179
slotSetupChanged()180 void ImportThumbnailBar::slotSetupChanged()
181 {
182 setScrollCurrentToCenter(ApplicationSettings::instance()->getScrollItemToCenter());
183 setToolTipEnabled(ImportSettings::instance()->showToolTipsIsValid());
184 setFont(ImportSettings::instance()->getIconViewFont());
185
186 ImportCategorizedView::slotSetupChanged();
187 }
188
assignRating(const QList<QModelIndex> & indexes,int rating)189 void ImportThumbnailBar::assignRating(const QList<QModelIndex>& indexes, int rating)
190 {
191 QList<QModelIndex> mappedIndexes = importSortFilterModel()->mapListToSource(indexes);
192
193 foreach (const QModelIndex& index, mappedIndexes)
194 {
195 if (index.isValid())
196 {
197 importItemModel()->camItemInfoRef(index).rating = rating;
198 }
199 }
200 }
201
event(QEvent * e)202 bool ImportThumbnailBar::event(QEvent* e)
203 {
204 // reset widget max/min sizes
205
206 if ((e->type() == QEvent::StyleChange) || (e->type() == QEvent::Show))
207 {
208 setFlow(flow());
209 }
210
211 return ImportCategorizedView::event(e);
212 }
213
nextIndex(const QModelIndex & index) const214 QModelIndex ImportThumbnailBar::nextIndex(const QModelIndex& index) const
215 {
216 return importFilterModel()->index(index.row() + 1, 0);
217 }
218
previousIndex(const QModelIndex & index) const219 QModelIndex ImportThumbnailBar::previousIndex(const QModelIndex& index) const
220 {
221 return importFilterModel()->index(index.row() - 1, 0);
222 }
223
firstIndex() const224 QModelIndex ImportThumbnailBar::firstIndex() const
225 {
226 return importFilterModel()->index(0, 0);
227 }
228
lastIndex() const229 QModelIndex ImportThumbnailBar::lastIndex() const
230 {
231 return importFilterModel()->index(importFilterModel()->rowCount() - 1, 0);
232 }
233
234 } // namespace Digikam
235