--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "proxyaction.h"
+
+using namespace Utils;
+
+ProxyAction::ProxyAction(QObject *parent) :
+ QAction(parent),
+ m_action(0),
+ m_attributes(0),
+ m_showShortcut(false)
+{
+ connect(this, SIGNAL(changed()), this, SLOT(updateToolTipWithKeySequence()));
+ updateState();
+}
+
+void ProxyAction::setAction(QAction *action)
+{
+ if (m_action == action)
+ return;
+ disconnectAction();
+ m_action = action;
+ connectAction();
+ updateState();
+}
+
+void ProxyAction::updateState()
+{
+ if (m_action) {
+ update(m_action, false);
+ } else {
+ // no active/delegate action, "visible" action is not enabled/visible
+ if (hasAttribute(Hide))
+ setVisible(false);
+ setEnabled(false);
+ }
+}
+
+void ProxyAction::disconnectAction()
+{
+ if (m_action) {
+ disconnect(m_action, SIGNAL(changed()), this, SLOT(actionChanged()));
+ disconnect(this, SIGNAL(triggered(bool)), m_action, SIGNAL(triggered(bool)));
+ disconnect(this, SIGNAL(toggled(bool)), m_action, SLOT(setChecked(bool)));
+ }
+}
+
+void ProxyAction::connectAction()
+{
+ if (m_action) {
+ connect(m_action, SIGNAL(changed()), this, SLOT(actionChanged()));
+ connect(this, SIGNAL(triggered(bool)), m_action, SIGNAL(triggered(bool)));
+ connect(this, SIGNAL(toggled(bool)), m_action, SLOT(setChecked(bool)));
+ }
+}
+
+QAction *ProxyAction::action() const
+{
+ return m_action;
+}
+
+void ProxyAction::setAttribute(ProxyAction::Attribute attribute)
+{
+ m_attributes |= attribute;
+}
+
+void ProxyAction::removeAttribute(ProxyAction::Attribute attribute)
+{
+ m_attributes &= ~attribute;
+}
+
+bool ProxyAction::hasAttribute(ProxyAction::Attribute attribute)
+{
+ return (m_attributes & attribute);
+}
+
+void ProxyAction::actionChanged()
+{
+ update(m_action, false);
+}
+
+void ProxyAction::initialize(QAction *action)
+{
+ update(action, true);
+}
+
+void ProxyAction::update(QAction *action, bool initialize)
+{
+ if (!action)
+ return;
+ disconnectAction();
+ disconnect(this, SIGNAL(changed()), this, SLOT(updateToolTipWithKeySequence()));
+ if (initialize)
+ setSeparator(action->isSeparator());
+ if (hasAttribute(UpdateIcon) || initialize) {
+ setIcon(action->icon());
+ setIconText(action->iconText());
+ setIconVisibleInMenu(action->isIconVisibleInMenu());
+ }
+ if (hasAttribute(UpdateText) || initialize) {
+ setText(action->text());
+ m_toolTip = action->toolTip();
+ updateToolTipWithKeySequence();
+ setStatusTip(action->statusTip());
+ setWhatsThis(action->whatsThis());
+ }
+
+ setCheckable(action->isCheckable());
+ setChecked(action->isChecked());
+
+ setEnabled(action->isEnabled());
+ setVisible(action->isVisible());
+ connectAction();
+ connect(this, SIGNAL(changed()), this, SLOT(updateToolTipWithKeySequence()));
+}
+
+bool ProxyAction::shortcutVisibleInToolTip() const
+{
+ return m_showShortcut;
+}
+
+void ProxyAction::setShortcutVisibleInToolTip(bool visible)
+{
+ m_showShortcut = visible;
+ updateToolTipWithKeySequence();
+}
+
+void ProxyAction::updateToolTipWithKeySequence()
+{
+ static bool block = false;
+ if (block)
+ return;
+ block = true;
+ if (!m_showShortcut || shortcut().isEmpty())
+ setToolTip(m_toolTip);
+ else
+ setToolTip(stringWithAppendedShortcut(m_toolTip, shortcut()));
+ block = false;
+}
+
+QString ProxyAction::stringWithAppendedShortcut(const QString &str, const QKeySequence &shortcut)
+{
+ return QString("%1 <span style=\"color: gray; font-size: small\">%2</span>").arg(str).arg(
+ shortcut.toString(QKeySequence::NativeText));
+}
--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef PROXYACTION_H
+#define PROXYACTION_H
+
+#include "utils_global.h"
+
+#include <QtCore/QPointer>
+#include <QtGui/QAction>
+
+namespace Utils {
+
+class QTCREATOR_UTILS_EXPORT ProxyAction : public QAction
+{
+ Q_OBJECT
+public:
+ enum Attribute {
+ Hide,
+ UpdateText,
+ UpdateIcon
+ };
+ Q_DECLARE_FLAGS(Attributes, Attribute)
+
+ explicit ProxyAction(QObject *parent = 0);
+
+ void initialize(QAction *action);
+
+ void setAction(QAction *action);
+ QAction *action() const;
+
+ bool shortcutVisibleInToolTip() const;
+ void setShortcutVisibleInToolTip(bool visible);
+
+ void setAttribute(Attribute attribute);
+ void removeAttribute(Attribute attribute);
+ bool hasAttribute(Attribute attribute);
+
+ static QString stringWithAppendedShortcut(const QString &str, const QKeySequence &shortcut);
+
+private slots:
+ void actionChanged();
+ void updateState();
+ void updateToolTipWithKeySequence();
+
+private:
+ void disconnectAction();
+ void connectAction();
+ void update(QAction *action, bool initialize);
+
+ QPointer<QAction> m_action;
+ Attributes m_attributes;
+ bool m_showShortcut;
+ QString m_toolTip;
+};
+
+} // namespace Utils
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(Utils::ProxyAction::Attributes)
+
+#endif // PROXYACTION_H
include($$PWD/../../qtcreatorlibrary.pri)
include(utils-lib.pri)
+
+HEADERS += \
+ proxyaction.h
+
+SOURCES += \
+ proxyaction.cpp
Command *ActionManagerPrivate::registerAction(QAction *action, const Id &id, const Context &context, bool scriptable)
{
- Action *a = 0;
- Command *c = registerOverridableAction(action, id, false);
- a = static_cast<Action *>(c);
- if (a)
+ Action *a = overridableAction(id);
+ if (a) {
a->addOverrideAction(action, context, scriptable);
- emit commandListChanged();
- emit commandAdded(id);
+ emit commandListChanged();
+ emit commandAdded(id);
+ }
return a;
}
-Command *ActionManagerPrivate::registerOverridableAction(QAction *action, const Id &id, bool checkUnique)
+Action *ActionManagerPrivate::overridableAction(const Id &id)
{
Action *a = 0;
const int uid = UniqueIDManager::instance()->uniqueIdentifier(id);
a = qobject_cast<Action *>(c);
if (!a) {
qWarning() << "registerAction: id" << id << "is registered with a different command type.";
- return c;
+ return 0;
}
} else {
a = new Action(uid);
m_idCmdMap.insert(uid, a);
+ m_mainWnd->addAction(a->action());
+ a->action()->setObjectName(id);
+ a->action()->setShortcutContext(Qt::ApplicationShortcut);
}
- if (!a->action()) {
- QAction *baseAction = new QAction(m_mainWnd);
- baseAction->setObjectName(id);
- baseAction->setCheckable(action->isCheckable());
- baseAction->setIcon(action->icon());
- baseAction->setIconText(action->iconText());
- baseAction->setText(action->text());
- baseAction->setToolTip(action->toolTip());
- baseAction->setStatusTip(action->statusTip());
- baseAction->setWhatsThis(action->whatsThis());
- baseAction->setChecked(action->isChecked());
- baseAction->setSeparator(action->isSeparator());
- baseAction->setShortcutContext(Qt::ApplicationShortcut);
- baseAction->setEnabled(false);
- baseAction->setParent(m_mainWnd);
-#ifdef Q_WS_MAC
- baseAction->setIconVisibleInMenu(false);
-#else
- baseAction->setIconVisibleInMenu(action->isIconVisibleInMenu());
-#endif
- a->setAction(baseAction);
- m_mainWnd->addAction(baseAction);
- } else if (checkUnique) {
- qWarning() << "registerOverridableAction: id" << id << "is already registered.";
- }
return a;
}
#define ACTIONMANAGERPRIVATE_H
#include <coreplugin/actionmanager/actionmanager.h>
+#include "command_p.h"
+
#include <coreplugin/icontext.h>
#include <QtCore/QMap>
class QSettings;
QT_END_NAMESPACE
-struct CommandLocation
-{
- int m_container;
- int m_position;
-};
-
namespace Core {
class UniqueIDManager;
private:
bool hasContext(const Context &context) const;
- Command *registerOverridableAction(QAction *action, const Id &id,
- bool checkUnique);
+ Action *overridableAction(const Id &id);
static ActionManagerPrivate *m_instance;
QList<int> m_defaultGroups;
QString CommandPrivate::stringWithAppendedShortcut(const QString &str) const
{
- return QString("%1 <span style=\"color: gray; font-size: small\">%2</span>").arg(str).arg(
- keySequence().toString(QKeySequence::NativeText));
+ return Utils::ProxyAction::stringWithAppendedShortcut(str, keySequence());
}
// ---------- Shortcut ------------
}
-QString Shortcut::name() const
-{
- if (!m_shortcut)
- return QString();
-
- return m_shortcut->whatsThis();
-}
-
void Shortcut::setShortcut(QShortcut *shortcut)
{
m_shortcut = shortcut;
return m_defaultText;
}
-bool Shortcut::setCurrentContext(const Core::Context &context)
+void Shortcut::setCurrentContext(const Core::Context &context)
{
foreach (int ctxt, m_context) {
if (context.contains(ctxt)) {
m_shortcut->setEnabled(true);
emit activeStateChanged();
}
- return true;
+ return;
}
}
if (m_shortcut->isEnabled()) {
m_shortcut->setEnabled(false);
emit activeStateChanged();
}
- return false;
+ return;
}
bool Shortcut::isActive() const
*/
Action::Action(int id)
: CommandPrivate(id),
- m_action(0),
- m_currentAction(0),
+ m_action(new Utils::ProxyAction(this)),
m_active(false),
m_contextInitialized(false)
{
-
-}
-
-QString Action::name() const
-{
- if (!m_action)
- return QString();
-
- return m_action->text();
-}
-
-void Action::setAction(QAction *action)
-{
- m_action = action;
- if (m_action) {
- m_action->setParent(this);
- m_toolTip = m_action->toolTip();
- }
+ m_action->setShortcutVisibleInToolTip(true);
+ connect(m_action, SIGNAL(changed()), this, SLOT(updateActiveState()));
}
QAction *Action::action() const
{
CommandPrivate::setKeySequence(key);
m_action->setShortcut(key);
- updateToolTipWithKeySequence();
emit keySequenceChanged();
}
-void Action::updateToolTipWithKeySequence()
-{
- if (m_action->shortcut().isEmpty())
- m_action->setToolTip(m_toolTip);
- else
- m_action->setToolTip(stringWithAppendedShortcut(m_toolTip));
-}
-
QKeySequence Action::keySequence() const
{
return m_action->shortcut();
}
-bool Action::setCurrentContext(const Core::Context &context)
+void Action::setCurrentContext(const Core::Context &context)
{
m_context = context;
- QAction *oldAction = m_currentAction;
- m_currentAction = 0;
+ QAction *currentAction = 0;
for (int i = 0; i < m_context.size(); ++i) {
if (QAction *a = m_contextActionMap.value(m_context.at(i), 0)) {
- m_currentAction = a;
+ currentAction = a;
break;
}
}
- if (m_currentAction == oldAction && m_contextInitialized)
- return true;
- m_contextInitialized = true;
+ m_action->setAction(currentAction);
+ updateActiveState();
+}
- if (oldAction) {
- disconnect(oldAction, SIGNAL(changed()), this, SLOT(actionChanged()));
- disconnect(m_action, SIGNAL(triggered(bool)), oldAction, SIGNAL(triggered(bool)));
- disconnect(m_action, SIGNAL(toggled(bool)), oldAction, SLOT(setChecked(bool)));
- }
- if (m_currentAction) {
- connect(m_currentAction, SIGNAL(changed()), this, SLOT(actionChanged()));
- // we want to avoid the toggling semantic on slot trigger(), so we just connect the signals
- connect(m_action, SIGNAL(triggered(bool)), m_currentAction, SIGNAL(triggered(bool)));
- // we need to update the checked state, so we connect to setChecked slot, which also fires a toggled signal
- connect(m_action, SIGNAL(toggled(bool)), m_currentAction, SLOT(setChecked(bool)));
- actionChanged();
- return true;
- }
- // no active/delegate action, "visible" action is not enabled/visible
- if (hasAttribute(CA_Hide))
- m_action->setVisible(false);
- m_action->setEnabled(false);
- setActive(false);
- return false;
+void Action::updateActiveState()
+{
+ setActive(m_action->isEnabled() && m_action->isVisible() && !m_action->isSeparator());
}
static inline QString msgActionWarning(QAction *newAction, int k, QAction *oldAction)
void Action::addOverrideAction(QAction *action, const Core::Context &context, bool scriptable)
{
+#ifdef Q_WS_MAC
+ action->setIconVisibleInMenu(false);
+#endif
+ if (isEmpty())
+ m_action->initialize(action);
if (context.isEmpty()) {
m_contextActionMap.insert(0, action);
} else {
setCurrentContext(m_context);
}
-void Action::actionChanged()
-{
- if (hasAttribute(CA_UpdateIcon)) {
- m_action->setIcon(m_currentAction->icon());
- m_action->setIconText(m_currentAction->iconText());
-#ifndef Q_WS_MAC
- m_action->setIconVisibleInMenu(m_currentAction->isIconVisibleInMenu());
-#endif
- }
- if (hasAttribute(CA_UpdateText)) {
- m_action->setText(m_currentAction->text());
- m_toolTip = m_currentAction->toolTip();
- updateToolTipWithKeySequence();
- m_action->setStatusTip(m_currentAction->statusTip());
- m_action->setWhatsThis(m_currentAction->whatsThis());
- }
-
- m_action->setCheckable(m_currentAction->isCheckable());
- bool block = m_action->blockSignals(true);
- m_action->setChecked(m_currentAction->isChecked());
- m_action->blockSignals(block);
-
- m_action->setEnabled(m_currentAction->isEnabled());
- m_action->setVisible(m_currentAction->isVisible());
- setActive(m_action->isEnabled() && m_action->isVisible() && !m_action->isSeparator());
-}
-
bool Action::isActive() const
{
return m_active;
bool Action::isScriptable(const Core::Context &context) const
{
- if (context == m_context && m_scriptableMap.contains(m_currentAction))
- return m_scriptableMap.value(m_currentAction);
+ if (context == m_context && m_scriptableMap.contains(m_action->action()))
+ return m_scriptableMap.value(m_action->action());
for (int i = 0; i < context.size(); ++i) {
if (QAction *a = m_contextActionMap.value(context.at(i), 0)) {
}
return false;
}
+
+void Action::setAttribute(CommandAttribute attr)
+{
+ CommandPrivate::setAttribute(attr);
+ switch (attr) {
+ case Core::Command::CA_Hide:
+ m_action->setAttribute(Utils::ProxyAction::Hide);
+ break;
+ case Core::Command::CA_UpdateText:
+ m_action->setAttribute(Utils::ProxyAction::UpdateText);
+ break;
+ case Core::Command::CA_UpdateIcon:
+ m_action->setAttribute(Utils::ProxyAction::UpdateIcon);
+ break;
+ case Core::Command::CA_NonConfigureable:
+ break;
+ }
+}
+
+void Action::removeAttribute(CommandAttribute attr)
+{
+ CommandPrivate::removeAttribute(attr);
+ switch (attr) {
+ case Core::Command::CA_Hide:
+ m_action->removeAttribute(Utils::ProxyAction::Hide);
+ break;
+ case Core::Command::CA_UpdateText:
+ m_action->removeAttribute(Utils::ProxyAction::UpdateText);
+ break;
+ case Core::Command::CA_UpdateIcon:
+ m_action->removeAttribute(Utils::ProxyAction::UpdateIcon);
+ break;
+ case Core::Command::CA_NonConfigureable:
+ break;
+ }
+}
Q_OBJECT
public:
enum CommandAttribute {
- CA_Hide = 0x0100,
- CA_UpdateText = 0x0200,
- CA_UpdateIcon = 0x0400,
- CA_NonConfigureable = 0x8000,
- CA_Mask = 0xFF00
+ CA_Hide,
+ CA_UpdateText,
+ CA_UpdateIcon,
+ CA_NonConfigureable
};
+ Q_DECLARE_FLAGS(CommandAttributes, CommandAttribute)
virtual void setDefaultKeySequence(const QKeySequence &key) = 0;
virtual QKeySequence defaultKeySequence() const = 0;
} // namespace Core
+Q_DECLARE_OPERATORS_FOR_FLAGS(Core::Command::CommandAttributes)
+
#endif // COMMAND_H
#define COMMAND_P_H
#include "command.h"
-#include "actionmanager_p.h"
+
+#include <utils/proxyaction.h>
+#include <coreplugin/icontext.h>
#include <QtCore/QList>
#include <QtCore/QMultiMap>
#include <QtCore/QMap>
#include <QtGui/QKeySequence>
+struct CommandLocation
+{
+ int m_container;
+ int m_position;
+};
+
namespace Core {
namespace Internal {
CommandPrivate(int id);
virtual ~CommandPrivate() {}
- virtual QString name() const = 0;
-
void setDefaultKeySequence(const QKeySequence &key);
QKeySequence defaultKeySequence() const;
void removeAttribute(CommandAttribute attr);
bool hasAttribute(CommandAttribute attr) const;
- virtual bool setCurrentContext(const Context &context) = 0;
+ virtual void setCurrentContext(const Context &context) = 0;
QString stringWithAppendedShortcut(const QString &str) const;
protected:
Context m_context;
- QString m_category;
- int m_attributes;
+ CommandAttributes m_attributes;
int m_id;
QKeySequence m_defaultKey;
QString m_defaultText;
public:
Shortcut(int id);
- QString name() const;
-
void setKeySequence(const QKeySequence &key);
QKeySequence keySequence() const;
void setContext(const Context &context);
Context context() const;
- bool setCurrentContext(const Context &context);
+ void setCurrentContext(const Context &context);
bool isActive() const;
public:
Action(int id);
- QString name() const;
-
void setKeySequence(const QKeySequence &key);
QKeySequence keySequence() const;
- virtual void setAction(QAction *action);
QAction *action() const;
void setLocations(const QList<CommandLocation> &locations);
QList<CommandLocation> locations() const;
- bool setCurrentContext(const Context &context);
+ void setCurrentContext(const Context &context);
bool isActive() const;
void addOverrideAction(QAction *action, const Context &context, bool scriptable);
void removeOverrideAction(QAction *action);
bool isScriptable() const;
bool isScriptable(const Context &context) const;
-protected:
- void updateToolTipWithKeySequence();
+ void setAttribute(CommandAttribute attr);
+ void removeAttribute(CommandAttribute attr);
private slots:
- void actionChanged();
+ void updateActiveState();
private:
void setActive(bool state);
- QAction *m_action;
+ Utils::ProxyAction *m_action;
QList<CommandLocation> m_locations;
QString m_toolTip;
- QPointer<QAction> m_currentAction;
QMap<int, QPointer<QAction> > m_contextActionMap;
QMap<QAction*, bool> m_scriptableMap;
bool m_active;
Core::IMode *helloMode = new HelloMode;
addAutoReleasedObject(helloMode);
- // Add the Hello World action command to the mode manager (with 0 priority)
- Core::ModeManager *modeManager = core->modeManager();
- modeManager->addAction(command, 0);
-
return true;
}