File indexing completed on 2024-05-05 04:19:14
0001 // vim: set tabstop=4 shiftwidth=4 expandtab: 0002 /* 0003 Gwenview: an image viewer 0004 Copyright 2008 Aurélien Gâteau <agateau@kde.org> 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public License 0008 as published by the Free Software Foundation; either version 2 0009 of the License, or (at your option) any later version. 0010 0011 This program is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 GNU General Public License for more details. 0015 0016 You should have received a copy of the GNU General Public License 0017 along with this program; if not, write to the Free Software 0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA. 0019 0020 */ 0021 // Self 0022 #include "browsemainpage.h" 0023 0024 // Qt 0025 #include <QActionGroup> 0026 #include <QDropEvent> 0027 #include <QMenu> 0028 #include <QVBoxLayout> 0029 0030 // KF 0031 #include <KActionCategory> 0032 #include <KActionCollection> 0033 #include <KActionMenu> 0034 #include <KDirModel> 0035 #include <KFileItem> 0036 #include <KFilePlacesModel> 0037 #include <KIconLoader> 0038 #include <KLocalizedString> 0039 #include <KUrlMimeData> 0040 #include <KUrlNavigator> 0041 0042 // Local 0043 #include <fileoperations.h> 0044 #include <filtercontroller.h> 0045 #include <gvcore.h> 0046 #include <lib/archiveutils.h> 0047 #include <lib/document/documentfactory.h> 0048 #include <lib/gvdebug.h> 0049 #include <lib/gwenviewconfig.h> 0050 #include <lib/semanticinfo/abstractsemanticinfobackend.h> 0051 #include <lib/semanticinfo/sorteddirmodel.h> 0052 #include <lib/semanticinfo/tagmodel.h> 0053 #include <lib/sorting.h> 0054 #include <lib/thumbnailview/previewitemdelegate.h> 0055 #include <lib/thumbnailview/thumbnailview.h> 0056 #include <mimetypeutils.h> 0057 #include <ui_browsemainpage.h> 0058 #ifndef GWENVIEW_SEMANTICINFO_BACKEND_NONE 0059 #include "lib/semanticinfo/semanticinfodirmodel.h" 0060 #endif 0061 0062 namespace Gwenview 0063 { 0064 inline Sorting::Enum sortingFromSortAction(const QAction *action) 0065 { 0066 Q_ASSERT(action); 0067 return Sorting::Enum(action->data().toInt()); 0068 } 0069 0070 struct BrowseMainPagePrivate : public Ui_BrowseMainPage { 0071 BrowseMainPage *q = nullptr; 0072 GvCore *mGvCore = nullptr; 0073 KFilePlacesModel *mFilePlacesModel = nullptr; 0074 KUrlNavigator *mUrlNavigator = nullptr; 0075 SortedDirModel *mDirModel = nullptr; 0076 int mDocumentCountImages; 0077 int mDocumentCountVideos; 0078 KFileItemList *mSelectedMediaItems = nullptr; 0079 KActionCollection *mActionCollection = nullptr; 0080 FilterController *mFilterController = nullptr; 0081 QActionGroup *mSortAction = nullptr; 0082 KToggleAction *mSortDescendingAction = nullptr; 0083 QActionGroup *mThumbnailDetailsActionGroup = nullptr; 0084 PreviewItemDelegate *mDelegate = nullptr; 0085 0086 void setupWidgets() 0087 { 0088 setupUi(q); 0089 q->layout()->setContentsMargins(0, 0, 0, 0); 0090 0091 int margins = q->style()->pixelMetric(QStyle::PM_ToolBarItemMargin) + q->style()->pixelMetric(QStyle::PM_ToolBarFrameWidth); 0092 mStatusBarContainer->layout()->setContentsMargins(margins, margins, margins, margins); 0093 mStatusBarContainer->layout()->setSpacing(q->style()->pixelMetric(QStyle::PM_ToolBarItemSpacing)); 0094 0095 // mThumbnailView 0096 mThumbnailView->setModel(mDirModel); 0097 0098 mDelegate = new PreviewItemDelegate(mThumbnailView); 0099 mThumbnailView->setItemDelegate(mDelegate); 0100 mThumbnailView->setSelectionMode(QAbstractItemView::ExtendedSelection); 0101 0102 // mUrlNavigator (use stupid layouting code because KUrlNavigator ctor 0103 // can't be used directly from Designer) 0104 mFilePlacesModel = new KFilePlacesModel(q); 0105 mUrlNavigator = new KUrlNavigator(mFilePlacesModel, QUrl(), mUrlNavigatorContainer); 0106 mUrlNavigatorContainer->setAutoFillBackground(true); 0107 mUrlNavigatorContainer->setBackgroundRole(QPalette::Mid); 0108 auto layout = new QVBoxLayout(mUrlNavigatorContainer); 0109 layout->setContentsMargins(0, 0, 0, 0); 0110 layout->addWidget(mUrlNavigator); 0111 QObject::connect(mUrlNavigator, SIGNAL(urlsDropped(QUrl, QDropEvent *)), q, SLOT(slotUrlsDropped(QUrl, QDropEvent *))); 0112 0113 // FullScreen Toolbar 0114 mFullScreenToolBar->setVisible(false); 0115 mFullScreenToolBar2->setVisible(false); 0116 mFullScreenToolBar->setAutoFillBackground(true); 0117 mFullScreenToolBar2->setAutoFillBackground(true); 0118 mFullScreenToolBar->setBackgroundRole(QPalette::Mid); 0119 mFullScreenToolBar2->setBackgroundRole(QPalette::Mid); 0120 0121 // Thumbnail slider 0122 QObject::connect(mThumbnailSlider, &ZoomSlider::valueChanged, mThumbnailView, &ThumbnailView::setThumbnailWidth); 0123 QObject::connect(mThumbnailView, &ThumbnailView::thumbnailWidthChanged, mThumbnailSlider, &ZoomSlider::setValue); 0124 0125 // Document count label 0126 QMargins labelMargins = mDocumentCountLabel->contentsMargins(); 0127 labelMargins.setLeft(15); 0128 labelMargins.setRight(15); 0129 mDocumentCountLabel->setContentsMargins(labelMargins); 0130 } 0131 0132 QAction *thumbnailDetailAction(const QString &text, PreviewItemDelegate::ThumbnailDetail detail) 0133 { 0134 auto action = new QAction(q); 0135 action->setText(text); 0136 action->setCheckable(true); 0137 action->setChecked(GwenviewConfig::thumbnailDetails() & detail); 0138 action->setData(QVariant(detail)); 0139 mThumbnailDetailsActionGroup->addAction(action); 0140 QObject::connect(action, SIGNAL(triggered(bool)), q, SLOT(updateThumbnailDetails())); 0141 return action; 0142 } 0143 0144 void setupActions(KActionCollection *actionCollection) 0145 { 0146 auto view = new KActionCategory(i18nc("@title actions category - means actions changing smth in interface", "View"), actionCollection); 0147 QAction *action = view->addAction("edit_location", q, SLOT(editLocation())); 0148 action->setText(i18nc("@action:inmenu Navigation Bar", "Edit Location")); 0149 actionCollection->setDefaultShortcut(action, Qt::Key_F6); 0150 0151 auto sortActionMenu = view->add<KActionMenu>("sort_by"); 0152 sortActionMenu->setText(i18nc("@action:inmenu", "Sort By")); 0153 sortActionMenu->setIcon(QIcon::fromTheme(QStringLiteral("view-sort"))); 0154 sortActionMenu->setPopupMode(QToolButton::InstantPopup); 0155 0156 mSortAction = new QActionGroup(actionCollection); 0157 action = new QAction(i18nc("@addAction:inmenu", "Name"), mSortAction); 0158 action->setCheckable(true); 0159 action->setData(QVariant(Sorting::Name)); 0160 action = new QAction(i18nc("@addAction:inmenu", "Date"), mSortAction); 0161 action->setCheckable(true); 0162 action->setData(QVariant(Sorting::Date)); 0163 action = new QAction(i18nc("@addAction:inmenu", "Size"), mSortAction); 0164 action->setCheckable(true); 0165 action->setData(QVariant(Sorting::Size)); 0166 #ifndef GWENVIEW_SEMANTICINFO_BACKEND_NONE 0167 action = new QAction(i18nc("@addAction:inmenu", "Rating"), mSortAction); 0168 action->setCheckable(true); 0169 action->setData(QVariant(Sorting::Rating)); 0170 #endif 0171 QObject::connect(mSortAction, SIGNAL(triggered(QAction *)), q, SLOT(updateSortOrder())); 0172 0173 mSortDescendingAction = view->add<KToggleAction>(QStringLiteral("sort_desc")); 0174 mSortDescendingAction->setText(i18nc("@action:inmenu Sort", "Descending")); 0175 QObject::connect(mSortDescendingAction, SIGNAL(toggled(bool)), q, SLOT(updateSortOrder())); 0176 0177 for (auto action : mSortAction->actions()) { 0178 sortActionMenu->addAction(action); 0179 } 0180 sortActionMenu->addSeparator(); 0181 sortActionMenu->addAction(mSortDescendingAction); 0182 0183 mThumbnailDetailsActionGroup = new QActionGroup(q); 0184 mThumbnailDetailsActionGroup->setExclusive(false); 0185 auto thumbnailDetailsAction = view->add<KActionMenu>(QStringLiteral("thumbnail_details")); 0186 thumbnailDetailsAction->setText(i18nc("@action:inmenu", "Thumbnail Details")); 0187 thumbnailDetailsAction->addAction(thumbnailDetailAction(i18nc("@action:inmenu", "Filename"), PreviewItemDelegate::FileNameDetail)); 0188 thumbnailDetailsAction->addAction(thumbnailDetailAction(i18nc("@action:inmenu", "Date"), PreviewItemDelegate::DateDetail)); 0189 thumbnailDetailsAction->addAction(thumbnailDetailAction(i18nc("@action:inmenu", "Image Size"), PreviewItemDelegate::ImageSizeDetail)); 0190 thumbnailDetailsAction->addAction(thumbnailDetailAction(i18nc("@action:inmenu", "File Size"), PreviewItemDelegate::FileSizeDetail)); 0191 #ifndef GWENVIEW_SEMANTICINFO_BACKEND_NONE 0192 thumbnailDetailsAction->addAction(thumbnailDetailAction(i18nc("@action:inmenu", "Rating"), PreviewItemDelegate::RatingDetail)); 0193 #endif 0194 0195 auto file = new KActionCategory(i18nc("@title actions category", "File"), actionCollection); 0196 action = file->addAction(QStringLiteral("add_folder_to_places"), q, SLOT(addFolderToPlaces())); 0197 action->setText(i18nc("@action:inmenu", "Add Folder to Places")); 0198 action->setIcon(QIcon::fromTheme(QStringLiteral("bookmark-new"))); 0199 } 0200 0201 void setupFilterController() 0202 { 0203 auto menu = new QMenu(mAddFilterButton); 0204 mFilterController = new FilterController(mFilterFrame, mDirModel); 0205 const auto actionList = mFilterController->actionList(); 0206 for (QAction *action : actionList) { 0207 menu->addAction(action); 0208 } 0209 mAddFilterButton->setMenu(menu); 0210 } 0211 0212 void setupFullScreenToolBar() 0213 { 0214 mFullScreenToolBar->setIconDimensions(KIconLoader::SizeMedium); 0215 mFullScreenToolBar->setToolButtonStyle(Qt::ToolButtonIconOnly); 0216 mFullScreenToolBar->addAction(mActionCollection->action(QStringLiteral("browse"))); 0217 mFullScreenToolBar->addAction(mActionCollection->action(QStringLiteral("view"))); 0218 0219 mFullScreenToolBar2->setIconDimensions(KIconLoader::SizeMedium); 0220 mFullScreenToolBar2->setToolButtonStyle(Qt::ToolButtonIconOnly); 0221 mFullScreenToolBar2->addAction(mActionCollection->action(QStringLiteral("leave_fullscreen"))); 0222 } 0223 0224 void updateSelectedMediaItems(const QItemSelection &selected, const QItemSelection &deselected) 0225 { 0226 for (auto index : selected.indexes()) { 0227 KFileItem item = mDirModel->itemForIndex(index); 0228 if (!ArchiveUtils::fileItemIsDirOrArchive(item)) { 0229 mSelectedMediaItems->append(item); 0230 } 0231 } 0232 for (auto index : deselected.indexes()) { 0233 KFileItem item = mDirModel->itemForIndex(index); 0234 mSelectedMediaItems->removeOne(item); 0235 } 0236 } 0237 0238 void updateDocumentCountLabel() 0239 { 0240 if (mSelectedMediaItems->count() > 1) { 0241 KIO::filesize_t totalSize = 0; 0242 for (const auto &item : *mSelectedMediaItems) { 0243 totalSize += item.size(); 0244 } 0245 const QString text = i18nc("@info:status %1 number of selected documents, %2 total number of documents, %3 total filesize of selected documents", 0246 "Selected %1 of %2 (%3)", 0247 mSelectedMediaItems->count(), 0248 mDocumentCountImages + mDocumentCountVideos, 0249 KIO::convertSize(totalSize)); 0250 mDocumentCountLabel->setText(text); 0251 } else { 0252 const QString imageText = i18ncp("@info:status Image files", "%1 image", "%1 images", mDocumentCountImages); 0253 const QString videoText = i18ncp("@info:status Video files", "%1 video", "%1 videos", mDocumentCountVideos); 0254 QString labelText; 0255 if (mDocumentCountImages > 0 && mDocumentCountVideos == 0) { 0256 labelText = imageText; 0257 } else if (mDocumentCountImages == 0 && mDocumentCountVideos > 0) { 0258 labelText = videoText; 0259 } else { 0260 labelText = i18nc("@info:status images, videos", "%1, %2", imageText, videoText); 0261 } 0262 mDocumentCountLabel->setText(labelText); 0263 } 0264 } 0265 0266 void documentCountsForIndexRange(const QModelIndex &parent, int start, int end, int &imageCountOut, int &videoCountOut) 0267 { 0268 imageCountOut = 0; 0269 videoCountOut = 0; 0270 for (int row = start; row <= end; ++row) { 0271 QModelIndex index = mDirModel->index(row, 0, parent); 0272 KFileItem item = mDirModel->itemForIndex(index); 0273 if (!ArchiveUtils::fileItemIsDirOrArchive(item)) { 0274 MimeTypeUtils::Kind kind = MimeTypeUtils::mimeTypeKind(item.mimetype()); 0275 if (kind == MimeTypeUtils::KIND_RASTER_IMAGE || kind == MimeTypeUtils::KIND_SVG_IMAGE) { 0276 imageCountOut++; 0277 } else if (kind == MimeTypeUtils::KIND_VIDEO) { 0278 videoCountOut++; 0279 } 0280 } 0281 } 0282 } 0283 0284 void updateContextBarActions() 0285 { 0286 PreviewItemDelegate::ContextBarActions actions; 0287 switch (GwenviewConfig::thumbnailActions()) { 0288 case ThumbnailActions::None: 0289 actions = PreviewItemDelegate::NoAction; 0290 break; 0291 case ThumbnailActions::ShowSelectionButtonOnly: 0292 actions = PreviewItemDelegate::SelectionAction; 0293 break; 0294 case ThumbnailActions::AllButtons: 0295 default: 0296 actions = PreviewItemDelegate::SelectionAction | PreviewItemDelegate::RotateAction; 0297 if (!q->window()->isFullScreen()) { 0298 actions |= PreviewItemDelegate::FullScreenAction; 0299 } 0300 break; 0301 } 0302 mDelegate->setContextBarActions(actions); 0303 } 0304 0305 void applyPalette(bool fullScreenmode) 0306 { 0307 q->setPalette(mGvCore->palette(fullScreenmode ? GvCore::FullScreenPalette : GvCore::NormalPalette)); 0308 mThumbnailView->setPalette(mGvCore->palette(fullScreenmode ? GvCore::FullScreenViewPalette : GvCore::NormalViewPalette)); 0309 } 0310 }; 0311 0312 BrowseMainPage::BrowseMainPage(QWidget *parent, KActionCollection *actionCollection, GvCore *gvCore) 0313 : QWidget(parent) 0314 , d(new BrowseMainPagePrivate) 0315 { 0316 d->q = this; 0317 d->mGvCore = gvCore; 0318 d->mDirModel = gvCore->sortedDirModel(); 0319 d->mDocumentCountImages = 0; 0320 d->mDocumentCountVideos = 0; 0321 d->mSelectedMediaItems = new KFileItemList; 0322 d->mActionCollection = actionCollection; 0323 d->setupWidgets(); 0324 d->setupActions(actionCollection); 0325 d->setupFilterController(); 0326 loadConfig(); 0327 updateSortOrder(); 0328 updateThumbnailDetails(); 0329 0330 // Set up connections for document count 0331 connect(d->mDirModel, &SortedDirModel::rowsInserted, this, &BrowseMainPage::slotDirModelRowsInserted); 0332 connect(d->mDirModel, &SortedDirModel::rowsAboutToBeRemoved, this, &BrowseMainPage::slotDirModelRowsAboutToBeRemoved); 0333 connect(d->mDirModel, &SortedDirModel::modelReset, this, &BrowseMainPage::slotDirModelReset); 0334 connect(thumbnailView(), &ThumbnailView::selectionChangedSignal, this, &BrowseMainPage::slotSelectionChanged); 0335 0336 connect(qApp, &QApplication::paletteChanged, this, [this]() { 0337 d->applyPalette(window()->isFullScreen()); 0338 }); 0339 0340 installEventFilter(this); 0341 } 0342 0343 BrowseMainPage::~BrowseMainPage() 0344 { 0345 d->mSelectedMediaItems->clear(); 0346 delete d->mSelectedMediaItems; 0347 delete d; 0348 } 0349 0350 void BrowseMainPage::loadConfig() 0351 { 0352 d->applyPalette(window()->isFullScreen()); 0353 d->mUrlNavigator->setUrlEditable(GwenviewConfig::urlNavigatorIsEditable()); 0354 d->mUrlNavigator->setShowFullPath(GwenviewConfig::urlNavigatorShowFullPath()); 0355 0356 d->mThumbnailSlider->setValue(GwenviewConfig::thumbnailSize()); 0357 d->mThumbnailSlider->updateToolTip(); 0358 // If GwenviewConfig::thumbnailSize() returns the current value of 0359 // mThumbnailSlider, it won't emit valueChanged() and the thumbnail view 0360 // won't be updated. That's why we do it ourself. 0361 d->mThumbnailView->setThumbnailAspectRatio(GwenviewConfig::thumbnailAspectRatio()); 0362 d->mThumbnailView->setThumbnailWidth(GwenviewConfig::thumbnailSize()); 0363 0364 const auto actionsList = d->mSortAction->actions(); 0365 for (QAction *action : actionsList) { 0366 if (sortingFromSortAction(action) == GwenviewConfig::sorting()) { 0367 action->setChecked(true); 0368 break; 0369 } 0370 } 0371 d->mSortDescendingAction->setChecked(GwenviewConfig::sortDescending()); 0372 0373 d->updateContextBarActions(); 0374 } 0375 0376 void BrowseMainPage::saveConfig() const 0377 { 0378 GwenviewConfig::setUrlNavigatorIsEditable(d->mUrlNavigator->isUrlEditable()); 0379 GwenviewConfig::setUrlNavigatorShowFullPath(d->mUrlNavigator->showFullPath()); 0380 GwenviewConfig::setThumbnailSize(d->mThumbnailSlider->value()); 0381 GwenviewConfig::setSorting(sortingFromSortAction(d->mSortAction->checkedAction())); 0382 GwenviewConfig::setSortDescending(d->mSortDescendingAction->isChecked()); 0383 GwenviewConfig::setThumbnailDetails(d->mDelegate->thumbnailDetails()); 0384 } 0385 0386 bool BrowseMainPage::eventFilter(QObject *watched, QEvent *event) 0387 { 0388 // Leave fullscreen when not viewing an image 0389 if (window()->isFullScreen() && event->type() == QEvent::ShortcutOverride) { 0390 const QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); 0391 if (keyEvent->key() == Qt::Key_Escape) { 0392 d->mActionCollection->action(QStringLiteral("leave_fullscreen"))->trigger(); 0393 event->accept(); 0394 } 0395 } 0396 return QWidget::eventFilter(watched, event); 0397 } 0398 0399 void BrowseMainPage::mousePressEvent(QMouseEvent *event) 0400 { 0401 switch (event->button()) { 0402 case Qt::ForwardButton: 0403 case Qt::BackButton: 0404 return; 0405 default: 0406 QWidget::mousePressEvent(event); 0407 } 0408 } 0409 0410 ThumbnailView *BrowseMainPage::thumbnailView() const 0411 { 0412 return d->mThumbnailView; 0413 } 0414 0415 KUrlNavigator *BrowseMainPage::urlNavigator() const 0416 { 0417 return d->mUrlNavigator; 0418 } 0419 0420 void BrowseMainPage::reload() 0421 { 0422 const QModelIndexList list = d->mThumbnailView->selectionModel()->selectedIndexes(); 0423 for (const QModelIndex &index : list) { 0424 d->mThumbnailView->reloadThumbnail(index); 0425 } 0426 d->mDirModel->reload(); 0427 } 0428 0429 void BrowseMainPage::editLocation() 0430 { 0431 d->mUrlNavigator->setUrlEditable(true); 0432 d->mUrlNavigator->setFocus(); 0433 } 0434 0435 void BrowseMainPage::addFolderToPlaces() 0436 { 0437 QUrl url = d->mUrlNavigator->locationUrl(); 0438 QString text = url.adjusted(QUrl::StripTrailingSlash).fileName(); 0439 if (text.isEmpty()) { 0440 text = url.toDisplayString(); 0441 } 0442 d->mFilePlacesModel->addPlace(text, url); 0443 } 0444 0445 void BrowseMainPage::slotDirModelRowsInserted(const QModelIndex &parent, int start, int end) 0446 { 0447 int imageCount; 0448 int videoCount; 0449 d->documentCountsForIndexRange(parent, start, end, imageCount, videoCount); 0450 if (imageCount > 0 || videoCount > 0) { 0451 d->mDocumentCountImages += imageCount; 0452 d->mDocumentCountVideos += videoCount; 0453 d->updateDocumentCountLabel(); 0454 } 0455 } 0456 0457 void BrowseMainPage::slotDirModelRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) 0458 { 0459 int imageCount; 0460 int videoCount; 0461 d->documentCountsForIndexRange(parent, start, end, imageCount, videoCount); 0462 if (imageCount > 0 || videoCount > 0) { 0463 d->mDocumentCountImages -= imageCount; 0464 d->mDocumentCountVideos -= videoCount; 0465 d->updateDocumentCountLabel(); 0466 } 0467 } 0468 0469 void BrowseMainPage::slotDirModelReset() 0470 { 0471 d->mDocumentCountImages = 0; 0472 d->mDocumentCountVideos = 0; 0473 d->mSelectedMediaItems->clear(); 0474 d->updateDocumentCountLabel(); 0475 } 0476 0477 void BrowseMainPage::slotSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) 0478 { 0479 d->updateSelectedMediaItems(selected, deselected); 0480 d->updateDocumentCountLabel(); 0481 } 0482 0483 void BrowseMainPage::updateSortOrder() 0484 { 0485 const QAction *action = d->mSortAction->checkedAction(); 0486 GV_RETURN_IF_FAIL(action); 0487 0488 const Qt::SortOrder order = d->mSortDescendingAction->isChecked() ? Qt::DescendingOrder : Qt::AscendingOrder; 0489 KDirModel::ModelColumns column = KDirModel::Name; 0490 int sortRole = Qt::DisplayRole; 0491 0492 // Map Sorting::Enum to model columns and sorting roles 0493 switch (sortingFromSortAction(action)) { 0494 case Sorting::Name: 0495 column = KDirModel::Name; 0496 break; 0497 case Sorting::Size: 0498 column = KDirModel::Size; 0499 break; 0500 case Sorting::Date: 0501 column = KDirModel::ModifiedTime; 0502 break; 0503 #ifndef GWENVIEW_SEMANTICINFO_BACKEND_NONE 0504 case Sorting::Rating: 0505 column = KDirModel::Name; 0506 sortRole = SemanticInfoDirModel::RatingRole; 0507 break; 0508 #endif 0509 } 0510 0511 d->mDirModel->setSortRole(sortRole); 0512 d->mDirModel->sort(column, order); 0513 d->mGvCore->setTrackFileManagerSorting(false); 0514 } 0515 0516 void BrowseMainPage::updateThumbnailDetails() 0517 { 0518 PreviewItemDelegate::ThumbnailDetails details = {}; 0519 const auto actionList = d->mThumbnailDetailsActionGroup->actions(); 0520 for (const QAction *action : actionList) { 0521 if (action->isChecked()) { 0522 details |= PreviewItemDelegate::ThumbnailDetail(action->data().toInt()); 0523 } 0524 } 0525 d->mDelegate->setThumbnailDetails(details); 0526 } 0527 0528 void BrowseMainPage::setFullScreenMode(bool fullScreen) 0529 { 0530 d->applyPalette(fullScreen); 0531 d->mUrlNavigatorContainer->setContentsMargins(fullScreen ? 6 : 0, 0, 0, 0); 0532 d->updateContextBarActions(); 0533 0534 d->mFullScreenToolBar->setVisible(fullScreen); 0535 d->mFullScreenToolBar2->setVisible(fullScreen); 0536 if (fullScreen && d->mFullScreenToolBar->actions().isEmpty()) { 0537 d->setupFullScreenToolBar(); 0538 } 0539 } 0540 0541 void BrowseMainPage::setStatusBarVisible(bool visible) 0542 { 0543 d->mStatusBarContainer->setVisible(visible); 0544 } 0545 0546 void BrowseMainPage::slotUrlsDropped(const QUrl &destUrl, QDropEvent *event) 0547 { 0548 const QList<QUrl> urlList = KUrlMimeData::urlsFromMimeData(event->mimeData()); 0549 if (urlList.isEmpty()) { 0550 return; 0551 } 0552 event->acceptProposedAction(); 0553 0554 // We can't call FileOperations::showMenuForDroppedUrls() directly because 0555 // we need the slot to return so that the drop event is accepted. Otherwise 0556 // the drop cursor is still visible when the menu is shown. 0557 QMetaObject::invokeMethod( 0558 this, 0559 [this, urlList, destUrl]() { 0560 showMenuForDroppedUrls(urlList, destUrl); 0561 }, 0562 Qt::QueuedConnection); 0563 } 0564 0565 void BrowseMainPage::showMenuForDroppedUrls(const QList<QUrl> &urlList, const QUrl &destUrl) 0566 { 0567 FileOperations::showMenuForDroppedUrls(d->mUrlNavigator, urlList, destUrl); 0568 } 0569 0570 QToolButton *BrowseMainPage::toggleSideBarButton() const 0571 { 0572 return d->mToggleSideBarButton; 0573 } 0574 0575 } // namespace 0576 0577 #include "moc_browsemainpage.cpp"