File indexing completed on 2025-01-19 03:50:46
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2002-16-10 0007 * Description : Item icon view interface - View methods. 0008 * 0009 * SPDX-FileCopyrightText: 2002-2005 by Renchi Raju <renchi dot raju at gmail dot com> 0010 * SPDX-FileCopyrightText: 2002-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * SPDX-FileCopyrightText: 2009-2011 by Johannes Wienke <languitar at semipol dot de> 0012 * SPDX-FileCopyrightText: 2010-2011 by Andi Clemens <andi dot clemens at gmail dot com> 0013 * SPDX-FileCopyrightText: 2011-2013 by Michael G. Hansen <mike at mghansen dot de> 0014 * SPDX-FileCopyrightText: 2014-2015 by Mohamed_Anwer <m_dot_anwer at gmx dot com> 0015 * SPDX-FileCopyrightText: 2017 by Simon Frei <freisim93 at gmail dot com> 0016 * 0017 * SPDX-License-Identifier: GPL-2.0-or-later 0018 * 0019 * ============================================================ */ 0020 0021 #include "itemiconview_p.h" 0022 0023 namespace Digikam 0024 { 0025 0026 void ItemIconView::connectIconViewFilter(FilterStatusBar* const filterbar) 0027 { 0028 ItemAlbumFilterModel* const model = d->iconView->imageAlbumFilterModel(); 0029 0030 connect(model, SIGNAL(filterMatches(bool)), 0031 filterbar, SLOT(slotFilterMatches(bool))); 0032 0033 connect(model, SIGNAL(filterSettingsChanged(ItemFilterSettings)), 0034 filterbar, SLOT(slotFilterSettingsChanged(ItemFilterSettings))); 0035 0036 connect(filterbar, SIGNAL(signalResetFilters()), 0037 d->filterWidget, SLOT(slotResetFilters())); 0038 0039 connect(filterbar, SIGNAL(signalPopupFiltersView()), 0040 this, SLOT(slotPopupFiltersView())); 0041 } 0042 0043 void ItemIconView::slotEscapePreview() 0044 { 0045 if ( 0046 (viewMode() == StackedView::IconViewMode) || 0047 (viewMode() == StackedView::MapWidgetMode) || 0048 (viewMode() == StackedView::TableViewMode) || 0049 (viewMode() == StackedView::TrashViewMode) || 0050 (viewMode() == StackedView::WelcomePageMode) 0051 ) 0052 { 0053 return; 0054 } 0055 0056 // pass a null image info, because we want to fall back to the old view mode 0057 0058 slotTogglePreviewMode(ItemInfo()); 0059 } 0060 0061 void ItemIconView::slotMapWidgetView() 0062 { 0063 d->stackedView->setViewMode(StackedView::MapWidgetMode); 0064 } 0065 0066 void ItemIconView::slotTableView() 0067 { 0068 d->stackedView->setViewMode(StackedView::TableViewMode); 0069 } 0070 0071 void ItemIconView::slotIconView() 0072 { 0073 if (viewMode() == StackedView::PreviewImageMode) 0074 { 0075 Q_EMIT signalThumbSizeChanged(d->thumbSize); 0076 } 0077 0078 // and switch to icon view 0079 0080 d->stackedView->setViewMode(StackedView::IconViewMode); 0081 0082 // make sure the next/previous buttons are updated 0083 0084 slotImageSelected(); 0085 } 0086 0087 void ItemIconView::slotImagePreview() 0088 { 0089 slotTogglePreviewMode(currentInfo()); 0090 } 0091 0092 /** 0093 * @brief This method toggles between AlbumView/MapWidgetView and ImagePreview modes, depending on the context. 0094 */ 0095 void ItemIconView::slotTogglePreviewMode(const ItemInfo& info) 0096 { 0097 if (((viewMode() == StackedView::IconViewMode) || 0098 (viewMode() == StackedView::TableViewMode) || 0099 (viewMode() == StackedView::MapWidgetMode)) && !info.isNull()) 0100 { 0101 if (info.isLocationAvailable()) 0102 { 0103 d->lastViewMode = viewMode(); 0104 0105 if (viewMode() == StackedView::IconViewMode) 0106 { 0107 d->stackedView->setPreviewItem(info, d->iconView->previousInfo(info), d->iconView->nextInfo(info)); 0108 } 0109 else 0110 { 0111 d->stackedView->setPreviewItem(info, ItemInfo(), ItemInfo()); 0112 } 0113 } 0114 else 0115 { 0116 QModelIndex index = d->iconView->indexForInfo(info); 0117 d->iconView->showIndexNotification(index, 0118 i18nc("@info: item icon view", "The storage location of this image\nis currently not available")); 0119 } 0120 } 0121 else 0122 { 0123 // go back to either AlbumViewMode or MapWidgetMode 0124 0125 d->stackedView->setViewMode(d->lastViewMode); 0126 } 0127 0128 // make sure the next/previous buttons are updated 0129 0130 slotImageSelected(); 0131 } 0132 0133 void ItemIconView::slotViewModeChanged() 0134 { 0135 toggleZoomActions(); 0136 0137 switch (viewMode()) 0138 { 0139 case StackedView::IconViewMode: 0140 { 0141 Q_EMIT signalSwitchedToIconView(); 0142 Q_EMIT signalThumbSizeChanged(d->thumbSize); 0143 break; 0144 } 0145 0146 case StackedView::PreviewImageMode: 0147 { 0148 Q_EMIT signalSwitchedToPreview(); 0149 slotZoomFactorChanged(d->stackedView->zoomFactor()); 0150 break; 0151 } 0152 0153 case StackedView::WelcomePageMode: 0154 { 0155 Q_EMIT signalSwitchedToIconView(); 0156 break; 0157 } 0158 0159 case StackedView::MediaPlayerMode: 0160 { 0161 Q_EMIT signalSwitchedToPreview(); 0162 break; 0163 } 0164 0165 case StackedView::MapWidgetMode: 0166 { 0167 Q_EMIT signalSwitchedToMapView(); 0168 // TODO: connect map view's zoom buttons to main status bar zoom buttons 0169 break; 0170 } 0171 0172 case StackedView::TableViewMode: 0173 { 0174 Q_EMIT signalSwitchedToTableView(); 0175 Q_EMIT signalThumbSizeChanged(d->thumbSize); 0176 break; 0177 } 0178 0179 case StackedView::TrashViewMode: 0180 { 0181 d->msgNotifyTimer->stop(); 0182 d->errorWidget->animatedHide(); 0183 0184 Q_EMIT signalSwitchedToTrashView(); 0185 break; 0186 } 0187 } 0188 } 0189 0190 void ItemIconView::toggleShowBar(bool b) 0191 { 0192 d->stackedView->thumbBarDock()->showThumbBar(b); 0193 0194 // See bug #319876 : force to reload current view mode to set thumbbar visibility properly. 0195 0196 d->stackedView->setViewMode(viewMode()); 0197 } 0198 0199 StackedView::StackedViewMode ItemIconView::viewMode() const 0200 { 0201 return d->stackedView->viewMode(); 0202 } 0203 0204 void ItemIconView::slotSetupMetadataFilters(int tab) 0205 { 0206 Setup::execMetadataFilters(this, tab); 0207 } 0208 0209 void ItemIconView::slotSetupExifTool() 0210 { 0211 Setup::execExifTool(this); 0212 } 0213 0214 void ItemIconView::toggleFullScreen(bool set) 0215 { 0216 d->stackedView->imagePreviewView()->toggleFullScreen(set); 0217 } 0218 0219 void ItemIconView::setToolsIconView(DCategorizedView* const view) 0220 { 0221 d->rightSideBar->appendTab(view, 0222 QIcon::fromTheme(QLatin1String("document-edit")), 0223 i18nc("@title: item icon view", "Tools")); 0224 } 0225 0226 void ItemIconView::refreshView() 0227 { 0228 d->rightSideBar->refreshTagsView(); 0229 } 0230 0231 void ItemIconView::slotShowContextMenu(QContextMenuEvent* event, 0232 const QList<QAction*>& extraGroupingActions) 0233 { 0234 Album* const album = currentAlbum(); 0235 0236 if (!album || 0237 album->isRoot() || 0238 ((album->type() != Album::PHYSICAL) && (album->type() != Album::TAG))) 0239 { 0240 return; 0241 } 0242 0243 QMenu menu(this); 0244 ContextMenuHelper cmHelper(&menu); 0245 0246 cmHelper.addAction(QLatin1String("full_screen")); 0247 cmHelper.addAction(QLatin1String("options_show_menubar")); 0248 cmHelper.addSeparator(); 0249 cmHelper.addStandardActionPaste(this, SLOT(slotImagePaste())); 0250 0251 if (!extraGroupingActions.isEmpty()) 0252 { 0253 cmHelper.addSeparator(); 0254 cmHelper.addGroupMenu(QList<qlonglong>(), extraGroupingActions); 0255 } 0256 0257 cmHelper.exec(event->globalPos()); 0258 } 0259 0260 void ItemIconView::slotShowContextMenuOnInfo(QContextMenuEvent* event, const ItemInfo& info, 0261 const QList<QAction*>& extraGroupingActions, 0262 ItemFilterModel* imageFilterModel) 0263 { 0264 QList<qlonglong> selectedImageIds = selectedInfoList(true, true).toImageIdList(); 0265 0266 // -------------------------------------------------------- 0267 0268 QMenu menu(this); 0269 ContextMenuHelper cmHelper(&menu); 0270 cmHelper.setItemFilterModel(imageFilterModel); 0271 0272 cmHelper.addAction(QLatin1String("full_screen")); 0273 cmHelper.addAction(QLatin1String("options_show_menubar")); 0274 cmHelper.addSeparator(); 0275 0276 // -------------------------------------------------------- 0277 0278 QAction* const viewAction = new QAction(i18nc("@action: View the selected image", "Preview"), this); 0279 viewAction->setIcon(QIcon::fromTheme(QLatin1String("view-preview"))); 0280 viewAction->setEnabled(selectedImageIds.count() == 1); 0281 cmHelper.addAction(viewAction); 0282 0283 cmHelper.addOpenAndNavigateActions(selectedImageIds); 0284 cmHelper.addSeparator(); 0285 0286 // -------------------------------------------------------- 0287 0288 cmHelper.addAction(QLatin1String("image_scan_for_faces")); 0289 cmHelper.addAction(QLatin1String("image_recognize_faces")); 0290 cmHelper.addAction(QLatin1String("image_remove_all_faces")); 0291 cmHelper.addSeparator(); 0292 0293 // -------------------------------------------------------- 0294 0295 cmHelper.addAction(QLatin1String("image_find_similar")); 0296 cmHelper.addStandardActionLightTable(); 0297 cmHelper.addQueueManagerMenu(); 0298 cmHelper.addSeparator(); 0299 0300 // -------------------------------------------------------- 0301 0302 cmHelper.addAction(QLatin1String("image_rotate")); 0303 cmHelper.addAction(QLatin1String("cut_album_selection")); 0304 cmHelper.addAction(QLatin1String("copy_album_selection")); 0305 cmHelper.addAction(QLatin1String("paste_album_selection")); 0306 cmHelper.addAction(QLatin1String("image_rename")); 0307 cmHelper.addStandardActionItemDelete(this, SLOT(slotImageDelete()), selectedImageIds.count()); 0308 cmHelper.addSeparator(); 0309 0310 // -------------------------------------------------------- 0311 0312 cmHelper.addIQSAction(this, SLOT(slotImageQualitySorter())); 0313 cmHelper.addSeparator(); 0314 0315 // -------------------------------------------------------- 0316 0317 cmHelper.addStandardActionThumbnail(selectedImageIds, currentAlbum()); 0318 cmHelper.addAssignTagsMenu(selectedImageIds); 0319 cmHelper.addRemoveTagsMenu(selectedImageIds); 0320 cmHelper.addRemoveAllTags(selectedImageIds); 0321 cmHelper.addLabelsAction(); 0322 0323 if (d->leftSideBar->getActiveTab() != d->peopleSideBar) 0324 { 0325 cmHelper.addSeparator(); 0326 0327 cmHelper.addGroupMenu(selectedImageIds, extraGroupingActions); 0328 } 0329 0330 // special action handling -------------------------------- 0331 0332 connect(&cmHelper, SIGNAL(signalAssignColorLabel(int)), 0333 this, SLOT(slotAssignColorLabel(int))); 0334 0335 connect(&cmHelper, SIGNAL(signalAssignPickLabel(int)), 0336 this, SLOT(slotAssignPickLabel(int))); 0337 0338 connect(&cmHelper, SIGNAL(signalAssignRating(int)), 0339 this, SLOT(slotAssignRating(int))); 0340 0341 connect(&cmHelper, SIGNAL(signalAssignTag(int)), 0342 this, SLOT(slotAssignTag(int))); 0343 0344 connect(&cmHelper, SIGNAL(signalRemoveTag(int)), 0345 this, SLOT(slotRemoveTag(int))); 0346 0347 connect(&cmHelper, SIGNAL(signalPopupTagsView()), 0348 d->rightSideBar, SLOT(slotPopupTagsView())); 0349 0350 connect(&cmHelper, SIGNAL(signalGotoTag(int)), 0351 this, SLOT(slotGotoTagAndItem(int))); 0352 0353 connect(&cmHelper, SIGNAL(signalGotoTag(int)), 0354 d->albumHistory, SLOT(slotClearSelectTAlbum(int))); 0355 0356 connect(&cmHelper, SIGNAL(signalGotoAlbum(ItemInfo)), 0357 this, SLOT(slotGotoAlbumAndItem(ItemInfo))); 0358 0359 connect(&cmHelper, SIGNAL(signalGotoAlbum(ItemInfo)), 0360 d->albumHistory, SLOT(slotClearSelectPAlbum(ItemInfo))); 0361 0362 connect(&cmHelper, SIGNAL(signalGotoDate(ItemInfo)), 0363 this, SLOT(slotGotoDateAndItem(ItemInfo))); 0364 0365 connect(&cmHelper, SIGNAL(signalSetThumbnail(ItemInfo)), 0366 this, SLOT(slotSetAsAlbumThumbnail(ItemInfo))); 0367 0368 connect(&cmHelper, SIGNAL(signalAddToExistingQueue(int)), 0369 this, SLOT(slotImageAddToExistingQueue(int))); 0370 0371 connect(&cmHelper, SIGNAL(signalCreateGroup()), 0372 this, SLOT(slotCreateGroupFromSelection())); 0373 0374 connect(&cmHelper, SIGNAL(signalCreateGroupByTime()), 0375 this, SLOT(slotCreateGroupByTimeFromSelection())); 0376 0377 connect(&cmHelper, SIGNAL(signalCreateGroupByFilename()), 0378 this, SLOT(slotCreateGroupByFilenameFromSelection())); 0379 0380 connect(&cmHelper, SIGNAL(signalCreateGroupByTimelapse()), 0381 this, SLOT(slotCreateGroupByTimelapseFromSelection())); 0382 0383 connect(&cmHelper, SIGNAL(signalRemoveFromGroup()), 0384 this, SLOT(slotRemoveSelectedFromGroup())); 0385 0386 connect(&cmHelper, SIGNAL(signalUngroup()), 0387 this, SLOT(slotUngroupSelected())); 0388 0389 // -------------------------------------------------------- 0390 0391 QAction* const choice = cmHelper.exec(event->globalPos()); 0392 0393 if (choice && (choice == viewAction)) 0394 { 0395 slotTogglePreviewMode(info); 0396 } 0397 } 0398 0399 void ItemIconView::slotShowGroupContextMenu(QContextMenuEvent* event, 0400 const QList<ItemInfo>& selectedInfos, 0401 ItemFilterModel* imageFilterModel) 0402 { 0403 QList<qlonglong> selectedImageIDs; 0404 0405 Q_FOREACH (const ItemInfo& info, selectedInfos) 0406 { 0407 selectedImageIDs << info.id(); 0408 } 0409 0410 QMenu popmenu(this); 0411 ContextMenuHelper cmhelper(&popmenu); 0412 cmhelper.setItemFilterModel(imageFilterModel); 0413 cmhelper.addGroupActions(selectedImageIDs); 0414 0415 // special action handling -------------------------------- 0416 0417 connect(&cmhelper, SIGNAL(signalCreateGroup()), 0418 this, SLOT(slotCreateGroupFromSelection())); 0419 0420 connect(&cmhelper, SIGNAL(signalCreateGroupByTime()), 0421 this, SLOT(slotCreateGroupByTimeFromSelection())); 0422 0423 connect(&cmhelper, SIGNAL(signalCreateGroupByFilename()), 0424 this, SLOT(slotCreateGroupByFilenameFromSelection())); 0425 0426 connect(&cmhelper, SIGNAL(signalCreateGroupByTimelapse()), 0427 this, SLOT(slotCreateGroupByTimelapseFromSelection())); 0428 0429 connect(&cmhelper, SIGNAL(signalUngroup()), 0430 this, SLOT(slotUngroupSelected())); 0431 0432 connect(&cmhelper, SIGNAL(signalRemoveFromGroup()), 0433 this, SLOT(slotRemoveSelectedFromGroup())); 0434 0435 cmhelper.exec(event->globalPos()); 0436 } 0437 0438 } // namespace Digikam