File indexing completed on 2025-01-05 03:51:15
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2002-16-10 0007 * Description : main digiKam interface implementation - Internal setup 0008 * 0009 * SPDX-FileCopyrightText: 2002-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "digikamapp_p.h" 0016 0017 namespace Digikam 0018 { 0019 0020 void DigikamApp::setupView() 0021 { 0022 if (d->splashScreen) 0023 { 0024 d->splashScreen->setMessage(i18nc("@info: setup", "Initializing Main View...")); 0025 } 0026 0027 d->view = new ItemIconView(this, d->modelCollection); 0028 setCentralWidget(d->view); 0029 d->view->applySettings(); 0030 } 0031 0032 void DigikamApp::setupViewConnections() 0033 { 0034 connect(d->view, SIGNAL(signalAlbumSelected(Album*)), 0035 this, SLOT(slotAlbumSelected(Album*))); 0036 0037 connect(d->view, SIGNAL(signalSelectionChanged(int)), 0038 this, SLOT(slotSelectionChanged(int))); 0039 0040 connect(d->view, SIGNAL(signalTrashSelectionChanged(QString)), 0041 this, SLOT(slotTrashSelectionChanged(QString))); 0042 0043 connect(d->view, SIGNAL(signalImageSelected(ItemInfoList,ItemInfoList)), 0044 this, SLOT(slotImageSelected(ItemInfoList,ItemInfoList))); 0045 0046 connect(d->view, SIGNAL(signalSwitchedToPreview()), 0047 this, SLOT(slotSwitchedToPreview())); 0048 0049 connect(d->view, SIGNAL(signalSwitchedToIconView()), 0050 this, SLOT(slotSwitchedToIconView())); 0051 0052 connect(d->view, SIGNAL(signalSwitchedToMapView()), 0053 this, SLOT(slotSwitchedToMapView())); 0054 0055 connect(d->view, SIGNAL(signalSwitchedToTableView()), 0056 this, SLOT(slotSwitchedToTableView())); 0057 0058 connect(d->view, SIGNAL(signalSwitchedToTrashView()), 0059 this, SLOT(slotSwitchedToTrashView())); 0060 } 0061 0062 void DigikamApp::setupStatusBar() 0063 { 0064 d->statusLabel = new DAdjustableLabel(statusBar()); 0065 d->statusLabel->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); 0066 statusBar()->addWidget(d->statusLabel, 80); 0067 0068 //------------------------------------------------------------------------------ 0069 0070 d->metadataStatusBar = new MetadataStatusBar(statusBar()); 0071 statusBar()->addWidget(d->metadataStatusBar, 50); 0072 0073 //------------------------------------------------------------------------------ 0074 0075 d->filterStatusBar = new FilterStatusBar(statusBar()); 0076 statusBar()->addWidget(d->filterStatusBar, 50); 0077 d->view->connectIconViewFilter(d->filterStatusBar); 0078 0079 //------------------------------------------------------------------------------ 0080 0081 ProgressView* const view = new ProgressView(statusBar(), this); 0082 view->hide(); 0083 0084 StatusbarProgressWidget* const littleProgress = new StatusbarProgressWidget(view, statusBar()); 0085 littleProgress->show(); 0086 statusBar()->addPermanentWidget(littleProgress); 0087 0088 //------------------------------------------------------------------------------ 0089 0090 d->zoomBar = new DZoomBar(statusBar()); 0091 d->zoomBar->setZoomToFitAction(d->zoomFitToWindowAction); 0092 d->zoomBar->setZoomTo100Action(d->zoomTo100percents); 0093 d->zoomBar->setZoomPlusAction(d->zoomPlusAction); 0094 d->zoomBar->setZoomMinusAction(d->zoomMinusAction); 0095 d->zoomBar->setBarMode(DZoomBar::ThumbsSizeCtrl); 0096 statusBar()->addPermanentWidget(d->zoomBar); 0097 0098 //------------------------------------------------------------------------------ 0099 0100 connect(d->zoomBar, SIGNAL(signalZoomSliderChanged(int)), 0101 this, SLOT(slotZoomSliderChanged(int))); 0102 0103 connect(this, SIGNAL(signalWindowHasMoved()), 0104 d->zoomBar, SLOT(slotUpdateTrackerPos())); 0105 0106 connect(d->zoomBar, SIGNAL(signalZoomValueEdited(double)), 0107 d->view, SLOT(setZoomFactor(double))); 0108 0109 connect(d->view, SIGNAL(signalZoomChanged(double)), 0110 this, SLOT(slotZoomChanged(double))); 0111 0112 connect(d->view, SIGNAL(signalThumbSizeChanged(int)), 0113 this, SLOT(slotThumbSizeChanged(int))); 0114 } 0115 0116 void DigikamApp::setupActions() 0117 { 0118 KActionCollection* const ac = actionCollection(); 0119 0120 d->solidCameraActionGroup = new QActionGroup(this); 0121 connect(d->solidCameraActionGroup, SIGNAL(triggered(QAction*)), 0122 this, SLOT(slotOpenSolidCamera(QAction*))); 0123 0124 d->solidUsmActionGroup = new QActionGroup(this); 0125 connect(d->solidUsmActionGroup, SIGNAL(triggered(QAction*)), 0126 this, SLOT(slotOpenSolidUsmDevice(QAction*))); 0127 0128 d->manualCameraActionGroup = new QActionGroup(this); 0129 connect(d->manualCameraActionGroup, SIGNAL(triggered(QAction*)), 0130 this, SLOT(slotOpenManualCamera(QAction*))); 0131 0132 // ----------------------------------------------------------------- 0133 0134 d->backwardActionMenu = new KToolBarPopupAction(QIcon::fromTheme(QLatin1String("go-previous")), 0135 i18nc("@action: setup", "&Back"), this); 0136 d->backwardActionMenu->setEnabled(false); 0137 ac->addAction(QLatin1String("album_back"), d->backwardActionMenu); 0138 ac->setDefaultShortcut(d->backwardActionMenu, Qt::ALT | Qt::Key_Left); 0139 0140 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0141 0142 connect(d->backwardActionMenu->popupMenu(), SIGNAL(aboutToShow()), 0143 this, SLOT(slotAboutToShowBackwardMenu())); 0144 0145 #else 0146 0147 connect(d->backwardActionMenu->menu(), SIGNAL(aboutToShow()), 0148 this, SLOT(slotAboutToShowBackwardMenu())); 0149 0150 #endif 0151 0152 connect(d->backwardActionMenu, &QAction::triggered, 0153 this, [this]() { d->view->slotAlbumHistoryBack(1); }); 0154 0155 // ----------------------------------------------------------------- 0156 0157 d->forwardActionMenu = new KToolBarPopupAction(QIcon::fromTheme(QLatin1String("go-next")), 0158 i18nc("@action: setup", "Forward"), this); 0159 d->forwardActionMenu->setEnabled(false); 0160 ac->addAction(QLatin1String("album_forward"), d->forwardActionMenu); 0161 ac->setDefaultShortcut(d->forwardActionMenu, Qt::ALT | Qt::Key_Right); 0162 0163 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0164 0165 connect(d->forwardActionMenu->popupMenu(), SIGNAL(aboutToShow()), 0166 this, SLOT(slotAboutToShowForwardMenu())); 0167 0168 #else 0169 0170 connect(d->forwardActionMenu->menu(), SIGNAL(aboutToShow()), 0171 this, SLOT(slotAboutToShowForwardMenu())); 0172 0173 #endif 0174 0175 connect(d->forwardActionMenu, &QAction::triggered, 0176 this, [this]() { d->view->slotAlbumHistoryForward(1); }); 0177 0178 // ----------------------------------------------------------------- 0179 0180 d->refreshAction = new QAction(QIcon::fromTheme(QLatin1String("view-refresh")), 0181 i18nc("@action: setup", "Refresh"), this); 0182 d->refreshAction->setWhatsThis(i18nc("@info: setup", "Refresh the current contents.")); 0183 connect(d->refreshAction, SIGNAL(triggered()), d->view, SLOT(slotRefresh())); 0184 ac->addAction(QLatin1String("view_refresh"), d->refreshAction); 0185 ac->setDefaultShortcuts(d->refreshAction, QList<QKeySequence>() << Qt::Key_F5 << (Qt::CTRL | Qt::Key_F5)); 0186 0187 // ----------------------------------------------------------------- 0188 0189 Q_FOREACH (SidebarWidget* const leftWidget, d->view->leftSidebarWidgets()) 0190 { 0191 QString actionName = QLatin1String("browse_") + leftWidget->objectName() 0192 .remove(QLatin1Char(' ')) 0193 .remove(QLatin1String("Sidebar")) 0194 .remove(QLatin1String("FolderView")) 0195 .remove(QLatin1String("View")).toLower(); 0196 qCDebug(DIGIKAM_GENERAL_LOG) << actionName; 0197 0198 QAction* const action = new QAction(leftWidget->getIcon(), leftWidget->getCaption(), this); 0199 ac->addAction(actionName, action); 0200 ac->setDefaultShortcut(action, QKeySequence(leftWidget->property("Shortcut").toInt())); 0201 0202 connect(action, &QAction::triggered, 0203 this, [this, leftWidget]() { d->view->slotLeftSideBarActivate(leftWidget); }); 0204 } 0205 0206 // ----------------------------------------------------------------- 0207 0208 d->newAction = new QAction(QIcon::fromTheme(QLatin1String("folder-new")), 0209 i18nc("@action: setup", "&New..."), this); 0210 d->newAction->setWhatsThis(i18nc("@info: setup", "Creates a new empty Album in the collection.")); 0211 connect(d->newAction, SIGNAL(triggered()), d->view, SLOT(slotNewAlbum())); 0212 ac->addAction(QLatin1String("album_new"), d->newAction); 0213 ac->setDefaultShortcut(d->newAction, Qt::CTRL | Qt::Key_N); 0214 0215 // ----------------------------------------------------------------- 0216 0217 d->moveSelectionToAlbumAction = new QAction(QIcon::fromTheme(QLatin1String("folder-new")), 0218 i18nc("@action: setup", "&Move to Album..."), this); 0219 d->moveSelectionToAlbumAction->setWhatsThis(i18nc("@info: setup", "Move selected images into an album.")); 0220 connect(d->moveSelectionToAlbumAction, SIGNAL(triggered()), d->view, SLOT(slotMoveSelectionToAlbum())); 0221 ac->addAction(QLatin1String("move_selection_to_album"), d->moveSelectionToAlbumAction); 0222 0223 // ----------------------------------------------------------------- 0224 0225 d->copySelectionToAction = new QAction(QIcon::fromTheme(QLatin1String("edit-copy")), 0226 i18nc("@action: setup", "&Copy to..."), this); 0227 d->copySelectionToAction->setWhatsThis(i18nc("@info: setup", "Copy selected images to a target folder.")); 0228 connect(d->copySelectionToAction, SIGNAL(triggered()), d->view, SLOT(slotCopySelectionTo())); 0229 ac->addAction(QLatin1String("copy_selection_to"), d->copySelectionToAction); 0230 0231 // ----------------------------------------------------------------- 0232 0233 d->deleteAction = new QAction(QIcon::fromTheme(QLatin1String("edit-delete")), 0234 i18nc("@action: setup", "Delete Album"), this); 0235 connect(d->deleteAction, SIGNAL(triggered()), d->view, SLOT(slotDeleteAlbum())); 0236 ac->addAction(QLatin1String("album_delete"), d->deleteAction); 0237 0238 // ----------------------------------------------------------------- 0239 0240 d->renameAction = new QAction(QIcon::fromTheme(QLatin1String("document-edit")), 0241 i18nc("@action: setup", "Rename..."), this); 0242 connect(d->renameAction, SIGNAL(triggered()), d->view, SLOT(slotRenameAlbum())); 0243 ac->addAction(QLatin1String("album_rename"), d->renameAction); 0244 ac->setDefaultShortcut(d->renameAction, Qt::SHIFT | Qt::Key_F2); 0245 0246 // ----------------------------------------------------------------- 0247 0248 d->propsEditAction = new QAction(QIcon::fromTheme(QLatin1String("configure")), 0249 i18nc("@action: setup", "Properties"), this); 0250 d->propsEditAction->setWhatsThis(i18nc("@info: setup", "Edit album properties and collection information.")); 0251 connect(d->propsEditAction, SIGNAL(triggered()), d->view, SLOT(slotAlbumPropsEdit())); 0252 ac->addAction(QLatin1String("album_propsEdit"), d->propsEditAction); 0253 ac->setDefaultShortcut(d->propsEditAction, Qt::ALT | Qt::Key_Return); 0254 0255 // ----------------------------------------------------------------- 0256 0257 d->writeAlbumMetadataAction = new QAction(QIcon::fromTheme(QLatin1String("document-edit")), 0258 i18nc("@action: setup", "Write Metadata to Files"), this); 0259 d->writeAlbumMetadataAction->setWhatsThis(i18nc("@info: setup", "Updates metadata of files in the current " 0260 "album with the contents of digiKam database " 0261 "(file metadata will be overwritten with data from " 0262 "the database).")); 0263 connect(d->writeAlbumMetadataAction, SIGNAL(triggered()), d->view, SLOT(slotAlbumWriteMetadata())); 0264 ac->addAction(QLatin1String("album_write_metadata"), d->writeAlbumMetadataAction); 0265 0266 // ----------------------------------------------------------------- 0267 0268 d->readAlbumMetadataAction = new QAction(QIcon::fromTheme(QLatin1String("edit-redo")), 0269 i18nc("@action: setup", "Reread Metadata From Files"), this); 0270 d->readAlbumMetadataAction->setWhatsThis(i18nc("@info: setup", "Updates the digiKam database from the metadata " 0271 "of the files in the current album " 0272 "(information in the database will be overwritten with data from " 0273 "the files' metadata).")); 0274 connect(d->readAlbumMetadataAction, SIGNAL(triggered()), d->view, SLOT(slotAlbumReadMetadata())); 0275 ac->addAction(QLatin1String("album_read_metadata"), d->readAlbumMetadataAction); 0276 0277 // ----------------------------------------------------------------- 0278 0279 d->openInFileManagerAction = new QAction(QIcon::fromTheme(QLatin1String("folder-open")), 0280 i18nc("@action: setup", "Open in File Manager"), this); 0281 connect(d->openInFileManagerAction, SIGNAL(triggered()), d->view, SLOT(slotAlbumOpenInFileManager())); 0282 ac->addAction(QLatin1String("album_openinfilemanager"), d->openInFileManagerAction); 0283 0284 // ----------------------------------------------------------- 0285 0286 d->openTagMngrAction = new QAction(QIcon::fromTheme(QLatin1String("tag")), 0287 i18nc("@action: setup", "Tag Manager"), this); 0288 connect(d->openTagMngrAction, SIGNAL(triggered()), d->view, SLOT(slotOpenTagsManager())); 0289 ac->addAction(QLatin1String("open_tag_mngr"), d->openTagMngrAction); 0290 0291 // ----------------------------------------------------------- 0292 0293 d->newTagAction = new QAction(QIcon::fromTheme(QLatin1String("tag-new")), 0294 i18nc("@action: new tag", "N&ew..."), this); 0295 connect(d->newTagAction, SIGNAL(triggered()), d->view, SLOT(slotNewTag())); 0296 ac->addAction(QLatin1String("tag_new"), d->newTagAction); 0297 0298 // ----------------------------------------------------------- 0299 0300 d->editTagAction = new QAction(QIcon::fromTheme(QLatin1String("tag-properties")), 0301 i18nc("@action: setup", "Properties"), this); 0302 connect(d->editTagAction, SIGNAL(triggered()), d->view, SLOT(slotEditTag())); 0303 ac->addAction(QLatin1String("tag_edit"), d->editTagAction); 0304 0305 // ----------------------------------------------------------- 0306 0307 d->deleteTagAction = new QAction(QIcon::fromTheme(QLatin1String("edit-delete")), 0308 i18nc("@action: setup", "Delete"), this); 0309 connect(d->deleteTagAction, SIGNAL(triggered()), d->view, SLOT(slotDeleteTag())); 0310 ac->addAction(QLatin1String("tag_delete"), d->deleteTagAction); 0311 0312 // ----------------------------------------------------------- 0313 0314 d->assignTagAction = new QAction(QIcon::fromTheme(QLatin1String("tag-new")), 0315 i18nc("@action: setup", "Assign Tag"), this); 0316 connect(d->assignTagAction, SIGNAL(triggered()), d->view, SLOT(slotAssignTag())); 0317 ac->addAction(QLatin1String("tag_assign"), d->assignTagAction); 0318 ac->setDefaultShortcut(d->assignTagAction, Qt::Key_T); 0319 0320 // ----------------------------------------------------------- 0321 0322 d->imageViewSelectionAction = new KSelectAction(QIcon::fromTheme(QLatin1String("view-preview")), 0323 i18nc("@action: setup", "Views"), this); 0324 ac->addAction(QLatin1String("view_selection"), d->imageViewSelectionAction); 0325 0326 d->imageIconViewAction = new QAction(QIcon::fromTheme(QLatin1String("view-list-icons")), 0327 i18nc("@action: Go to thumbnails (icon) view", "Thumbnails"), this); 0328 d->imageIconViewAction->setCheckable(true); 0329 ac->addAction(QLatin1String("icon_view"), d->imageIconViewAction); 0330 connect(d->imageIconViewAction, SIGNAL(triggered()), d->view, SLOT(slotIconView())); 0331 d->imageViewSelectionAction->addAction(d->imageIconViewAction); 0332 0333 d->imagePreviewAction = new QAction(QIcon::fromTheme(QLatin1String("view-preview")), 0334 i18nc("@action: View the selected image", "Preview"), this); 0335 d->imagePreviewAction->setCheckable(true); 0336 ac->addAction(QLatin1String("image_view"), d->imagePreviewAction); 0337 ac->setDefaultShortcut(d->imagePreviewAction, Qt::Key_F3); 0338 connect(d->imagePreviewAction, SIGNAL(triggered()), d->view, SLOT(slotImagePreview())); 0339 d->imageViewSelectionAction->addAction(d->imagePreviewAction); 0340 0341 #ifdef HAVE_GEOLOCATION 0342 0343 d->imageMapViewAction = new QAction(QIcon::fromTheme(QLatin1String("globe")), 0344 i18nc("@action: Switch to map view", "Map"), this); 0345 d->imageMapViewAction->setCheckable(true); 0346 ac->addAction(QLatin1String("map_view"), d->imageMapViewAction); 0347 connect(d->imageMapViewAction, SIGNAL(triggered()), d->view, SLOT(slotMapWidgetView())); 0348 d->imageViewSelectionAction->addAction(d->imageMapViewAction); 0349 0350 #endif // HAVE_GEOLOCATION 0351 0352 d->imageTableViewAction = new QAction(QIcon::fromTheme(QLatin1String("view-list-details")), 0353 i18nc("@action: Switch to table view", "Table"), this); 0354 d->imageTableViewAction->setCheckable(true); 0355 ac->addAction(QLatin1String("table_view"), d->imageTableViewAction); 0356 connect(d->imageTableViewAction, SIGNAL(triggered()), d->view, SLOT(slotTableView())); 0357 d->imageViewSelectionAction->addAction(d->imageTableViewAction); 0358 0359 // ----------------------------------------------------------- 0360 0361 d->imageViewAction = new QAction(QIcon::fromTheme(QLatin1String("quickopen-file")), 0362 i18nc("@action: setup", "Open..."), this); 0363 d->imageViewAction->setWhatsThis(i18nc("@info: setup", "Open the selected item.")); 0364 connect(d->imageViewAction, SIGNAL(triggered()), d->view, SLOT(slotImageEdit())); 0365 ac->addAction(QLatin1String("image_edit"), d->imageViewAction); 0366 ac->setDefaultShortcut(d->imageViewAction, Qt::Key_F4); 0367 0368 d->openWithAction = new QAction(QIcon::fromTheme(QLatin1String("preferences-desktop-filetype-association")), 0369 i18nc("@action: setup", "Open With Default Application"), this); 0370 d->openWithAction->setWhatsThis(i18nc("@info: setup", "Open the selected item with default assigned application.")); 0371 connect(d->openWithAction, SIGNAL(triggered()), d->view, SLOT(slotFileWithDefaultApplication())); 0372 ac->addAction(QLatin1String("open_with_default_application"), d->openWithAction); 0373 ac->setDefaultShortcut(d->openWithAction, Qt::CTRL | Qt::Key_F4); 0374 0375 d->ieAction = new QAction(QIcon::fromTheme(QLatin1String("document-edit")), 0376 i18nc("@action: setup", "Image Editor"), this); 0377 d->ieAction->setWhatsThis(i18nc("@action: setup", "Open the image editor.")); 0378 connect(d->ieAction, SIGNAL(triggered()), d->view, SLOT(slotEditor())); 0379 ac->addAction(QLatin1String("imageeditor"), d->ieAction); 0380 0381 // ----------------------------------------------------------- 0382 0383 d->ltAction = new QAction(QIcon::fromTheme(QLatin1String("lighttable")), 0384 i18nc("@action: setup", "Light Table"), this); 0385 connect(d->ltAction, SIGNAL(triggered()), d->view, SLOT(slotLightTable())); 0386 ac->addAction(QLatin1String("light_table"), d->ltAction); 0387 ac->setDefaultShortcut(d->ltAction, Qt::SHIFT | Qt::Key_L); 0388 0389 d->imageLightTableAction = new QAction(QIcon::fromTheme(QLatin1String("lighttable")), 0390 i18nc("@action: setup", "Place onto Light Table"), this); 0391 d->imageLightTableAction->setWhatsThis(i18nc("@info: setup", "Place the selected items on the light table thumbbar.")); 0392 connect(d->imageLightTableAction, SIGNAL(triggered()), d->view, SLOT(slotImageLightTable())); 0393 ac->addAction(QLatin1String("image_lighttable"), d->imageLightTableAction); 0394 ac->setDefaultShortcut(d->imageLightTableAction, Qt::CTRL | Qt::Key_L); 0395 0396 d->imageAddLightTableAction = new QAction(QIcon::fromTheme(QLatin1String("list-add")), 0397 i18nc("@action: setup", "Add to Light Table"), this); 0398 d->imageAddLightTableAction->setWhatsThis(i18nc("@info: setup", "Add selected items to the light table thumbbar.")); 0399 connect(d->imageAddLightTableAction, SIGNAL(triggered()), d->view, SLOT(slotImageAddToLightTable())); 0400 ac->addAction(QLatin1String("image_add_to_lighttable"), d->imageAddLightTableAction); 0401 ac->setDefaultShortcut(d->imageAddLightTableAction, Qt::CTRL | Qt::SHIFT | Qt::Key_L); 0402 0403 // ----------------------------------------------------------- 0404 0405 d->bqmAction = new QAction(QIcon::fromTheme(QLatin1String("run-build")), 0406 i18nc("@action: setup", "Batch Queue Manager"), this); 0407 connect(d->bqmAction, SIGNAL(triggered()), d->view, SLOT(slotQueueMgr())); 0408 ac->addAction(QLatin1String("queue_manager"), d->bqmAction); 0409 ac->setDefaultShortcut(d->bqmAction, Qt::SHIFT | Qt::Key_B); 0410 0411 d->imageAddCurrentQueueAction = new QAction(QIcon::fromTheme(QLatin1String("go-up")), 0412 i18nc("@action: setup", "Add to Current Queue"), this); 0413 d->imageAddCurrentQueueAction->setWhatsThis(i18nc("@info: setup", "Add selected items to current queue from batch manager.")); 0414 connect(d->imageAddCurrentQueueAction, SIGNAL(triggered()), d->view, SLOT(slotImageAddToCurrentQueue())); 0415 ac->addAction(QLatin1String("image_add_to_current_queue"), d->imageAddCurrentQueueAction); 0416 ac->setDefaultShortcut(d->imageAddCurrentQueueAction, Qt::CTRL | Qt::Key_B); 0417 0418 d->imageAddNewQueueAction = new QAction(QIcon::fromTheme(QLatin1String("list-add")), 0419 i18nc("@action: setup", "Add to New Queue"), this); 0420 d->imageAddNewQueueAction->setWhatsThis(i18nc("@info: setup", "Add selected items to a new queue from batch manager.")); 0421 connect(d->imageAddNewQueueAction, SIGNAL(triggered()), d->view, SLOT(slotImageAddToNewQueue())); 0422 ac->addAction(QLatin1String("image_add_to_new_queue"), d->imageAddNewQueueAction); 0423 ac->setDefaultShortcut(d->imageAddNewQueueAction, Qt::CTRL | Qt::SHIFT | Qt::Key_B); 0424 0425 // ----------------------------------------------------------------- 0426 0427 d->quickImportMenu->setTitle(i18nc("@action: Import photos from camera", "Import")); 0428 d->quickImportMenu->setIcon(QIcon::fromTheme(QLatin1String("camera-photo"))); 0429 ac->addAction(QLatin1String("import_auto"), d->quickImportMenu->menuAction()); 0430 0431 // ----------------------------------------------------------------- 0432 0433 d->imageWriteMetadataAction = new QAction(QIcon::fromTheme(QLatin1String("document-edit")), 0434 i18nc("@action: setup", "Write Metadata to Selected Files"), this); 0435 d->imageWriteMetadataAction->setWhatsThis(i18nc("@info: setup", "Updates metadata of files in the current " 0436 "album with the contents of digiKam database " 0437 "(file metadata will be overwritten with data from " 0438 "the database).")); 0439 connect(d->imageWriteMetadataAction, SIGNAL(triggered()), d->view, SLOT(slotImageWriteMetadata())); 0440 ac->addAction(QLatin1String("image_write_metadata"), d->imageWriteMetadataAction); 0441 0442 // ----------------------------------------------------------------- 0443 0444 d->imageReadMetadataAction = new QAction(QIcon::fromTheme(QLatin1String("edit-redo")), 0445 i18nc("@action: setup", "Reread Metadata From Selected Files"), this); 0446 d->imageReadMetadataAction->setWhatsThis(i18nc("@info: setup", "Updates the digiKam database from the metadata " 0447 "of the files in the current album " 0448 "(information in the database will be overwritten with data from " 0449 "the files' metadata).")); 0450 connect(d->imageReadMetadataAction, SIGNAL(triggered()), d->view, SLOT(slotImageReadMetadata())); 0451 ac->addAction(QLatin1String("image_read_metadata"), d->imageReadMetadataAction); 0452 0453 // ----------------------------------------------------------- 0454 0455 d->imageScanForFacesAction = new QAction(QIcon::fromTheme(QLatin1String("list-add-user")), 0456 i18nc("@action: setup", "Scan for Faces"), this); 0457 connect(d->imageScanForFacesAction, SIGNAL(triggered()), d->view, SLOT(slotImageScanForFaces())); 0458 ac->addAction(QLatin1String("image_scan_for_faces"), d->imageScanForFacesAction); 0459 0460 d->imageRecognizeFacesAction = new QAction(QIcon::fromTheme(QLatin1String("edit-find-user")), 0461 i18nc("@action: setup", "Recognize Faces"), this); 0462 connect(d->imageRecognizeFacesAction, SIGNAL(triggered()), d->view, SLOT(slotImageRecognizeFaces())); 0463 ac->addAction(QLatin1String("image_recognize_faces"), d->imageRecognizeFacesAction); 0464 0465 d->imageRemoveAllFacesAction = new QAction(QIcon::fromTheme(QLatin1String("list-remove-user")), 0466 i18nc("@action: setup", "Remove all Faces"), this); 0467 connect(d->imageRemoveAllFacesAction, SIGNAL(triggered()), d->view, SLOT(slotImageRemoveAllFaces())); 0468 ac->addAction(QLatin1String("image_remove_all_faces"), d->imageRemoveAllFacesAction); 0469 0470 // ----------------------------------------------------------- 0471 0472 d->imageFindSimilarAction = new QAction(QIcon::fromTheme(QLatin1String("tools-wizard")), 0473 i18nc("@action: setup", "Find Similar..."), this); 0474 d->imageFindSimilarAction->setWhatsThis(i18nc("@info: setup", "Find similar images using selected item as reference.")); 0475 connect(d->imageFindSimilarAction, SIGNAL(triggered()), d->view, SLOT(slotImageFindSimilar())); 0476 ac->addAction(QLatin1String("image_find_similar"), d->imageFindSimilarAction); 0477 0478 // ----------------------------------------------------------- 0479 0480 d->imageRenameAction = new QAction(QIcon::fromTheme(QLatin1String("document-edit")), 0481 i18nc("@action: setup", "Rename..."), this); 0482 d->imageRenameAction->setWhatsThis(i18nc("@info: setup", "Change the filename of the currently selected item.")); 0483 connect(d->imageRenameAction, SIGNAL(triggered()), d->view, SLOT(slotImageRename())); 0484 ac->addAction(QLatin1String("image_rename"), d->imageRenameAction); 0485 ac->setDefaultShortcut(d->imageRenameAction, Qt::Key_F2); 0486 0487 // ----------------------------------------------------------- 0488 0489 // Pop up dialog to ask user whether to move to trash 0490 0491 d->imageDeleteAction = new QAction(QIcon::fromTheme(QLatin1String("user-trash")), 0492 i18nc("@action: Non-pluralized", "Move to Trash"), this); 0493 connect(d->imageDeleteAction, SIGNAL(triggered()), d->view, SLOT(slotImageDelete())); 0494 ac->addAction(QLatin1String("image_delete"), d->imageDeleteAction); 0495 ac->setDefaultShortcut(d->imageDeleteAction, Qt::Key_Delete); 0496 0497 // ----------------------------------------------------------- 0498 0499 // Pop up dialog to ask user whether to permanently delete 0500 // FIXME: This action is never used?? How can someone delete a album directly, without moving it to the trash first? 0501 // This is especially important when deleting from a different partition or from a net source. 0502 // Also note that we use the wrong icon for the default album delete action, which should have a trashcan icon instead 0503 // of a red cross, it confuses users. 0504 0505 d->imageDeletePermanentlyAction = new QAction(QIcon::fromTheme(QLatin1String("edit-delete")), 0506 i18nc("@action: setup", "Delete Permanently"), this); 0507 connect(d->imageDeletePermanentlyAction, SIGNAL(triggered()), d->view, SLOT(slotImageDeletePermanently())); 0508 ac->addAction(QLatin1String("image_delete_permanently"), d->imageDeletePermanentlyAction); 0509 ac->setDefaultShortcut(d->imageDeletePermanentlyAction, Qt::SHIFT | Qt::Key_Delete); 0510 0511 // ----------------------------------------------------------- 0512 0513 // These two actions are hidden, no menu entry, no toolbar entry, no shortcut. 0514 // Power users may add them. 0515 0516 d->imageDeletePermanentlyDirectlyAction = new QAction(QIcon::fromTheme(QLatin1String("edit-delete")), 0517 i18nc("@action: setup", "Delete permanently without confirmation"), this); 0518 connect(d->imageDeletePermanentlyDirectlyAction, SIGNAL(triggered()), 0519 d->view, SLOT(slotImageDeletePermanentlyDirectly())); 0520 ac->addAction(QLatin1String("image_delete_permanently_directly"), d->imageDeletePermanentlyDirectlyAction); 0521 0522 // ----------------------------------------------------------- 0523 0524 d->imageTrashDirectlyAction = new QAction(QIcon::fromTheme(QLatin1String("user-trash")), 0525 i18nc("@action: setup", "Move to trash without confirmation"), this); 0526 connect(d->imageTrashDirectlyAction, SIGNAL(triggered()), 0527 d->view, SLOT(slotImageTrashDirectly())); 0528 ac->addAction(QLatin1String("image_trash_directly"), d->imageTrashDirectlyAction); 0529 0530 // ----------------------------------------------------------------- 0531 0532 d->albumSortAction = new KSelectAction(i18nc("@action: setup", "&Sort Albums"), this); 0533 d->albumSortAction->setWhatsThis(i18nc("@info: setup", "Sort Albums in tree-view.")); 0534 0535 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0536 0537 connect(d->albumSortAction, SIGNAL(indexTriggered(int)), 0538 d->view, SLOT(slotSortAlbums(int))); 0539 0540 #else 0541 0542 connect(d->albumSortAction, SIGNAL(triggered(int)), 0543 d->view, SLOT(slotSortAlbums(int))); 0544 0545 #endif 0546 0547 ac->addAction(QLatin1String("album_sort"), d->albumSortAction); 0548 0549 // Use same list order as in applicationsettings enum 0550 0551 QStringList sortActionList; 0552 sortActionList.append(i18nc("@action: setup", "By Folder")); 0553 sortActionList.append(i18nc("@action: setup", "By Category")); 0554 sortActionList.append(i18nc("@action: setup", "By Date")); 0555 d->albumSortAction->setItems(sortActionList); 0556 0557 // ----------------------------------------------------------- 0558 0559 d->recurseAlbumsAction = new QAction(i18nc("@action: setup", "Include Album Sub-Tree"), this); 0560 d->recurseAlbumsAction->setCheckable(true); 0561 d->recurseAlbumsAction->setWhatsThis(i18nc("@info: setup", "Activate this option to show all sub-albums below " 0562 "the current album.")); 0563 connect(d->recurseAlbumsAction, SIGNAL(toggled(bool)), this, SLOT(slotRecurseAlbums(bool))); 0564 ac->addAction(QLatin1String("albums_recursive"), d->recurseAlbumsAction); 0565 0566 d->recurseTagsAction = new QAction(i18nc("@action: setup", "Include Tag Sub-Tree"), this); 0567 d->recurseTagsAction->setCheckable(true); 0568 d->recurseTagsAction->setWhatsThis(i18nc("@info: setup", "Activate this option to show all images marked by the given tag " 0569 "and all its sub-tags.")); 0570 connect(d->recurseTagsAction, SIGNAL(toggled(bool)), this, SLOT(slotRecurseTags(bool))); 0571 ac->addAction(QLatin1String("tags_recursive"), d->recurseTagsAction); 0572 0573 d->allGroupsOpenAction = new QAction(i18nc("@action: setup", "Show All Grouped Items As Open"), this); 0574 d->allGroupsOpenAction->setCheckable(true); 0575 d->allGroupsOpenAction->setWhatsThis(i18nc("@info: setup", "Activate this option to show all grouped items as open.")); 0576 connect(d->allGroupsOpenAction, SIGNAL(toggled(bool)), this, SLOT(slotAllGroupsOpen(bool))); 0577 ac->addAction(QLatin1String("all_groups_open"), d->allGroupsOpenAction); 0578 0579 // ----------------------------------------------------------- 0580 0581 d->imageSortAction = new KSelectAction(i18nc("@action: setup", "&Sort Items"), this); 0582 d->imageSortAction->setWhatsThis(i18nc("@info: setup", "The value by which the images in one album are sorted in the thumbnail view")); 0583 ac->addAction(QLatin1String("image_sort"), d->imageSortAction); 0584 0585 // map to ItemSortSettings enum 0586 0587 QAction* const sortByNameAction = d->imageSortAction->addAction(i18nc("@action: setup", "By Name")); 0588 QAction* const sortByPathAction = d->imageSortAction->addAction(i18nc("@action: setup", "By Path")); 0589 QAction* const sortByDateAction = d->imageSortAction->addAction(i18nc("@action: setup", "By Creation Date")); 0590 QAction* const sortByModDateAction = d->imageSortAction->addAction(i18nc("@action: setup", "By Modification Date")); 0591 QAction* const sortByFileSizeAction = d->imageSortAction->addAction(i18nc("@action: setup", "By File Size")); 0592 QAction* const sortByRatingAction = d->imageSortAction->addAction(i18nc("@action: setup", "By Rating")); 0593 QAction* const sortByImageSizeAction = d->imageSortAction->addAction(i18nc("@action: setup", "By Image Size")); 0594 QAction* const sortByAspectRatioAction = d->imageSortAction->addAction(i18nc("@action: setup", "By Aspect Ratio")); 0595 QAction* const sortByFacesAction = d->imageSortAction->addAction(i18nc("@action: setup", "By Face type")); 0596 QAction* const sortBySimilarityAction = d->imageSortAction->addAction(i18nc("@action: setup", "By Similarity")); 0597 QAction* const sortByManualOrderAndNameAction = d->imageSortAction->addAction(i18nc("@action: setup", "By Manual and Name")); 0598 QAction* const sortByManualOrderAndDateAction = d->imageSortAction->addAction(i18nc("@action: setup", "By Manual and Date")); 0599 0600 // activate the sort by similarity if the fuzzy search sidebar is active. Deactivate at start. 0601 0602 sortBySimilarityAction->setEnabled(false); 0603 connect(d->view, SIGNAL(signalFuzzySidebarActive(bool)), sortBySimilarityAction, SLOT(setEnabled(bool))); 0604 0605 connect(sortByNameAction, &QAction::triggered, 0606 this, [this]() { d->view->slotSortImages((int)ItemSortSettings::SortByFileName); }); 0607 0608 connect(sortByPathAction, &QAction::triggered, 0609 this, [this]() { d->view->slotSortImages((int)ItemSortSettings::SortByFilePath); }); 0610 0611 connect(sortByDateAction, &QAction::triggered, 0612 this, [this]() { d->view->slotSortImages((int)ItemSortSettings::SortByCreationDate); }); 0613 0614 connect(sortByModDateAction, &QAction::triggered, 0615 this, [this]() { d->view->slotSortImages((int)ItemSortSettings::SortByModificationDate); }); 0616 0617 connect(sortByFileSizeAction, &QAction::triggered, 0618 this, [this]() { d->view->slotSortImages((int)ItemSortSettings::SortByFileSize); }); 0619 0620 connect(sortByRatingAction, &QAction::triggered, 0621 this, [this]() { d->view->slotSortImages((int)ItemSortSettings::SortByRating); }); 0622 0623 connect(sortByImageSizeAction, &QAction::triggered, 0624 this, [this]() { d->view->slotSortImages((int)ItemSortSettings::SortByImageSize); }); 0625 0626 connect(sortByAspectRatioAction, &QAction::triggered, 0627 this, [this]() { d->view->slotSortImages((int)ItemSortSettings::SortByAspectRatio); }); 0628 0629 connect(sortByFacesAction, &QAction::triggered, 0630 this, [this]() { d->view->slotSortImages((int)ItemSortSettings::SortByFaces); }); 0631 0632 connect(sortBySimilarityAction, &QAction::triggered, 0633 this, [this]() { d->view->slotSortImages((int)ItemSortSettings::SortBySimilarity); }); 0634 0635 connect(sortByManualOrderAndNameAction, &QAction::triggered, 0636 this, [this]() { d->view->slotSortImages((int)ItemSortSettings::SortByManualOrderAndName); }); 0637 0638 connect(sortByManualOrderAndDateAction, &QAction::triggered, 0639 this, [this]() { d->view->slotSortImages((int)ItemSortSettings::SortByManualOrderAndDate); }); 0640 0641 // ----------------------------------------------------------- 0642 0643 d->imageSortOrderAction = new KSelectAction(i18nc("@action: setup", "Item Sort &Order"), this); 0644 d->imageSortOrderAction->setWhatsThis(i18nc("@info: setup", "Defines whether images are sorted in ascending or descending manner.")); 0645 ac->addAction(QLatin1String("image_sort_order"), d->imageSortOrderAction); 0646 0647 QAction* const sortAscendingAction = d->imageSortOrderAction->addAction(QIcon::fromTheme(QLatin1String("view-sort-ascending")), 0648 i18nc("@action: setup", "Ascending")); 0649 QAction* const sortDescendingAction = d->imageSortOrderAction->addAction(QIcon::fromTheme(QLatin1String("view-sort-descending")), 0650 i18nc("@action: setup", "Descending")); 0651 0652 connect(sortAscendingAction, &QAction::triggered, 0653 this, [this]() { d->view->slotSortImagesOrder((int)ItemSortSettings::AscendingOrder); }); 0654 0655 connect(sortDescendingAction, &QAction::triggered, 0656 this, [this]() { d->view->slotSortImagesOrder((int)ItemSortSettings::DescendingOrder); }); 0657 0658 // ----------------------------------------------------------- 0659 0660 d->imageSeparationAction = new KSelectAction(i18nc("@action: setup", "Separate Items"), this); 0661 d->imageSeparationAction->setWhatsThis(i18nc("@info: setup", "The categories in which the images in the thumbnail view are displayed")); 0662 ac->addAction(QLatin1String("image_separation"), d->imageSeparationAction); 0663 0664 // map to ItemSortSettings enum 0665 0666 QAction* const noCategoriesAction = d->imageSeparationAction->addAction(i18nc("@action: setup", "Flat List")); 0667 QAction* const separateByAlbumAction = d->imageSeparationAction->addAction(i18nc("@action: setup", "By Album")); 0668 QAction* const separateByFormatAction = d->imageSeparationAction->addAction(i18nc("@action: setup", "By Format")); 0669 QAction* const separateByMonthAction = d->imageSeparationAction->addAction(i18nc("@action: setup", "By Month")); 0670 QAction* const separateByFacesAction = d->imageSeparationAction->addAction(i18nc("@action: setup", "By Faces")); 0671 0672 connect(noCategoriesAction, &QAction::triggered, 0673 this, [this]() { d->view->slotSeparateImages((int)ItemSortSettings::OneCategory); }); 0674 0675 connect(separateByAlbumAction, &QAction::triggered, 0676 this, [this]() { d->view->slotSeparateImages((int)ItemSortSettings::CategoryByAlbum); }); 0677 0678 connect(separateByFormatAction, &QAction::triggered, 0679 this, [this]() { d->view->slotSeparateImages((int)ItemSortSettings::CategoryByFormat); }); 0680 0681 connect(separateByMonthAction, &QAction::triggered, 0682 this, [this]() { d->view->slotSeparateImages((int)ItemSortSettings::CategoryByMonth); }); 0683 0684 connect(separateByFacesAction, &QAction::triggered, 0685 this, [this]() { d->view->slotSeparateImages((int)ItemSortSettings::CategoryByFaces); }); 0686 0687 connect(d->view, &ItemIconView::signalSeparationModeChanged, 0688 this, [this](int category) 0689 { 0690 d->imageSeparationAction->blockSignals(true); 0691 d->imageSeparationAction->setCurrentItem(category-1); 0692 d->imageSeparationAction->blockSignals(false); 0693 } 0694 ); 0695 0696 // ----------------------------------------------------------------- 0697 0698 d->imageSeparationSortOrderAction = new KSelectAction(i18nc("@action: setup", "Item Separation Order"), this); 0699 d->imageSeparationSortOrderAction->setWhatsThis(i18nc("@info: setup", "The sort order of the groups of separated items")); 0700 ac->addAction(QLatin1String("image_separation_sort_order"), d->imageSeparationSortOrderAction); 0701 0702 QAction* const sortSeparationsAscending = d->imageSeparationSortOrderAction->addAction(QIcon::fromTheme(QLatin1String("view-sort-ascending")), 0703 i18nc("@action: setup", "Ascending")); 0704 QAction* const sortSeparationsDescending = d->imageSeparationSortOrderAction->addAction(QIcon::fromTheme(QLatin1String("view-sort-descending")), 0705 i18nc("@action: setup", "Descending")); 0706 0707 connect(sortSeparationsAscending, &QAction::triggered, 0708 this, [this]() { d->view->slotImageSeparationSortOrder((int)ItemSortSettings::AscendingOrder); }); 0709 0710 connect(sortSeparationsDescending, &QAction::triggered, 0711 this, [this]() { d->view->slotImageSeparationSortOrder((int)ItemSortSettings::DescendingOrder); }); 0712 0713 // ----------------------------------------------------------------- 0714 0715 setupImageTransformActions(); 0716 setupExifOrientationActions(); 0717 0718 // ----------------------------------------------------------------- 0719 0720 d->selectAllAction = new QAction(i18nc("@action: setup", "Select All"), this); 0721 connect(d->selectAllAction, SIGNAL(triggered()), d->view, SLOT(slotSelectAll())); 0722 ac->addAction(QLatin1String("selectAll"), d->selectAllAction); 0723 ac->setDefaultShortcut(d->selectAllAction, Qt::CTRL | Qt::Key_A); 0724 0725 // ----------------------------------------------------------------- 0726 0727 d->selectNoneAction = new QAction(i18nc("@action: setup", "Select None"), this); 0728 connect(d->selectNoneAction, SIGNAL(triggered()), d->view, SLOT(slotSelectNone())); 0729 ac->addAction(QLatin1String("selectNone"), d->selectNoneAction); 0730 ac->setDefaultShortcut(d->selectNoneAction, Qt::CTRL | Qt::SHIFT | Qt::Key_A); 0731 0732 // ----------------------------------------------------------------- 0733 0734 d->selectInvertAction = new QAction(i18nc("@action: setup", "Invert Selection"), this); 0735 connect(d->selectInvertAction, SIGNAL(triggered()), d->view, SLOT(slotSelectInvert())); 0736 ac->addAction(QLatin1String("selectInvert"), d->selectInvertAction); 0737 ac->setDefaultShortcut(d->selectInvertAction, Qt::CTRL | Qt::Key_I); 0738 0739 // ----------------------------------------------------------- 0740 0741 d->showBarAction = new QAction(QIcon::fromTheme(QLatin1String("view-choose")), 0742 i18nc("@action: setup", "Show Thumbbar"), this); 0743 d->showBarAction->setCheckable(true); 0744 connect(d->showBarAction, SIGNAL(triggered()), this, SLOT(slotToggleShowBar())); 0745 ac->addAction(QLatin1String("showthumbs"), d->showBarAction); 0746 ac->setDefaultShortcut(d->showBarAction, Qt::CTRL | Qt::Key_T); 0747 0748 // Provides a menu entry that allows showing/hiding the toolbar(s) 0749 0750 setStandardToolBarMenuEnabled(true); 0751 0752 // Provides a menu entry that allows showing/hiding the statusbar 0753 0754 createStandardStatusBarAction(); 0755 0756 // Standard 'Configure' menu actions 0757 0758 createSettingsActions(); 0759 0760 // ----------------------------------------------------------- 0761 0762 d->zoomPlusAction = buildStdAction(StdZoomInAction, d->view, SLOT(slotZoomIn()), this); 0763 ac->addAction(QLatin1String("album_zoomin"), d->zoomPlusAction); 0764 0765 // ----------------------------------------------------------- 0766 0767 d->zoomMinusAction = buildStdAction(StdZoomOutAction, d->view, SLOT(slotZoomOut()), this); 0768 ac->addAction(QLatin1String("album_zoomout"), d->zoomMinusAction); 0769 0770 // ----------------------------------------------------------- 0771 0772 d->zoomTo100percents = new QAction(QIcon::fromTheme(QLatin1String("zoom-original")), 0773 i18nc("@action: setup", "Zoom to 100%"), this); 0774 connect(d->zoomTo100percents, SIGNAL(triggered()), d->view, SLOT(slotZoomTo100Percents())); 0775 ac->addAction(QLatin1String("album_zoomto100percents"), d->zoomTo100percents); 0776 ac->setDefaultShortcut(d->zoomTo100percents, Qt::CTRL | Qt::Key_Period); 0777 0778 // ----------------------------------------------------------- 0779 0780 d->zoomFitToWindowAction = new QAction(QIcon::fromTheme(QLatin1String("zoom-fit-best")), 0781 i18nc("@action: setup", "Fit to &Window"), this); 0782 connect(d->zoomFitToWindowAction, SIGNAL(triggered()), d->view, SLOT(slotFitToWindow())); 0783 ac->addAction(QLatin1String("album_zoomfit2window"), d->zoomFitToWindowAction); 0784 ac->setDefaultShortcut(d->zoomFitToWindowAction, Qt::CTRL | Qt::ALT | Qt::Key_E); 0785 0786 // ----------------------------------------------------------- 0787 0788 createFullScreenAction(QLatin1String("full_screen")); 0789 createSidebarActions(); 0790 0791 // ----------------------------------------------------------- 0792 0793 d->viewCMViewAction = new QAction(QIcon::fromTheme(QLatin1String("video-display")), 0794 i18nc("@action: setup", "Color-Managed View"), this); 0795 d->viewCMViewAction->setCheckable(true); 0796 connect(d->viewCMViewAction, SIGNAL(triggered()), this, SLOT(slotToggleColorManagedView())); 0797 ac->addAction(QLatin1String("color_managed_view"), d->viewCMViewAction); 0798 ac->setDefaultShortcut(d->viewCMViewAction, Qt::Key_F12); 0799 0800 // ----------------------------------------------------------- 0801 0802 d->quitAction = buildStdAction(StdQuitAction, this, SLOT(slotExit()), this); 0803 ac->addAction(QLatin1String("app_exit"), d->quitAction); 0804 0805 // ----------------------------------------------------------- 0806 0807 createHelpActions(QLatin1String("main_window")); 0808 0809 // ----------------------------------------------------------- 0810 0811 QAction* const findAction = new QAction(QIcon::fromTheme(QLatin1String("edit-find")), 0812 i18nc("@action: setup", "Search..."), this); 0813 connect(findAction, SIGNAL(triggered()), d->view, SLOT(slotNewKeywordSearch())); 0814 ac->addAction(QLatin1String("search_quick"), findAction); 0815 ac->setDefaultShortcut(findAction, Qt::CTRL | Qt::Key_F); 0816 0817 // ----------------------------------------------------------- 0818 0819 d->advSearchAction = new QAction(QIcon::fromTheme(QLatin1String("edit-find")), 0820 i18nc("@action: setup", "Advanced Search..."), this); 0821 connect(d->advSearchAction, SIGNAL(triggered()), d->view, SLOT(slotNewAdvancedSearch())); 0822 ac->addAction(QLatin1String("search_advanced"), d->advSearchAction); 0823 ac->setDefaultShortcut(d->advSearchAction, Qt::CTRL | Qt::ALT | Qt::Key_F); 0824 0825 // ----------------------------------------------------------- 0826 0827 QAction* const duplicatesAction = new QAction(QIcon::fromTheme(QLatin1String("tools-wizard")), 0828 i18nc("@action: setup", "Find Duplicates..."), this); 0829 connect(duplicatesAction, SIGNAL(triggered()), d->view, SLOT(slotNewDuplicatesSearch())); 0830 ac->addAction(QLatin1String("find_duplicates"), duplicatesAction); 0831 ac->setDefaultShortcut(duplicatesAction, Qt::CTRL | Qt::Key_D); 0832 0833 // ----------------------------------------------------------- 0834 0835 #ifdef HAVE_MYSQLSUPPORT 0836 0837 QAction* const databaseMigrationAction = new QAction(QIcon::fromTheme(QLatin1String("network-server-database")), 0838 i18nc("@action: setup", "Database Migration..."), this); 0839 connect(databaseMigrationAction, SIGNAL(triggered()), this, SLOT(slotDatabaseMigration())); 0840 ac->addAction(QLatin1String("database_migration"), databaseMigrationAction); 0841 0842 #endif 0843 0844 // ----------------------------------------------------------- 0845 0846 d->maintenanceAction = new QAction(QIcon::fromTheme(QLatin1String("run-build-prune")), 0847 i18nc("@action: setup", "Maintenance..."), this); 0848 connect(d->maintenanceAction, SIGNAL(triggered()), this, SLOT(slotMaintenance())); 0849 ac->addAction(QLatin1String("maintenance"), d->maintenanceAction); 0850 0851 // ----------------------------------------------------------- 0852 0853 d->scanNewItemsAction = new QAction(QIcon::fromTheme(QLatin1String("view-refresh")), 0854 i18nc("@action: setup", "Scan for new Items"), this); 0855 connect(d->scanNewItemsAction, SIGNAL(triggered()), this, SLOT(slotScanNewItems())); 0856 ac->addAction(QLatin1String("scan_newitems"), d->scanNewItemsAction); 0857 0858 // ----------------------------------------------------------- 0859 0860 QAction* const cameraAction = new QAction(i18nc("@action: setup", "Add Camera Manually..."), this); 0861 connect(cameraAction, SIGNAL(triggered()), this, SLOT(slotSetupCamera())); 0862 ac->addAction(QLatin1String("camera_add"), cameraAction); 0863 0864 // ----------------------------------------------------------- 0865 0866 // Load Cameras -- do this before the createGUI so that the cameras 0867 // are plugged into the toolbar at startup 0868 0869 if (d->splashScreen) 0870 { 0871 d->splashScreen->setMessage(i18nc("@info: setup", "Loading cameras...")); 0872 } 0873 0874 loadCameras(); 0875 0876 // Load Themes 0877 0878 populateThemes(); 0879 0880 createGUI(xmlFile()); 0881 0882 registerPluginsActions(); 0883 0884 cleanupActions(); 0885 0886 // NOTE: see bug #252130 and #283281 : we need to disable these actions when BQM is running. 0887 // These connections must be done after loading color theme else theme menu cannot be plugged to Settings menu, 0888 0889 connect(QueueMgrWindow::queueManagerWindow(), SIGNAL(signalBqmIsBusy(bool)), 0890 d->bqmAction, SLOT(setDisabled(bool))); 0891 0892 connect(QueueMgrWindow::queueManagerWindow(), SIGNAL(signalBqmIsBusy(bool)), 0893 d->imageAddCurrentQueueAction, SLOT(setDisabled(bool))); 0894 0895 connect(QueueMgrWindow::queueManagerWindow(), SIGNAL(signalBqmIsBusy(bool)), 0896 d->imageAddNewQueueAction, SLOT(setDisabled(bool))); 0897 } 0898 0899 void DigikamApp::setupAccelerators() 0900 { 0901 KActionCollection* const ac = actionCollection(); 0902 0903 // Action are added by <MainWindow> tag in ui.rc XML file 0904 0905 QAction* const escapeAction = new QAction(i18nc("@action: setup", "Exit Preview Mode"), this); 0906 ac->addAction(QLatin1String("exit_preview_mode"), escapeAction); 0907 ac->setDefaultShortcut(escapeAction, Qt::Key_Escape); 0908 connect(escapeAction, SIGNAL(triggered()), this, SIGNAL(signalEscapePressed())); 0909 0910 QAction* const nextImageAction = new QAction(i18nc("@action: setup", "Next Image"), this); 0911 nextImageAction->setIcon(QIcon::fromTheme(QLatin1String("go-next"))); 0912 ac->addAction(QLatin1String("next_image"), nextImageAction); 0913 ac->setDefaultShortcut(nextImageAction, Qt::Key_Space); 0914 connect(nextImageAction, SIGNAL(triggered()), this, SIGNAL(signalNextItem())); 0915 0916 QAction* const previousImageAction = new QAction(i18nc("@action: setup", "Previous Image"), this); 0917 previousImageAction->setIcon(QIcon::fromTheme(QLatin1String("go-previous"))); 0918 ac->addAction(QLatin1String("previous_image"), previousImageAction); 0919 ac->setDefaultShortcuts(previousImageAction, QList<QKeySequence>() << Qt::Key_Backspace << (Qt::SHIFT | Qt::Key_Space)); 0920 connect(previousImageAction, SIGNAL(triggered()), this, SIGNAL(signalPrevItem())); 0921 0922 QAction* const firstImageAction = new QAction(i18nc("@action: setup", "First Image"), this); 0923 ac->addAction(QLatin1String("first_image"), firstImageAction); 0924 ac->setDefaultShortcut(firstImageAction, Qt::CTRL | Qt::Key_Home); 0925 connect(firstImageAction, SIGNAL(triggered()), this, SIGNAL(signalFirstItem())); 0926 0927 QAction* const lastImageAction = new QAction(i18nc("@action: setup", "Last Image"), this); 0928 ac->addAction(QLatin1String("last_image"), lastImageAction); 0929 ac->setDefaultShortcut(lastImageAction, Qt::CTRL | Qt::Key_End); 0930 connect(lastImageAction, SIGNAL(triggered()), this, SIGNAL(signalLastItem())); 0931 0932 d->cutItemsAction = new QAction(i18nc("@action: setup", "Cu&t"), this); 0933 d->cutItemsAction->setIcon(QIcon::fromTheme(QLatin1String("edit-cut"))); 0934 d->cutItemsAction->setWhatsThis(i18nc("@action: setup", "Cut selection to clipboard")); 0935 ac->addAction(QLatin1String("cut_album_selection"), d->cutItemsAction); 0936 0937 // NOTE: shift+del keyboard shortcut must not be assigned to Cut action 0938 // else the shortcut for Delete permanently collides with secondary shortcut of Cut 0939 0940 ac->setDefaultShortcut(d->cutItemsAction, Qt::CTRL | Qt::Key_X); 0941 connect(d->cutItemsAction, SIGNAL(triggered()), this, SIGNAL(signalCutAlbumItemsSelection())); 0942 0943 d->copyItemsAction = buildStdAction(StdCopyAction, this, SIGNAL(signalCopyAlbumItemsSelection()), this); 0944 ac->addAction(QLatin1String("copy_album_selection"), d->copyItemsAction); 0945 0946 d->pasteItemsAction = buildStdAction(StdPasteAction, this, SIGNAL(signalPasteAlbumItemsSelection()), this); 0947 ac->addAction(QLatin1String("paste_album_selection"), d->pasteItemsAction); 0948 0949 // Labels shortcuts must be registered here to be saved in XML GUI files if user customize it. 0950 0951 d->tagsActionManager->registerLabelsActions(ac); 0952 0953 QAction* const editTitles = new QAction(i18nc("@action: setup", "Edit Titles"), this); 0954 ac->addAction(QLatin1String("edit_titles"), editTitles); 0955 ac->setDefaultShortcut(editTitles, Qt::ALT | Qt::SHIFT | Qt::Key_T); 0956 connect(editTitles, SIGNAL(triggered()), d->view, SLOT(slotRightSideBarActivateTitles())); 0957 0958 QAction* const editComments = new QAction(i18nc("@action: setup", "Edit Comments"), this); 0959 ac->addAction(QLatin1String("edit_comments"), editComments); 0960 ac->setDefaultShortcut(editComments, Qt::ALT | Qt::SHIFT | Qt::Key_C); 0961 connect(editComments, SIGNAL(triggered()), d->view, SLOT(slotRightSideBarActivateComments())); 0962 0963 QAction* const assignedTags = new QAction(i18nc("@action: setup", "Show Assigned Tags"), this); 0964 ac->addAction(QLatin1String("assigned_tags"), assignedTags); 0965 ac->setDefaultShortcut(assignedTags, Qt::ALT | Qt::SHIFT | Qt::Key_A); 0966 connect(assignedTags, SIGNAL(triggered()), d->view, SLOT(slotRightSideBarActivateAssignedTags())); 0967 } 0968 0969 void DigikamApp::setupExifOrientationActions() 0970 { 0971 KActionCollection* const ac = actionCollection(); 0972 d->imageExifOrientationActionMenu = new QMenu(i18nc("@action: setup", "Adjust Exif Orientation Tag"), this); 0973 ac->addAction(QLatin1String("image_set_exif_orientation"), d->imageExifOrientationActionMenu->menuAction()); 0974 0975 d->imageSetExifOrientation1Action = new QAction(i18nc("@action: normal exif orientation", "Normal"), this); 0976 d->imageSetExifOrientation1Action->setCheckable(true); 0977 d->imageSetExifOrientation2Action = new QAction(i18nc("@action: setup", "Flipped Horizontally"), this); 0978 d->imageSetExifOrientation2Action->setCheckable(true); 0979 d->imageSetExifOrientation3Action = new QAction(i18nc("@action: setup", "Rotated Upside Down"), this); 0980 d->imageSetExifOrientation3Action->setCheckable(true); 0981 d->imageSetExifOrientation4Action = new QAction(i18nc("@action: setup", "Flipped Vertically"), this); 0982 d->imageSetExifOrientation4Action->setCheckable(true); 0983 d->imageSetExifOrientation5Action = new QAction(i18nc("@action: setup", "Rotated Right / Horiz. Flipped"), this); 0984 d->imageSetExifOrientation5Action->setCheckable(true); 0985 d->imageSetExifOrientation6Action = new QAction(i18nc("@action: setup", "Rotated Right"), this); 0986 d->imageSetExifOrientation6Action->setCheckable(true); 0987 d->imageSetExifOrientation7Action = new QAction(i18nc("@action: setup", "Rotated Right / Vert. Flipped"), this); 0988 d->imageSetExifOrientation7Action->setCheckable(true); 0989 d->imageSetExifOrientation8Action = new QAction(i18nc("@action: setup", "Rotated Left"), this); 0990 d->imageSetExifOrientation8Action->setCheckable(true); 0991 0992 d->exifOrientationActionGroup = new QActionGroup(d->imageExifOrientationActionMenu); 0993 d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation1Action); 0994 d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation2Action); 0995 d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation3Action); 0996 d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation4Action); 0997 d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation5Action); 0998 d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation6Action); 0999 d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation7Action); 1000 d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation8Action); 1001 d->imageSetExifOrientation1Action->setChecked(true); 1002 1003 ac->addAction(QLatin1String("image_set_exif_orientation_normal"), d->imageSetExifOrientation1Action); 1004 ac->addAction(QLatin1String("image_set_exif_orientation_flipped_horizontal"), d->imageSetExifOrientation2Action); 1005 ac->addAction(QLatin1String("image_set_exif_orientation_rotated_upside_down"), d->imageSetExifOrientation3Action); 1006 ac->addAction(QLatin1String("image_set_exif_orientation_flipped_vertically"), d->imageSetExifOrientation4Action); 1007 ac->addAction(QLatin1String("image_set_exif_orientation_rotated_right_hor_flipped"), d->imageSetExifOrientation5Action); 1008 ac->addAction(QLatin1String("image_set_exif_orientation_rotated_right"), d->imageSetExifOrientation6Action); 1009 ac->addAction(QLatin1String("image_set_exif_orientation_rotated_right_ver_flipped"), d->imageSetExifOrientation7Action); 1010 ac->addAction(QLatin1String("image_set_exif_orientation_rotated_left"), d->imageSetExifOrientation8Action); 1011 1012 d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation1Action); 1013 d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation2Action); 1014 d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation3Action); 1015 d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation4Action); 1016 d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation5Action); 1017 d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation6Action); 1018 d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation7Action); 1019 d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation8Action); 1020 1021 connect(d->imageSetExifOrientation1Action, &QAction::triggered, 1022 this, [this]() { d->view->slotImageExifOrientation(1); }); 1023 1024 connect(d->imageSetExifOrientation2Action, &QAction::triggered, 1025 this, [this]() { d->view->slotImageExifOrientation(2); }); 1026 1027 connect(d->imageSetExifOrientation3Action, &QAction::triggered, 1028 this, [this]() { d->view->slotImageExifOrientation(3); }); 1029 1030 connect(d->imageSetExifOrientation4Action, &QAction::triggered, 1031 this, [this]() { d->view->slotImageExifOrientation(4); }); 1032 1033 connect(d->imageSetExifOrientation5Action, &QAction::triggered, 1034 this, [this]() { d->view->slotImageExifOrientation(5); }); 1035 1036 connect(d->imageSetExifOrientation6Action, &QAction::triggered, 1037 this, [this]() { d->view->slotImageExifOrientation(6); }); 1038 1039 connect(d->imageSetExifOrientation7Action, &QAction::triggered, 1040 this, [this]() { d->view->slotImageExifOrientation(7); }); 1041 1042 connect(d->imageSetExifOrientation8Action, &QAction::triggered, 1043 this, [this]() { d->view->slotImageExifOrientation(8); }); 1044 } 1045 1046 void DigikamApp::setupImageTransformActions() 1047 { 1048 KActionCollection* const ac = actionCollection(); 1049 1050 d->imageRotateActionMenu = new QMenu(i18nc("@action: setup", "Rotate"), this); 1051 d->imageRotateActionMenu->setIcon(QIcon::fromTheme(QLatin1String("object-rotate-right"))); 1052 1053 QAction* const left = ac->addAction(QLatin1String("rotate_ccw")); 1054 left->setText(i18nc("@action: rotate image left", "Left")); 1055 ac->setDefaultShortcut(left, Qt::CTRL | Qt::SHIFT | Qt::Key_Left); 1056 connect(left, SIGNAL(triggered(bool)), 1057 this, SLOT(slotTransformAction())); 1058 d->imageRotateActionMenu->addAction(left); 1059 1060 QAction* const right = ac->addAction(QLatin1String("rotate_cw")); 1061 right->setText(i18nc("@action: rotate image right", "Right")); 1062 ac->setDefaultShortcut(right, Qt::CTRL | Qt::SHIFT | Qt::Key_Right); 1063 connect(right, SIGNAL(triggered(bool)), 1064 this, SLOT(slotTransformAction())); 1065 d->imageRotateActionMenu->addAction(right); 1066 1067 ac->addAction(QLatin1String("image_rotate"), d->imageRotateActionMenu->menuAction()); 1068 1069 // ----------------------------------------------------------------------------------- 1070 1071 d->imageFlipActionMenu = new QMenu(i18nc("@action: setup", "Flip"), this); 1072 d->imageFlipActionMenu->setIcon(QIcon::fromTheme(QLatin1String("flip-horizontal"))); 1073 1074 QAction* const hori = ac->addAction(QLatin1String("flip_horizontal")); 1075 hori->setText(i18nc("@action: setup", "Horizontally")); 1076 ac->setDefaultShortcut(hori, Qt::CTRL | Qt::Key_Asterisk); 1077 connect(hori, SIGNAL(triggered(bool)), 1078 this, SLOT(slotTransformAction())); 1079 d->imageFlipActionMenu->addAction(hori); 1080 1081 QAction* const verti = ac->addAction(QLatin1String("flip_vertical")); 1082 verti->setText(i18nc("@action: setup", "Vertically")); 1083 ac->setDefaultShortcut(verti, Qt::CTRL | Qt::Key_Slash); 1084 connect(verti, SIGNAL(triggered(bool)), 1085 this, SLOT(slotTransformAction())); 1086 d->imageFlipActionMenu->addAction(verti); 1087 1088 ac->addAction(QLatin1String("image_flip"), d->imageFlipActionMenu->menuAction()); 1089 1090 // ----------------------------------------------------------------------------------- 1091 1092 d->imageAutoExifActionMenu = new QAction(i18nc("@action: setup", "Auto Rotate/Flip Using Exif Information"), this); 1093 connect(d->imageAutoExifActionMenu, SIGNAL(triggered(bool)), 1094 this, SLOT(slotTransformAction())); 1095 1096 ac->addAction(QLatin1String("image_transform_exif"), d->imageAutoExifActionMenu); 1097 } 1098 1099 void DigikamApp::populateThemes() 1100 { 1101 if (d->splashScreen) 1102 { 1103 d->splashScreen->setMessage(i18nc("@info: setup", "Loading themes...")); 1104 } 1105 1106 ThemeManager::instance()->setThemeMenuAction(new QMenu(i18nc("@action: setup", "&Themes"), this)); 1107 ThemeManager::instance()->registerThemeActions(this); 1108 ThemeManager::instance()->setCurrentTheme(ApplicationSettings::instance()->getCurrentTheme()); 1109 1110 connect(ThemeManager::instance(), SIGNAL(signalThemeChanged()), 1111 this, SLOT(slotThemeChanged())); 1112 } 1113 1114 void DigikamApp::preloadWindows() 1115 { 1116 if (d->splashScreen) 1117 { 1118 d->splashScreen->setMessage(i18nc("@info: setup", "Loading tools...")); 1119 } 1120 1121 ImageWindow::imageWindow(); 1122 QueueMgrWindow::queueManagerWindow(); 1123 LightTableWindow::lightTableWindow(); 1124 1125 d->tagsActionManager->registerTagsActionCollections(); 1126 } 1127 1128 void DigikamApp::initGui() 1129 { 1130 // Initialize Actions --------------------------------------- 1131 1132 d->deleteAction->setEnabled(false); 1133 d->renameAction->setEnabled(false); 1134 d->propsEditAction->setEnabled(false); 1135 d->openInFileManagerAction->setEnabled(false); 1136 1137 d->imageViewAction->setEnabled(false); 1138 d->imagePreviewAction->setEnabled(false); 1139 d->imageLightTableAction->setEnabled(false); 1140 d->imageAddLightTableAction->setEnabled(false); 1141 d->imageScanForFacesAction->setEnabled(false); 1142 d->imageRemoveAllFacesAction->setEnabled(false); 1143 d->imageFindSimilarAction->setEnabled(false); 1144 d->imageRenameAction->setEnabled(false); 1145 d->imageDeleteAction->setEnabled(false); 1146 d->imageExifOrientationActionMenu->setEnabled(false); 1147 d->openWithAction->setEnabled(false); 1148 d->imageAutoExifActionMenu->setEnabled(false); 1149 1150 Q_FOREACH (DPluginAction* const ac, DPluginLoader::instance()->pluginsActions(DPluginAction::GenericMetadata, this)) 1151 { 1152 ac->setEnabled(false); 1153 } 1154 1155 d->albumSortAction->setCurrentItem((int)ApplicationSettings::instance()->getAlbumSortRole()); 1156 d->imageSortAction->setCurrentItem((int)ApplicationSettings::instance()->getImageSortOrder()); 1157 d->imageSortOrderAction->setCurrentItem((int)ApplicationSettings::instance()->getImageSorting()); 1158 d->imageSeparationAction->setCurrentItem((int)ApplicationSettings::instance()->getImageSeparationMode()-1); // no action for enum 0 1159 d->imageSeparationSortOrderAction->setCurrentItem((int)ApplicationSettings::instance()->getImageSeparationSortOrder()); 1160 d->allGroupsOpenAction->setChecked(ApplicationSettings::instance()->getAllGroupsOpen()); 1161 d->recurseAlbumsAction->setChecked(ApplicationSettings::instance()->getRecurseAlbums()); 1162 d->recurseTagsAction->setChecked(ApplicationSettings::instance()->getRecurseTags()); 1163 d->showBarAction->setChecked(ApplicationSettings::instance()->getShowThumbbar()); 1164 showMenuBarAction()->setChecked(!menuBar()->isHidden()); // NOTE: workaround for bug #171080 1165 1166 slotSwitchedToIconView(); 1167 } 1168 1169 } // namespace Digikam