diff --git a/core/app/main/digikamapp.h b/core/app/main/digikamapp.h index 368820c29b..3e2cddffd9 100644 --- a/core/app/main/digikamapp.h +++ b/core/app/main/digikamapp.h @@ -1,294 +1,294 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2002-16-10 * Description : main digiKam interface implementation * * Copyright (C) 2002-2005 by Renchi Raju * Copyright (C) 2006 by Tom Albers * Copyright (C) 2002-2018 by Gilles Caulier * Copyright (C) 2009-2011 by Andi Clemens * Copyright (C) 2013 by Michael G. Hansen * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #ifndef DIGIKAM_APP_H #define DIGIKAM_APP_H // Qt includes #include #include #include // KDE includes #include // Local includes #include "digikam_config.h" #include "dxmlguiwindow.h" #include "digikam_export.h" namespace Solid { class Device; } namespace Digikam { class Album; class DigikamView; class FaceScanSettings; class FilterStatusBar; class ImageInfo; class ImageInfoList; class CameraType; class DIGIKAM_EXPORT DigikamApp : public DXmlGuiWindow { Q_OBJECT public: explicit DigikamApp(); ~DigikamApp(); virtual void show(); void restoreSession(); void enableZoomPlusAction(bool val); void enableZoomMinusAction(bool val); void enableAlbumBackwardHistory(bool enable); void enableAlbumForwardHistory(bool enable); DigikamView* view() const; QMenu* slideShowMenu() const; static DigikamApp* instance(); Q_SIGNALS: void signalEscapePressed(); void signalNextItem(); void signalPrevItem(); void signalFirstItem(); void signalLastItem(); void signalCutAlbumItemsSelection(); void signalCopyAlbumItemsSelection(); void signalPasteAlbumItemsSelection(); void signalWindowHasMoved(); protected: bool queryClose(); void moveEvent(QMoveEvent* e); void closeEvent(QCloseEvent* e); private: void showThumbBar(bool visible); void showSideBars(bool visible); bool thumbbarVisibility() const; void customizedFullScreenMode(bool set); void toggleShowBar(); private Q_SLOTS: void slotAlbumSelected(Album*); void slotImageSelected(const ImageInfoList&, const ImageInfoList&); void slotSelectionChanged(int selectionCount); void slotExit(); void slotDBStat(); void slotComponentsInfo(); void slotRecurseAlbums(bool); void slotRecurseTags(bool); void slotAboutToShowForwardMenu(); void slotAboutToShowBackwardMenu(); void slotColorManagementOptionsChanged(); void slotToggleColorManagedView(); void slotSetCheckedExifOrientationAction(const ImageInfo& info); void slotResetExifOrientationActions(); void slotTransformAction(); void slotToggleLeftSideBar(); void slotToggleRightSideBar(); void slotPreviousLeftSideBarTab(); void slotNextLeftSideBarTab(); void slotPreviousRightSideBarTab(); void slotNextRightSideBarTab(); void slotToggleShowBar(); void slotZoomSliderChanged(int); void slotThumbSizeChanged(int); void slotZoomChanged(double); void slotSwitchedToPreview(); void slotSwitchedToIconView(); void slotSwitchedToMapView(); void slotSwitchedToTableView(); void slotSwitchedToTrashView(); // -- Internal setup methods implemented in digikamapp_setup.cpp ---------------------------------------- public: void rebuild(); private: void setupView(); void setupViewConnections(); void setupStatusBar(); void setupActions(); void setupAccelerators(); void setupExifOrientationActions(); void setupImageTransformActions(); void populateThemes(); void preloadWindows(); void initGui(); // -- Extra tool methods implemented in digikamapp_tools.cpp ---------------------------------------- private: void setupSelectToolsAction(); private Q_SLOTS: void slotMaintenance(); void slotMaintenanceDone(); void slotDatabaseMigration(); + void slotTimeAdjust(); void slotEditMetadata(); void slotEditGeolocation(); void slotPresentation(); void slotPrintCreator(); - void slotTimeAdjust(); // -- Configure methods implemented in digikamapp_config.cpp ---------------------------------------- private: bool setup(); bool setupICC(); private Q_SLOTS: void slotSetup(); void slotSetupChanged(); void slotEditKeys(); void slotThemeChanged(); - + // -- Export tools methods implemented in digikamapp_export.cpp ------------------------------------- private Q_SLOTS: void slotExpoBlending(); void slotPanorama(); void slotVideoSlideshow(); void slotSendByMail(); void slotHtmlGallery(); void slotCalendar(); void slotMediaServer(); void slotExportTool(); // -- Import tools methods implemented in digikamapp_import.cpp ------------------------------------- public: static QString scannerTargetPlace(); private: void updateQuickImportAction(); private Q_SLOTS: void slotImportAddImages(); void slotImportAddFolders(); void slotImportFromScanner(); void slotImportTool(); // -- Camera management methods implemented in digikamapp_camera.cpp -------------------------------- public: void autoDetect(); void downloadFrom(const QString& cameraGuiPath); void downloadFromUdi(const QString& udi); Q_SIGNALS: void queuedOpenCameraUiFromPath(const QString& path); private: void loadCameras(); void updateCameraMenu(); private Q_SLOTS: void slotSetupCamera(); void slotOpenManualCamera(QAction*); void slotCameraAdded(CameraType*); void slotCameraRemoved(QAction*); void slotCameraAutoDetect(); void slotOpenCameraUiFromPath(const QString& path); void downloadImages(const QString& folder); void cameraAutoDetect(); // -- Solid based methods implemented in digikamapp_solid.cpp --------------------------------------- Q_SIGNALS: void queuedOpenSolidDevice(const QString& udi); private: void fillSolidMenus(); bool checkSolidCamera(const Solid::Device& cameraDevice); QString labelForSolidCamera(const Solid::Device& cameraDevice); void openSolidCamera(const QString& udi, const QString& label = QString()); void openSolidUsmDevice(const QString& udi, const QString& label = QString()); private Q_SLOTS: void slotOpenSolidCamera(QAction*); void slotOpenSolidUsmDevice(QAction*); void slotOpenSolidDevice(const QString& udi); void slotSolidSetupDone(Solid::ErrorType errorType, QVariant errorData, const QString& udi); void slotSolidDeviceChanged(const QString& udi); // -- Internal private container -------------------------------------------------------------------- private: class Private; Private* const d; static DigikamApp* m_instance; }; } // namespace Digikam #endif // DIGIKAM_APP_H diff --git a/core/app/main/digikamapp_setup.cpp b/core/app/main/digikamapp_setup.cpp index cea60db78e..dfd1ab6b90 100644 --- a/core/app/main/digikamapp_setup.cpp +++ b/core/app/main/digikamapp_setup.cpp @@ -1,1113 +1,1113 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2002-16-10 * Description : main digiKam interface implementation - Internal setup * * Copyright (C) 2002-2018 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "digikamapp.h" #include "digikamapp_p.h" namespace Digikam { void DigikamApp::rebuild() { QString file = xmlFile(); if (!file.isEmpty()) { setXMLGUIBuildDocument(QDomDocument()); loadStandardsXmlFile(); setXMLFile(file, true); } } void DigikamApp::setupView() { if (d->splashScreen) { d->splashScreen->setMessage(i18n("Initializing Main View...")); } d->view = new DigikamView(this, d->modelCollection); setCentralWidget(d->view); d->view->applySettings(); } void DigikamApp::setupViewConnections() { connect(d->view, SIGNAL(signalAlbumSelected(Album*)), this, SLOT(slotAlbumSelected(Album*))); connect(d->view, SIGNAL(signalSelectionChanged(int)), this, SLOT(slotSelectionChanged(int))); connect(d->view, SIGNAL(signalImageSelected(ImageInfoList,ImageInfoList)), this, SLOT(slotImageSelected(ImageInfoList,ImageInfoList))); connect(d->view, SIGNAL(signalSwitchedToPreview()), this, SLOT(slotSwitchedToPreview())); connect(d->view, SIGNAL(signalSwitchedToIconView()), this, SLOT(slotSwitchedToIconView())); connect(d->view, SIGNAL(signalSwitchedToMapView()), this, SLOT(slotSwitchedToMapView())); connect(d->view, SIGNAL(signalSwitchedToTableView()), this, SLOT(slotSwitchedToTableView())); connect(d->view, SIGNAL(signalSwitchedToTrashView()), this, SLOT(slotSwitchedToTrashView())); } void DigikamApp::setupStatusBar() { d->statusLabel = new DAdjustableLabel(statusBar()); d->statusLabel->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); statusBar()->addWidget(d->statusLabel, 80); //------------------------------------------------------------------------------ d->metadataStatusBar = new MetadataStatusBar(statusBar()); statusBar()->addWidget(d->metadataStatusBar, 50); //------------------------------------------------------------------------------ d->filterStatusBar = new FilterStatusBar(statusBar()); statusBar()->addWidget(d->filterStatusBar, 50); d->view->connectIconViewFilter(d->filterStatusBar); //------------------------------------------------------------------------------ ProgressView* const view = new ProgressView(statusBar(), this); view->hide(); StatusbarProgressWidget* const littleProgress = new StatusbarProgressWidget(view, statusBar()); littleProgress->show(); statusBar()->addPermanentWidget(littleProgress); //------------------------------------------------------------------------------ d->zoomBar = new DZoomBar(statusBar()); d->zoomBar->setZoomToFitAction(d->zoomFitToWindowAction); d->zoomBar->setZoomTo100Action(d->zoomTo100percents); d->zoomBar->setZoomPlusAction(d->zoomPlusAction); d->zoomBar->setZoomMinusAction(d->zoomMinusAction); d->zoomBar->setBarMode(DZoomBar::ThumbsSizeCtrl); statusBar()->addPermanentWidget(d->zoomBar); //------------------------------------------------------------------------------ connect(d->zoomBar, SIGNAL(signalZoomSliderChanged(int)), this, SLOT(slotZoomSliderChanged(int))); connect(this, SIGNAL(signalWindowHasMoved()), d->zoomBar, SLOT(slotUpdateTrackerPos())); connect(d->zoomBar, SIGNAL(signalZoomValueEdited(double)), d->view, SLOT(setZoomFactor(double))); connect(d->view, SIGNAL(signalZoomChanged(double)), this, SLOT(slotZoomChanged(double))); connect(d->view, SIGNAL(signalThumbSizeChanged(int)), this, SLOT(slotThumbSizeChanged(int))); } void DigikamApp::setupActions() { KActionCollection* const ac = actionCollection(); d->solidCameraActionGroup = new QActionGroup(this); connect(d->solidCameraActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotOpenSolidCamera(QAction*))); d->solidUsmActionGroup = new QActionGroup(this); connect(d->solidUsmActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotOpenSolidUsmDevice(QAction*))); d->manualCameraActionGroup = new QActionGroup(this); connect(d->manualCameraActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotOpenManualCamera(QAction*))); // ----------------------------------------------------------------- d->backwardActionMenu = new KToolBarPopupAction(QIcon::fromTheme(QLatin1String("go-previous")), i18n("&Back"), this); d->backwardActionMenu->setEnabled(false); ac->addAction(QLatin1String("album_back"), d->backwardActionMenu); ac->setDefaultShortcut(d->backwardActionMenu, Qt::ALT+Qt::Key_Left); connect(d->backwardActionMenu->menu(), SIGNAL(aboutToShow()), this, SLOT(slotAboutToShowBackwardMenu())); // we are using a signal mapper to identify which of a bunch of actions was triggered d->backwardSignalMapper = new QSignalMapper(this); // connect mapper to view connect(d->backwardSignalMapper, SIGNAL(mapped(int)), d->view, SLOT(slotAlbumHistoryBack(int))); // connect action to mapper connect(d->backwardActionMenu, SIGNAL(triggered()), d->backwardSignalMapper, SLOT(map())); // inform mapper about number of steps d->backwardSignalMapper->setMapping(d->backwardActionMenu, 1); // ----------------------------------------------------------------- d->forwardActionMenu = new KToolBarPopupAction(QIcon::fromTheme(QLatin1String("go-next")), i18n("Forward"), this); d->forwardActionMenu->setEnabled(false); ac->addAction(QLatin1String("album_forward"), d->forwardActionMenu); ac->setDefaultShortcut(d->forwardActionMenu, Qt::ALT+Qt::Key_Right); connect(d->forwardActionMenu->menu(), SIGNAL(aboutToShow()), this, SLOT(slotAboutToShowForwardMenu())); d->forwardSignalMapper = new QSignalMapper(this); connect(d->forwardSignalMapper, SIGNAL(mapped(int)), d->view, SLOT(slotAlbumHistoryForward(int))); connect(d->forwardActionMenu, SIGNAL(triggered()), d->forwardSignalMapper, SLOT(map())); d->forwardSignalMapper->setMapping(d->forwardActionMenu, 1); // ----------------------------------------------------------------- d->refreshAction = new QAction(QIcon::fromTheme(QLatin1String("view-refresh")), i18n("Refresh"), this); d->refreshAction->setWhatsThis(i18n("Refresh the current contents.")); connect(d->refreshAction, SIGNAL(triggered()), d->view, SLOT(slotRefresh())); ac->addAction(QLatin1String("view_refresh"), d->refreshAction); ac->setDefaultShortcut(d->refreshAction, Qt::Key_F5); // ----------------------------------------------------------------- QSignalMapper* const browseActionsMapper = new QSignalMapper(this); connect(browseActionsMapper, SIGNAL(mapped(QWidget*)), d->view, SLOT(slotLeftSideBarActivate(QWidget*))); foreach(SidebarWidget* const leftWidget, d->view->leftSidebarWidgets()) { QString actionName = QLatin1String("browse_") + leftWidget->objectName() .remove(QLatin1Char(' ')) .remove(QLatin1String("Sidebar")) .remove(QLatin1String("FolderView")) .remove(QLatin1String("View")).toLower(); qCDebug(DIGIKAM_GENERAL_LOG) << actionName; QAction* const action = new QAction(leftWidget->getIcon(), leftWidget->getCaption(), this); ac->addAction(actionName, action); ac->setDefaultShortcut(action, QKeySequence(leftWidget->property("Shortcut").toInt())); connect(action, SIGNAL(triggered()), browseActionsMapper, SLOT(map())); browseActionsMapper->setMapping(action, leftWidget); } // ----------------------------------------------------------------- d->newAction = new QAction(QIcon::fromTheme(QLatin1String("folder-new")), i18n("&New..."), this); d->newAction->setWhatsThis(i18n("Creates a new empty Album in the collection.")); connect(d->newAction, SIGNAL(triggered()), d->view, SLOT(slotNewAlbum())); ac->addAction(QLatin1String("album_new"), d->newAction); ac->setDefaultShortcuts(d->newAction, QList() << Qt::CTRL + Qt::Key_N); // ----------------------------------------------------------------- d->moveSelectionToAlbumAction = new QAction(QIcon::fromTheme(QLatin1String("folder-new")), i18n("&Move to Album..."), this); d->moveSelectionToAlbumAction->setWhatsThis(i18n("Move selected images into an album.")); connect(d->moveSelectionToAlbumAction, SIGNAL(triggered()), d->view, SLOT(slotMoveSelectionToAlbum())); ac->addAction(QLatin1String("move_selection_to_album"), d->moveSelectionToAlbumAction); // ----------------------------------------------------------------- d->deleteAction = new QAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18n("Delete Album"), this); connect(d->deleteAction, SIGNAL(triggered()), d->view, SLOT(slotDeleteAlbum())); ac->addAction(QLatin1String("album_delete"), d->deleteAction); // ----------------------------------------------------------------- d->renameAction = new QAction(QIcon::fromTheme(QLatin1String("document-edit")), i18n("Rename..."), this); connect(d->renameAction, SIGNAL(triggered()), d->view, SLOT(slotRenameAlbum())); ac->addAction(QLatin1String("album_rename"), d->renameAction); ac->setDefaultShortcut(d->renameAction, Qt::SHIFT + Qt::Key_F2); // ----------------------------------------------------------------- d->propsEditAction = new QAction(QIcon::fromTheme(QLatin1String("configure")), i18n("Properties"), this); d->propsEditAction->setWhatsThis(i18n("Edit album properties and collection information.")); connect(d->propsEditAction, SIGNAL(triggered()), d->view, SLOT(slotAlbumPropsEdit())); ac->addAction(QLatin1String("album_propsEdit"), d->propsEditAction); ac->setDefaultShortcut(d->propsEditAction, Qt::ALT + Qt::Key_Return); // ----------------------------------------------------------------- d->writeAlbumMetadataAction = new QAction(QIcon::fromTheme(QLatin1String("document-edit")), i18n("Write Metadata to Files"), this); d->writeAlbumMetadataAction->setWhatsThis(i18n("Updates metadata of files in the current " "album with the contents of digiKam database " "(file metadata will be overwritten with data from " "the database).")); connect(d->writeAlbumMetadataAction, SIGNAL(triggered()), d->view, SLOT(slotAlbumWriteMetadata())); ac->addAction(QLatin1String("album_write_metadata"), d->writeAlbumMetadataAction); // ----------------------------------------------------------------- d->readAlbumMetadataAction = new QAction(QIcon::fromTheme(QLatin1String("edit-redo")), i18n("Reread Metadata From Files"), this); d->readAlbumMetadataAction->setWhatsThis(i18n("Updates the digiKam database from the metadata " "of the files in the current album " "(information in the database will be overwritten with data from " "the files' metadata).")); connect(d->readAlbumMetadataAction, SIGNAL(triggered()), d->view, SLOT(slotAlbumReadMetadata())); ac->addAction(QLatin1String("album_read_metadata"), d->readAlbumMetadataAction); // ----------------------------------------------------------------- d->openInFileManagerAction = new QAction(QIcon::fromTheme(QLatin1String("folder-open")), i18n("Open in File Manager"), this); connect(d->openInFileManagerAction, SIGNAL(triggered()), d->view, SLOT(slotAlbumOpenInFileManager())); ac->addAction(QLatin1String("album_openinfilemanager"), d->openInFileManagerAction); // ----------------------------------------------------------- d->openTagMngrAction = new QAction(QIcon::fromTheme(QLatin1String("tag")), i18n("Tag Manager"), this); connect(d->openTagMngrAction, SIGNAL(triggered()), d->view, SLOT(slotOpenTagsManager())); ac->addAction(QLatin1String("open_tag_mngr"), d->openTagMngrAction); // ----------------------------------------------------------- d->newTagAction = new QAction(QIcon::fromTheme(QLatin1String("tag-new")), i18nc("new tag", "N&ew..."), this); connect(d->newTagAction, SIGNAL(triggered()), d->view, SLOT(slotNewTag())); ac->addAction(QLatin1String("tag_new"), d->newTagAction); // ----------------------------------------------------------- d->editTagAction = new QAction(QIcon::fromTheme(QLatin1String("tag-properties")), i18n("Properties"), this); connect(d->editTagAction, SIGNAL(triggered()), d->view, SLOT(slotEditTag())); ac->addAction(QLatin1String("tag_edit"), d->editTagAction); // ----------------------------------------------------------- d->deleteTagAction = new QAction(QIcon::fromTheme(QLatin1String("user-trash")), i18n("Delete"), this); connect(d->deleteTagAction, SIGNAL(triggered()), d->view, SLOT(slotDeleteTag())); ac->addAction(QLatin1String("tag_delete"), d->deleteTagAction); // ----------------------------------------------------------- d->assignTagAction = new QAction(QIcon::fromTheme(QLatin1String("tag-new")), i18n("Assign Tag"), this); connect(d->assignTagAction, SIGNAL(triggered()), d->view, SLOT(slotAssignTag())); ac->addAction(QLatin1String("tag_assign"), d->assignTagAction); ac->setDefaultShortcut(d->assignTagAction, Qt::Key_T); // ----------------------------------------------------------- d->imageViewSelectionAction = new KSelectAction(QIcon::fromTheme(QLatin1String("view-preview")), i18n("Views"), this); ac->addAction(QLatin1String("view_selection"), d->imageViewSelectionAction); d->imageIconViewAction = new QAction(QIcon::fromTheme(QLatin1String("view-list-icons")), i18nc("@action Go to thumbnails (icon) view", "Thumbnails"), this); d->imageIconViewAction->setCheckable(true); ac->addAction(QLatin1String("icon_view"), d->imageIconViewAction); connect(d->imageIconViewAction, SIGNAL(triggered()), d->view, SLOT(slotIconView())); d->imageViewSelectionAction->addAction(d->imageIconViewAction); d->imagePreviewAction = new QAction(QIcon::fromTheme(QLatin1String("view-preview")), i18nc("View the selected image", "Preview"), this); d->imagePreviewAction->setCheckable(true); ac->addAction(QLatin1String("image_view"), d->imagePreviewAction); ac->setDefaultShortcut(d->imagePreviewAction, Qt::Key_F3); connect(d->imagePreviewAction, SIGNAL(triggered()), d->view, SLOT(slotImagePreview())); d->imageViewSelectionAction->addAction(d->imagePreviewAction); #ifdef HAVE_MARBLE d->imageMapViewAction = new QAction(QIcon::fromTheme(QLatin1String("globe")), i18nc("@action Switch to map view", "Map"), this); d->imageMapViewAction->setCheckable(true); ac->addAction(QLatin1String("map_view"), d->imageMapViewAction); connect(d->imageMapViewAction, SIGNAL(triggered()), d->view, SLOT(slotMapWidgetView())); d->imageViewSelectionAction->addAction(d->imageMapViewAction); #endif // HAVE_MARBLE d->imageTableViewAction = new QAction(QIcon::fromTheme(QLatin1String("view-list-details")), i18nc("@action Switch to table view", "Table"), this); d->imageTableViewAction->setCheckable(true); ac->addAction(QLatin1String("table_view"), d->imageTableViewAction); connect(d->imageTableViewAction, SIGNAL(triggered()), d->view, SLOT(slotTableView())); d->imageViewSelectionAction->addAction(d->imageTableViewAction); // ----------------------------------------------------------- d->imageViewAction = new QAction(QIcon::fromTheme(QLatin1String("quickopen-file")), i18n("Open..."), this); d->imageViewAction->setWhatsThis(i18n("Open the selected item.")); connect(d->imageViewAction, SIGNAL(triggered()), d->view, SLOT(slotImageEdit())); ac->addAction(QLatin1String("image_edit"), d->imageViewAction); ac->setDefaultShortcut(d->imageViewAction, Qt::Key_F4); d->openWithAction = new QAction(QIcon::fromTheme(QLatin1String("preferences-desktop-filetype-association")), i18n("Open With Default Application"), this); d->openWithAction->setWhatsThis(i18n("Open the selected item with default assigned application.")); connect(d->openWithAction, SIGNAL(triggered()), d->view, SLOT(slotFileWithDefaultApplication())); ac->addAction(QLatin1String("open_with_default_application"), d->openWithAction); ac->setDefaultShortcut(d->openWithAction, Qt::META + Qt::Key_F4); d->ieAction = new QAction(QIcon::fromTheme(QLatin1String("document-edit")), i18n("Image Editor"), this); d->ieAction->setWhatsThis(i18n("Open the image editor.")); connect(d->ieAction, SIGNAL(triggered()), d->view, SLOT(slotEditor())); ac->addAction(QLatin1String("imageeditor"), d->ieAction); // ----------------------------------------------------------- d->ltAction = new QAction(QIcon::fromTheme(QLatin1String("lighttable")), i18n("Light Table"), this); connect(d->ltAction, SIGNAL(triggered()), d->view, SLOT(slotLightTable())); ac->addAction(QLatin1String("light_table"), d->ltAction); ac->setDefaultShortcut(d->ltAction, Qt::Key_L); d->imageLightTableAction = new QAction(QIcon::fromTheme(QLatin1String("lighttable")), i18n("Place onto Light Table"), this); d->imageLightTableAction->setWhatsThis(i18n("Place the selected items on the light table thumbbar.")); connect(d->imageLightTableAction, SIGNAL(triggered()), d->view, SLOT(slotImageLightTable())); ac->addAction(QLatin1String("image_lighttable"), d->imageLightTableAction); ac->setDefaultShortcut(d->imageLightTableAction, Qt::CTRL+Qt::Key_L); d->imageAddLightTableAction = new QAction(QIcon::fromTheme(QLatin1String("list-add")), i18n("Add to Light Table"), this); d->imageAddLightTableAction->setWhatsThis(i18n("Add selected items to the light table thumbbar.")); connect(d->imageAddLightTableAction, SIGNAL(triggered()), d->view, SLOT(slotImageAddToLightTable())); ac->addAction(QLatin1String("image_add_to_lighttable"), d->imageAddLightTableAction); ac->setDefaultShortcut(d->imageAddLightTableAction, Qt::SHIFT+Qt::CTRL+Qt::Key_L); // ----------------------------------------------------------- d->bqmAction = new QAction(QIcon::fromTheme(QLatin1String("run-build")), i18n("Batch Queue Manager"), this); connect(d->bqmAction, SIGNAL(triggered()), d->view, SLOT(slotQueueMgr())); ac->addAction(QLatin1String("queue_manager"), d->bqmAction); ac->setDefaultShortcut(d->bqmAction, Qt::Key_B); d->imageAddCurrentQueueAction = new QAction(QIcon::fromTheme(QLatin1String("go-up")), i18n("Add to Current Queue"), this); d->imageAddCurrentQueueAction->setWhatsThis(i18n("Add selected items to current queue from batch manager.")); connect(d->imageAddCurrentQueueAction, SIGNAL(triggered()), d->view, SLOT(slotImageAddToCurrentQueue())); ac->addAction(QLatin1String("image_add_to_current_queue"), d->imageAddCurrentQueueAction); ac->setDefaultShortcut(d->imageAddCurrentQueueAction, Qt::CTRL+Qt::Key_B); d->imageAddNewQueueAction = new QAction(QIcon::fromTheme(QLatin1String("list-add")), i18n("Add to New Queue"), this); d->imageAddNewQueueAction->setWhatsThis(i18n("Add selected items to a new queue from batch manager.")); connect(d->imageAddNewQueueAction, SIGNAL(triggered()), d->view, SLOT(slotImageAddToNewQueue())); ac->addAction(QLatin1String("image_add_to_new_queue"), d->imageAddNewQueueAction); ac->setDefaultShortcut(d->imageAddNewQueueAction, Qt::SHIFT+Qt::CTRL+Qt::Key_B); // ----------------------------------------------------------------- d->quickImportMenu->setTitle(i18nc("@action Import photos from camera", "Import")); d->quickImportMenu->setIcon(QIcon::fromTheme(QLatin1String("camera-photo"))); ac->addAction(QLatin1String("import_auto"), d->quickImportMenu->menuAction()); // ----------------------------------------------------------------- d->imageWriteMetadataAction = new QAction(QIcon::fromTheme(QLatin1String("document-edit")), i18n("Write Metadata to Selected Files"), this); d->imageWriteMetadataAction->setWhatsThis(i18n("Updates metadata of files in the current " "album with the contents of digiKam database " "(file metadata will be overwritten with data from " "the database).")); connect(d->imageWriteMetadataAction, SIGNAL(triggered()), d->view, SLOT(slotImageWriteMetadata())); ac->addAction(QLatin1String("image_write_metadata"), d->imageWriteMetadataAction); // ----------------------------------------------------------------- d->imageReadMetadataAction = new QAction(QIcon::fromTheme(QLatin1String("edit-redo")), i18n("Reread Metadata From Selected Files"), this); d->imageReadMetadataAction->setWhatsThis(i18n("Updates the digiKam database from the metadata " "of the files in the current album " "(information in the database will be overwritten with data from " "the files' metadata).")); connect(d->imageReadMetadataAction, SIGNAL(triggered()), d->view, SLOT(slotImageReadMetadata())); ac->addAction(QLatin1String("image_read_metadata"), d->imageReadMetadataAction); // ----------------------------------------------------------- d->imageScanForFacesAction = new QAction(QIcon::fromTheme(QLatin1String("list-add-user")), i18n("Scan for Faces"), this); connect(d->imageScanForFacesAction, SIGNAL(triggered()), d->view, SLOT(slotImageScanForFaces())); ac->addAction(QLatin1String("image_scan_for_faces"), d->imageScanForFacesAction); // ----------------------------------------------------------- d->imageFindSimilarAction = new QAction(QIcon::fromTheme(QLatin1String("tools-wizard")), i18n("Find Similar..."), this); d->imageFindSimilarAction->setWhatsThis(i18n("Find similar images using selected item as reference.")); connect(d->imageFindSimilarAction, SIGNAL(triggered()), d->view, SLOT(slotImageFindSimilar())); ac->addAction(QLatin1String("image_find_similar"), d->imageFindSimilarAction); // ----------------------------------------------------------- d->imageRenameAction = new QAction(QIcon::fromTheme(QLatin1String("document-edit")), i18n("Rename..."), this); d->imageRenameAction->setWhatsThis(i18n("Change the filename of the currently selected item.")); connect(d->imageRenameAction, SIGNAL(triggered()), d->view, SLOT(slotImageRename())); ac->addAction(QLatin1String("image_rename"), d->imageRenameAction); ac->setDefaultShortcut(d->imageRenameAction, Qt::Key_F2); // ----------------------------------------------------------- // Pop up dialog to ask user whether to move to trash d->imageDeleteAction = new QAction(QIcon::fromTheme(QLatin1String("user-trash")), i18nc("Non-pluralized", "Move to Trash"), this); connect(d->imageDeleteAction, SIGNAL(triggered()), d->view, SLOT(slotImageDelete())); ac->addAction(QLatin1String("image_delete"), d->imageDeleteAction); ac->setDefaultShortcut(d->imageDeleteAction, Qt::Key_Delete); // ----------------------------------------------------------- // Pop up dialog to ask user whether to permanently delete // FIXME: This action is never used?? How can someone delete a album directly, without moving it to the trash first? // This is especially important when deleting from a different partition or from a net source. // Also note that we use the wrong icon for the default album delete action, which should have a trashcan icon instead // of a red cross, it confuses users. d->imageDeletePermanentlyAction = new QAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18n("Delete Permanently"), this); connect(d->imageDeletePermanentlyAction, SIGNAL(triggered()), d->view, SLOT(slotImageDeletePermanently())); ac->addAction(QLatin1String("image_delete_permanently"), d->imageDeletePermanentlyAction); ac->setDefaultShortcut(d->imageDeletePermanentlyAction, Qt::SHIFT+Qt::Key_Delete); // ----------------------------------------------------------- // These two actions are hidden, no menu entry, no toolbar entry, no shortcut. // Power users may add them. d->imageDeletePermanentlyDirectlyAction = new QAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18n("Delete permanently without confirmation"), this); connect(d->imageDeletePermanentlyDirectlyAction, SIGNAL(triggered()), d->view, SLOT(slotImageDeletePermanentlyDirectly())); ac->addAction(QLatin1String("image_delete_permanently_directly"), d->imageDeletePermanentlyDirectlyAction); // ----------------------------------------------------------- d->imageTrashDirectlyAction = new QAction(QIcon::fromTheme(QLatin1String("user-trash")), i18n("Move to trash without confirmation"), this); connect(d->imageTrashDirectlyAction, SIGNAL(triggered()), d->view, SLOT(slotImageTrashDirectly())); ac->addAction(QLatin1String("image_trash_directly"), d->imageTrashDirectlyAction); // ----------------------------------------------------------------- d->albumSortAction = new KSelectAction(i18n("&Sort Albums"), this); d->albumSortAction->setWhatsThis(i18n("Sort Albums in tree-view.")); connect(d->albumSortAction, SIGNAL(triggered(int)), d->view, SLOT(slotSortAlbums(int))); ac->addAction(QLatin1String("album_sort"), d->albumSortAction); // Use same list order as in applicationsettings enum QStringList sortActionList; sortActionList.append(i18n("By Folder")); sortActionList.append(i18n("By Category")); sortActionList.append(i18n("By Date")); d->albumSortAction->setItems(sortActionList); // ----------------------------------------------------------- d->recurseAlbumsAction = new QAction(i18n("Include Album Sub-Tree"), this); d->recurseAlbumsAction->setCheckable(true); d->recurseAlbumsAction->setWhatsThis(i18n("Activate this option to show all sub-albums below " "the current album.")); connect(d->recurseAlbumsAction, SIGNAL(toggled(bool)), this, SLOT(slotRecurseAlbums(bool))); ac->addAction(QLatin1String("albums_recursive"), d->recurseAlbumsAction); d->recurseTagsAction = new QAction(i18n("Include Tag Sub-Tree"), this); d->recurseTagsAction->setCheckable(true); d->recurseTagsAction->setWhatsThis(i18n("Activate this option to show all images marked by the given tag " "and all its sub-tags.")); connect(d->recurseTagsAction, SIGNAL(toggled(bool)), this, SLOT(slotRecurseTags(bool))); ac->addAction(QLatin1String("tags_recursive"), d->recurseTagsAction); // ----------------------------------------------------------- d->imageSortAction = new KSelectAction(i18n("&Sort Items"), this); d->imageSortAction->setWhatsThis(i18n("The value by which the images in one album are sorted in the thumbnail view")); QSignalMapper* const imageSortMapper = new QSignalMapper(this); connect(imageSortMapper, SIGNAL(mapped(int)), d->view, SLOT(slotSortImages(int))); ac->addAction(QLatin1String("image_sort"), d->imageSortAction); // map to ImageSortSettings enum QAction* const sortByNameAction = d->imageSortAction->addAction(i18n("By Name")); QAction* const sortByPathAction = d->imageSortAction->addAction(i18n("By Path")); QAction* const sortByDateAction = d->imageSortAction->addAction(i18n("By Date")); QAction* const sortByFileSizeAction = d->imageSortAction->addAction(i18n("By File Size")); QAction* const sortByRatingAction = d->imageSortAction->addAction(i18n("By Rating")); QAction* const sortByImageSizeAction = d->imageSortAction->addAction(i18n("By Image Size")); QAction* const sortByAspectRatioAction = d->imageSortAction->addAction(i18n("By Aspect Ratio")); QAction* const sortBySimilarityAction = d->imageSortAction->addAction(i18n("By Similarity")); QAction* const sortByManualOrderAction = d->imageSortAction->addAction(i18n("By Manual")); // activate the sort by similarity if the fuzzy search sidebar is active. Deactivate at start. sortBySimilarityAction->setEnabled(false); connect(d->view, SIGNAL(signalFuzzySidebarActive(bool)), sortBySimilarityAction, SLOT(setEnabled(bool))); connect(sortByNameAction, SIGNAL(triggered()), imageSortMapper, SLOT(map())); connect(sortByPathAction, SIGNAL(triggered()), imageSortMapper, SLOT(map())); connect(sortByDateAction, SIGNAL(triggered()), imageSortMapper, SLOT(map())); connect(sortByFileSizeAction, SIGNAL(triggered()), imageSortMapper, SLOT(map())); connect(sortByRatingAction, SIGNAL(triggered()), imageSortMapper, SLOT(map())); connect(sortByImageSizeAction, SIGNAL(triggered()), imageSortMapper, SLOT(map())); connect(sortByAspectRatioAction, SIGNAL(triggered()), imageSortMapper, SLOT(map())); connect(sortBySimilarityAction, SIGNAL(triggered()), imageSortMapper, SLOT(map())); connect(sortByManualOrderAction, SIGNAL(triggered()), imageSortMapper, SLOT(map())); imageSortMapper->setMapping(sortByNameAction, (int)ImageSortSettings::SortByFileName); imageSortMapper->setMapping(sortByPathAction, (int)ImageSortSettings::SortByFilePath); imageSortMapper->setMapping(sortByDateAction, (int)ImageSortSettings::SortByCreationDate); imageSortMapper->setMapping(sortByFileSizeAction, (int)ImageSortSettings::SortByFileSize); imageSortMapper->setMapping(sortByRatingAction, (int)ImageSortSettings::SortByRating); imageSortMapper->setMapping(sortByImageSizeAction, (int)ImageSortSettings::SortByImageSize); imageSortMapper->setMapping(sortByAspectRatioAction, (int)ImageSortSettings::SortByAspectRatio); imageSortMapper->setMapping(sortBySimilarityAction, (int)ImageSortSettings::SortBySimilarity); imageSortMapper->setMapping(sortByManualOrderAction, (int)ImageSortSettings::SortByManualOrder); // ----------------------------------------------------------- d->imageSortOrderAction = new KSelectAction(i18n("Item Sort &Order"), this); d->imageSortOrderAction->setWhatsThis(i18n("Defines whether images are sorted in ascending or descending manner.")); QSignalMapper* const imageSortOrderMapper = new QSignalMapper(this); connect(imageSortOrderMapper, SIGNAL(mapped(int)), d->view, SLOT(slotSortImagesOrder(int))); ac->addAction(QLatin1String("image_sort_order"), d->imageSortOrderAction); QAction* const sortAscendingAction = d->imageSortOrderAction->addAction(QIcon::fromTheme(QLatin1String("view-sort-ascending")), i18n("Ascending")); QAction* const sortDescendingAction = d->imageSortOrderAction->addAction(QIcon::fromTheme(QLatin1String("view-sort-descending")), i18n("Descending")); connect(sortAscendingAction, SIGNAL(triggered()), imageSortOrderMapper, SLOT(map())); connect(sortDescendingAction, SIGNAL(triggered()), imageSortOrderMapper, SLOT(map())); imageSortOrderMapper->setMapping(sortAscendingAction, (int)ImageSortSettings::AscendingOrder); imageSortOrderMapper->setMapping(sortDescendingAction, (int)ImageSortSettings::DescendingOrder); // ----------------------------------------------------------- d->imageSeparationAction = new KSelectAction(i18n("Separate Items"), this); d->imageSeparationAction->setWhatsThis(i18n("The categories in which the images in the thumbnail view are displayed")); QSignalMapper* const imageSeparationMapper = new QSignalMapper(this); connect(imageSeparationMapper, SIGNAL(mapped(int)), d->view, SLOT(slotSeparateImages(int))); ac->addAction(QLatin1String("image_separation"), d->imageSeparationAction); // map to ImageSortSettings enum QAction* const noCategoriesAction = d->imageSeparationAction->addAction(i18n("Flat List")); QAction* const separateByAlbumAction = d->imageSeparationAction->addAction(i18n("By Album")); QAction* const separateByFormatAction = d->imageSeparationAction->addAction(i18n("By Format")); QAction* const separateByMonthAction = d->imageSeparationAction->addAction(i18n("By Month")); connect(noCategoriesAction, SIGNAL(triggered()), imageSeparationMapper, SLOT(map())); connect(separateByAlbumAction, SIGNAL(triggered()), imageSeparationMapper, SLOT(map())); connect(separateByFormatAction, SIGNAL(triggered()), imageSeparationMapper, SLOT(map())); connect(separateByMonthAction, SIGNAL(triggered()), imageSeparationMapper, SLOT(map())); imageSeparationMapper->setMapping(noCategoriesAction, (int)ImageSortSettings::OneCategory); imageSeparationMapper->setMapping(separateByAlbumAction, (int)ImageSortSettings::CategoryByAlbum); imageSeparationMapper->setMapping(separateByFormatAction, (int)ImageSortSettings::CategoryByFormat); imageSeparationMapper->setMapping(separateByMonthAction, (int)ImageSortSettings::CategoryByMonth); // ----------------------------------------------------------------- d->imageSeparationSortOrderAction = new KSelectAction(i18n("Item Separation Order"), this); d->imageSeparationSortOrderAction->setWhatsThis(i18n("The sort order of the groups of separated items")); QSignalMapper* const imageSeparationSortOrderMapper = new QSignalMapper(this); connect(imageSeparationSortOrderMapper, SIGNAL(mapped(int)), d->view, SLOT(slotImageSeparationSortOrder(int))); ac->addAction(QLatin1String("image_separation_sort_order"), d->imageSeparationSortOrderAction); QAction* const sortSeparationsAscending = d->imageSeparationSortOrderAction->addAction(QIcon::fromTheme(QLatin1String("view-sort-ascending")), i18n("Ascending")); QAction* const sortSeparationsDescending = d->imageSeparationSortOrderAction->addAction(QIcon::fromTheme(QLatin1String("view-sort-descending")), i18n("Descending")); connect(sortSeparationsAscending, SIGNAL(triggered()), imageSeparationSortOrderMapper, SLOT(map())); connect(sortSeparationsDescending, SIGNAL(triggered()), imageSeparationSortOrderMapper, SLOT(map())); imageSeparationSortOrderMapper->setMapping(sortSeparationsAscending, (int)ImageSortSettings::AscendingOrder); imageSeparationSortOrderMapper->setMapping(sortSeparationsDescending, (int)ImageSortSettings::DescendingOrder); // ----------------------------------------------------------------- setupImageTransformActions(); setupExifOrientationActions(); - createMetadataEditAction(); createTimeAdjustAction(); + createMetadataEditAction(); createGeolocationEditAction(); createExportActions(); createImportActions(); // ----------------------------------------------------------------- d->selectAllAction = new QAction(i18n("Select All"), this); connect(d->selectAllAction, SIGNAL(triggered()), d->view, SLOT(slotSelectAll())); ac->addAction(QLatin1String("selectAll"), d->selectAllAction); ac->setDefaultShortcut(d->selectAllAction, Qt::CTRL+Qt::Key_A); // ----------------------------------------------------------------- d->selectNoneAction = new QAction(i18n("Select None"), this); connect(d->selectNoneAction, SIGNAL(triggered()), d->view, SLOT(slotSelectNone())); ac->addAction(QLatin1String("selectNone"), d->selectNoneAction); ac->setDefaultShortcut(d->selectNoneAction, Qt::CTRL+Qt::SHIFT+Qt::Key_A); // ----------------------------------------------------------------- d->selectInvertAction = new QAction(i18n("Invert Selection"), this); connect(d->selectInvertAction, SIGNAL(triggered()), d->view, SLOT(slotSelectInvert())); ac->addAction(QLatin1String("selectInvert"), d->selectInvertAction); ac->setDefaultShortcut(d->selectInvertAction, Qt::CTRL+Qt::Key_I); // ----------------------------------------------------------- d->showBarAction = new QAction(QIcon::fromTheme(QLatin1String("view-choose")), i18n("Show Thumbbar"), this); d->showBarAction->setCheckable(true); connect(d->showBarAction, SIGNAL(triggered()), this, SLOT(slotToggleShowBar())); ac->addAction(QLatin1String("showthumbs"), d->showBarAction); ac->setDefaultShortcut(d->showBarAction, Qt::CTRL+Qt::Key_T); // Provides a menu entry that allows showing/hiding the toolbar(s) setStandardToolBarMenuEnabled(true); // Provides a menu entry that allows showing/hiding the statusbar createStandardStatusBarAction(); // Standard 'Configure' menu actions createSettingsActions(); // ----------------------------------------------------------- d->zoomPlusAction = buildStdAction(StdZoomInAction, d->view, SLOT(slotZoomIn()), this); QKeySequence keysPlus(d->zoomPlusAction->shortcut()[0], Qt::Key_Plus); ac->addAction(QLatin1String("album_zoomin"), d->zoomPlusAction); ac->setDefaultShortcut(d->zoomPlusAction, keysPlus); // ----------------------------------------------------------- d->zoomMinusAction = buildStdAction(StdZoomOutAction, d->view, SLOT(slotZoomOut()), this); QKeySequence keysMinus(d->zoomMinusAction->shortcut()[0], Qt::Key_Minus); ac->addAction(QLatin1String("album_zoomout"), d->zoomMinusAction); ac->setDefaultShortcut(d->zoomMinusAction, keysMinus); // ----------------------------------------------------------- d->zoomTo100percents = new QAction(QIcon::fromTheme(QLatin1String("zoom-original")), i18n("Zoom to 100%"), this); connect(d->zoomTo100percents, SIGNAL(triggered()), d->view, SLOT(slotZoomTo100Percents())); ac->addAction(QLatin1String("album_zoomto100percents"), d->zoomTo100percents); ac->setDefaultShortcut(d->zoomTo100percents, Qt::CTRL + Qt::Key_Period); // ----------------------------------------------------------- d->zoomFitToWindowAction = new QAction(QIcon::fromTheme(QLatin1String("zoom-fit-best")), i18n("Fit to &Window"), this); connect(d->zoomFitToWindowAction, SIGNAL(triggered()), d->view, SLOT(slotFitToWindow())); ac->addAction(QLatin1String("album_zoomfit2window"), d->zoomFitToWindowAction); ac->setDefaultShortcut(d->zoomFitToWindowAction, Qt::ALT + Qt::CTRL + Qt::Key_E); // ----------------------------------------------------------- createFullScreenAction(QLatin1String("full_screen")); createSidebarActions(); // ----------------------------------------------------------- d->slideShowAction = new QMenu(i18n("Slideshow"), this); d->slideShowAction->setIcon(QIcon::fromTheme(QLatin1String("view-presentation"))); ac->addAction(QLatin1String("slideshow"), d->slideShowAction->menuAction()); d->slideShowAllAction = new QAction(i18n("All"), this); connect(d->slideShowAllAction, SIGNAL(triggered()), d->view, SLOT(slotSlideShowAll())); ac->addAction(QLatin1String("slideshow_all"), d->slideShowAllAction); ac->setDefaultShortcut(d->slideShowAllAction, Qt::Key_F9); d->slideShowAction->addAction(d->slideShowAllAction); d->slideShowSelectionAction = new QAction(i18n("Selection"), this); connect(d->slideShowSelectionAction, SIGNAL(triggered()), d->view, SLOT(slotSlideShowSelection())); ac->addAction(QLatin1String("slideshow_selected"), d->slideShowSelectionAction); ac->setDefaultShortcut(d->slideShowSelectionAction, Qt::ALT+Qt::Key_F9); d->slideShowAction->addAction(d->slideShowSelectionAction); d->slideShowRecursiveAction = new QAction(i18n("With All Sub-Albums"), this); connect(d->slideShowRecursiveAction, SIGNAL(triggered()), d->view, SLOT(slotSlideShowRecursive())); ac->addAction(QLatin1String("slideshow_recursive"), d->slideShowRecursiveAction); ac->setDefaultShortcut(d->slideShowRecursiveAction, Qt::SHIFT+Qt::Key_F9); d->slideShowAction->addAction(d->slideShowRecursiveAction); createPresentationAction(); // ----------------------------------------------------------- d->viewCMViewAction = new QAction(QIcon::fromTheme(QLatin1String("video-display")), i18n("Color-Managed View"), this); d->viewCMViewAction->setCheckable(true); connect(d->viewCMViewAction, SIGNAL(triggered()), this, SLOT(slotToggleColorManagedView())); ac->addAction(QLatin1String("color_managed_view"), d->viewCMViewAction); ac->setDefaultShortcut(d->viewCMViewAction, Qt::Key_F12); // ----------------------------------------------------------- d->quitAction = buildStdAction(StdQuitAction, this, SLOT(slotExit()), this); ac->addAction(QLatin1String("app_exit"), d->quitAction); // ----------------------------------------------------------- createHelpActions(); // ----------------------------------------------------------- QAction* const findAction = new QAction(QIcon::fromTheme(QLatin1String("edit-find")), i18n("Search..."), this); connect(findAction, SIGNAL(triggered()), d->view, SLOT(slotNewKeywordSearch())); ac->addAction(QLatin1String("search_quick"), findAction); ac->setDefaultShortcut(findAction, Qt::CTRL+Qt::Key_F); // ----------------------------------------------------------- d->advSearchAction = new QAction(QIcon::fromTheme(QLatin1String("edit-find")), i18n("Advanced Search..."), this); connect(d->advSearchAction, SIGNAL(triggered()), d->view, SLOT(slotNewAdvancedSearch())); ac->addAction(QLatin1String("search_advanced"), d->advSearchAction); ac->setDefaultShortcut(d->advSearchAction, Qt::CTRL+Qt::ALT+Qt::Key_F); // ----------------------------------------------------------- QAction* const duplicatesAction = new QAction(QIcon::fromTheme(QLatin1String("tools-wizard")), i18n("Find Duplicates..."), this); connect(duplicatesAction, SIGNAL(triggered()), d->view, SLOT(slotNewDuplicatesSearch())); ac->addAction(QLatin1String("find_duplicates"), duplicatesAction); ac->setDefaultShortcut(duplicatesAction, Qt::CTRL+Qt::Key_D); // ----------------------------------------------------------- #ifdef HAVE_MYSQLSUPPORT QAction* const databaseMigrationAction = new QAction(QIcon::fromTheme(QLatin1String("network-server-database")), i18n("Database Migration..."), this); connect(databaseMigrationAction, SIGNAL(triggered()), this, SLOT(slotDatabaseMigration())); ac->addAction(QLatin1String("database_migration"), databaseMigrationAction); #endif // ----------------------------------------------------------- d->maintenanceAction = new QAction(QIcon::fromTheme(QLatin1String("run-build-prune")), i18n("Maintenance..."), this); connect(d->maintenanceAction, SIGNAL(triggered()), this, SLOT(slotMaintenance())); ac->addAction(QLatin1String("maintenance"), d->maintenanceAction); createExpoBlendingAction(); createPanoramaAction(); createHtmlGalleryAction(); createCalendarAction(); createVideoSlideshowAction(); createSendByMailAction(); createPrintCreatorAction(); createMediaServerAction(); // ----------------------------------------------------------- QAction* const cameraAction = new QAction(i18n("Add Camera Manually..."), this); connect(cameraAction, SIGNAL(triggered()), this, SLOT(slotSetupCamera())); ac->addAction(QLatin1String("camera_add"), cameraAction); // ----------------------------------------------------------- // Load Cameras -- do this before the createGUI so that the cameras // are plugged into the toolbar at startup if (d->splashScreen) { d->splashScreen->setMessage(i18n("Loading cameras...")); } loadCameras(); // Load Themes populateThemes(); createGUI(xmlFile()); cleanupActions(); // NOTE: see bug #252130 and #283281 : we need to disable these actions when BQM is running. // These connections must be done after loading color theme else theme menu cannot be plugged to Settings menu, connect(QueueMgrWindow::queueManagerWindow(), SIGNAL(signalBqmIsBusy(bool)), d->bqmAction, SLOT(setDisabled(bool))); connect(QueueMgrWindow::queueManagerWindow(), SIGNAL(signalBqmIsBusy(bool)), d->imageAddCurrentQueueAction, SLOT(setDisabled(bool))); connect(QueueMgrWindow::queueManagerWindow(), SIGNAL(signalBqmIsBusy(bool)), d->imageAddNewQueueAction, SLOT(setDisabled(bool))); } void DigikamApp::setupAccelerators() { KActionCollection* const ac = actionCollection(); // Action are added by tag in ui.rc XML file QAction* const escapeAction = new QAction(i18n("Exit Preview Mode"), this); ac->addAction(QLatin1String("exit_preview_mode"), escapeAction); ac->setDefaultShortcut(escapeAction, Qt::Key_Escape); connect(escapeAction, SIGNAL(triggered()), this, SIGNAL(signalEscapePressed())); QAction* const nextImageAction = new QAction(i18n("Next Image"), this); nextImageAction->setIcon(QIcon::fromTheme(QLatin1String("go-next"))); ac->addAction(QLatin1String("next_image"), nextImageAction); ac->setDefaultShortcut(nextImageAction, Qt::Key_Space); connect(nextImageAction, SIGNAL(triggered()), this, SIGNAL(signalNextItem())); QAction* const previousImageAction = new QAction(i18n("Previous Image"), this); previousImageAction->setIcon(QIcon::fromTheme(QLatin1String("go-previous"))); ac->addAction(QLatin1String("previous_image"), previousImageAction); ac->setDefaultShortcuts(previousImageAction, QList() << Qt::Key_Backspace << Qt::SHIFT+Qt::Key_Space); connect(previousImageAction, SIGNAL(triggered()), this, SIGNAL(signalPrevItem())); QAction* const firstImageAction = new QAction(i18n("First Image"), this); ac->addAction(QLatin1String("first_image"), firstImageAction); ac->setDefaultShortcuts(firstImageAction, QList() << Qt::CTRL + Qt::Key_Home); connect(firstImageAction, SIGNAL(triggered()), this, SIGNAL(signalFirstItem())); QAction* const lastImageAction = new QAction(i18n("Last Image"), this); ac->addAction(QLatin1String("last_image"), lastImageAction); ac->setDefaultShortcuts(lastImageAction, QList() << Qt::CTRL + Qt::Key_End); connect(lastImageAction, SIGNAL(triggered()), this, SIGNAL(signalLastItem())); d->cutItemsAction = new QAction(i18n("Cu&t"), this); d->cutItemsAction->setIcon(QIcon::fromTheme(QLatin1String("edit-cut"))); d->cutItemsAction->setWhatsThis(i18n("Cut selection to clipboard")); ac->addAction(QLatin1String("cut_album_selection"), d->cutItemsAction); // NOTE: shift+del keyboard shortcut must not be assigned to Cut action // else the shortcut for Delete permanently collides with secondary shortcut of Cut ac->setDefaultShortcut(d->cutItemsAction, Qt::CTRL + Qt::Key_X); connect(d->cutItemsAction, SIGNAL(triggered()), this, SIGNAL(signalCutAlbumItemsSelection())); d->copyItemsAction = buildStdAction(StdCopyAction, this, SIGNAL(signalCopyAlbumItemsSelection()), this); ac->addAction(QLatin1String("copy_album_selection"), d->copyItemsAction); d->pasteItemsAction = buildStdAction(StdPasteAction, this, SIGNAL(signalPasteAlbumItemsSelection()), this); ac->addAction(QLatin1String("paste_album_selection"), d->pasteItemsAction); // Labels shortcuts must be registered here to be saved in XML GUI files if user customize it. d->tagsActionManager->registerLabelsActions(ac); QAction* const editTitles = new QAction(i18n("Edit Titles"), this); ac->addAction(QLatin1String("edit_titles"), editTitles); ac->setDefaultShortcut(editTitles, Qt::META + Qt::Key_T); connect(editTitles, SIGNAL(triggered()), d->view, SLOT(slotRightSideBarActivateTitles())); QAction* const editComments = new QAction(i18n("Edit Comments"), this); ac->addAction(QLatin1String("edit_comments"), editComments); ac->setDefaultShortcut(editComments, Qt::META + Qt::Key_C); connect(editComments, SIGNAL(triggered()), d->view, SLOT(slotRightSideBarActivateComments())); QAction* const assignedTags = new QAction(i18n("Show Assigned Tags"), this); ac->addAction(QLatin1String("assigned _tags"), assignedTags); ac->setDefaultShortcut(assignedTags, Qt::META + Qt::Key_A); connect(assignedTags, SIGNAL(triggered()), d->view, SLOT(slotRightSideBarActivateAssignedTags())); } void DigikamApp::setupExifOrientationActions() { KActionCollection* const ac = actionCollection(); QSignalMapper* const exifOrientationMapper = new QSignalMapper(d->view); connect(exifOrientationMapper, SIGNAL(mapped(int)), d->view, SLOT(slotImageExifOrientation(int))); d->imageExifOrientationActionMenu = new QMenu(i18n("Adjust Exif Orientation Tag"), this); ac->addAction(QLatin1String("image_set_exif_orientation"), d->imageExifOrientationActionMenu->menuAction()); d->imageSetExifOrientation1Action = new QAction(i18nc("normal exif orientation", "Normal"), this); d->imageSetExifOrientation1Action->setCheckable(true); d->imageSetExifOrientation2Action = new QAction(i18n("Flipped Horizontally"), this); d->imageSetExifOrientation2Action->setCheckable(true); d->imageSetExifOrientation3Action = new QAction(i18n("Rotated Upside Down"), this); d->imageSetExifOrientation3Action->setCheckable(true); d->imageSetExifOrientation4Action = new QAction(i18n("Flipped Vertically"), this); d->imageSetExifOrientation4Action->setCheckable(true); d->imageSetExifOrientation5Action = new QAction(i18n("Rotated Right / Horiz. Flipped"), this); d->imageSetExifOrientation5Action->setCheckable(true); d->imageSetExifOrientation6Action = new QAction(i18n("Rotated Right"), this); d->imageSetExifOrientation6Action->setCheckable(true); d->imageSetExifOrientation7Action = new QAction(i18n("Rotated Right / Vert. Flipped"), this); d->imageSetExifOrientation7Action->setCheckable(true); d->imageSetExifOrientation8Action = new QAction(i18n("Rotated Left"), this); d->imageSetExifOrientation8Action->setCheckable(true); d->exifOrientationActionGroup = new QActionGroup(d->imageExifOrientationActionMenu); d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation1Action); d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation2Action); d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation3Action); d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation4Action); d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation5Action); d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation6Action); d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation7Action); d->exifOrientationActionGroup->addAction(d->imageSetExifOrientation8Action); d->imageSetExifOrientation1Action->setChecked(true); ac->addAction(QLatin1String("image_set_exif_orientation_normal"), d->imageSetExifOrientation1Action); ac->addAction(QLatin1String("image_set_exif_orientation_flipped_horizontal"), d->imageSetExifOrientation2Action); ac->addAction(QLatin1String("image_set_exif_orientation_rotated_upside_down"), d->imageSetExifOrientation3Action); ac->addAction(QLatin1String("image_set_exif_orientation_flipped_vertically"), d->imageSetExifOrientation4Action); ac->addAction(QLatin1String("image_set_exif_orientation_rotated_right_hor_flipped"), d->imageSetExifOrientation5Action); ac->addAction(QLatin1String("image_set_exif_orientation_rotated_right"), d->imageSetExifOrientation6Action); ac->addAction(QLatin1String("image_set_exif_orientation_rotated_right_ver_flipped"), d->imageSetExifOrientation7Action); ac->addAction(QLatin1String("image_set_exif_orientation_rotated_left"), d->imageSetExifOrientation8Action); d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation1Action); d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation2Action); d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation3Action); d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation4Action); d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation5Action); d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation6Action); d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation7Action); d->imageExifOrientationActionMenu->addAction(d->imageSetExifOrientation8Action); connect(d->imageSetExifOrientation1Action, SIGNAL(triggered()), exifOrientationMapper, SLOT(map())); connect(d->imageSetExifOrientation2Action, SIGNAL(triggered()), exifOrientationMapper, SLOT(map())); connect(d->imageSetExifOrientation3Action, SIGNAL(triggered()), exifOrientationMapper, SLOT(map())); connect(d->imageSetExifOrientation4Action, SIGNAL(triggered()), exifOrientationMapper, SLOT(map())); connect(d->imageSetExifOrientation5Action, SIGNAL(triggered()), exifOrientationMapper, SLOT(map())); connect(d->imageSetExifOrientation6Action, SIGNAL(triggered()), exifOrientationMapper, SLOT(map())); connect(d->imageSetExifOrientation7Action, SIGNAL(triggered()), exifOrientationMapper, SLOT(map())); connect(d->imageSetExifOrientation8Action, SIGNAL(triggered()), exifOrientationMapper, SLOT(map())); exifOrientationMapper->setMapping(d->imageSetExifOrientation1Action, 1); exifOrientationMapper->setMapping(d->imageSetExifOrientation2Action, 2); exifOrientationMapper->setMapping(d->imageSetExifOrientation3Action, 3); exifOrientationMapper->setMapping(d->imageSetExifOrientation4Action, 4); exifOrientationMapper->setMapping(d->imageSetExifOrientation5Action, 5); exifOrientationMapper->setMapping(d->imageSetExifOrientation6Action, 6); exifOrientationMapper->setMapping(d->imageSetExifOrientation7Action, 7); exifOrientationMapper->setMapping(d->imageSetExifOrientation8Action, 8); } void DigikamApp::setupImageTransformActions() { KActionCollection* const ac = actionCollection(); d->imageRotateActionMenu = new QMenu(i18n("Rotate"), this); d->imageRotateActionMenu->setIcon(QIcon::fromTheme(QLatin1String("object-rotate-right"))); QAction* const left = ac->addAction(QLatin1String("rotate_ccw")); left->setText(i18nc("rotate image left", "Left")); ac->setDefaultShortcut(left, Qt::SHIFT+Qt::CTRL+Qt::Key_Left); connect(left, SIGNAL(triggered(bool)), this, SLOT(slotTransformAction())); d->imageRotateActionMenu->addAction(left); QAction* const right = ac->addAction(QLatin1String("rotate_cw")); right->setText(i18nc("rotate image right", "Right")); ac->setDefaultShortcut(right, Qt::SHIFT+Qt::CTRL+Qt::Key_Right); connect(right, SIGNAL(triggered(bool)), this, SLOT(slotTransformAction())); d->imageRotateActionMenu->addAction(right); ac->addAction(QLatin1String("image_rotate"), d->imageRotateActionMenu->menuAction()); // ----------------------------------------------------------------------------------- d->imageFlipActionMenu = new QMenu(i18n("Flip"), this); d->imageFlipActionMenu->setIcon(QIcon::fromTheme(QLatin1String("flip-horizontal"))); QAction* const hori = ac->addAction(QLatin1String("flip_horizontal")); hori->setText(i18n("Horizontally")); ac->setDefaultShortcut(hori, Qt::CTRL+Qt::Key_Asterisk); connect(hori, SIGNAL(triggered(bool)), this, SLOT(slotTransformAction())); d->imageFlipActionMenu->addAction(hori); QAction* const verti = ac->addAction(QLatin1String("flip_vertical")); verti->setText(i18n("Vertically")); ac->setDefaultShortcut(verti, Qt::CTRL+Qt::Key_Slash); connect(verti, SIGNAL(triggered(bool)), this, SLOT(slotTransformAction())); d->imageFlipActionMenu->addAction(verti); ac->addAction(QLatin1String("image_flip"), d->imageFlipActionMenu->menuAction()); // ----------------------------------------------------------------------------------- d->imageAutoExifActionMenu = new QAction(i18n("Auto Rotate/Flip Using Exif Information"), this); connect(d->imageAutoExifActionMenu, SIGNAL(triggered(bool)), this, SLOT(slotTransformAction())); ac->addAction(QLatin1String("image_transform_exif"), d->imageAutoExifActionMenu); } void DigikamApp::populateThemes() { if (d->splashScreen) { d->splashScreen->setMessage(i18n("Loading themes...")); } ThemeManager::instance()->setThemeMenuAction(new QMenu(i18n("&Themes"), this)); ThemeManager::instance()->registerThemeActions(this); ThemeManager::instance()->setCurrentTheme(ApplicationSettings::instance()->getCurrentTheme()); connect(ThemeManager::instance(), SIGNAL(signalThemeChanged()), this, SLOT(slotThemeChanged())); } void DigikamApp::preloadWindows() { if (d->splashScreen) { d->splashScreen->setMessage(i18n("Loading tools...")); } QueueMgrWindow::queueManagerWindow(); ImageWindow::imageWindow(); LightTableWindow::lightTableWindow(); d->tagsActionManager->registerTagsActionCollections(); } void DigikamApp::initGui() { // Initialize Actions --------------------------------------- d->deleteAction->setEnabled(false); d->renameAction->setEnabled(false); d->addImagesAction->setEnabled(false); d->propsEditAction->setEnabled(false); d->openInFileManagerAction->setEnabled(false); d->imageViewAction->setEnabled(false); d->imagePreviewAction->setEnabled(false); d->imageLightTableAction->setEnabled(false); d->imageAddLightTableAction->setEnabled(false); d->imageScanForFacesAction->setEnabled(false); d->imageFindSimilarAction->setEnabled(false); d->imageRenameAction->setEnabled(false); d->imageDeleteAction->setEnabled(false); d->imageExifOrientationActionMenu->setEnabled(false); d->openWithAction->setEnabled(false); d->slideShowSelectionAction->setEnabled(false); m_metadataEditAction->setEnabled(false); d->imageAutoExifActionMenu->setEnabled(false); #ifdef HAVE_MARBLE m_geolocationEditAction->setEnabled(false); #endif d->albumSortAction->setCurrentItem((int)ApplicationSettings::instance()->getAlbumSortRole()); d->imageSortAction->setCurrentItem((int)ApplicationSettings::instance()->getImageSortOrder()); d->imageSortOrderAction->setCurrentItem((int)ApplicationSettings::instance()->getImageSorting()); d->imageSeparationAction->setCurrentItem((int)ApplicationSettings::instance()->getImageSeparationMode()-1); // no action for enum 0 d->imageSeparationSortOrderAction->setCurrentItem((int)ApplicationSettings::instance()->getImageSeparationSortOrder()); d->recurseAlbumsAction->setChecked(ApplicationSettings::instance()->getRecurseAlbums()); d->recurseTagsAction->setChecked(ApplicationSettings::instance()->getRecurseTags()); d->showBarAction->setChecked(ApplicationSettings::instance()->getShowThumbbar()); showMenuBarAction()->setChecked(!menuBar()->isHidden()); // NOTE: workaround for bug #171080 slotSwitchedToIconView(); } } // namespace Digikam diff --git a/core/app/main/digikamapp_tools.cpp b/core/app/main/digikamapp_tools.cpp index bd6efa9b45..d6447f5b40 100644 --- a/core/app/main/digikamapp_tools.cpp +++ b/core/app/main/digikamapp_tools.cpp @@ -1,227 +1,227 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2002-16-10 * Description : main digiKam interface implementation - Extra tools * * Copyright (C) 2002-2018 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "digikamapp.h" #include "digikamapp_p.h" namespace Digikam { void DigikamApp::setupSelectToolsAction() { // Create action model ActionItemModel* const actionModel = new ActionItemModel(this); actionModel->setMode(ActionItemModel::ToplevelMenuCategory | ActionItemModel::SortCategoriesByInsertionOrder); // Builtin actions QString mainCategory = i18nc("@title Main Tools", "Main Tools"); actionModel->addAction(d->ieAction, mainCategory); actionModel->addAction(d->openTagMngrAction, mainCategory); actionModel->addAction(d->bqmAction, mainCategory); actionModel->addAction(d->maintenanceAction, mainCategory); actionModel->addAction(d->ltAction, mainCategory); actionModel->addAction(d->advSearchAction, mainCategory); QString postCategory = i18nc("@title Post Processing Tools", "Post-Processing"); actionModel->addAction(m_expoBlendingAction, postCategory); actionModel->addAction(m_calendarAction, postCategory); actionModel->addAction(m_metadataEditAction, postCategory); actionModel->addAction(m_presentationAction, postCategory); actionModel->addAction(m_sendByMailAction, postCategory); actionModel->addAction(m_printCreatorAction, postCategory); actionModel->addAction(m_mediaServerAction, postCategory); #ifdef HAVE_PANORAMA actionModel->addAction(m_panoramaAction, postCategory); #endif #ifdef HAVE_MEDIAPLAYER actionModel->addAction(m_videoslideshowAction, postCategory); #endif #ifdef HAVE_HTMLGALLERY actionModel->addAction(m_htmlGalleryAction, postCategory); #endif #ifdef HAVE_MARBLE actionModel->addAction(m_geolocationEditAction, postCategory); #endif QString exportCategory = i18nc("@title Export Tools", "Export"); foreach(QAction* const ac, exportActions()) { actionModel->addAction(ac, exportCategory); } QString importCategory = i18nc("@title Import Tools", "Import"); foreach(QAction* const ac, importActions()) { actionModel->addAction(ac, importCategory); } #ifdef HAVE_KSANE actionModel->addAction(m_ksaneAction, importCategory); #endif // setup categorized view DCategorizedSortFilterProxyModel* const filterModel = actionModel->createFilterModel(); ActionCategorizedView* const selectToolsActionView = new ActionCategorizedView; selectToolsActionView->setupIconMode(); selectToolsActionView->setModel(filterModel); selectToolsActionView->adjustGridSize(); connect(selectToolsActionView, SIGNAL(clicked(QModelIndex)), actionModel, SLOT(trigger(QModelIndex))); d->view->setToolsIconView(selectToolsActionView); } void DigikamApp::slotMaintenance() { MaintenanceDlg* const dlg = new MaintenanceDlg(this); if (dlg->exec() == QDialog::Accepted) { d->maintenanceAction->setEnabled(false); MaintenanceMngr* const mngr = new MaintenanceMngr(this); connect(mngr, SIGNAL(signalComplete()), this, SLOT(slotMaintenanceDone())); mngr->setSettings(dlg->settings()); } } void DigikamApp::slotMaintenanceDone() { d->maintenanceAction->setEnabled(true); d->view->refreshView(); if (LightTableWindow::lightTableWindowCreated()) { LightTableWindow::lightTableWindow()->refreshView(); } if (QueueMgrWindow::queueManagerWindowCreated()) { QueueMgrWindow::queueManagerWindow()->refreshView(); } } void DigikamApp::slotDatabaseMigration() { DatabaseMigrationDialog dlg(this); dlg.exec(); } +void DigikamApp::slotTimeAdjust() +{ + QList urls = view()->selectedUrls(ApplicationSettings::Metadata); + + if (urls.isEmpty()) + return; + + QPointer dialog = new TimeAdjustDialog(this, new DBInfoIface(this, urls, ApplicationSettings::Metadata)); + dialog->exec(); + + delete dialog; + + // Refresh Database with new metadata from files. + CollectionScanner scanner; + + foreach(const QUrl& url, urls) + { + scanner.scanFile(url.toLocalFile(), CollectionScanner::Rescan); + ImageAttributesWatch::instance()->fileMetadataChanged(url); + } +} + void DigikamApp::slotEditMetadata() { QList urls = view()->selectedUrls(ApplicationSettings::Metadata); if (urls.isEmpty()) return; QPointer dialog = new MetadataEditDialog(QApplication::activeWindow(), urls); dialog->exec(); delete dialog; // Refresh Database with new metadata from files. CollectionScanner scanner; foreach(const QUrl& url, urls) { scanner.scanFile(url.toLocalFile(), CollectionScanner::Rescan); ImageAttributesWatch::instance()->fileMetadataChanged(url); } } void DigikamApp::slotEditGeolocation() { #ifdef HAVE_MARBLE ImageInfoList infos = d->view->selectedInfoList(ApplicationSettings::Metadata); if (infos.isEmpty()) return; TagModel* const tagModel = new TagModel(AbstractAlbumModel::IgnoreRootAlbum, this); TagPropertiesFilterModel* const filterModel = new TagPropertiesFilterModel(this); filterModel->setSourceAlbumModel(tagModel); filterModel->sort(0); QPointer dialog = new GeolocationEdit(filterModel, new DBInfoIface(this, QList(), ApplicationSettings::Tools), QApplication::activeWindow()); dialog->setItems(ImageGPS::infosToItems(infos)); dialog->exec(); delete dialog; // Refresh Database with new metadata from files. foreach(const ImageInfo& inf, infos) { ScanController::instance()->scannedInfo(inf.fileUrl().toLocalFile()); } #endif } void DigikamApp::slotPresentation() { d->view->presentation(); } void DigikamApp::slotPrintCreator() { QPointer w = new AdvPrintWizard(this, new DBInfoIface(this, QList(), ApplicationSettings::Tools)); w->exec(); delete w; } -void DigikamApp::slotTimeAdjust() -{ - QList urls = view()->selectedUrls(ApplicationSettings::Metadata); - - if (urls.isEmpty()) - return; - - QPointer dialog = new TimeAdjustDialog(this, new DBInfoIface(this, urls, ApplicationSettings::Metadata)); - dialog->exec(); - - delete dialog; - - // Refresh Database with new metadata from files. - CollectionScanner scanner; - - foreach(const QUrl& url, urls) - { - scanner.scanFile(url.toLocalFile(), CollectionScanner::Rescan); - ImageAttributesWatch::instance()->fileMetadataChanged(url); - } -} - } // namespace Digikam diff --git a/core/utilities/lighttable/lighttablewindow.h b/core/utilities/lighttable/lighttablewindow.h index 8246c1f3f3..00501782da 100644 --- a/core/utilities/lighttable/lighttablewindow.h +++ b/core/utilities/lighttable/lighttablewindow.h @@ -1,231 +1,232 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2007-03-05 * Description : digiKam light table GUI * * Copyright (C) 2007-2018 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #ifndef DIGIKAM_LIGHT_TABLE_WINDOW_H #define DIGIKAM_LIGHT_TABLE_WINDOW_H // Qt includes #include #include #include // Local includes #include "dxmlguiwindow.h" #include "imageinfo.h" namespace Digikam { class SlideShowSettings; class LightTableWindow : public DXmlGuiWindow { Q_OBJECT public: ~LightTableWindow(); static LightTableWindow* lightTableWindow(); static bool lightTableWindowCreated(); void loadImageInfos(const ImageInfoList& list, const ImageInfo& imageInfoCurrent, bool addTo); void setLeftRightItems(const ImageInfoList& list, bool addTo); void refreshView(); bool isEmpty() const; void toggleTag(int tagID); Q_SIGNALS: void signalWindowHasMoved(); public Q_SLOTS: void slotFileChanged(const QString& filePath); void slotAssignPickLabel(int pickId); void slotAssignColorLabel(int colorId); void slotAssignRating(int rating); protected: void moveEvent(QMoveEvent* e); private: void customizedFullScreenMode(bool set); void showSideBars(bool visible); void closeEvent(QCloseEvent* e); void showEvent(QShowEvent*); void deleteItem(bool permanently); void deleteItem(const ImageInfo& info, bool permanently); LightTableWindow(); private Q_SLOTS: void slotBackward(); void slotForward(); void slotFirst(); void slotLast(); void slotSetItemLeft(); void slotSetItemRight(); void slotSetItemOnLeftPanel(const ImageInfo&); void slotSetItemOnRightPanel(const ImageInfo&); void slotLeftDroppedItems(const ImageInfoList&); void slotRightDroppedItems(const ImageInfoList&); void slotLeftPanelLeftButtonClicked(); void slotRightPanelLeftButtonClicked(); void slotLeftPreviewLoaded(bool); void slotRightPreviewLoaded(bool); void slotLeftZoomFactorChanged(double); void slotRightZoomFactorChanged(double); void slotToggleOnSyncPreview(bool); void slotToggleSyncPreview(); void slotToggleNavigateByPair(); void slotDeleteItem(); void slotDeleteItem(const ImageInfo&); void slotDeleteFinalItem(); void slotDeleteFinalItem(const ImageInfo&); void slotRemoveItem(); void slotRemoveItem(const ImageInfo&); void slotItemSelected(const ImageInfo&); void slotClearItemsList(); void slotThumbbarDroppedItems(const QList&); void slotToggleColorManagedView(); void slotComponentsInfo(); void slotDBStat(); void slotFileWithDefaultApplication(); void slotRefreshStatusBar(); void slotToggleLeftSideBar(); void slotToggleRightSideBar(); void slotPreviousLeftSideBarTab(); void slotNextLeftSideBarTab(); void slotPreviousRightSideBarTab(); void slotNextRightSideBarTab(); void slotRightSideBarActivateTitles(); void slotRightSideBarActivateComments(); void slotRightSideBarActivateAssignedTags(); void slotLeftSideBarActivateTitles(); void slotLeftSideBarActivateComments(); void slotLeftSideBarActivateAssignedTags(); // -- Internal setup methods implemented in lighttablewindow_config.cpp ---------------------------------------- public: void applySettings(); private: void readSettings(); void writeSettings(); public Q_SLOTS: void slotSetup(); void slotColorManagementOptionsChanged(); void slotThemeChanged(); void slotApplicationSettingsChanged(); // -- Internal setup methods implemented in lighttablewindow_setup.cpp ---------------------------------------- private: void setupActions(); void setupConnections(); void setupUserArea(); void setupStatusBar(); // -- Extra tool methods implemented in lighttablewindow_tools.cpp ---------------------------------------- private Q_SLOTS: void slotEditItem(); void slotEditItem(const ImageInfo&); - + + void slotTimeAdjust(); void slotEditMetadata(); void slotEditGeolocation(); void slotPrintCreator(); void slotPresentation(); void slotSlideShowAll(); void slotLeftSlideShowManualFromCurrent(); void slotRightSlideShowManualFromCurrent(); void slotSlideShowLastItemUrl(const QUrl&); void slotSlideShowManualFrom(const ImageInfo&); void slotSlideShowBuilderComplete(const SlideShowSettings&); // -- Export tools methods implemented in lighttablewindow_export.cpp ------------------------------------- private Q_SLOTS: void slotHtmlGallery(); void slotCalendar(); void slotExpoBlending(); void slotPanorama(); void slotVideoSlideshow(); void slotSendByMail(); void slotMediaServer(); void slotExportTool(); // -- Import tools methods implemented in lighttablewindow_import.cpp ------------------------------------- private Q_SLOTS: void slotImportFromScanner(); void slotImportedImagefromScanner(const QUrl& url); void slotImportTool(); // -- Internal private container -------------------------------------------------------------------- private: class Private; Private* const d; static LightTableWindow* m_instance; }; } // namespace Digikam #endif // DIGIKAM_LIGHT_TABLE_WINDOW_H diff --git a/core/utilities/lighttable/lighttablewindow_p.h b/core/utilities/lighttable/lighttablewindow_p.h index a7a2125cbb..55172c3fde 100644 --- a/core/utilities/lighttable/lighttablewindow_p.h +++ b/core/utilities/lighttable/lighttablewindow_p.h @@ -1,227 +1,228 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2007-03-05 * Description : digiKam light table GUI * * Copyright (C) 2007-2018 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #ifndef DIGIKAM_LIGHT_TABLE_WINDOW_PRIVATE_H #define DIGIKAM_LIGHT_TABLE_WINDOW_PRIVATE_H // Qt includes #include #include #include #include #include #include #include #include #include // KDE includes #include #include // Local includes #include "digikam_globals.h" #include "imagepropertiessidebardb.h" #include "statusprogressbar.h" #include "dzoombar.h" #include "lighttableview.h" #include "lighttablethumbbar.h" #include "thumbbardock.h" #include "drawdecoder.h" #include "digikam_debug.h" #include "componentsinfo.h" #include "digikamapp.h" #include "thememanager.h" #include "dimg.h" #include "dio.h" #include "dmetadata.h" #include "dfileoperations.h" #include "metadatasettings.h" #include "metadataedit.h" #include "applicationsettings.h" #include "albummanager.h" #include "loadingcacheinterface.h" #include "deletedialog.h" #include "iccsettings.h" #include "imagewindow.h" #include "imagegps.h" #include "imagedescedittab.h" #include "presentationmngr.h" #include "slideshowbuilder.h" #include "slideshow.h" #include "setup.h" #include "syncjob.h" #include "lighttablepreview.h" #include "albummodel.h" #include "albumfiltermodel.h" #include "coredbchangesets.h" #include "collectionscanner.h" #include "scancontroller.h" #include "tagsactionmngr.h" #include "thumbnailsize.h" #include "thumbnailloadthread.h" #include "dexpanderbox.h" #include "dbinfoiface.h" #include "calwizard.h" #include "expoblendingmanager.h" #include "mailwizard.h" #include "advprintwizard.h" #include "dmediaserverdlg.h" +#include "timeadjustdialog.h" #include "wsstarter.h" #ifdef HAVE_MARBLE # include "geolocationedit.h" #endif #ifdef HAVE_HTMLGALLERY # include "htmlwizard.h" #endif #ifdef HAVE_PANORAMA # include "panomanager.h" #endif #ifdef HAVE_MEDIAPLAYER # include "vidslidewizard.h" #endif namespace Digikam { class DAdjustableLabel; class Q_DECL_HIDDEN LightTableWindow::Private { public: Private() : autoLoadOnRightPanel(true), autoSyncPreview(true), fromLeftPreview(true), setItemLeftAction(0), setItemRightAction(0), clearListAction(0), editItemAction(0), removeItemAction(0), fileDeleteAction(0), fileDeleteFinalAction(0), slideShowAction(0), leftZoomPlusAction(0), leftZoomMinusAction(0), leftZoomTo100percents(0), leftZoomFitToWindowAction(0), rightZoomPlusAction(0), rightZoomMinusAction(0), rightZoomTo100percents(0), rightZoomFitToWindowAction(0), forwardAction(0), backwardAction(0), firstAction(0), lastAction(0), showBarAction(0), viewCMViewAction(0), syncPreviewAction(0), navigateByPairAction(0), clearOnCloseAction(0), leftFileName(0), rightFileName(0), hSplitter(0), barViewDock(0), thumbView(0), previewView(0), leftZoomBar(0), rightZoomBar(0), statusProgressBar(0), leftSideBar(0), rightSideBar(0) { } void addPageUpDownActions(LightTableWindow* const q, QWidget* const w) { defineShortcut(w, Qt::Key_Down, q, SLOT(slotForward())); defineShortcut(w, Qt::Key_Right, q, SLOT(slotForward())); defineShortcut(w, Qt::Key_Up, q, SLOT(slotBackward())); defineShortcut(w, Qt::Key_Left, q, SLOT(slotBackward())); } public: bool autoLoadOnRightPanel; bool autoSyncPreview; bool fromLeftPreview; QAction* setItemLeftAction; QAction* setItemRightAction; QAction* clearListAction; QAction* editItemAction; QAction* removeItemAction; QAction* fileDeleteAction; QAction* fileDeleteFinalAction; QAction* slideShowAction; QAction* leftZoomPlusAction; QAction* leftZoomMinusAction; QAction* leftZoomTo100percents; QAction* leftZoomFitToWindowAction; QAction* rightZoomPlusAction; QAction* rightZoomMinusAction; QAction* rightZoomTo100percents; QAction* rightZoomFitToWindowAction; QAction* forwardAction; QAction* backwardAction; QAction* firstAction; QAction* lastAction; QAction* showBarAction; QAction* viewCMViewAction; QAction* syncPreviewAction; QAction* navigateByPairAction; QAction* clearOnCloseAction; DAdjustableLabel* leftFileName; DAdjustableLabel* rightFileName; SidebarSplitter* hSplitter; ThumbBarDock* barViewDock; LightTableThumbBar* thumbView; LightTableView* previewView; DZoomBar* leftZoomBar; DZoomBar* rightZoomBar; StatusProgressBar* statusProgressBar; ImagePropertiesSideBarDB* leftSideBar; ImagePropertiesSideBarDB* rightSideBar; }; } // namespace Digikam #endif // DIGIKAM_LIGHT_TABLE_WINDOW_PRIVATE_H diff --git a/core/utilities/lighttable/lighttablewindow_setup.cpp b/core/utilities/lighttable/lighttablewindow_setup.cpp index f4894dc7e6..71144db7df 100644 --- a/core/utilities/lighttable/lighttablewindow_setup.cpp +++ b/core/utilities/lighttable/lighttablewindow_setup.cpp @@ -1,484 +1,485 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2004-11-22 * Description : digiKam light table - Configure * * Copyright (C) 2007-2018 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "lighttablewindow.h" #include "lighttablewindow_p.h" namespace Digikam { void LightTableWindow::setupActions() { // -- Standard 'File' menu actions --------------------------------------------- KActionCollection* const ac = actionCollection(); d->backwardAction = buildStdAction(StdBackAction, this, SLOT(slotBackward()), this); ac->addAction(QLatin1String("lighttable_backward"), d->backwardAction); ac->setDefaultShortcuts(d->backwardAction, QList() << Qt::Key_PageUp << Qt::Key_Backspace); d->forwardAction = buildStdAction(StdForwardAction, this, SLOT(slotForward()), this); ac->addAction(QLatin1String("lighttable_forward"), d->forwardAction); ac->setDefaultShortcuts(d->forwardAction, QList() << Qt::Key_PageDown << Qt::Key_Space); d->forwardAction->setEnabled(false); d->firstAction = new QAction(QIcon::fromTheme(QLatin1String("go-first")), i18n("&First"), this); d->firstAction->setEnabled(false); connect(d->firstAction, SIGNAL(triggered()), this, SLOT(slotFirst())); ac->addAction(QLatin1String("lighttable_first"), d->firstAction); ac->setDefaultShortcuts(d->firstAction, QList() << Qt::CTRL + Qt::Key_Home); d->lastAction = new QAction(QIcon::fromTheme(QLatin1String("go-last")), i18n("&Last"), this); d->lastAction->setEnabled(false); connect(d->lastAction, SIGNAL(triggered()), this, SLOT(slotLast())); ac->addAction(QLatin1String("lighttable_last"), d->lastAction); ac->setDefaultShortcuts(d->lastAction, QList() << Qt::CTRL + Qt::Key_End); d->setItemLeftAction = new QAction(QIcon::fromTheme(QLatin1String("go-previous")), i18n("On left"), this); d->setItemLeftAction->setEnabled(false); d->setItemLeftAction->setWhatsThis(i18n("Show item on left panel")); connect(d->setItemLeftAction, SIGNAL(triggered()), this, SLOT(slotSetItemLeft())); ac->addAction(QLatin1String("lighttable_setitemleft"), d->setItemLeftAction); ac->setDefaultShortcut(d->setItemLeftAction, Qt::CTRL + Qt::Key_L); d->setItemRightAction = new QAction(QIcon::fromTheme(QLatin1String("go-next")), i18n("On right"), this); d->setItemRightAction->setEnabled(false); d->setItemRightAction->setWhatsThis(i18n("Show item on right panel")); connect(d->setItemRightAction, SIGNAL(triggered()), this, SLOT(slotSetItemRight())); ac->addAction(QLatin1String("lighttable_setitemright"), d->setItemRightAction); ac->setDefaultShortcut(d->setItemRightAction, Qt::CTRL + Qt::Key_R); d->editItemAction = new QAction(QIcon::fromTheme(QLatin1String("document-edit")), i18n("Edit"), this); d->editItemAction->setEnabled(false); connect(d->editItemAction, SIGNAL(triggered()), this, SLOT(slotEditItem())); ac->addAction(QLatin1String("lighttable_edititem"), d->editItemAction); ac->setDefaultShortcut(d->editItemAction, Qt::Key_F4); QAction* const openWithAction = new QAction(QIcon::fromTheme(QLatin1String("preferences-desktop-filetype-association")), i18n("Open With Default Application"), this); openWithAction->setWhatsThis(i18n("Open the item with default assigned application.")); connect(openWithAction, SIGNAL(triggered()), this, SLOT(slotFileWithDefaultApplication())); ac->addAction(QLatin1String("open_with_default_application"), openWithAction); ac->setDefaultShortcut(openWithAction, Qt::META + Qt::Key_F4); d->removeItemAction = new QAction(QIcon::fromTheme(QLatin1String("list-remove")), i18n("Remove item from LightTable"), this); d->removeItemAction->setEnabled(false); connect(d->removeItemAction, SIGNAL(triggered()), this, SLOT(slotRemoveItem())); ac->addAction(QLatin1String("lighttable_removeitem"), d->removeItemAction); ac->setDefaultShortcut(d->removeItemAction, Qt::CTRL + Qt::Key_K); d->clearListAction = new QAction(QIcon::fromTheme(QLatin1String("edit-clear")), i18n("Remove all items from LightTable"), this); d->clearListAction->setEnabled(false); connect(d->clearListAction, SIGNAL(triggered()), this, SLOT(slotClearItemsList())); ac->addAction(QLatin1String("lighttable_clearlist"), d->clearListAction); ac->setDefaultShortcut(d->clearListAction, Qt::CTRL + Qt::SHIFT + Qt::Key_K); d->fileDeleteAction = new QAction(QIcon::fromTheme(QLatin1String("user-trash")), i18nc("Non-pluralized", "Move to Trash"), this); d->fileDeleteAction->setEnabled(false); connect(d->fileDeleteAction, SIGNAL(triggered()), this, SLOT(slotDeleteItem())); ac->addAction(QLatin1String("lighttable_filedelete"), d->fileDeleteAction); ac->setDefaultShortcut(d->fileDeleteAction, Qt::Key_Delete); d->fileDeleteFinalAction = new QAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18n("Delete immediately"), this); d->fileDeleteFinalAction->setEnabled(false); connect(d->fileDeleteFinalAction, SIGNAL(triggered()), this, SLOT(slotDeleteFinalItem())); ac->addAction(QLatin1String("lighttable_filefinaldelete"), d->fileDeleteFinalAction); ac->setDefaultShortcut(d->fileDeleteFinalAction, Qt::SHIFT + Qt::Key_Delete); QAction* const closeAction = buildStdAction(StdCloseAction, this, SLOT(close()), this); ac->addAction(QLatin1String("lighttable_close"), closeAction); // -- Standard 'View' menu actions --------------------------------------------- d->syncPreviewAction = new QAction(QIcon::fromTheme(QLatin1String("view-split-left-right")), i18n("Synchronize"), this); d->syncPreviewAction->setEnabled(false); d->syncPreviewAction->setCheckable(true); d->syncPreviewAction->setWhatsThis(i18n("Synchronize preview from left and right panels")); connect(d->syncPreviewAction, SIGNAL(triggered()), this, SLOT(slotToggleSyncPreview())); ac->addAction(QLatin1String("lighttable_syncpreview"), d->syncPreviewAction); ac->setDefaultShortcut(d->syncPreviewAction, Qt::CTRL + Qt::SHIFT + Qt::Key_Y); d->navigateByPairAction = new QAction(QIcon::fromTheme(QLatin1String("system-run")), i18n("By Pair"), this); d->navigateByPairAction->setEnabled(false); d->navigateByPairAction->setCheckable(true); d->navigateByPairAction->setWhatsThis(i18n("Navigate by pairs with all items")); connect(d->navigateByPairAction, SIGNAL(triggered()), this, SLOT(slotToggleNavigateByPair())); ac->addAction(QLatin1String("lighttable_navigatebypair"), d->navigateByPairAction); ac->setDefaultShortcut(d->navigateByPairAction, Qt::CTRL + Qt::SHIFT + Qt::Key_P); d->clearOnCloseAction = new QAction(QIcon::fromTheme(QLatin1String("edit-clear")), i18n("Clear On Close"), this); d->clearOnCloseAction->setEnabled(true); d->clearOnCloseAction->setCheckable(true); d->clearOnCloseAction->setToolTip(i18n("Clear light table when it is closed")); d->clearOnCloseAction->setWhatsThis(i18n("Remove all images from the light table when it is closed")); ac->addAction(QLatin1String("lighttable_clearonclose"), d->clearOnCloseAction); ac->setDefaultShortcut(d->clearOnCloseAction, Qt::CTRL + Qt::SHIFT + Qt::Key_C); d->showBarAction = d->barViewDock->getToggleAction(this); ac->addAction(QLatin1String("lighttable_showthumbbar"), d->showBarAction); ac->setDefaultShortcut(d->showBarAction, Qt::CTRL + Qt::Key_T); createFullScreenAction(QLatin1String("lighttable_fullscreen")); createSidebarActions(); d->slideShowAction = new QAction(QIcon::fromTheme(QLatin1String("view-presentation")), i18n("Slideshow"), this); connect(d->slideShowAction, SIGNAL(triggered()), this, SLOT(slotSlideShowAll())); ac->addAction(QLatin1String("lighttable_slideshow"), d->slideShowAction); ac->setDefaultShortcut(d->slideShowAction, Qt::Key_F9); createPresentationAction(); // -- Standard 'Tools' menu actions ------------------------ + createTimeAdjustAction(); createMetadataEditAction(); createGeolocationEditAction(); createHtmlGalleryAction(); createPanoramaAction(); createExpoBlendingAction(); createCalendarAction(); createVideoSlideshowAction(); createSendByMailAction(); createPrintCreatorAction(); createMediaServerAction(); createExportActions(); createImportActions(); // Left Panel Zoom Actions d->leftZoomPlusAction = buildStdAction(StdZoomInAction, d->previewView, SLOT(slotIncreaseLeftZoom()), this); d->leftZoomPlusAction->setEnabled(false); QKeySequence leftKeysPlus(d->leftZoomPlusAction->shortcut()[0], Qt::Key_Plus); ac->addAction(QLatin1String("lighttable_zoomplus_left"), d->leftZoomPlusAction); ac->setDefaultShortcut(d->leftZoomPlusAction, leftKeysPlus); d->leftZoomMinusAction = buildStdAction(StdZoomOutAction, d->previewView, SLOT(slotDecreaseLeftZoom()), this); d->leftZoomMinusAction->setEnabled(false); QKeySequence leftKeysMinus(d->leftZoomMinusAction->shortcut()[0], Qt::Key_Minus); ac->addAction(QLatin1String("lighttable_zoomminus_left"), d->leftZoomMinusAction); ac->setDefaultShortcut(d->leftZoomMinusAction, leftKeysMinus); d->leftZoomTo100percents = new QAction(QIcon::fromTheme(QLatin1String("zoom-original")), i18n("Zoom to 100%"), this); connect(d->leftZoomTo100percents, SIGNAL(triggered()), d->previewView, SLOT(slotLeftZoomTo100())); ac->addAction(QLatin1String("lighttable_zoomto100percents_left"), d->leftZoomTo100percents); ac->setDefaultShortcut(d->leftZoomTo100percents, Qt::CTRL + Qt::Key_Period); d->leftZoomFitToWindowAction = new QAction(QIcon::fromTheme(QLatin1String("zoom-fit-best")), i18n("Fit to &Window"), this); connect(d->leftZoomFitToWindowAction, SIGNAL(triggered()), d->previewView, SLOT(slotLeftFitToWindow())); ac->addAction(QLatin1String("lighttable_zoomfit2window_left"), d->leftZoomFitToWindowAction); ac->setDefaultShortcut(d->leftZoomFitToWindowAction, Qt::ALT + Qt::CTRL + Qt::Key_E); // Right Panel Zoom Actions d->rightZoomPlusAction = buildStdAction(StdZoomInAction, d->previewView, SLOT(slotIncreaseRightZoom()), this); d->rightZoomPlusAction->setEnabled(false); QKeySequence rightKeysPlus(d->rightZoomPlusAction->shortcut()[0], Qt::SHIFT + Qt::CTRL + Qt::Key_Plus, Qt::SHIFT + Qt::Key_Plus); ac->addAction(QLatin1String("lighttable_zoomplus_right"), d->rightZoomPlusAction); ac->setDefaultShortcut(d->rightZoomPlusAction, rightKeysPlus); d->rightZoomMinusAction = buildStdAction(StdZoomOutAction, d->previewView, SLOT(slotDecreaseRightZoom()), this); d->rightZoomMinusAction->setEnabled(false); QKeySequence rightKeysMinus(d->rightZoomMinusAction->shortcut()[0], Qt::SHIFT + Qt::CTRL + Qt::Key_Minus, Qt::SHIFT + Qt::Key_Minus); ac->addAction(QLatin1String("lighttable_zoomminus_right"), d->rightZoomMinusAction); ac->setDefaultShortcut(d->rightZoomMinusAction, rightKeysMinus); d->rightZoomTo100percents = new QAction(QIcon::fromTheme(QLatin1String("zoom-original")), i18n("Zoom to 100%"), this); connect(d->rightZoomTo100percents, SIGNAL(triggered()), d->previewView, SLOT(slotRightZoomTo100())); ac->addAction(QLatin1String("lighttable_zoomto100percents_right"), d->rightZoomTo100percents); ac->setDefaultShortcut(d->rightZoomTo100percents, Qt::SHIFT + Qt::CTRL + Qt::Key_Period); d->rightZoomFitToWindowAction = new QAction(QIcon::fromTheme(QLatin1String("zoom-fit-best")), i18n("Fit to &Window"), this); connect(d->rightZoomFitToWindowAction, SIGNAL(triggered()), d->previewView, SLOT(slotRightFitToWindow())); ac->addAction(QLatin1String("lighttable_zoomfit2window_right"), d->rightZoomFitToWindowAction); ac->setDefaultShortcut(d->rightZoomFitToWindowAction, Qt::SHIFT + Qt::CTRL + Qt::Key_E); // ----------------------------------------------------------- d->viewCMViewAction = new QAction(QIcon::fromTheme(QLatin1String("video-display")), i18n("Color-Managed View"), this); d->viewCMViewAction->setCheckable(true); connect(d->viewCMViewAction, SIGNAL(triggered()), this, SLOT(slotToggleColorManagedView())); ac->addAction(QLatin1String("color_managed_view"), d->viewCMViewAction); ac->setDefaultShortcut(d->viewCMViewAction, Qt::Key_F12); // ----------------------------------------------------------------------------- ThemeManager::instance()->registerThemeActions(this); // Standard 'Help' menu actions createHelpActions(); // Provides a menu entry that allows showing/hiding the toolbar(s) setStandardToolBarMenuEnabled(true); // Provides a menu entry that allows showing/hiding the statusbar createStandardStatusBarAction(); // Standard 'Configure' menu actions createSettingsActions(); // -- Keyboard-only actions ---------------------------------------------------- d->addPageUpDownActions(this, this); QAction* const altBackwardAction = new QAction(i18n("Previous Image"), this); ac->addAction(QLatin1String("lighttable_backward_shift_space"), altBackwardAction); ac->setDefaultShortcut(altBackwardAction, Qt::SHIFT + Qt::Key_Space); connect(altBackwardAction, SIGNAL(triggered()), this, SLOT(slotBackward())); // Labels shortcuts must be registered here to be saved in XML GUI files if user customize it. TagsActionMngr::defaultManager()->registerLabelsActions(ac); QAction* const editTitlesRight = new QAction(i18n("Edit Titles on the Right"), this); ac->addAction(QLatin1String("edit_titles_right"), editTitlesRight); ac->setDefaultShortcut(editTitlesRight, Qt::META + Qt::Key_T); connect(editTitlesRight, SIGNAL(triggered()), this, SLOT(slotRightSideBarActivateTitles())); QAction* const editCommentsRight = new QAction(i18n("Edit Comments on the Right"), this); ac->addAction(QLatin1String("edit_comments_right"), editCommentsRight); ac->setDefaultShortcut(editCommentsRight, Qt::META + Qt::Key_C); connect(editCommentsRight, SIGNAL(triggered()), this, SLOT(slotRightSideBarActivateComments())); QAction* const editTitlesLeft = new QAction(i18n("Edit Titles on the Left"), this); ac->addAction(QLatin1String("edit_titles_left"), editTitlesLeft); ac->setDefaultShortcut(editTitlesLeft, Qt::SHIFT + Qt::META + Qt::Key_T); connect(editTitlesLeft, SIGNAL(triggered()), this, SLOT(slotLeftSideBarActivateTitles())); QAction* const editCommentsLeft = new QAction(i18n("Edit Comments on the Left"), this); ac->addAction(QLatin1String("edit_comments_left"), editCommentsLeft); ac->setDefaultShortcut(editCommentsLeft, Qt::SHIFT + Qt::META + Qt::Key_C); connect(editCommentsLeft, SIGNAL(triggered()), this, SLOT(slotLeftSideBarActivateComments())); QAction* const assignedTagsRight = new QAction(i18n("Show Assigned Tags on the Right"), this); ac->addAction(QLatin1String("assigned _tags_right"), assignedTagsRight); ac->setDefaultShortcut(assignedTagsRight, Qt::META + Qt::Key_A); connect(assignedTagsRight, SIGNAL(triggered()), this, SLOT(slotRightSideBarActivateAssignedTags())); QAction* const assignedTagsLeft = new QAction(i18n("Show Assigned Tags on the Left"), this); ac->addAction(QLatin1String("assigned _tags_left"), assignedTagsLeft); ac->setDefaultShortcut(assignedTagsLeft, Qt::SHIFT + Qt::META + Qt::Key_A); connect(assignedTagsLeft, SIGNAL(triggered()), this, SLOT(slotLeftSideBarActivateAssignedTags())); // --------------------------------------------------------------------------------- createGUI(xmlFile()); cleanupActions(); showMenuBarAction()->setChecked(!menuBar()->isHidden()); // NOTE: workaround for bug #171080 } void LightTableWindow::setupStatusBar() { d->leftZoomBar = new DZoomBar(statusBar()); d->leftZoomBar->setZoomToFitAction(d->leftZoomFitToWindowAction); d->leftZoomBar->setZoomTo100Action(d->leftZoomTo100percents); d->leftZoomBar->setZoomPlusAction(d->leftZoomPlusAction); d->leftZoomBar->setZoomMinusAction(d->leftZoomMinusAction); d->leftZoomBar->setBarMode(DZoomBar::PreviewZoomCtrl); d->leftZoomBar->setEnabled(false); statusBar()->addWidget(d->leftZoomBar, 1); d->leftFileName = new DAdjustableLabel(statusBar()); d->leftFileName->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); statusBar()->addWidget(d->leftFileName, 10); d->statusProgressBar = new StatusProgressBar(statusBar()); d->statusProgressBar->setAlignment(Qt::AlignCenter); statusBar()->addWidget(d->statusProgressBar, 10); d->rightFileName = new DAdjustableLabel(statusBar()); d->rightFileName->setAlignment(Qt::AlignRight | Qt::AlignVCenter); statusBar()->addWidget(d->rightFileName, 10); d->rightZoomBar = new DZoomBar(statusBar()); d->rightZoomBar->setZoomToFitAction(d->rightZoomFitToWindowAction); d->rightZoomBar->setZoomTo100Action(d->rightZoomTo100percents); d->rightZoomBar->setZoomPlusAction(d->rightZoomPlusAction); d->rightZoomBar->setZoomMinusAction(d->rightZoomMinusAction); d->rightZoomBar->setBarMode(DZoomBar::PreviewZoomCtrl); d->rightZoomBar->setEnabled(false); statusBar()->addWidget(d->rightZoomBar, 1); } void LightTableWindow::setupConnections() { connect(ApplicationSettings::instance(), SIGNAL(setupChanged()), this, SLOT(slotApplicationSettingsChanged())); connect(ThemeManager::instance(), SIGNAL(signalThemeChanged()), this, SLOT(slotThemeChanged())); connect(IccSettings::instance(), SIGNAL(settingsChanged()), this, SLOT(slotColorManagementOptionsChanged())); // Thumbs bar connections --------------------------------------- connect(d->thumbView, SIGNAL(signalSetItemOnLeftPanel(ImageInfo)), this, SLOT(slotSetItemOnLeftPanel(ImageInfo))); connect(d->thumbView, SIGNAL(signalSetItemOnRightPanel(ImageInfo)), this, SLOT(slotSetItemOnRightPanel(ImageInfo))); connect(d->thumbView, SIGNAL(signalRemoveItem(ImageInfo)), this, SLOT(slotRemoveItem(ImageInfo))); connect(d->thumbView, SIGNAL(signalEditItem(ImageInfo)), this, SLOT(slotEditItem(ImageInfo))); connect(d->thumbView, SIGNAL(signalClearAll()), this, SLOT(slotClearItemsList())); connect(d->thumbView, SIGNAL(signalDroppedItems(QList)), this, SLOT(slotThumbbarDroppedItems(QList))); connect(d->thumbView, SIGNAL(currentChanged(ImageInfo)), this, SLOT(slotItemSelected(ImageInfo))); connect(d->thumbView, SIGNAL(signalContentChanged()), this, SLOT(slotRefreshStatusBar())); // Zoom bars connections ----------------------------------------- connect(d->leftZoomBar, SIGNAL(signalZoomSliderChanged(int)), d->previewView, SLOT(slotLeftZoomSliderChanged(int))); connect(d->leftZoomBar, SIGNAL(signalZoomValueEdited(double)), d->previewView, SLOT(setLeftZoomFactor(double))); connect(d->rightZoomBar, SIGNAL(signalZoomSliderChanged(int)), d->previewView, SLOT(slotRightZoomSliderChanged(int))); connect(d->rightZoomBar, SIGNAL(signalZoomValueEdited(double)), d->previewView, SLOT(setRightZoomFactor(double))); // View connections --------------------------------------------- connect(d->previewView, SIGNAL(signalLeftPopupTagsView()), d->leftSideBar, SLOT(slotPopupTagsView())); connect(d->previewView, SIGNAL(signalRightPopupTagsView()), d->rightSideBar, SLOT(slotPopupTagsView())); connect(d->previewView, SIGNAL(signalLeftZoomFactorChanged(double)), this, SLOT(slotLeftZoomFactorChanged(double))); connect(d->previewView, SIGNAL(signalRightZoomFactorChanged(double)), this, SLOT(slotRightZoomFactorChanged(double))); connect(d->previewView, SIGNAL(signalEditItem(ImageInfo)), this, SLOT(slotEditItem(ImageInfo))); connect(d->previewView, SIGNAL(signalDeleteItem(ImageInfo)), this, SLOT(slotDeleteItem(ImageInfo))); connect(d->previewView, SIGNAL(signalLeftSlideShowCurrent()), this, SLOT(slotLeftSlideShowManualFromCurrent())); connect(d->previewView, SIGNAL(signalRightSlideShowCurrent()), this, SLOT(slotRightSlideShowManualFromCurrent())); connect(d->previewView, SIGNAL(signalLeftDroppedItems(ImageInfoList)), this, SLOT(slotLeftDroppedItems(ImageInfoList))); connect(d->previewView, SIGNAL(signalRightDroppedItems(ImageInfoList)), this, SLOT(slotRightDroppedItems(ImageInfoList))); connect(d->previewView, SIGNAL(signalToggleOnSyncPreview(bool)), this, SLOT(slotToggleOnSyncPreview(bool))); connect(d->previewView, SIGNAL(signalLeftPreviewLoaded(bool)), this, SLOT(slotLeftPreviewLoaded(bool))); connect(d->previewView, SIGNAL(signalRightPreviewLoaded(bool)), this, SLOT(slotRightPreviewLoaded(bool))); connect(d->previewView, SIGNAL(signalLeftPanelLeftButtonClicked()), this, SLOT(slotLeftPanelLeftButtonClicked())); connect(d->previewView, SIGNAL(signalRightPanelLeftButtonClicked()), this, SLOT(slotRightPanelLeftButtonClicked())); connect(this, SIGNAL(signalWindowHasMoved()), d->leftZoomBar, SLOT(slotUpdateTrackerPos())); connect(this, SIGNAL(signalWindowHasMoved()), d->rightZoomBar, SLOT(slotUpdateTrackerPos())); // -- FileWatch connections ------------------------------ LoadingCacheInterface::connectToSignalFileChanged(this, SLOT(slotFileChanged(QString))); } void LightTableWindow::setupUserArea() { QWidget* const mainW = new QWidget(this); d->hSplitter = new SidebarSplitter(Qt::Horizontal, mainW); QHBoxLayout* const hlay = new QHBoxLayout(mainW); // The left sidebar d->leftSideBar = new ImagePropertiesSideBarDB(mainW, d->hSplitter, Qt::LeftEdge, true); // The central preview is wrapped in a KMainWindow so that the thumbnail // bar can float around it. KMainWindow* const viewContainer = new KMainWindow(mainW, Qt::Widget); d->hSplitter->addWidget(viewContainer); d->previewView = new LightTableView(viewContainer); viewContainer->setCentralWidget(d->previewView); // The right sidebar. d->rightSideBar = new ImagePropertiesSideBarDB(mainW, d->hSplitter, Qt::RightEdge, true); hlay->addWidget(d->leftSideBar); hlay->addWidget(d->hSplitter); hlay->addWidget(d->rightSideBar); hlay->setSpacing(0); hlay->setContentsMargins(QMargins()); hlay->setStretchFactor(d->hSplitter, 10); d->hSplitter->setFrameStyle(QFrame::NoFrame); d->hSplitter->setFrameShadow(QFrame::Plain); d->hSplitter->setFrameShape(QFrame::NoFrame); d->hSplitter->setOpaqueResize(false); d->hSplitter->setStretchFactor(1, 10); // set previewview+thumbbar container default size to max. // The thumb bar is placed in a detachable/dockable widget. d->barViewDock = new ThumbBarDock(viewContainer, Qt::Tool); d->barViewDock->setObjectName(QLatin1String("lighttable_thumbbar")); d->barViewDock->setWindowTitle(i18n("Light Table Thumbnail Dock")); d->thumbView = new LightTableThumbBar(d->barViewDock); d->barViewDock->setWidget(d->thumbView); viewContainer->addDockWidget(Qt::TopDockWidgetArea, d->barViewDock); d->barViewDock->setFloating(false); // Restore the previous state. This doesn't emit the proper signals to the // dock widget, so it has to be manually reinitialized. viewContainer->setAutoSaveSettings(QLatin1String("LightTable Thumbbar"), true); connect(d->barViewDock, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), d->thumbView, SLOT(slotDockLocationChanged(Qt::DockWidgetArea))); d->barViewDock->reInitialize(); setCentralWidget(mainW); } } // namespace Digikam diff --git a/core/utilities/lighttable/lighttablewindow_tools.cpp b/core/utilities/lighttable/lighttablewindow_tools.cpp index 4afb881323..b184d34311 100644 --- a/core/utilities/lighttable/lighttablewindow_tools.cpp +++ b/core/utilities/lighttable/lighttablewindow_tools.cpp @@ -1,218 +1,239 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2004-11-22 * Description : digiKam light table - Extra tools * * Copyright (C) 2007-2018 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "lighttablewindow.h" #include "lighttablewindow_p.h" namespace Digikam { void LightTableWindow::slotEditItem() { if (!d->thumbView->currentInfo().isNull()) { slotEditItem(d->thumbView->currentInfo()); } } void LightTableWindow::slotEditItem(const ImageInfo& info) { ImageWindow* const im = ImageWindow::imageWindow(); ImageInfoList list = d->thumbView->allImageInfos(); im->loadImageInfos(list, info, i18n("Light Table")); if (im->isHidden()) { im->show(); } else { im->raise(); } im->setFocus(); } +void LightTableWindow::slotTimeAdjust() +{ + QList urls = d->thumbView->allUrls(); + + if (urls.isEmpty()) + return; + + QPointer dialog = new TimeAdjustDialog(this, new DBInfoIface(this, urls, ApplicationSettings::Metadata)); + dialog->exec(); + + delete dialog; + + // Refresh Database with new metadata from files. + CollectionScanner scanner; + + foreach(const QUrl& url, urls) + { + scanner.scanFile(url.toLocalFile(), CollectionScanner::Rescan); + } +} + void LightTableWindow::slotEditMetadata() { if (d->thumbView->currentInfo().isNull()) { return; } QUrl url = d->thumbView->currentInfo().fileUrl(); QPointer dialog = new MetadataEditDialog(QApplication::activeWindow(), QList() << url); dialog->exec(); delete dialog; // Refresh Database with new metadata from file. CollectionScanner scanner; scanner.scanFile(url.toLocalFile(), CollectionScanner::Rescan); } void LightTableWindow::slotEditGeolocation() { #ifdef HAVE_MARBLE ImageInfoList infos = d->thumbView->allImageInfos(); if (infos.isEmpty()) { return; } TagModel* const tagModel = new TagModel(AbstractAlbumModel::IgnoreRootAlbum, this); TagPropertiesFilterModel* const filterModel = new TagPropertiesFilterModel(this); filterModel->setSourceAlbumModel(tagModel); filterModel->sort(0); QPointer dialog = new GeolocationEdit(filterModel, new DBInfoIface(this, d->thumbView->allUrls()), QApplication::activeWindow()); dialog->setItems(ImageGPS::infosToItems(infos)); dialog->exec(); delete dialog; // Refresh Database with new metadata from files. foreach(const ImageInfo& inf, infos) { ScanController::instance()->scannedInfo(inf.fileUrl().toLocalFile()); } #endif } void LightTableWindow::slotPrintCreator() { QPointer w = new AdvPrintWizard(this, new DBInfoIface(this, d->thumbView->allUrls())); w->exec(); delete w; } void LightTableWindow::slotPresentation() { QPointer mngr = new PresentationMngr(this); foreach(const ImageInfo& info, d->thumbView->allImageInfos()) { mngr->addFile(info.fileUrl(), info.comment()); qApp->processEvents(); } mngr->showConfigDialog(); } void LightTableWindow::slotSlideShowAll() { SlideShowBuilder* const builder = new SlideShowBuilder(d->thumbView->allImageInfos()); d->statusProgressBar->setProgressBarMode(StatusProgressBar::TextMode, i18n("Preparing slideshow. Please wait...")); connect(builder, SIGNAL(signalComplete(SlideShowSettings)), this, SLOT(slotSlideShowBuilderComplete(SlideShowSettings))); builder->run(); } void LightTableWindow::slotLeftSlideShowManualFromCurrent() { slotSlideShowManualFrom(d->previewView->leftImageInfo()); d->fromLeftPreview = true; } void LightTableWindow::slotRightSlideShowManualFromCurrent() { slotSlideShowManualFrom(d->previewView->rightImageInfo()); d->fromLeftPreview = false; } void LightTableWindow::slotSlideShowManualFrom(const ImageInfo& info) { SlideShowBuilder* const builder = new SlideShowBuilder(d->thumbView->allImageInfos()); builder->setOverrideStartFrom(info); builder->setAutoPlayEnabled(false); d->statusProgressBar->setProgressBarMode(StatusProgressBar::TextMode, i18n("Preparing slideshow. Please wait...")); connect(builder, SIGNAL(signalComplete(SlideShowSettings)), this, SLOT(slotSlideShowBuilderComplete(SlideShowSettings))); builder->run(); } void LightTableWindow::slotSlideShowBuilderComplete(const SlideShowSettings& settings) { QPointer slide = new SlideShow(settings); TagsActionMngr::defaultManager()->registerActionsToWidget(slide); d->statusProgressBar->setProgressBarMode(StatusProgressBar::TextMode, QString()); slotRefreshStatusBar(); if (settings.imageUrl.isValid()) { slide->setCurrentItem(settings.imageUrl); } else if (settings.startWithCurrent) { slide->setCurrentItem(d->thumbView->currentInfo().fileUrl()); } connect(slide, SIGNAL(signalRatingChanged(QUrl,int)), d->thumbView, SLOT(slotRatingChanged(QUrl,int))); connect(slide, SIGNAL(signalColorLabelChanged(QUrl,int)), d->thumbView, SLOT(slotColorLabelChanged(QUrl,int))); connect(slide, SIGNAL(signalPickLabelChanged(QUrl,int)), d->thumbView, SLOT(slotPickLabelChanged(QUrl,int))); connect(slide, SIGNAL(signalToggleTag(QUrl,int)), d->thumbView, SLOT(slotToggleTag(QUrl,int))); connect(slide, SIGNAL(signalLastItemUrl(QUrl)), this, SLOT(slotSlideShowLastItemUrl(QUrl))); slide->show(); } void LightTableWindow::slotSlideShowLastItemUrl(const QUrl& url) { if (d->fromLeftPreview && !d->navigateByPairAction->isChecked()) { d->thumbView->blockSignals(true); d->thumbView->setCurrentUrl(url); d->thumbView->blockSignals(false); slotSetItemLeft(); } else { d->thumbView->setCurrentUrl(url); } } } // namespace Digikam diff --git a/core/utilities/lighttable/lighttablewindowui5.rc b/core/utilities/lighttable/lighttablewindowui5.rc index dc2eb990c9..0754cf6b71 100644 --- a/core/utilities/lighttable/lighttablewindowui5.rc +++ b/core/utilities/lighttable/lighttablewindowui5.rc @@ -1,143 +1,144 @@ - + &File &View &Left Panel &Right Panel &Tools + I&mport &Export &Settings &Help Main Toolbar