diff --git a/shell/mainwindow_p.cpp b/shell/mainwindow_p.cpp --- a/shell/mainwindow_p.cpp +++ b/shell/mainwindow_p.cpp @@ -39,6 +39,7 @@ #include #include +#include #include #include @@ -104,6 +105,8 @@ connect(plugin, &IPlugin::destroyed, this, &MainWindowPrivate::pluginDestroyed); m_mainWindow->guiFactory()->addClient(ownClient); } + + new ActionToolTipModifier(plugin->actionCollection(), plugin); } void MainWindowPrivate::pluginDestroyed(QObject* pluginObj) @@ -322,6 +325,8 @@ //Load themes actionCollection()->addAction(QStringLiteral("colorscheme_menu"), new ColorSchemeChooser(actionCollection())); + + new ActionToolTipModifier(actionCollection(), this); } void MainWindowPrivate::toggleArea(bool b) diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt --- a/util/CMakeLists.txt +++ b/util/CMakeLists.txt @@ -16,6 +16,7 @@ environmentgrouplist.cpp jobstatus.cpp activetooltip.cpp + actiontooltipmodifier.cpp executecompositejob.cpp shellutils.cpp multilevellistview.cpp @@ -73,6 +74,7 @@ ksharedobject.h focusedtreeview.h activetooltip.h + actiontooltipmodifier.h processlinemaker.h commandexecutor.h environmentselectionwidget.h diff --git a/util/actiontooltipmodifier.h b/util/actiontooltipmodifier.h new file mode 100644 --- /dev/null +++ b/util/actiontooltipmodifier.h @@ -0,0 +1,64 @@ +/* + * Copyright 2017 Kevin Funk + * + * 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 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef KDEVPLATFORM_ACTIONTOOLTIPMODIFIER_H +#define KDEVPLATFORM_ACTIONTOOLTIPMODIFIER_H + +#include "utilexport.h" + +#include + +#include + +class KActionCollection; + +class QAction; + +namespace KDevelop { + +class ActionToolTipModifierPrivate; + +/** + * @brief This helper tracks actions in an action collection and adjusts tool tips with shortcut text + * + * Every action tracked will get its shortcut string added to the tooltip text. + * + * Example: + * Tooltip before: "Build selection" + * Tooltip after: "Build selection (F8)" + * + * The shortcut string is dynamically updated when the shortcut is changed + */ +class KDEVPLATFORMUTIL_EXPORT ActionToolTipModifier : public QObject +{ + Q_OBJECT + +public: + ActionToolTipModifier(KActionCollection* actionCollection, QObject* parent = nullptr); + ~ActionToolTipModifier() override; + +private: + QScopedPointer d; +}; + +} + +#endif diff --git a/util/actiontooltipmodifier.cpp b/util/actiontooltipmodifier.cpp new file mode 100644 --- /dev/null +++ b/util/actiontooltipmodifier.cpp @@ -0,0 +1,93 @@ +/* + * Copyright 2017 Kevin Funk + * + * 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 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "actiontooltipmodifier.h" + +#include +#include + +#include +#include + +using namespace KDevelop; + +namespace { +const char ORIGINAL_TOOLTIP_PROPERTY[] = "__kdev_original_tooltip"; +} + +namespace KDevelop { + +class ActionToolTipModifierPrivate +{ +public: + ActionToolTipModifierPrivate(ActionToolTipModifier* qq) : q(qq) {} + + void updateActionTooltips(KActionCollection* actionCollection); + void updateActionTooltip(QAction* action); + + ActionToolTipModifier* q; +}; + +} + +ActionToolTipModifier::ActionToolTipModifier(KActionCollection* actionCollection, QObject* parent) + : QObject(parent) + , d(new ActionToolTipModifierPrivate(this)) +{ + connect(actionCollection, &KActionCollection::inserted, this, + [this](QAction* action) { d->updateActionTooltip(action); }, + Qt::QueuedConnection); + + d->updateActionTooltips(actionCollection); +} + +ActionToolTipModifier::~ActionToolTipModifier() +{ +} + +void ActionToolTipModifierPrivate::updateActionTooltips(KActionCollection* actionCollection) +{ + foreach(QAction *action, actionCollection->actions()) { + updateActionTooltip(action); + } +} + +void ActionToolTipModifierPrivate::updateActionTooltip(QAction* action) +{ + QString tooltip = action->property(ORIGINAL_TOOLTIP_PROPERTY).toString(); + if (tooltip.isEmpty()) { + tooltip = action->toolTip(); + action->setProperty(ORIGINAL_TOOLTIP_PROPERTY, tooltip); + } + + auto shortcut = action->shortcut(); + if (!shortcut.isEmpty()) { + tooltip = i18nc("%1: original tooltip, %2 shortcut", "%1 (%2)", tooltip, shortcut.toString()); + } + action->setToolTip(tooltip); + + // track changes of QAction::shortcut property + q->connect(action, &QAction::changed, q, [this, action]() { + // note: if the action is ever removed from the action collection, this will still update the action tool tip + // not worth handling IMO: likely never a problem though. we don't remove actions from collections usually + updateActionTooltip(action); + }); +}