File indexing completed on 2025-12-07 04:08:30

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2013-04-29
0007  * Description : digiKam XML GUI window - Actions methods.
0008  *
0009  * SPDX-FileCopyrightText: 2013-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "dxmlguiwindow_p.h"
0016 
0017 namespace Digikam
0018 {
0019 
0020 void DXmlGuiWindow::registerPluginsActions()
0021 {
0022     guiFactory()->removeClient(this);
0023 
0024     DPluginLoader* const dpl      = DPluginLoader::instance();
0025     dpl->registerGenericPlugins(this);
0026 
0027     QList<DPluginAction*> actions = dpl->pluginsActions(DPluginAction::Generic, this);
0028 
0029     Q_FOREACH (DPluginAction* const ac, actions)
0030     {
0031         actionCollection()->addActions(QList<QAction*>() << ac);
0032         actionCollection()->setDefaultShortcuts(ac, ac->shortcuts());
0033     }
0034 
0035     QString dom = domDocument().toString();
0036     dom.replace(QLatin1String("<!-- _DPLUGINS_GENERIC_TOOL_ACTIONS_ -->"),     dpl->pluginXmlSections(DPluginAction::GenericTool,     this));
0037     dom.replace(QLatin1String("<!-- _DPLUGINS_GENERIC_METADATA_ACTIONS_ -->"), dpl->pluginXmlSections(DPluginAction::GenericMetadata, this));
0038     dom.replace(QLatin1String("<!-- _DPLUGINS_GENERIC_IMPORT_ACTIONS_ -->"),   dpl->pluginXmlSections(DPluginAction::GenericImport,   this));
0039     dom.replace(QLatin1String("<!-- _DPLUGINS_GENERIC_EXPORT_ACTIONS_ -->"),   dpl->pluginXmlSections(DPluginAction::GenericExport,   this));
0040     dom.replace(QLatin1String("<!-- _DPLUGINS_GENERIC_VIEW_ACTIONS_ -->"),     dpl->pluginXmlSections(DPluginAction::GenericView,     this));
0041 
0042     registerExtraPluginsActions(dom);
0043 
0044     setXML(dom);
0045 
0046     guiFactory()->reset();
0047     guiFactory()->addClient(this);
0048 
0049     checkAmbiguousShortcuts();
0050 }
0051 
0052 void DXmlGuiWindow::createHelpActions(const QString& handbookSection, bool coreOptions)
0053 {
0054     d->handbookSection                  = handbookSection;
0055 
0056     d->libsInfoAction                   = new QAction(QIcon::fromTheme(QLatin1String("help-about")), i18n("Components Information"), this);
0057     connect(d->libsInfoAction, SIGNAL(triggered()), this, SLOT(slotComponentsInfo()));
0058     actionCollection()->addAction(QLatin1String("help_librariesinfo"), d->libsInfoAction);
0059 
0060     d->about                            = new DAboutData(this);
0061 
0062     QAction* const rawCameraListAction  = new QAction(QIcon::fromTheme(QLatin1String("image-x-adobe-dng")), i18n("Supported RAW Cameras"), this);
0063     connect(rawCameraListAction, SIGNAL(triggered()), this, SLOT(slotRawCameraList()));
0064     actionCollection()->addAction(QLatin1String("help_rawcameralist"), rawCameraListAction);
0065 
0066     QAction* const solidHardwareAction  = new QAction(QIcon::fromTheme(QLatin1String("preferences-devices-tree")), i18n("List of Detected Hardware"), this);
0067     connect(solidHardwareAction, SIGNAL(triggered()), this, SLOT(slotSolidHardwareList()));
0068     actionCollection()->addAction(QLatin1String("help_solidhardwarelist"), solidHardwareAction);
0069 
0070     QAction* const donateMoneyAction    = new QAction(QIcon::fromTheme(QLatin1String("globe")), i18n("Donate..."), this);
0071     connect(donateMoneyAction, SIGNAL(triggered()), this, SLOT(slotDonateMoney()));
0072     actionCollection()->addAction(QLatin1String("help_donatemoney"), donateMoneyAction);
0073 
0074     QAction* const recipesBookAction    = new QAction(QIcon::fromTheme(QLatin1String("globe")), i18n("Recipes Book..."), this);
0075     connect(recipesBookAction, SIGNAL(triggered()), this, SLOT(slotRecipesBook()));
0076     actionCollection()->addAction(QLatin1String("help_recipesbook"), recipesBookAction);
0077 
0078     QAction* const contributeAction     = new QAction(QIcon::fromTheme(QLatin1String("globe")), i18n("Contribute..."), this);
0079     connect(contributeAction, SIGNAL(triggered()), this, SLOT(slotContribute()));
0080     actionCollection()->addAction(QLatin1String("help_contribute"), contributeAction);
0081 
0082     QAction* const onlineVerCheckAction = new QAction(QIcon::fromTheme(QLatin1String("globe")), i18n("Check for New Version..."), this);
0083     connect(onlineVerCheckAction, SIGNAL(triggered()), this, SLOT(slotOnlineVersionCheck()));
0084     actionCollection()->addAction(QLatin1String("help_onlineversioncheck"), onlineVerCheckAction);
0085 
0086     QAction* const helpAction           = new QAction(QIcon::fromTheme(QLatin1String("globe")), i18n("Online Handbook..."), this);
0087     connect(helpAction, SIGNAL(triggered()), this, SLOT(slotHelpContents()));
0088     actionCollection()->addAction(QLatin1String("help_handbook"), helpAction);
0089 
0090     m_animLogo                          = new DLogoAction(this);
0091     actionCollection()->addAction(QLatin1String("logo_action"), m_animLogo);
0092 
0093     // Add options only for core components (typically all excepted Showfoto)
0094 
0095     if (coreOptions)
0096     {
0097         d->dbStatAction = new QAction(QIcon::fromTheme(QLatin1String("network-server-database")), i18n("Database Statistics"), this);
0098         connect(d->dbStatAction, SIGNAL(triggered()), this, SLOT(slotDBStat()));
0099         actionCollection()->addAction(QLatin1String("help_dbstat"), d->dbStatAction);
0100     }
0101 }
0102 
0103 void DXmlGuiWindow::cleanupActions()
0104 {
0105     QAction* ac = actionCollection()->action(QLatin1String("help_about_kde"));
0106     if (ac) actionCollection()->removeAction(ac);
0107 
0108     ac          = actionCollection()->action(QLatin1String("help_donate"));
0109     if (ac) actionCollection()->removeAction(ac);
0110 
0111     ac          = actionCollection()->action(QLatin1String("help_contents"));
0112     if (ac) actionCollection()->removeAction(ac);
0113 
0114 /*
0115     Q_FOREACH (QAction* const act, actionCollection()->actions())
0116     {
0117         qCDebug(DIGIKAM_WIDGETS_LOG) << "action: " << act->objectName();
0118     }
0119 */
0120 }
0121 
0122 void DXmlGuiWindow::createSidebarActions()
0123 {
0124     KActionCollection* const ac = actionCollection();
0125     QAction* const tlsb         = new QAction(i18n("Toggle Left Side-bar"), this);
0126     connect(tlsb, SIGNAL(triggered()), this, SLOT(slotToggleLeftSideBar()));
0127     ac->addAction(QLatin1String("toggle-left-sidebar"), tlsb);
0128     ac->setDefaultShortcut(tlsb, Qt::CTRL | Qt::ALT | Qt::Key_Left);
0129 
0130     QAction* const trsb = new QAction(i18n("Toggle Right Side-bar"), this);
0131     connect(trsb, SIGNAL(triggered()), this, SLOT(slotToggleRightSideBar()));
0132     ac->addAction(QLatin1String("toggle-right-sidebar"), trsb);
0133     ac->setDefaultShortcut(trsb, Qt::CTRL | Qt::ALT | Qt::Key_Right);
0134 
0135     QAction* const plsb = new QAction(i18n("Previous Left Side-bar Tab"), this);
0136     connect(plsb, SIGNAL(triggered()), this, SLOT(slotPreviousLeftSideBarTab()));
0137     ac->addAction(QLatin1String("previous-left-sidebar-tab"), plsb);
0138     ac->setDefaultShortcut(plsb, Qt::CTRL | Qt::ALT | Qt::Key_Home);
0139 
0140     QAction* const nlsb = new QAction(i18n("Next Left Side-bar Tab"), this);
0141     connect(nlsb, SIGNAL(triggered()), this, SLOT(slotNextLeftSideBarTab()));
0142     ac->addAction(QLatin1String("next-left-sidebar-tab"), nlsb);
0143     ac->setDefaultShortcut(nlsb, Qt::CTRL | Qt::ALT | Qt::Key_End);
0144 
0145     QAction* const prsb = new QAction(i18n("Previous Right Side-bar Tab"), this);
0146     connect(prsb, SIGNAL(triggered()), this, SLOT(slotPreviousRightSideBarTab()));
0147     ac->addAction(QLatin1String("previous-right-sidebar-tab"), prsb);
0148     ac->setDefaultShortcut(prsb, Qt::CTRL | Qt::ALT | Qt::Key_PageUp);
0149 
0150     QAction* const nrsb = new QAction(i18n("Next Right Side-bar Tab"), this);
0151     connect(nrsb, SIGNAL(triggered()), this, SLOT(slotNextRightSideBarTab()));
0152     ac->addAction(QLatin1String("next-right-sidebar-tab"), nrsb);
0153     ac->setDefaultShortcut(nrsb, Qt::CTRL | Qt::ALT | Qt::Key_PageDown);
0154 }
0155 
0156 void DXmlGuiWindow::createSettingsActions()
0157 {
0158     d->showMenuBarAction   = KStandardAction::showMenubar(this, SLOT(slotShowMenuBar()), actionCollection());
0159 
0160 #ifdef Q_OS_MACOS
0161 
0162     // Under MacOS the menu bar visibility is managed by desktop.
0163 
0164     d->showMenuBarAction->setVisible(false);
0165 
0166 #endif
0167 
0168     d->showStatusBarAction = actionCollection()->action(QLatin1String("options_show_statusbar"));
0169 
0170     if (!d->showStatusBarAction)
0171     {
0172         qCWarning(DIGIKAM_WIDGETS_LOG) << "Status bar menu action cannot be found in action collection";
0173 
0174         d->showStatusBarAction = new QAction(i18n("Show Statusbar"), this);
0175         d->showStatusBarAction->setCheckable(true);
0176         d->showStatusBarAction->setChecked(true);
0177         connect(d->showStatusBarAction, SIGNAL(toggled(bool)), this, SLOT(slotShowStatusBar()));
0178         actionCollection()->addAction(QLatin1String("options_show_statusbar"), d->showStatusBarAction);
0179     }
0180 
0181     KStandardAction::keyBindings(this,            SLOT(slotEditKeys()),          actionCollection());
0182     KStandardAction::preferences(this,            SLOT(slotSetup()),             actionCollection());
0183     KStandardAction::configureToolbars(this,      SLOT(slotConfToolbars()),      actionCollection());
0184 
0185 #ifdef HAVE_KNOTIFYCONFIG
0186 
0187     KStandardAction::configureNotifications(this, SLOT(slotConfNotifications()), actionCollection());
0188 
0189 #endif
0190 
0191 #if KCONFIGWIDGETS_VERSION > QT_VERSION_CHECK(5, 80, 0)
0192 
0193     d->hamburgerMenu = KStandardAction::hamburgerMenu(nullptr, nullptr, actionCollection());
0194     d->hamburgerMenu->setShowMenuBarAction(d->showMenuBarAction);
0195     d->hamburgerMenu->setMenuBar(menuBar());
0196 
0197     connect(d->hamburgerMenu, &KHamburgerMenu::aboutToShowMenu,
0198             this, [this]()
0199             {
0200                 // Immediately disconnect. We only need to run this once, but on demand.
0201                 // NOTE: The nullptr at the end disconnects all connections between
0202                 // this and d->hamburgerMenu's aboutToShowMenu signal.
0203                 disconnect(d->hamburgerMenu, &KHamburgerMenu::aboutToShowMenu,
0204                            this, nullptr);
0205             }
0206     );
0207 
0208 #endif
0209 
0210 }
0211 
0212 QAction* DXmlGuiWindow::showMenuBarAction() const
0213 {
0214     return d->showMenuBarAction;
0215 }
0216 
0217 QAction* DXmlGuiWindow::showStatusBarAction() const
0218 {
0219     return d->showStatusBarAction;
0220 }
0221 
0222 QAction* DXmlGuiWindow::buildStdAction(StdActionType type, const QObject* const recvr,
0223                                        const char* const slot, QObject* const parent)
0224 {
0225     switch (type)
0226     {
0227         case StdCopyAction:
0228         {
0229             return KStandardAction::copy(recvr, slot, parent);
0230         }
0231 
0232         case StdPasteAction:
0233         {
0234             return KStandardAction::paste(recvr, slot, parent);
0235         }
0236 
0237         case StdCutAction:
0238         {
0239             return KStandardAction::cut(recvr, slot, parent);
0240         }
0241 
0242         case StdQuitAction:
0243         {
0244             return KStandardAction::quit(recvr, slot, parent);
0245         }
0246 
0247         case StdCloseAction:
0248         {
0249             return KStandardAction::close(recvr, slot, parent);
0250         }
0251 
0252         case StdZoomInAction:
0253         {
0254             return KStandardAction::zoomIn(recvr, slot, parent);
0255         }
0256 
0257         case StdZoomOutAction:
0258         {
0259             return KStandardAction::zoomOut(recvr, slot, parent);
0260         }
0261 
0262         case StdOpenAction:
0263         {
0264 #ifndef __clang_analyzer__
0265             // NOTE: disable false positive report from scan build about open()
0266             return KStandardAction::open(recvr, slot, parent);
0267 #endif
0268         }
0269 
0270         case StdSaveAction:
0271         {
0272             return KStandardAction::save(recvr, slot, parent);
0273         }
0274 
0275         case StdSaveAsAction:
0276         {
0277             return KStandardAction::saveAs(recvr, slot, parent);
0278         }
0279 
0280         case StdRevertAction:
0281         {
0282             return KStandardAction::revert(recvr, slot, parent);
0283         }
0284 
0285         case StdBackAction:
0286         {
0287             return KStandardAction::back(recvr, slot, parent);
0288         }
0289 
0290         case StdForwardAction:
0291         {
0292             return KStandardAction::forward(recvr, slot, parent);
0293         }
0294 
0295         default:
0296         {
0297             break;
0298         }
0299     }
0300 
0301     return nullptr;
0302 }
0303 
0304 QList<QAction*> DXmlGuiWindow::allActions() const
0305 {
0306     return (actionCollection()->actions());
0307 }
0308 
0309 } // namespace Digikam