1 // vim: set tabstop=4 shiftwidth=4 expandtab:
2 /*
3 Gwenview: an image viewer
4 Copyright 2008 Aurélien Gâteau <agateau@kde.org>
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA.
19
20 */
21 // Self
22 #include "browsemainpage.h"
23
24 // Qt
25 #include <QDropEvent>
26 #include <QMenu>
27 #include <QVBoxLayout>
28
29 // KF
30 #include <KActionCategory>
31 #include <KActionCollection>
32 #include <KActionMenu>
33 #include <KDirModel>
34 #include <KFileItem>
35 #include <KFilePlacesModel>
36 #include <KFormat>
37 #include <KIconLoader>
38 #include <KLocalizedString>
39 #include <KUrlMimeData>
40 #include <KUrlNavigator>
41
42 // Local
43 #include <fileoperations.h>
44 #include <filtercontroller.h>
45 #include <gvcore.h>
46 #include <lib/archiveutils.h>
47 #include <lib/document/documentfactory.h>
48 #include <lib/gvdebug.h>
49 #include <lib/gwenviewconfig.h>
50 #include <lib/semanticinfo/abstractsemanticinfobackend.h>
51 #include <lib/semanticinfo/sorteddirmodel.h>
52 #include <lib/semanticinfo/tagmodel.h>
53 #include <lib/sorting.h>
54 #include <lib/thumbnailview/previewitemdelegate.h>
55 #include <lib/thumbnailview/thumbnailview.h>
56 #include <mimetypeutils.h>
57 #include <ui_browsemainpage.h>
58 #ifndef GWENVIEW_SEMANTICINFO_BACKEND_NONE
59 #include "lib/semanticinfo/semanticinfodirmodel.h"
60 #endif
61
62 namespace Gwenview
63 {
sortingFromSortAction(const QAction * action)64 inline Sorting::Enum sortingFromSortAction(const QAction *action)
65 {
66 Q_ASSERT(action);
67 return Sorting::Enum(action->data().toInt());
68 }
69
70 struct BrowseMainPagePrivate : public Ui_BrowseMainPage {
71 BrowseMainPage *q;
72 GvCore *mGvCore;
73 KFilePlacesModel *mFilePlacesModel;
74 KUrlNavigator *mUrlNavigator;
75 SortedDirModel *mDirModel;
76 int mDocumentCountImages;
77 int mDocumentCountVideos;
78 KFileItemList *mSelectedMediaItems;
79 KActionCollection *mActionCollection;
80 FilterController *mFilterController;
81 QActionGroup *mSortAction;
82 KToggleAction *mSortDescendingAction;
83 QActionGroup *mThumbnailDetailsActionGroup;
84 PreviewItemDelegate *mDelegate;
85
setupWidgetsGwenview::BrowseMainPagePrivate86 void setupWidgets()
87 {
88 setupUi(q);
89 q->layout()->setContentsMargins(0, 0, 0, 0);
90
91 int margins = q->style()->pixelMetric(QStyle::PM_ToolBarItemMargin) + q->style()->pixelMetric(QStyle::PM_ToolBarFrameWidth);
92 mStatusBarContainer->layout()->setContentsMargins(margins, margins, margins, margins);
93 mStatusBarContainer->layout()->setSpacing(q->style()->pixelMetric(QStyle::PM_ToolBarItemSpacing));
94
95 // mThumbnailView
96 mThumbnailView->setModel(mDirModel);
97
98 mDelegate = new PreviewItemDelegate(mThumbnailView);
99 mThumbnailView->setItemDelegate(mDelegate);
100 mThumbnailView->setSelectionMode(QAbstractItemView::ExtendedSelection);
101
102 // mUrlNavigator (use stupid layouting code because KUrlNavigator ctor
103 // can't be used directly from Designer)
104 mFilePlacesModel = new KFilePlacesModel(q);
105 mUrlNavigator = new KUrlNavigator(mFilePlacesModel, QUrl(), mUrlNavigatorContainer);
106 mUrlNavigatorContainer->setAutoFillBackground(true);
107 mUrlNavigatorContainer->setBackgroundRole(QPalette::Mid);
108 auto *layout = new QVBoxLayout(mUrlNavigatorContainer);
109 layout->setContentsMargins(0, 0, 0, 0);
110 layout->addWidget(mUrlNavigator);
111 QObject::connect(mUrlNavigator, SIGNAL(urlsDropped(QUrl, QDropEvent *)), q, SLOT(slotUrlsDropped(QUrl, QDropEvent *)));
112
113 // FullScreen Toolbar
114 mFullScreenToolBar->setVisible(false);
115 mFullScreenToolBar2->setVisible(false);
116 mFullScreenToolBar->setAutoFillBackground(true);
117 mFullScreenToolBar2->setAutoFillBackground(true);
118 mFullScreenToolBar->setBackgroundRole(QPalette::Mid);
119 mFullScreenToolBar2->setBackgroundRole(QPalette::Mid);
120
121 // Thumbnail slider
122 QObject::connect(mThumbnailSlider, &ZoomSlider::valueChanged, mThumbnailView, &ThumbnailView::setThumbnailWidth);
123 QObject::connect(mThumbnailView, &ThumbnailView::thumbnailWidthChanged, mThumbnailSlider, &ZoomSlider::setValue);
124
125 // Document count label
126 QMargins labelMargins = mDocumentCountLabel->contentsMargins();
127 labelMargins.setLeft(15);
128 labelMargins.setRight(15);
129 mDocumentCountLabel->setContentsMargins(labelMargins);
130 }
131
thumbnailDetailActionGwenview::BrowseMainPagePrivate132 QAction *thumbnailDetailAction(const QString &text, PreviewItemDelegate::ThumbnailDetail detail)
133 {
134 auto *action = new QAction(q);
135 action->setText(text);
136 action->setCheckable(true);
137 action->setChecked(GwenviewConfig::thumbnailDetails() & detail);
138 action->setData(QVariant(detail));
139 mThumbnailDetailsActionGroup->addAction(action);
140 QObject::connect(action, SIGNAL(triggered(bool)), q, SLOT(updateThumbnailDetails()));
141 return action;
142 }
143
setupActionsGwenview::BrowseMainPagePrivate144 void setupActions(KActionCollection *actionCollection)
145 {
146 auto *view = new KActionCategory(i18nc("@title actions category - means actions changing smth in interface", "View"), actionCollection);
147 QAction *action = view->addAction("edit_location", q, SLOT(editLocation()));
148 action->setText(i18nc("@action:inmenu Navigation Bar", "Edit Location"));
149 actionCollection->setDefaultShortcut(action, Qt::Key_F6);
150
151 auto *sortActionMenu = view->add<KActionMenu>("sort_by");
152 sortActionMenu->setText(i18nc("@action:inmenu", "Sort By"));
153 sortActionMenu->setIcon(QIcon::fromTheme(QStringLiteral("view-sort")));
154 sortActionMenu->setPopupMode(QToolButton::InstantPopup);
155
156 mSortAction = new QActionGroup(actionCollection);
157 action = new QAction(i18nc("@addAction:inmenu", "Name"), mSortAction);
158 action->setCheckable(true);
159 action->setData(QVariant(Sorting::Name));
160 action = new QAction(i18nc("@addAction:inmenu", "Date"), mSortAction);
161 action->setCheckable(true);
162 action->setData(QVariant(Sorting::Date));
163 action = new QAction(i18nc("@addAction:inmenu", "Size"), mSortAction);
164 action->setCheckable(true);
165 action->setData(QVariant(Sorting::Size));
166 #ifndef GWENVIEW_SEMANTICINFO_BACKEND_NONE
167 action = new QAction(i18nc("@addAction:inmenu", "Rating"), mSortAction);
168 action->setCheckable(true);
169 action->setData(QVariant(Sorting::Rating));
170 #endif
171 QObject::connect(mSortAction, SIGNAL(triggered(QAction *)), q, SLOT(updateSortOrder()));
172
173 mSortDescendingAction = view->add<KToggleAction>("sort_desc");
174 mSortDescendingAction->setText(i18nc("@action:inmenu Sort", "Descending"));
175 QObject::connect(mSortDescendingAction, SIGNAL(toggled(bool)), q, SLOT(updateSortOrder()));
176
177 for (auto action : mSortAction->actions()) {
178 sortActionMenu->addAction(action);
179 }
180 sortActionMenu->addSeparator();
181 sortActionMenu->addAction(mSortDescendingAction);
182
183 mThumbnailDetailsActionGroup = new QActionGroup(q);
184 mThumbnailDetailsActionGroup->setExclusive(false);
185 auto *thumbnailDetailsAction = view->add<KActionMenu>("thumbnail_details");
186 thumbnailDetailsAction->setText(i18nc("@action:inmenu", "Thumbnail Details"));
187 thumbnailDetailsAction->addAction(thumbnailDetailAction(i18nc("@action:inmenu", "Filename"), PreviewItemDelegate::FileNameDetail));
188 thumbnailDetailsAction->addAction(thumbnailDetailAction(i18nc("@action:inmenu", "Date"), PreviewItemDelegate::DateDetail));
189 thumbnailDetailsAction->addAction(thumbnailDetailAction(i18nc("@action:inmenu", "Image Size"), PreviewItemDelegate::ImageSizeDetail));
190 thumbnailDetailsAction->addAction(thumbnailDetailAction(i18nc("@action:inmenu", "File Size"), PreviewItemDelegate::FileSizeDetail));
191 #ifndef GWENVIEW_SEMANTICINFO_BACKEND_NONE
192 thumbnailDetailsAction->addAction(thumbnailDetailAction(i18nc("@action:inmenu", "Rating"), PreviewItemDelegate::RatingDetail));
193 #endif
194
195 auto *file = new KActionCategory(i18nc("@title actions category", "File"), actionCollection);
196 action = file->addAction(QStringLiteral("add_folder_to_places"), q, SLOT(addFolderToPlaces()));
197 action->setText(i18nc("@action:inmenu", "Add Folder to Places"));
198 action->setIcon(QIcon::fromTheme(QStringLiteral("bookmark-new")));
199 }
200
setupFilterControllerGwenview::BrowseMainPagePrivate201 void setupFilterController()
202 {
203 auto *menu = new QMenu(mAddFilterButton);
204 mFilterController = new FilterController(mFilterFrame, mDirModel);
205 const auto actionList = mFilterController->actionList();
206 for (QAction *action : actionList) {
207 menu->addAction(action);
208 }
209 mAddFilterButton->setMenu(menu);
210 }
211
setupFullScreenToolBarGwenview::BrowseMainPagePrivate212 void setupFullScreenToolBar()
213 {
214 mFullScreenToolBar->setIconDimensions(KIconLoader::SizeMedium);
215 mFullScreenToolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
216 mFullScreenToolBar->addAction(mActionCollection->action(QStringLiteral("browse")));
217 mFullScreenToolBar->addAction(mActionCollection->action(QStringLiteral("view")));
218
219 mFullScreenToolBar2->setIconDimensions(KIconLoader::SizeMedium);
220 mFullScreenToolBar2->setToolButtonStyle(Qt::ToolButtonIconOnly);
221 mFullScreenToolBar2->addAction(mActionCollection->action(QStringLiteral("leave_fullscreen")));
222 }
223
updateSelectedMediaItemsGwenview::BrowseMainPagePrivate224 void updateSelectedMediaItems(const QItemSelection &selected, const QItemSelection &deselected)
225 {
226 for (auto index : selected.indexes()) {
227 KFileItem item = mDirModel->itemForIndex(index);
228 if (!ArchiveUtils::fileItemIsDirOrArchive(item)) {
229 mSelectedMediaItems->append(item);
230 }
231 }
232 for (auto index : deselected.indexes()) {
233 KFileItem item = mDirModel->itemForIndex(index);
234 mSelectedMediaItems->removeOne(item);
235 }
236 }
237
updateDocumentCountLabelGwenview::BrowseMainPagePrivate238 void updateDocumentCountLabel()
239 {
240 if (mSelectedMediaItems->count() > 1) {
241 KIO::filesize_t totalSize = 0;
242 for (const auto &item : *mSelectedMediaItems) {
243 totalSize += item.size();
244 }
245 const QString text = i18nc("@info:status %1 number of selected documents, %2 total number of documents, %3 total filesize of selected documents",
246 "Selected %1 of %2 (%3)",
247 mSelectedMediaItems->count(),
248 mDocumentCountImages + mDocumentCountVideos,
249 KFormat().formatByteSize(totalSize));
250 mDocumentCountLabel->setText(text);
251 } else {
252 const QString imageText = i18ncp("@info:status Image files", "%1 image", "%1 images", mDocumentCountImages);
253 const QString videoText = i18ncp("@info:status Video files", "%1 video", "%1 videos", mDocumentCountVideos);
254 QString labelText;
255 if (mDocumentCountImages > 0 && mDocumentCountVideos == 0) {
256 labelText = imageText;
257 } else if (mDocumentCountImages == 0 && mDocumentCountVideos > 0) {
258 labelText = videoText;
259 } else {
260 labelText = i18nc("@info:status images, videos", "%1, %2", imageText, videoText);
261 }
262 mDocumentCountLabel->setText(labelText);
263 }
264 }
265
documentCountsForIndexRangeGwenview::BrowseMainPagePrivate266 void documentCountsForIndexRange(const QModelIndex &parent, int start, int end, int &imageCountOut, int &videoCountOut)
267 {
268 imageCountOut = 0;
269 videoCountOut = 0;
270 for (int row = start; row <= end; ++row) {
271 QModelIndex index = mDirModel->index(row, 0, parent);
272 KFileItem item = mDirModel->itemForIndex(index);
273 if (!ArchiveUtils::fileItemIsDirOrArchive(item)) {
274 MimeTypeUtils::Kind kind = MimeTypeUtils::mimeTypeKind(item.mimetype());
275 if (kind == MimeTypeUtils::KIND_RASTER_IMAGE || kind == MimeTypeUtils::KIND_SVG_IMAGE) {
276 imageCountOut++;
277 } else if (kind == MimeTypeUtils::KIND_VIDEO) {
278 videoCountOut++;
279 }
280 }
281 }
282 }
283
updateContextBarActionsGwenview::BrowseMainPagePrivate284 void updateContextBarActions()
285 {
286 PreviewItemDelegate::ContextBarActions actions;
287 switch (GwenviewConfig::thumbnailActions()) {
288 case ThumbnailActions::None:
289 actions = PreviewItemDelegate::NoAction;
290 break;
291 case ThumbnailActions::ShowSelectionButtonOnly:
292 actions = PreviewItemDelegate::SelectionAction;
293 break;
294 case ThumbnailActions::AllButtons:
295 default:
296 actions = PreviewItemDelegate::SelectionAction | PreviewItemDelegate::RotateAction;
297 if (!q->window()->isFullScreen()) {
298 actions |= PreviewItemDelegate::FullScreenAction;
299 }
300 break;
301 }
302 mDelegate->setContextBarActions(actions);
303 }
304
applyPaletteGwenview::BrowseMainPagePrivate305 void applyPalette(bool fullScreenmode)
306 {
307 q->setPalette(mGvCore->palette(fullScreenmode ? GvCore::FullScreenPalette : GvCore::NormalPalette));
308 mThumbnailView->setPalette(mGvCore->palette(fullScreenmode ? GvCore::FullScreenViewPalette : GvCore::NormalViewPalette));
309 }
310 };
311
BrowseMainPage(QWidget * parent,KActionCollection * actionCollection,GvCore * gvCore)312 BrowseMainPage::BrowseMainPage(QWidget *parent, KActionCollection *actionCollection, GvCore *gvCore)
313 : QWidget(parent)
314 , d(new BrowseMainPagePrivate)
315 {
316 d->q = this;
317 d->mGvCore = gvCore;
318 d->mDirModel = gvCore->sortedDirModel();
319 d->mDocumentCountImages = 0;
320 d->mDocumentCountVideos = 0;
321 d->mSelectedMediaItems = new KFileItemList;
322 d->mActionCollection = actionCollection;
323 d->setupWidgets();
324 d->setupActions(actionCollection);
325 d->setupFilterController();
326 loadConfig();
327 updateSortOrder();
328 updateThumbnailDetails();
329
330 // Set up connections for document count
331 connect(d->mDirModel, &SortedDirModel::rowsInserted, this, &BrowseMainPage::slotDirModelRowsInserted);
332 connect(d->mDirModel, &SortedDirModel::rowsAboutToBeRemoved, this, &BrowseMainPage::slotDirModelRowsAboutToBeRemoved);
333 connect(d->mDirModel, &SortedDirModel::modelReset, this, &BrowseMainPage::slotDirModelReset);
334 connect(thumbnailView(), &ThumbnailView::selectionChangedSignal, this, &BrowseMainPage::slotSelectionChanged);
335
336 connect(qApp, &QApplication::paletteChanged, this, [this]() {
337 d->applyPalette(window()->isFullScreen());
338 });
339
340 installEventFilter(this);
341 }
342
~BrowseMainPage()343 BrowseMainPage::~BrowseMainPage()
344 {
345 d->mSelectedMediaItems->clear();
346 delete d->mSelectedMediaItems;
347 delete d;
348 }
349
loadConfig()350 void BrowseMainPage::loadConfig()
351 {
352 d->applyPalette(window()->isFullScreen());
353 d->mUrlNavigator->setUrlEditable(GwenviewConfig::urlNavigatorIsEditable());
354 d->mUrlNavigator->setShowFullPath(GwenviewConfig::urlNavigatorShowFullPath());
355
356 d->mThumbnailSlider->setValue(GwenviewConfig::thumbnailSize());
357 d->mThumbnailSlider->updateToolTip();
358 // If GwenviewConfig::thumbnailSize() returns the current value of
359 // mThumbnailSlider, it won't emit valueChanged() and the thumbnail view
360 // won't be updated. That's why we do it ourself.
361 d->mThumbnailView->setThumbnailAspectRatio(GwenviewConfig::thumbnailAspectRatio());
362 d->mThumbnailView->setThumbnailWidth(GwenviewConfig::thumbnailSize());
363
364 const auto actionsList = d->mSortAction->actions();
365 for (QAction *action : actionsList) {
366 if (sortingFromSortAction(action) == GwenviewConfig::sorting()) {
367 action->setChecked(true);
368 break;
369 }
370 }
371 d->mSortDescendingAction->setChecked(GwenviewConfig::sortDescending());
372
373 d->updateContextBarActions();
374 }
375
saveConfig() const376 void BrowseMainPage::saveConfig() const
377 {
378 GwenviewConfig::setUrlNavigatorIsEditable(d->mUrlNavigator->isUrlEditable());
379 GwenviewConfig::setUrlNavigatorShowFullPath(d->mUrlNavigator->showFullPath());
380 GwenviewConfig::setThumbnailSize(d->mThumbnailSlider->value());
381 GwenviewConfig::setSorting(sortingFromSortAction(d->mSortAction->checkedAction()));
382 GwenviewConfig::setSortDescending(d->mSortDescendingAction->isChecked());
383 GwenviewConfig::setThumbnailDetails(d->mDelegate->thumbnailDetails());
384 }
385
eventFilter(QObject * watched,QEvent * event)386 bool BrowseMainPage::eventFilter(QObject *watched, QEvent *event)
387 {
388 // Leave fullscreen when not viewing an image
389 if (window()->isFullScreen() && event->type() == QEvent::ShortcutOverride) {
390 const QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
391 if (keyEvent->key() == Qt::Key_Escape) {
392 d->mActionCollection->action(QStringLiteral("leave_fullscreen"))->trigger();
393 event->accept();
394 }
395 }
396 return QWidget::eventFilter(watched, event);
397 }
398
mousePressEvent(QMouseEvent * event)399 void BrowseMainPage::mousePressEvent(QMouseEvent *event)
400 {
401 switch (event->button()) {
402 case Qt::ForwardButton:
403 case Qt::BackButton:
404 return;
405 default:
406 QWidget::mousePressEvent(event);
407 }
408 }
409
thumbnailView() const410 ThumbnailView *BrowseMainPage::thumbnailView() const
411 {
412 return d->mThumbnailView;
413 }
414
urlNavigator() const415 KUrlNavigator *BrowseMainPage::urlNavigator() const
416 {
417 return d->mUrlNavigator;
418 }
419
reload()420 void BrowseMainPage::reload()
421 {
422 const QModelIndexList list = d->mThumbnailView->selectionModel()->selectedIndexes();
423 for (const QModelIndex &index : list) {
424 d->mThumbnailView->reloadThumbnail(index);
425 }
426 d->mDirModel->reload();
427 }
428
editLocation()429 void BrowseMainPage::editLocation()
430 {
431 d->mUrlNavigator->setUrlEditable(true);
432 d->mUrlNavigator->setFocus();
433 }
434
addFolderToPlaces()435 void BrowseMainPage::addFolderToPlaces()
436 {
437 QUrl url = d->mUrlNavigator->locationUrl();
438 QString text = url.adjusted(QUrl::StripTrailingSlash).fileName();
439 if (text.isEmpty()) {
440 text = url.toDisplayString();
441 }
442 d->mFilePlacesModel->addPlace(text, url);
443 }
444
slotDirModelRowsInserted(const QModelIndex & parent,int start,int end)445 void BrowseMainPage::slotDirModelRowsInserted(const QModelIndex &parent, int start, int end)
446 {
447 int imageCount;
448 int videoCount;
449 d->documentCountsForIndexRange(parent, start, end, imageCount, videoCount);
450 if (imageCount > 0 || videoCount > 0) {
451 d->mDocumentCountImages += imageCount;
452 d->mDocumentCountVideos += videoCount;
453 d->updateDocumentCountLabel();
454 }
455 }
456
slotDirModelRowsAboutToBeRemoved(const QModelIndex & parent,int start,int end)457 void BrowseMainPage::slotDirModelRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
458 {
459 int imageCount;
460 int videoCount;
461 d->documentCountsForIndexRange(parent, start, end, imageCount, videoCount);
462 if (imageCount > 0 || videoCount > 0) {
463 d->mDocumentCountImages -= imageCount;
464 d->mDocumentCountVideos -= videoCount;
465 d->updateDocumentCountLabel();
466 }
467 }
468
slotDirModelReset()469 void BrowseMainPage::slotDirModelReset()
470 {
471 d->mDocumentCountImages = 0;
472 d->mDocumentCountVideos = 0;
473 d->mSelectedMediaItems->clear();
474 d->updateDocumentCountLabel();
475 }
476
slotSelectionChanged(const QItemSelection & selected,const QItemSelection & deselected)477 void BrowseMainPage::slotSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
478 {
479 d->updateSelectedMediaItems(selected, deselected);
480 d->updateDocumentCountLabel();
481 }
482
updateSortOrder()483 void BrowseMainPage::updateSortOrder()
484 {
485 const QAction *action = d->mSortAction->checkedAction();
486 GV_RETURN_IF_FAIL(action);
487
488 const Qt::SortOrder order = d->mSortDescendingAction->isChecked() ? Qt::DescendingOrder : Qt::AscendingOrder;
489 KDirModel::ModelColumns column = KDirModel::Name;
490 int sortRole = Qt::DisplayRole;
491
492 // Map Sorting::Enum to model columns and sorting roles
493 switch (sortingFromSortAction(action)) {
494 case Sorting::Name:
495 column = KDirModel::Name;
496 break;
497 case Sorting::Size:
498 column = KDirModel::Size;
499 break;
500 case Sorting::Date:
501 column = KDirModel::ModifiedTime;
502 break;
503 #ifndef GWENVIEW_SEMANTICINFO_BACKEND_NONE
504 case Sorting::Rating:
505 column = KDirModel::Name;
506 sortRole = SemanticInfoDirModel::RatingRole;
507 break;
508 #endif
509 }
510
511 d->mDirModel->setSortRole(sortRole);
512 d->mDirModel->sort(column, order);
513 }
514
updateThumbnailDetails()515 void BrowseMainPage::updateThumbnailDetails()
516 {
517 PreviewItemDelegate::ThumbnailDetails details = {};
518 const auto actionList = d->mThumbnailDetailsActionGroup->actions();
519 for (const QAction *action : actionList) {
520 if (action->isChecked()) {
521 details |= PreviewItemDelegate::ThumbnailDetail(action->data().toInt());
522 }
523 }
524 d->mDelegate->setThumbnailDetails(details);
525 }
526
setFullScreenMode(bool fullScreen)527 void BrowseMainPage::setFullScreenMode(bool fullScreen)
528 {
529 d->applyPalette(fullScreen);
530 d->mUrlNavigatorContainer->setContentsMargins(fullScreen ? 6 : 0, 0, 0, 0);
531 d->updateContextBarActions();
532
533 d->mFullScreenToolBar->setVisible(fullScreen);
534 d->mFullScreenToolBar2->setVisible(fullScreen);
535 if (fullScreen && d->mFullScreenToolBar->actions().isEmpty()) {
536 d->setupFullScreenToolBar();
537 }
538 }
539
setStatusBarVisible(bool visible)540 void BrowseMainPage::setStatusBarVisible(bool visible)
541 {
542 d->mStatusBarContainer->setVisible(visible);
543 }
544
slotUrlsDropped(const QUrl & destUrl,QDropEvent * event)545 void BrowseMainPage::slotUrlsDropped(const QUrl &destUrl, QDropEvent *event)
546 {
547 const QList<QUrl> urlList = KUrlMimeData::urlsFromMimeData(event->mimeData());
548 if (urlList.isEmpty()) {
549 return;
550 }
551 event->acceptProposedAction();
552
553 // We can't call FileOperations::showMenuForDroppedUrls() directly because
554 // we need the slot to return so that the drop event is accepted. Otherwise
555 // the drop cursor is still visible when the menu is shown.
556 QMetaObject::invokeMethod(
557 this,
558 [this, urlList, destUrl]() {
559 showMenuForDroppedUrls(urlList, destUrl);
560 },
561 Qt::QueuedConnection);
562 }
563
showMenuForDroppedUrls(const QList<QUrl> & urlList,const QUrl & destUrl)564 void BrowseMainPage::showMenuForDroppedUrls(const QList<QUrl> &urlList, const QUrl &destUrl)
565 {
566 FileOperations::showMenuForDroppedUrls(d->mUrlNavigator, urlList, destUrl);
567 }
568
toggleSideBarButton() const569 QToolButton *BrowseMainPage::toggleSideBarButton() const
570 {
571 return d->mToggleSideBarButton;
572 }
573
574 } // namespace
575