diff --git a/src/plugins/coreplugin/actionmanager/actioncontainer.cpp b/src/plugins/coreplugin/actionmanager/actioncontainer.cpp index fb50edfd95b966c4ca811ff5123db25cd17ed09c..aa8ff2c7ed725459e73b4408066e36793480a4c8 100644 --- a/src/plugins/coreplugin/actionmanager/actioncontainer.cpp +++ b/src/plugins/coreplugin/actionmanager/actioncontainer.cpp @@ -36,6 +36,7 @@ #include "uniqueidmanager.h" #include <QtCore/QDebug> +#include <QtCore/QTimer> #include <QtGui/QAction> #include <QtGui/QMenuBar> @@ -152,7 +153,7 @@ using namespace Core::Internal; */ ActionContainerPrivate::ActionContainerPrivate(int id) - : m_data(0), m_id(id) + : m_data(0), m_id(id), m_updateRequested(false) { } @@ -253,6 +254,7 @@ void ActionContainerPrivate::addAction(Command *action, int pos, bool setpos) m_commands.append(action); m_posmap.insert(pos, action->id()); + connect(action, SIGNAL(activeStateChanged()), this, SLOT(scheduleUpdate())); insertAction(ba, a->action()); } @@ -320,6 +322,20 @@ int ActionContainerPrivate::calcPosition(int pos, int prevKey) const return grp + (prevKey & 0xFFFF) + 10; } +void ActionContainerPrivate::scheduleUpdate() +{ + if (m_updateRequested) + return; + m_updateRequested = true; + QTimer::singleShot(0, this, SLOT(update())); +} + +void ActionContainerPrivate::update() +{ + updateInternal(); + m_updateRequested = false; +} + // ---------- MenuActionContainer ------------ /*! @@ -368,7 +384,7 @@ CommandLocation MenuActionContainer::location() const return m_location; } -bool MenuActionContainer::update() +bool MenuActionContainer::updateInternal() { if (hasEmptyAction(EA_None)) return true; @@ -380,7 +396,7 @@ bool MenuActionContainer::update() qWarning() << Q_FUNC_INFO << "container" << (this->menu() ? this->menu()->title() : "") << "contains itself as subcontainer"; continue; } - if (container->update()) { + if (qobject_cast<ActionContainerPrivate*>(container)->updateInternal()) { hasitems = true; break; } @@ -441,7 +457,7 @@ void MenuBarActionContainer::insertMenu(QAction *before, QMenu *menu) m_menuBar->insertMenu(before, menu); } -bool MenuBarActionContainer::update() +bool MenuBarActionContainer::updateInternal() { if (hasEmptyAction(EA_None)) return true; diff --git a/src/plugins/coreplugin/actionmanager/actioncontainer.h b/src/plugins/coreplugin/actionmanager/actioncontainer.h index 2fa268ba3f60722fcd350218cdc5fe58e7eade41..042921df65bf2509fb7c6678a695300435717c83 100644 --- a/src/plugins/coreplugin/actionmanager/actioncontainer.h +++ b/src/plugins/coreplugin/actionmanager/actioncontainer.h @@ -66,7 +66,6 @@ public: virtual void addAction(Core::Command *action, const QString &group = QString()) = 0; virtual void addMenu(Core::ActionContainer *menu, const QString &group = QString()) = 0; - virtual bool update() = 0; virtual ~ActionContainer() {} }; diff --git a/src/plugins/coreplugin/actionmanager/actioncontainer_p.h b/src/plugins/coreplugin/actionmanager/actioncontainer_p.h index ba9f7ed6c0c3901e053da75a362b668663a1995a..226fcc35acffa663606065f8bf1d18013e1db437 100644 --- a/src/plugins/coreplugin/actionmanager/actioncontainer_p.h +++ b/src/plugins/coreplugin/actionmanager/actioncontainer_p.h @@ -40,6 +40,8 @@ namespace Internal { class ActionContainerPrivate : public Core::ActionContainer { + Q_OBJECT + public: ActionContainerPrivate(int id); virtual ~ActionContainerPrivate() {} @@ -62,6 +64,9 @@ public: QList<Command *> commands() const { return m_commands; } QList<ActionContainer *> subContainers() const { return m_subContainers; } + + virtual bool updateInternal() = 0; + protected: bool canAddAction(Command *action) const; bool canAddMenu(ActionContainer *menu) const; @@ -70,6 +75,10 @@ protected: void addAction(Command *action, int pos, bool setpos); void addMenu(ActionContainer *menu, int pos, bool setpos); +private slots: + void scheduleUpdate(); + void update(); + private: QAction *beforeAction(int pos, int *prevKey) const; int calcPosition(int pos, int prevKey) const; @@ -80,6 +89,7 @@ private: QMap<int, int> m_posmap; QList<ActionContainer *> m_subContainers; QList<Command *> m_commands; + bool m_updateRequested; }; class MenuActionContainer : public ActionContainerPrivate @@ -95,10 +105,11 @@ public: void insertAction(QAction *before, QAction *action); void insertMenu(QAction *before, QMenu *menu); - bool update(); protected: bool canBeAddedToMenu() const; + bool updateInternal(); + private: QMenu *m_menu; CommandLocation m_location; @@ -114,10 +125,11 @@ public: void insertAction(QAction *before, QAction *action); void insertMenu(QAction *before, QMenu *menu); - bool update(); protected: bool canBeAddedToMenu() const; + bool updateInternal(); + private: QMenuBar *m_menuBar; }; diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index 91289fb1c9abdfb4afaac469a88cc418a8ac35f1..ff219e117f9f9d855804fc8b1ea376905e46ce85 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -274,10 +274,6 @@ void ActionManagerPrivate::setContext(const QList<int> &context) const IdCmdMap::const_iterator cmdcend = m_idCmdMap.constEnd(); for (IdCmdMap::const_iterator it = m_idCmdMap.constBegin(); it != cmdcend; ++it) it.value()->setCurrentContext(m_context); - - const IdContainerMap::const_iterator acend = m_idContainerMap.constEnd(); - for (IdContainerMap::const_iterator it = m_idContainerMap.constBegin(); it != acend; ++it) - it.value()->update(); } bool ActionManagerPrivate::hasContext(QList<int> context) const diff --git a/src/plugins/coreplugin/actionmanager/command.cpp b/src/plugins/coreplugin/actionmanager/command.cpp index 5cb8ad0f398162f5f185a83bc32e6256d293f960..015f4f344c9061b870a6e82a02900223842558c6 100644 --- a/src/plugins/coreplugin/actionmanager/command.cpp +++ b/src/plugins/coreplugin/actionmanager/command.cpp @@ -337,11 +337,17 @@ bool Shortcut::setCurrentContext(const QList<int> &context) { foreach (int ctxt, m_context) { if (context.contains(ctxt)) { - m_shortcut->setEnabled(true); + if (!m_shortcut->isEnabled()) { + m_shortcut->setEnabled(true); + emit activeStateChanged(); + } return true; } } - m_shortcut->setEnabled(false); + if (m_shortcut->isEnabled()) { + m_shortcut->setEnabled(false); + emit activeStateChanged(); + } return false; } @@ -454,14 +460,13 @@ bool Action::setCurrentContext(const QList<int> &context) // 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(); - m_active = true; return true; } // no active/delegate action, "visible" action is not enabled/visible if (hasAttribute(CA_Hide)) m_action->setVisible(false); m_action->setEnabled(false); - m_active = false; + setActive(false); return false; } @@ -517,9 +522,18 @@ void Action::actionChanged() 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; } + +void Action::setActive(bool state) +{ + if (state != m_active) { + m_active = state; + emit activeStateChanged(); + } +} diff --git a/src/plugins/coreplugin/actionmanager/command.h b/src/plugins/coreplugin/actionmanager/command.h index 88651f6cd66b689969b030791d7ab4407a65ed8b..2d842b13f8301cc24bd0ca7e0a732e27eeb709a3 100644 --- a/src/plugins/coreplugin/actionmanager/command.h +++ b/src/plugins/coreplugin/actionmanager/command.h @@ -81,6 +81,7 @@ public: signals: void keySequenceChanged(); + void activeStateChanged(); }; } // namespace Core diff --git a/src/plugins/coreplugin/actionmanager/command_p.h b/src/plugins/coreplugin/actionmanager/command_p.h index aaf6da028b359c5e4a4723643556369201b150c8..6c99cab2e94cc9428f77a7691846e863f8079734 100644 --- a/src/plugins/coreplugin/actionmanager/command_p.h +++ b/src/plugins/coreplugin/actionmanager/command_p.h @@ -137,6 +137,8 @@ private slots: void actionChanged(); private: + void setActive(bool state); + QAction *m_action; QList<CommandLocation> m_locations; QString m_toolTip;