diff --git a/src/plugins/coreplugin/actionmanager/actioncontainer.cpp b/src/plugins/coreplugin/actionmanager/actioncontainer.cpp index f47313f5692..31e68bd70db 100644 --- a/src/plugins/coreplugin/actionmanager/actioncontainer.cpp +++ b/src/plugins/coreplugin/actionmanager/actioncontainer.cpp @@ -39,6 +39,8 @@ #include "coreconstants.h" #include "uniqueidmanager.h" +#include + #include #include #include @@ -165,6 +167,9 @@ using namespace Core::Internal; ActionContainerPrivate::ActionContainerPrivate(int id) : m_onAllDisabledBehavior(Disable), m_id(id), m_updateRequested(false) { + appendGroup(QLatin1String(Constants::G_DEFAULT_ONE)); + appendGroup(QLatin1String(Constants::G_DEFAULT_TWO)); + appendGroup(QLatin1String(Constants::G_DEFAULT_THREE)); scheduleUpdate(); } @@ -178,51 +183,92 @@ ActionContainer::OnAllDisabledBehavior ActionContainerPrivate::onAllDisabledBeha return m_onAllDisabledBehavior; } -void ActionContainerPrivate::appendGroup(const QString &group) +void ActionContainerPrivate::appendGroup(const QString &groupId) { - int gid = UniqueIDManager::instance()->uniqueIdentifier(group); - m_groups << gid; + m_groups.append(Group(groupId)); } -QAction *ActionContainerPrivate::insertLocation(const QString &group) const +QList::const_iterator ActionContainerPrivate::findGroup(const QString &groupId) const { - int grpid = UniqueIDManager::instance()->uniqueIdentifier(group); - int prevKey = 0; - int pos = ((grpid << 16) | 0xFFFF); - return beforeAction(pos, &prevKey); + QList::const_iterator it = m_groups.constBegin(); + while (it != m_groups.constEnd()) { + if (it->id == groupId) + break; + ++it; + } + return it; } -void ActionContainerPrivate::addAction(Command *action, const QString &group) + +QAction *ActionContainerPrivate::insertLocation(const QString &groupId) const { - if (!canAddAction(action)) + QList::const_iterator it = findGroup(groupId); + QTC_ASSERT(it != m_groups.constEnd(), return 0); + return insertLocation(it); +} + +QAction *ActionContainerPrivate::insertLocation(QList::const_iterator group) const +{ + if (group == m_groups.constEnd()) + return 0; + ++group; + while (group != m_groups.constEnd()) { + if (!group->items.isEmpty()) { + QObject *item = group->items.first(); + if (Command *cmd = qobject_cast(item)) { + return cmd->action(); + } else if (ActionContainer *container = qobject_cast(item)) { + if (container->menu()) + return container->menu()->menuAction(); + } + QTC_ASSERT(false, return 0); + } + ++group; + } + return 0; +} + +void ActionContainerPrivate::addAction(Command *command, const QString &groupId) +{ + if (!canAddAction(command)) return; - ActionManagerPrivate *am = ActionManagerPrivate::instance(); - UniqueIDManager *idmanager = UniqueIDManager::instance(); - int grpid = idmanager->uniqueIdentifier(Constants::G_DEFAULT_TWO); - if (!group.isEmpty()) - grpid = idmanager->uniqueIdentifier(group); - if (!m_groups.contains(grpid) && !am->defaultGroups().contains(grpid)) - qWarning() << "*** addAction(): Unknown group: " << group; - int pos = ((grpid << 16) | 0xFFFF); - addActionInternal(action, pos); + QString actualGroupId; + if (groupId.isEmpty()) + actualGroupId = QLatin1String(Constants::G_DEFAULT_TWO); + else + actualGroupId = groupId; + + QList::const_iterator groupIt = findGroup(actualGroupId); + QTC_ASSERT(groupIt != m_groups.constEnd(), return); + QAction *beforeAction = insertLocation(groupIt); + m_groups[groupIt-m_groups.constBegin()].items.append(command); + + connect(command, SIGNAL(activeStateChanged()), this, SLOT(scheduleUpdate())); + insertAction(beforeAction, command->action()); + scheduleUpdate(); } -void ActionContainerPrivate::addMenu(ActionContainer *menu, const QString &group) +void ActionContainerPrivate::addMenu(ActionContainer *menu, const QString &groupId) { - ActionContainerPrivate *container = static_cast(menu); - if (!container->canBeAddedToMenu()) + ActionContainerPrivate *containerPrivate = static_cast(menu); + if (!containerPrivate->canBeAddedToMenu()) return; + MenuActionContainer *container = static_cast(containerPrivate); - ActionManagerPrivate *am = ActionManagerPrivate::instance(); - UniqueIDManager *idmanager = UniqueIDManager::instance(); - int grpid = idmanager->uniqueIdentifier(Constants::G_DEFAULT_TWO); - if (!group.isEmpty()) - grpid = idmanager->uniqueIdentifier(group); - if (!m_groups.contains(grpid) && !am->defaultGroups().contains(grpid)) - qWarning() << "*** addMenu(): Unknown group: " << group; - int pos = ((grpid << 16) | 0xFFFF); - addMenuInternal(menu, pos); + QString actualGroupId; + if (groupId.isEmpty()) + actualGroupId = QLatin1String(Constants::G_DEFAULT_TWO); + else + actualGroupId = groupId; + + QList::const_iterator groupIt = findGroup(actualGroupId); + QTC_ASSERT(groupIt != m_groups.constEnd(), return); + QAction *beforeAction = insertLocation(groupIt); + m_groups[groupIt-m_groups.constBegin()].items.append(menu); + + insertMenu(beforeAction, container->menu()); + scheduleUpdate(); } int ActionContainerPrivate::id() const @@ -245,79 +291,6 @@ bool ActionContainerPrivate::canAddAction(Command *action) const return (action->action() != 0); } -void ActionContainerPrivate::addActionInternal(Command *action, int pos) -{ - Action *a = static_cast(action); - - int prevKey = 0; - QAction *ba = beforeAction(pos, &prevKey); - pos = calcPosition(pos, prevKey); - - m_commands.append(action); - m_posmap.insert(pos, action->id()); - connect(action, SIGNAL(activeStateChanged()), this, SLOT(scheduleUpdate())); - insertAction(ba, a->action()); - scheduleUpdate(); -} - -void ActionContainerPrivate::addMenuInternal(ActionContainer *menu, int pos) -{ - MenuActionContainer *mc = static_cast(menu); - - int prevKey = 0; - QAction *ba = beforeAction(pos, &prevKey); - pos = calcPosition(pos, prevKey); - - m_subContainers.append(menu); - m_posmap.insert(pos, menu->id()); - insertMenu(ba, mc->menu()); - scheduleUpdate(); -} - -QAction *ActionContainerPrivate::beforeAction(int pos, int *prevKey) const -{ - ActionManagerPrivate *am = ActionManagerPrivate::instance(); - - int baId = -1; - - (*prevKey) = -1; - - QMap::const_iterator i = m_posmap.constBegin(); - while (i != m_posmap.constEnd()) { - if (i.key() > pos) { - baId = i.value(); - break; - } - (*prevKey) = i.key(); - ++i; - } - - if (baId == -1) - return 0; - - if (Command *cmd = am->command(baId)) - return cmd->action(); - if (ActionContainer *container = am->actionContainer(baId)) - if (QMenu *menu = container->menu()) - return menu->menuAction(); - - return 0; -} - -int ActionContainerPrivate::calcPosition(int pos, int prevKey) const -{ - int grp = (pos & 0xFFFF0000); - if (prevKey == -1) - return grp; - - int prevgrp = (prevKey & 0xFFFF0000); - - if (grp != prevgrp) - return grp; - - return grp + (prevKey & 0xFFFF) + 10; -} - void ActionContainerPrivate::scheduleUpdate() { if (m_updateRequested) @@ -378,25 +351,32 @@ bool MenuActionContainer::updateInternal() bool hasitems = false; QList actions = m_menu->actions(); - foreach (ActionContainer *container, subContainers()) { - actions.removeAll(container->menu()->menuAction()); - if (container == this) { - qWarning() << Q_FUNC_INFO << "container" << (this->menu() ? this->menu()->title() : "") << "contains itself as subcontainer"; - continue; - } - if (qobject_cast(container)->updateInternal()) { - hasitems = true; - break; - } - } - if (!hasitems) { - foreach (Command *command, commands()) { - actions.removeAll(command->action()); - if (command->isActive()) { - hasitems = true; - break; + QListIterator it(m_groups); + while (it.hasNext()) { + const Group &group = it.next(); + foreach (QObject *item, group.items) { + if (ActionContainerPrivate *container = qobject_cast(item)) { + actions.removeAll(container->menu()->menuAction()); + if (container == this) { + qWarning() << Q_FUNC_INFO << "container" << (this->menu() ? this->menu()->title() : "") << "contains itself as subcontainer"; + continue; + } + if (container->updateInternal()) { + hasitems = true; + break; + } + } else if (Command *command = qobject_cast(item)) { + actions.removeAll(command->action()); + if (command->isActive()) { + hasitems = true; + break; + } + } else { + QTC_ASSERT(false, continue); } } + if (hasitems) + break; } if (!hasitems) { // look if there were actions added that we don't control and check if they are enabled diff --git a/src/plugins/coreplugin/actionmanager/actioncontainer_p.h b/src/plugins/coreplugin/actionmanager/actioncontainer_p.h index 6beae138cef..8d313dc98ee 100644 --- a/src/plugins/coreplugin/actionmanager/actioncontainer_p.h +++ b/src/plugins/coreplugin/actionmanager/actioncontainer_p.h @@ -42,6 +42,12 @@ namespace Core { namespace Internal { +struct Group { + Group(const QString &id) : id(id) {} + QString id; + QList items; // Command * or ActionContainer * +}; + class ActionContainerPrivate : public Core::ActionContainer { Q_OBJECT @@ -54,7 +60,7 @@ public: ActionContainer::OnAllDisabledBehavior onAllDisabledBehavior() const; QAction *insertLocation(const QString &group) const; - void appendGroup(const QString &group); + void appendGroup(const QString &id); void addAction(Command *action, const QString &group = QString()); void addMenu(ActionContainer *menu, const QString &group = QString()); @@ -66,9 +72,6 @@ public: virtual void insertAction(QAction *before, QAction *action) = 0; virtual void insertMenu(QAction *before, QMenu *menu) = 0; - QList commands() const { return m_commands; } - QList subContainers() const { return m_subContainers; } - virtual bool updateInternal() = 0; protected: @@ -76,23 +79,19 @@ protected: bool canAddMenu(ActionContainer *menu) const; virtual bool canBeAddedToMenu() const = 0; - void addActionInternal(Command *action, int pos); - void addMenuInternal(ActionContainer *menu, int pos); + // groupId --> list of Command* and ActionContainer* + QList m_groups; private slots: void scheduleUpdate(); void update(); private: - QAction *beforeAction(int pos, int *prevKey) const; - int calcPosition(int pos, int prevKey) const; + QList::const_iterator findGroup(const QString &groupId) const; + QAction *insertLocation(QList::const_iterator group) const; - QList m_groups; OnAllDisabledBehavior m_onAllDisabledBehavior; int m_id; - QMap m_posmap; - QList m_subContainers; - QList m_commands; bool m_updateRequested; }; diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index 5f17c3ecebd..e28f44abbf3 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -242,12 +242,7 @@ ActionManagerPrivate::ActionManagerPrivate(MainWindow *mainWnd) : ActionManager(mainWnd), m_mainWnd(mainWnd) { - UniqueIDManager *uidmgr = UniqueIDManager::instance(); - m_defaultGroups << uidmgr->uniqueIdentifier(Constants::G_DEFAULT_ONE); - m_defaultGroups << uidmgr->uniqueIdentifier(Constants::G_DEFAULT_TWO); - m_defaultGroups << uidmgr->uniqueIdentifier(Constants::G_DEFAULT_THREE); m_instance = this; - } ActionManagerPrivate::~ActionManagerPrivate() @@ -261,11 +256,6 @@ ActionManagerPrivate *ActionManagerPrivate::instance() return m_instance; } -QList ActionManagerPrivate::defaultGroups() const -{ - return m_defaultGroups; -} - QList ActionManagerPrivate::commands() const { // transform list of CommandPrivate into list of Command diff --git a/src/plugins/coreplugin/actionmanager/actionmanager_p.h b/src/plugins/coreplugin/actionmanager/actionmanager_p.h index 4e1304965bb..4b953a5a9b2 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager_p.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager_p.h @@ -69,7 +69,6 @@ public: static ActionManagerPrivate *instance(); void saveSettings(QSettings *settings); - QList defaultGroups() const; QList commands() const; @@ -98,7 +97,6 @@ private: Action *overridableAction(const Id &id); static ActionManagerPrivate *m_instance; - QList m_defaultGroups; typedef QHash IdCmdMap; IdCmdMap m_idCmdMap;