forked from qt-creator/qt-creator
Core: Keep track of modes in the ModeManager directly
... instead of having the indirection of the global object pool. ModeManagerPrivate has been maintaining the list of instantiated modes by tracking (all...) pool object additions / removals. This can be achieved more directly by calling functions from the IMode base constructor/destructor. The pattern used deviates a bit from the otherwise used 'static QList<Foo *> allFoos();' acessor pattern as there is some sorting logic etc. associated each time a mode is appended. Sticking to the preexisting structure seemed less effort for now. Change-Id: Ic1b4e641e155f949248890acc48cafbe74025115 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -25,13 +25,17 @@
|
|||||||
|
|
||||||
#include "imode.h"
|
#include "imode.h"
|
||||||
|
|
||||||
|
#include "modemanager.h"
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
IMode::IMode(QObject *parent) : IContext(parent)
|
IMode::IMode(QObject *parent) : IContext(parent)
|
||||||
{
|
{
|
||||||
|
ModeManager::instance()->addMode(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMode::~IMode()
|
IMode::~IMode()
|
||||||
{
|
{
|
||||||
|
ModeManager::instance()->removeMode(this);
|
||||||
delete m_menu;
|
delete m_menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -311,7 +311,6 @@ bool MainWindow::init(QString *errorMessage)
|
|||||||
|
|
||||||
PluginManager::addObject(m_coreImpl);
|
PluginManager::addObject(m_coreImpl);
|
||||||
m_statusBarManager->init();
|
m_statusBarManager->init();
|
||||||
m_modeManager->init();
|
|
||||||
m_progressManager->init(); // needs the status bar manager
|
m_progressManager->init(); // needs the status bar manager
|
||||||
|
|
||||||
PluginManager::addObject(m_generalSettings);
|
PluginManager::addObject(m_generalSettings);
|
||||||
|
@@ -59,6 +59,8 @@ namespace Core {
|
|||||||
struct ModeManagerPrivate
|
struct ModeManagerPrivate
|
||||||
{
|
{
|
||||||
void showMenu(int index, QMouseEvent *event);
|
void showMenu(int index, QMouseEvent *event);
|
||||||
|
void addModeHelper(IMode *mode);
|
||||||
|
void enabledStateChanged(IMode *mode);
|
||||||
|
|
||||||
Internal::MainWindow *m_mainWindow;
|
Internal::MainWindow *m_mainWindow;
|
||||||
Internal::FancyTabWidget *m_modeStack;
|
Internal::FancyTabWidget *m_modeStack;
|
||||||
@@ -111,14 +113,6 @@ ModeManager::ModeManager(Internal::MainWindow *mainWindow,
|
|||||||
this, [](int index, QMouseEvent *e) { d->showMenu(index, e); });
|
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()
|
ModeManager::~ModeManager()
|
||||||
{
|
{
|
||||||
delete d;
|
delete d;
|
||||||
@@ -150,34 +144,41 @@ void ModeManager::activateMode(Id id)
|
|||||||
d->m_modeStack->setCurrentIndex(newIndex);
|
d->m_modeStack->setCurrentIndex(newIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModeManager::objectAdded(QObject *obj)
|
void ModeManager::addMode(IMode *mode)
|
||||||
{
|
{
|
||||||
IMode *mode = qobject_cast<IMode *>(obj);
|
// Delay needed to get access to subclass's IMode::widget().
|
||||||
if (!mode)
|
QTimer::singleShot(0, [mode] { d->addModeHelper(mode); });
|
||||||
return;
|
}
|
||||||
|
|
||||||
d->m_mainWindow->addContextObject(mode);
|
void ModeManagerPrivate::addModeHelper(IMode *mode)
|
||||||
|
{
|
||||||
|
m_mainWindow->addContextObject(mode);
|
||||||
|
|
||||||
// Count the number of modes with a higher priority
|
// Count the number of modes with a higher priority
|
||||||
int index = 0;
|
int index = 0;
|
||||||
foreach (const IMode *m, d->m_modes)
|
foreach (const IMode *m, m_modes)
|
||||||
if (m->priority() > mode->priority())
|
if (m->priority() > mode->priority())
|
||||||
++index;
|
++index;
|
||||||
|
|
||||||
d->m_modes.insert(index, mode);
|
m_modes.insert(index, mode);
|
||||||
d->m_modeStack->insertTab(index, mode->widget(), mode->icon(), mode->displayName(),
|
m_modeStack->insertTab(index, mode->widget(), mode->icon(), mode->displayName(),
|
||||||
mode->menu() != nullptr);
|
mode->menu() != nullptr);
|
||||||
d->m_modeStack->setTabEnabled(index, mode->isEnabled());
|
m_modeStack->setTabEnabled(index, mode->isEnabled());
|
||||||
|
|
||||||
// Register mode shortcut
|
// Register mode shortcut
|
||||||
const Id actionId = mode->id().withPrefix("QtCreator.Mode.");
|
const Id actionId = mode->id().withPrefix("QtCreator.Mode.");
|
||||||
QAction *action = new QAction(tr("Switch to <b>%1</b> mode").arg(mode->displayName()), this);
|
QAction *action = new QAction(ModeManager::tr("Switch to <b>%1</b> mode").arg(mode->displayName()), m_instance);
|
||||||
Command *cmd = ActionManager::registerAction(action, actionId);
|
Command *cmd = ActionManager::registerAction(action, actionId);
|
||||||
|
|
||||||
d->m_modeCommands.insert(index, cmd);
|
m_modeCommands.insert(index, cmd);
|
||||||
connect(cmd, &Command::keySequenceChanged, m_instance, &ModeManager::updateModeToolTip);
|
QObject::connect(cmd, &Command::keySequenceChanged, m_instance, [cmd, this] {
|
||||||
for (int i = 0; i < d->m_modeCommands.size(); ++i) {
|
int index = m_modeCommands.indexOf(cmd);
|
||||||
Command *currentCmd = d->m_modeCommands.at(i);
|
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
|
// we need this hack with currentlyHasDefaultSequence
|
||||||
// because we call setDefaultShortcut multiple times on the same cmd
|
// because we call setDefaultShortcut multiple times on the same cmd
|
||||||
// and still expect the current shortcut to change with it
|
// and still expect the current shortcut to change with it
|
||||||
@@ -190,52 +191,35 @@ void ModeManager::objectAdded(QObject *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Id id = mode->id();
|
Id id = mode->id();
|
||||||
connect(action, &QAction::triggered, [id] {
|
QObject::connect(action, &QAction::triggered, [this, id] {
|
||||||
m_instance->activateMode(id);
|
ModeManager::activateMode(id);
|
||||||
ICore::raiseWindow(d->m_modeStack);
|
ICore::raiseWindow(m_modeStack);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(mode, &IMode::enabledStateChanged,
|
QObject::connect(mode, &IMode::enabledStateChanged, [this, mode] { enabledStateChanged(mode); });
|
||||||
m_instance, &ModeManager::enabledStateChanged);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModeManager::updateModeToolTip()
|
void ModeManagerPrivate::enabledStateChanged(IMode *mode)
|
||||||
{
|
{
|
||||||
Command *cmd = qobject_cast<Command *>(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<IMode *>(sender());
|
|
||||||
QTC_ASSERT(mode, return);
|
|
||||||
int index = d->m_modes.indexOf(mode);
|
int index = d->m_modes.indexOf(mode);
|
||||||
QTC_ASSERT(index >= 0, return);
|
QTC_ASSERT(index >= 0, return);
|
||||||
d->m_modeStack->setTabEnabled(index, mode->isEnabled());
|
d->m_modeStack->setTabEnabled(index, mode->isEnabled());
|
||||||
|
|
||||||
// Make sure we leave any disabled mode to prevent possible crashes:
|
// 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.
|
// This assumes that there is always at least one enabled mode.
|
||||||
for (int i = 0; i < d->m_modes.count(); ++i) {
|
for (int i = 0; i < d->m_modes.count(); ++i) {
|
||||||
if (d->m_modes.at(i) != mode &&
|
if (d->m_modes.at(i) != mode &&
|
||||||
d->m_modes.at(i)->isEnabled()) {
|
d->m_modes.at(i)->isEnabled()) {
|
||||||
activateMode(d->m_modes.at(i)->id());
|
ModeManager::activateMode(d->m_modes.at(i)->id());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModeManager::aboutToRemoveObject(QObject *obj)
|
void ModeManager::removeMode(IMode *mode)
|
||||||
{
|
{
|
||||||
IMode *mode = qobject_cast<IMode *>(obj);
|
|
||||||
if (!mode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const int index = d->m_modes.indexOf(mode);
|
const int index = d->m_modes.indexOf(mode);
|
||||||
d->m_modes.remove(index);
|
d->m_modes.remove(index);
|
||||||
d->m_modeCommands.remove(index);
|
d->m_modeCommands.remove(index);
|
||||||
|
@@ -34,6 +34,8 @@ QT_END_NAMESPACE
|
|||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
|
class IMode;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
class FancyTabWidget;
|
class FancyTabWidget;
|
||||||
@@ -68,15 +70,12 @@ private:
|
|||||||
explicit ModeManager(Internal::MainWindow *mainWindow, Internal::FancyTabWidget *modeStack);
|
explicit ModeManager(Internal::MainWindow *mainWindow, Internal::FancyTabWidget *modeStack);
|
||||||
~ModeManager();
|
~ModeManager();
|
||||||
|
|
||||||
static void init();
|
static void addMode(IMode *mode);
|
||||||
|
static void removeMode(IMode *mode);
|
||||||
void objectAdded(QObject *obj);
|
|
||||||
void aboutToRemoveObject(QObject *obj);
|
|
||||||
void currentTabAboutToChange(int index);
|
void currentTabAboutToChange(int index);
|
||||||
void currentTabChanged(int index);
|
void currentTabChanged(int index);
|
||||||
void updateModeToolTip();
|
|
||||||
void enabledStateChanged();
|
|
||||||
|
|
||||||
|
friend class IMode;
|
||||||
friend class Core::Internal::MainWindow;
|
friend class Core::Internal::MainWindow;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user