diff --git a/src/plugins/coreplugin/imode.cpp b/src/plugins/coreplugin/imode.cpp index 4dd1b94e663..7c5fd8e9ad5 100644 --- a/src/plugins/coreplugin/imode.cpp +++ b/src/plugins/coreplugin/imode.cpp @@ -25,13 +25,17 @@ #include "imode.h" +#include "modemanager.h" + using namespace Core; IMode::IMode(QObject *parent) : IContext(parent) { + ModeManager::instance()->addMode(this); } IMode::~IMode() { + ModeManager::instance()->removeMode(this); delete m_menu; } diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 87daf95bf9a..68a7831239e 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -311,7 +311,6 @@ bool MainWindow::init(QString *errorMessage) PluginManager::addObject(m_coreImpl); m_statusBarManager->init(); - m_modeManager->init(); m_progressManager->init(); // needs the status bar manager PluginManager::addObject(m_generalSettings); diff --git a/src/plugins/coreplugin/modemanager.cpp b/src/plugins/coreplugin/modemanager.cpp index f82c47cd4e8..74dd7321cd7 100644 --- a/src/plugins/coreplugin/modemanager.cpp +++ b/src/plugins/coreplugin/modemanager.cpp @@ -59,6 +59,8 @@ namespace Core { struct ModeManagerPrivate { void showMenu(int index, QMouseEvent *event); + void addModeHelper(IMode *mode); + void enabledStateChanged(IMode *mode); Internal::MainWindow *m_mainWindow; Internal::FancyTabWidget *m_modeStack; @@ -111,14 +113,6 @@ ModeManager::ModeManager(Internal::MainWindow *mainWindow, this, [](int index, QMouseEvent *e) { d->showMenu(index, e); }); } -void ModeManager::init() -{ - QObject::connect(ExtensionSystem::PluginManager::instance(), &ExtensionSystem::PluginManager::objectAdded, - m_instance, &ModeManager::objectAdded); - QObject::connect(ExtensionSystem::PluginManager::instance(), &ExtensionSystem::PluginManager::aboutToRemoveObject, - m_instance, &ModeManager::aboutToRemoveObject); -} - ModeManager::~ModeManager() { delete d; @@ -150,34 +144,41 @@ void ModeManager::activateMode(Id id) d->m_modeStack->setCurrentIndex(newIndex); } -void ModeManager::objectAdded(QObject *obj) +void ModeManager::addMode(IMode *mode) { - IMode *mode = qobject_cast(obj); - if (!mode) - return; + // Delay needed to get access to subclass's IMode::widget(). + QTimer::singleShot(0, [mode] { d->addModeHelper(mode); }); +} - d->m_mainWindow->addContextObject(mode); +void ModeManagerPrivate::addModeHelper(IMode *mode) +{ + m_mainWindow->addContextObject(mode); // Count the number of modes with a higher priority int index = 0; - foreach (const IMode *m, d->m_modes) + foreach (const IMode *m, m_modes) if (m->priority() > mode->priority()) ++index; - d->m_modes.insert(index, mode); - d->m_modeStack->insertTab(index, mode->widget(), mode->icon(), mode->displayName(), - mode->menu() != nullptr); - d->m_modeStack->setTabEnabled(index, mode->isEnabled()); + m_modes.insert(index, mode); + m_modeStack->insertTab(index, mode->widget(), mode->icon(), mode->displayName(), + mode->menu() != nullptr); + m_modeStack->setTabEnabled(index, mode->isEnabled()); // Register mode shortcut const Id actionId = mode->id().withPrefix("QtCreator.Mode."); - QAction *action = new QAction(tr("Switch to %1 mode").arg(mode->displayName()), this); + QAction *action = new QAction(ModeManager::tr("Switch to %1 mode").arg(mode->displayName()), m_instance); Command *cmd = ActionManager::registerAction(action, actionId); - d->m_modeCommands.insert(index, cmd); - connect(cmd, &Command::keySequenceChanged, m_instance, &ModeManager::updateModeToolTip); - for (int i = 0; i < d->m_modeCommands.size(); ++i) { - Command *currentCmd = d->m_modeCommands.at(i); + m_modeCommands.insert(index, cmd); + QObject::connect(cmd, &Command::keySequenceChanged, m_instance, [cmd, this] { + int index = m_modeCommands.indexOf(cmd); + if (index != -1) + m_modeStack->setTabToolTip(index, cmd->action()->toolTip()); + }); + + for (int i = 0; i < m_modeCommands.size(); ++i) { + Command *currentCmd = m_modeCommands.at(i); // we need this hack with currentlyHasDefaultSequence // because we call setDefaultShortcut multiple times on the same cmd // and still expect the current shortcut to change with it @@ -190,52 +191,35 @@ void ModeManager::objectAdded(QObject *obj) } Id id = mode->id(); - connect(action, &QAction::triggered, [id] { - m_instance->activateMode(id); - ICore::raiseWindow(d->m_modeStack); + QObject::connect(action, &QAction::triggered, [this, id] { + ModeManager::activateMode(id); + ICore::raiseWindow(m_modeStack); }); - connect(mode, &IMode::enabledStateChanged, - m_instance, &ModeManager::enabledStateChanged); + QObject::connect(mode, &IMode::enabledStateChanged, [this, mode] { enabledStateChanged(mode); }); } -void ModeManager::updateModeToolTip() +void ModeManagerPrivate::enabledStateChanged(IMode *mode) { - Command *cmd = qobject_cast(sender()); - if (cmd) { - int index = d->m_modeCommands.indexOf(cmd); - if (index != -1) - d->m_modeStack->setTabToolTip(index, cmd->action()->toolTip()); - } -} - -void ModeManager::enabledStateChanged() -{ - IMode *mode = qobject_cast(sender()); - QTC_ASSERT(mode, return); int index = d->m_modes.indexOf(mode); QTC_ASSERT(index >= 0, return); d->m_modeStack->setTabEnabled(index, mode->isEnabled()); // Make sure we leave any disabled mode to prevent possible crashes: - if (mode->id() == currentMode() && !mode->isEnabled()) { + if (mode->id() == ModeManager::currentMode() && !mode->isEnabled()) { // This assumes that there is always at least one enabled mode. for (int i = 0; i < d->m_modes.count(); ++i) { if (d->m_modes.at(i) != mode && d->m_modes.at(i)->isEnabled()) { - activateMode(d->m_modes.at(i)->id()); + ModeManager::activateMode(d->m_modes.at(i)->id()); break; } } } } -void ModeManager::aboutToRemoveObject(QObject *obj) +void ModeManager::removeMode(IMode *mode) { - IMode *mode = qobject_cast(obj); - if (!mode) - return; - const int index = d->m_modes.indexOf(mode); d->m_modes.remove(index); d->m_modeCommands.remove(index); diff --git a/src/plugins/coreplugin/modemanager.h b/src/plugins/coreplugin/modemanager.h index 8f5dbdbba77..1927f6f375c 100644 --- a/src/plugins/coreplugin/modemanager.h +++ b/src/plugins/coreplugin/modemanager.h @@ -34,6 +34,8 @@ QT_END_NAMESPACE namespace Core { +class IMode; + namespace Internal { class MainWindow; class FancyTabWidget; @@ -68,15 +70,12 @@ private: explicit ModeManager(Internal::MainWindow *mainWindow, Internal::FancyTabWidget *modeStack); ~ModeManager(); - static void init(); - - void objectAdded(QObject *obj); - void aboutToRemoveObject(QObject *obj); + static void addMode(IMode *mode); + static void removeMode(IMode *mode); void currentTabAboutToChange(int index); void currentTabChanged(int index); - void updateModeToolTip(); - void enabledStateChanged(); + friend class IMode; friend class Core::Internal::MainWindow; };