Files
qt-creator/src/plugins/coreplugin/designmode.cpp
Eike Ziller 8b5f5744dc Rename Qt Designer -> Qt Widgets Designer
Fixes: QTCREATORBUG-30756
Change-Id: Icb4a2513e230b71b5bb5033ead6a09ad3a8963ab
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
2024-05-23 11:37:08 +00:00

240 lines
6.4 KiB
C++

// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "designmode.h"
#include "coreconstants.h"
#include "coreicons.h"
#include "coreplugintr.h"
#include "editormanager/editormanager.h"
#include "editormanager/ieditor.h"
#include "icore.h"
#include "idocument.h"
#include "modemanager.h"
#include <extensionsystem/pluginmanager.h>
#include <utils/fancymainwindow.h>
#include <aggregation/aggregate.h>
#include <QDebug>
#include <QPointer>
#include <QStackedWidget>
#include <QStringList>
using namespace Utils;
/*!
\class Core::DesignMode
\inmodule QtCreator
\brief The DesignMode class implements the mode for the Design mode, which is
for example used by \QMLD and \QD.
Other plugins can register themselves with registerDesignWidget(),
giving a list of MIME types that the editor understands, as well as an instance
to the main editor widget itself.
*/
namespace Core {
struct DesignEditorInfo
{
int widgetIndex = -1;
QStringList mimeTypes;
Context context;
QWidget *widget = nullptr;
FancyMainWindow *mainWindow = nullptr;
};
class DesignModePrivate
{
public:
DesignModePrivate();
~DesignModePrivate();
public:
QPointer<IEditor> m_currentEditor;
bool m_isActive = false;
QList<DesignEditorInfo*> m_editors;
QStackedWidget *m_stackWidget;
Context m_activeContext;
};
DesignModePrivate::DesignModePrivate()
: m_stackWidget(new QStackedWidget)
{}
DesignModePrivate::~DesignModePrivate()
{
delete m_stackWidget;
}
static DesignMode *m_instance = nullptr;
static DesignModePrivate *d = nullptr;
DesignMode::DesignMode()
{
ICore::addPreCloseListener([] {
m_instance->currentEditorChanged(nullptr);
return true;
});
setObjectName(QLatin1String("DesignMode"));
setEnabled(false);
setContext(Context(Constants::C_DESIGN_MODE));
setWidget(d->m_stackWidget);
setDisplayName(Tr::tr("Design"));
setIcon(Utils::Icon::modeIcon(Icons::MODE_DESIGN_CLASSIC,
Icons::MODE_DESIGN_FLAT, Icons::MODE_DESIGN_FLAT_ACTIVE));
setPriority(Constants::P_MODE_DESIGN);
setId(Constants::MODE_DESIGN);
connect(EditorManager::instance(), &EditorManager::currentEditorChanged,
this, &DesignMode::currentEditorChanged);
connect(ModeManager::instance(), &ModeManager::currentModeChanged,
this, &DesignMode::updateContext);
}
DesignMode::~DesignMode()
{
qDeleteAll(d->m_editors);
}
DesignMode *DesignMode::instance()
{
return m_instance;
}
void DesignMode::setDesignModeIsRequired()
{
// d != nullptr indicates "isRequired".
if (!d)
d = new DesignModePrivate;
}
/**
* Registers a widget to be displayed when an editor with a file specified in
* mimeTypes is opened. This also appends the additionalContext in ICore to
* the context, specified here.
*/
void DesignMode::registerDesignWidget(QWidget *widget,
const QStringList &mimeTypes,
const Context &context,
Utils::FancyMainWindow *mainWindow)
{
setDesignModeIsRequired();
int index = d->m_stackWidget->addWidget(widget);
auto info = new DesignEditorInfo;
info->mimeTypes = mimeTypes;
info->context = context;
info->widgetIndex = index;
info->widget = widget;
info->mainWindow = mainWindow;
d->m_editors.append(info);
}
void DesignMode::unregisterDesignWidget(QWidget *widget)
{
d->m_stackWidget->removeWidget(widget);
for (DesignEditorInfo *info : std::as_const(d->m_editors)) {
if (info->widget == widget) {
d->m_editors.removeAll(info);
delete info;
break;
}
}
}
// if editor changes, check if we have valid mimetype registered.
void DesignMode::currentEditorChanged(IEditor *editor)
{
if (editor && (d->m_currentEditor.data() == editor))
return;
bool mimeEditorAvailable = false;
if (editor) {
const QString mimeType = editor->document()->mimeType();
if (!mimeType.isEmpty()) {
for (const DesignEditorInfo *editorInfo : std::as_const(d->m_editors)) {
for (const QString &mime : editorInfo->mimeTypes) {
if (mime == mimeType) {
d->m_stackWidget->setCurrentIndex(editorInfo->widgetIndex);
setMainWindow(editorInfo->mainWindow);
setActiveContext(editorInfo->context);
mimeEditorAvailable = true;
setEnabled(true);
break;
}
}
if (mimeEditorAvailable)
break;
}
}
}
if (d->m_currentEditor)
disconnect(d->m_currentEditor.data()->document(), &IDocument::changed, this, &DesignMode::updateActions);
if (!mimeEditorAvailable) {
setActiveContext(Context());
if (ModeManager::currentModeId() == id())
ModeManager::activateMode(Constants::MODE_EDIT);
setEnabled(false);
d->m_currentEditor = nullptr;
emit actionsUpdated(d->m_currentEditor.data());
} else {
d->m_currentEditor = editor;
if (d->m_currentEditor)
connect(d->m_currentEditor.data()->document(), &IDocument::changed, this, &DesignMode::updateActions);
emit actionsUpdated(d->m_currentEditor.data());
}
}
void DesignMode::updateActions()
{
emit actionsUpdated(d->m_currentEditor.data());
}
void DesignMode::updateContext(Utils::Id newMode, Utils::Id oldMode)
{
if (newMode == id())
ICore::addAdditionalContext(d->m_activeContext);
else if (oldMode == id())
ICore::removeAdditionalContext(d->m_activeContext);
}
void DesignMode::setActiveContext(const Context &context)
{
if (d->m_activeContext == context)
return;
if (ModeManager::currentModeId() == id())
ICore::updateAdditionalContexts(d->m_activeContext, context);
d->m_activeContext = context;
}
void DesignMode::createModeIfRequired()
{
if (d) {
m_instance = new DesignMode;
ExtensionSystem::PluginManager::addObject(m_instance);
}
}
void DesignMode::destroyModeIfRequired()
{
if (m_instance) {
ExtensionSystem::PluginManager::removeObject(m_instance);
delete m_instance;
}
delete d;
}
} // namespace Core