Commit e58c1ab0 authored by Eike Ziller's avatar Eike Ziller

ActionManager: Remove QShortcut registration API

Registering QShortcuts doesn't solve any problem that is not already
solved by registering QActions, and shortcuts are in fact much more
limited (not being able to register multiple shortcuts for different
contexts).

Change-Id: I9478e601b2cbc3c5e12fb5baee43cacc20d0fb9c
Reviewed-by: default avatarDaniel Teske <daniel.teske@digia.com>
Reviewed-by: default avatarEike Ziller <eike.ziller@digia.com>
parent 92e930b3
......@@ -258,56 +258,6 @@ Command *ActionManager::registerAction(QAction *action, Id id, const Context &co
return a;
}
/*!
Makes a \a shortcut known to the system under the specified \a id.
Returns a command object that represents the shortcut in the application and is
owned by the ActionManager. You can registered several shortcuts with the
same \a id as long as the \a context is different. In this case
a trigger of the actual shortcut is forwarded to the registered QShortcut
for the currently active context.
A scriptable shortcut can be called from a script without the need for the user
to interact with it.
*/
Command *ActionManager::registerShortcut(QShortcut *shortcut, Id id, const Context &context, bool scriptable)
{
QTC_CHECK(!context.isEmpty());
Shortcut *sc = 0;
if (CommandPrivate *c = d->m_idCmdMap.value(id, 0)) {
sc = qobject_cast<Shortcut *>(c);
if (!sc) {
qWarning() << "registerShortcut: id" << id.name()
<< "is registered with a different command type.";
return c;
}
} else {
sc = new Shortcut(id);
d->m_idCmdMap.insert(id, sc);
}
if (sc->shortcut()) {
qWarning() << "registerShortcut: action already registered, id" << id.name() << ".";
return sc;
}
if (!d->hasContext(context))
shortcut->setEnabled(false);
shortcut->setObjectName(id.toString());
shortcut->setParent(ICore::mainWindow());
shortcut->setContext(Qt::ApplicationShortcut);
sc->setShortcut(shortcut);
sc->setScriptable(scriptable);
sc->setContext(context);
d->readUserSettings(id, sc);
emit m_instance->commandListChanged();
emit m_instance->commandAdded(id.toString());
if (isPresentationModeEnabled())
connect(sc->shortcut(), SIGNAL(activated()), d, SLOT(shortcutTriggered()));
return sc;
}
/*!
Returns the Command object that is known to the system
under the given \a id.
......@@ -350,7 +300,7 @@ ActionContainer *ActionManager::actionContainer(Id id)
*/
QList<Command *> ActionManager::commands()
{
// transform list of CommandPrivate into list of Command
// transform list of Action into list of Command
QList<Command *> result;
foreach (Command *cmd, d->m_idCmdMap)
result << cmd;
......@@ -367,10 +317,7 @@ QList<Command *> ActionManager::commands()
*/
void ActionManager::unregisterAction(QAction *action, Id id)
{
Action *a = 0;
CommandPrivate *c = d->m_idCmdMap.value(id, 0);
QTC_ASSERT(c, return);
a = qobject_cast<Action *>(c);
Action *a = d->m_idCmdMap.value(id, 0);
if (!a) {
qWarning() << "unregisterAction: id" << id.name()
<< "is registered with a different command type.";
......@@ -388,31 +335,6 @@ void ActionManager::unregisterAction(QAction *action, Id id)
emit m_instance->commandListChanged();
}
/*!
Removes the knowledge about a shortcut under the specified \a id.
Usually you do not need to unregister shortcuts. The only valid use case for unregistering
shortcuts, is for shortcuts that represent user definable actions. If the user removes such an action,
a corresponding shortcut also has to be unregistered from the action manager,
to make it disappear from shortcut settings etc.
*/
void ActionManager::unregisterShortcut(Id id)
{
Shortcut *sc = 0;
CommandPrivate *c = d->m_idCmdMap.value(id, 0);
QTC_ASSERT(c, return);
sc = qobject_cast<Shortcut *>(c);
if (!sc) {
qWarning() << "unregisterShortcut: id" << id.name()
<< "is registered with a different command type.";
return;
}
delete sc->shortcut();
d->m_idCmdMap.remove(id);
delete sc;
emit m_instance->commandListChanged();
}
/*!
Handles the display of the used shortcuts in the presentation mode. The presentation mode is
enabled when starting \QC with the command line argument \c{-presentationMode}. In the
......@@ -431,12 +353,6 @@ void ActionManager::setPresentationModeEnabled(bool enabled)
else
disconnect(c->action(), SIGNAL(triggered()), d, SLOT(actionTriggered()));
}
if (c->shortcut()) {
if (enabled)
connect(c->shortcut(), SIGNAL(activated()), d, SLOT(shortcutTriggered()));
else
disconnect(c->shortcut(), SIGNAL(activated()), d, SLOT(shortcutTriggered()));
}
}
// The label for the shortcuts:
......@@ -538,13 +454,6 @@ void ActionManagerPrivate::actionTriggered()
showShortcutPopup(action->shortcut().toString());
}
void ActionManagerPrivate::shortcutTriggered()
{
QShortcut *sc = qobject_cast<QShortcut *>(QObject::sender());
if (sc)
showShortcutPopup(sc->key().toString());
}
void ActionManagerPrivate::showShortcutPopup(const QString &shortcut)
{
if (shortcut.isEmpty() || !ActionManager::isPresentationModeEnabled())
......@@ -563,15 +472,8 @@ void ActionManagerPrivate::showShortcutPopup(const QString &shortcut)
Action *ActionManagerPrivate::overridableAction(Id id)
{
Action *a = 0;
if (CommandPrivate *c = m_idCmdMap.value(id, 0)) {
a = qobject_cast<Action *>(c);
if (!a) {
qWarning() << "registerAction: id" << id.name()
<< "is registered with a different command type.";
return 0;
}
} else {
Action *a = m_idCmdMap.value(id, 0);
if (!a) {
a = new Action(id);
m_idCmdMap.insert(id, a);
readUserSettings(id, a);
......@@ -587,7 +489,7 @@ Action *ActionManagerPrivate::overridableAction(Id id)
return a;
}
void ActionManagerPrivate::readUserSettings(Id id, CommandPrivate *cmd)
void ActionManagerPrivate::readUserSettings(Id id, Action *cmd)
{
QSettings *settings = Core::ICore::settings();
settings->beginGroup(QLatin1String(kKeyboardSettingsKey));
......@@ -635,7 +537,7 @@ void ActionManagerPrivate::saveSettings(QSettings *settings)
const IdCmdMap::const_iterator cmdcend = m_idCmdMap.constEnd();
for (IdCmdMap::const_iterator j = m_idCmdMap.constBegin(); j != cmdcend; ++j) {
const Id id = j.key();
CommandPrivate *cmd = j.value();
Action *cmd = j.value();
QKeySequence key = cmd->keySequence();
if (key != cmd->defaultKeySequence())
settings->setValue(id.toString(), key.toString());
......
......@@ -60,7 +60,6 @@ public:
static ActionContainer *createMenuBar(Id id);
static Command *registerAction(QAction *action, Id id, const Context &context, bool scriptable = false);
static Command *registerShortcut(QShortcut *shortcut, Id id, const Context &context, bool scriptable = false);
static Command *command(Id id);
static ActionContainer *actionContainer(Id id);
......@@ -68,7 +67,6 @@ public:
static QList<Command *> commands();
static void unregisterAction(QAction *action, Id id);
static void unregisterShortcut(Id id);
static void setPresentationModeEnabled(bool enabled);
static bool isPresentationModeEnabled();
......
......@@ -48,16 +48,16 @@ namespace Core {
namespace Internal {
class Action;
class ActionContainerPrivate;
class MainWindow;
class CommandPrivate;
class ActionManagerPrivate : public QObject
{
Q_OBJECT
public:
typedef QHash<Core::Id, CommandPrivate *> IdCmdMap;
typedef QHash<Core::Id, Action *> IdCmdMap;
typedef QHash<Core::Id, ActionContainerPrivate *> IdContainerMap;
explicit ActionManagerPrivate();
......@@ -74,13 +74,12 @@ public:
bool hasContext(const Context &context) const;
Action *overridableAction(Id id);
void readUserSettings(Id id, CommandPrivate *cmd);
void readUserSettings(Id id, Action *cmd);
public slots:
void containerDestroyed();
void actionTriggered();
void shortcutTriggered();
public:
IdCmdMap m_idCmdMap;
......
......@@ -204,196 +204,81 @@ using namespace Core;
using namespace Core::Internal;
/*!
\class CommandPrivate
\internal
\class Action
\internal
*/
Action::Action(Id id)
: m_attributes(0),
m_id(id),
m_isKeyInitialized(false),
m_action(new Utils::ProxyAction(this)),
m_active(false),
m_contextInitialized(false)
{
m_action->setShortcutVisibleInToolTip(true);
connect(m_action, SIGNAL(changed()), this, SLOT(updateActiveState()));
}
CommandPrivate::CommandPrivate(Id id)
: m_attributes(0), m_id(id), m_isKeyInitialized(false)
Id Action::id() const
{
return m_id;
}
void CommandPrivate::setDefaultKeySequence(const QKeySequence &key)
void Action::setDefaultKeySequence(const QKeySequence &key)
{
if (!m_isKeyInitialized)
setKeySequence(key);
m_defaultKey = key;
}
QKeySequence CommandPrivate::defaultKeySequence() const
QKeySequence Action::defaultKeySequence() const
{
return m_defaultKey;
}
void CommandPrivate::setKeySequence(const QKeySequence &key)
{
Q_UNUSED(key)
m_isKeyInitialized = true;
}
void CommandPrivate::setDescription(const QString &text)
{
m_defaultText = text;
}
QString CommandPrivate::description() const
{
if (!m_defaultText.isEmpty())
return m_defaultText;
if (action()) {
QString text = action()->text();
text.remove(QRegExp(QLatin1String("&(?!&)")));
if (!text.isEmpty())
return text;
} else if (shortcut()) {
if (!shortcut()->whatsThis().isEmpty())
return shortcut()->whatsThis();
}
return id().toString();
}
Id CommandPrivate::id() const
{
return m_id;
}
Core::Context CommandPrivate::context() const
{
return m_context;
}
void CommandPrivate::setAttribute(CommandAttribute attr)
{
m_attributes |= attr;
}
void CommandPrivate::removeAttribute(CommandAttribute attr)
{
m_attributes &= ~attr;
}
bool CommandPrivate::hasAttribute(CommandAttribute attr) const
QAction *Action::action() const
{
return (m_attributes & attr);
return m_action;
}
QString CommandPrivate::stringWithAppendedShortcut(const QString &str) const
QString Action::stringWithAppendedShortcut(const QString &str) const
{
return Utils::ProxyAction::stringWithAppendedShortcut(str, keySequence());
}
// ---------- Shortcut ------------
/*!
\class Shortcut
\internal
*/
Shortcut::Shortcut(Id id)
: CommandPrivate(id), m_shortcut(0), m_scriptable(false)
{}
void Shortcut::setShortcut(QShortcut *shortcut)
{
m_shortcut = shortcut;
}
QShortcut *Shortcut::shortcut() const
{
return m_shortcut;
}
void Shortcut::setContext(const Core::Context &context)
{
m_context = context;
}
Core::Context Shortcut::context() const
Context Action::context() const
{
return m_context;
}
void Shortcut::setKeySequence(const QKeySequence &key)
void Action::setKeySequence(const QKeySequence &key)
{
CommandPrivate::setKeySequence(key);
m_shortcut->setKey(key);
m_isKeyInitialized = true;
m_action->setShortcut(key);
emit keySequenceChanged();
}
QKeySequence Shortcut::keySequence() const
{
return m_shortcut->key();
}
void Shortcut::setCurrentContext(const Core::Context &context)
{
foreach (Id id, m_context) {
if (context.contains(id)) {
if (!m_shortcut->isEnabled()) {
m_shortcut->setEnabled(true);
emit activeStateChanged();
}
return;
}
}
if (m_shortcut->isEnabled()) {
m_shortcut->setEnabled(false);
emit activeStateChanged();
}
return;
}
bool Shortcut::isActive() const
{
return m_shortcut->isEnabled();
}
bool Shortcut::isScriptable() const
{
return m_scriptable;
}
bool Shortcut::isScriptable(const Core::Context &) const
{
return m_scriptable;
}
void Shortcut::setScriptable(bool value)
{
m_scriptable = value;
}
// ---------- Action ------------
/*!
\class Action
\internal
*/
Action::Action(Id id)
: CommandPrivate(id),
m_action(new Utils::ProxyAction(this)),
m_active(false),
m_contextInitialized(false)
{
m_action->setShortcutVisibleInToolTip(true);
connect(m_action, SIGNAL(changed()), this, SLOT(updateActiveState()));
}
QAction *Action::action() const
QKeySequence Action::keySequence() const
{
return m_action;
return m_action->shortcut();
}
void Action::setKeySequence(const QKeySequence &key)
void Action::setDescription(const QString &text)
{
CommandPrivate::setKeySequence(key);
m_action->setShortcut(key);
emit keySequenceChanged();
m_defaultText = text;
}
QKeySequence Action::keySequence() const
QString Action::description() const
{
return m_action->shortcut();
if (!m_defaultText.isEmpty())
return m_defaultText;
if (action()) {
QString text = action()->text();
text.remove(QRegExp(QLatin1String("&(?!&)")));
if (!text.isEmpty())
return text;
}
return id().toString();
}
void Action::setCurrentContext(const Core::Context &context)
......@@ -502,7 +387,7 @@ bool Action::isScriptable(const Core::Context &context) const
void Action::setAttribute(CommandAttribute attr)
{
CommandPrivate::setAttribute(attr);
m_attributes |= attr;
switch (attr) {
case Core::Command::CA_Hide:
m_action->setAttribute(Utils::ProxyAction::Hide);
......@@ -520,7 +405,7 @@ void Action::setAttribute(CommandAttribute attr)
void Action::removeAttribute(CommandAttribute attr)
{
CommandPrivate::removeAttribute(attr);
m_attributes &= ~attr;
switch (attr) {
case Core::Command::CA_Hide:
m_action->removeAttribute(Utils::ProxyAction::Hide);
......@@ -535,3 +420,8 @@ void Action::removeAttribute(CommandAttribute attr)
break;
}
}
bool Action::hasAttribute(Command::CommandAttribute attr) const
{
return (m_attributes & attr);
}
......@@ -77,7 +77,6 @@ public:
virtual Id id() const = 0;
virtual QAction *action() const = 0;
virtual QShortcut *shortcut() const = 0;
virtual Context context() const = 0;
virtual void setAttribute(CommandAttribute attr) = 0;
......
......@@ -46,85 +46,30 @@
namespace Core {
namespace Internal {
class CommandPrivate : public Core::Command
class Action : public Core::Command
{
Q_OBJECT
public:
CommandPrivate(Id id);
virtual ~CommandPrivate() {}
Action(Id id);
Id id() const;
void setDefaultKeySequence(const QKeySequence &key);
QKeySequence defaultKeySequence() const;
void setKeySequence(const QKeySequence &key);
QKeySequence keySequence() const;
void setDescription(const QString &text);
QString description() const;
Id id() const;
Context context() const;
void setAttribute(CommandAttribute attr);
void removeAttribute(CommandAttribute attr);
bool hasAttribute(CommandAttribute attr) const;
virtual void setCurrentContext(const Context &context) = 0;
QAction *action() const;
QString stringWithAppendedShortcut(const QString &str) const;
protected:
Context m_context;
CommandAttributes m_attributes;
Id m_id;
QKeySequence m_defaultKey;
QString m_defaultText;
bool m_isKeyInitialized;
};
class Shortcut : public CommandPrivate
{
Q_OBJECT
public:
Shortcut(Id id);
void setKeySequence(const QKeySequence &key);
QKeySequence keySequence() const;
void setShortcut(QShortcut *shortcut);
QShortcut *shortcut() const;
QAction *action() const { return 0; }
void setContext(const Context &context);
Context context() const;
void setCurrentContext(const Context &context);
bool isActive() const;
bool isScriptable() const;
bool isScriptable(const Context &) const;
void setScriptable(bool value);
private:
QShortcut *m_shortcut;
bool m_scriptable;
};
class Action : public CommandPrivate
{
Q_OBJECT
public:
Action(Id id);
void setKeySequence(const QKeySequence &key);
QKeySequence keySequence() const;
QAction *action() const;
QShortcut *shortcut() const { return 0; }
void setCurrentContext(const Context &context);
bool isActive() const;
void addOverrideAction(QAction *action, const Context &context, bool scriptable);
void removeOverrideAction(QAction *action);
......@@ -135,6 +80,7 @@ public:
void setAttribute(CommandAttribute attr);
void removeAttribute(CommandAttribute attr);
bool hasAttribute(CommandAttribute attr) const;
private slots:
void updateActiveState();
......@@ -142,6 +88,13 @@ private slots:
private:
void setActive(bool state);
Context m_context;
CommandAttributes m_attributes;
Id m_id;