Files
qt-creator/src/plugins/coreplugin/designmode.cpp
Marc Mutz 8eb4d52342 Port from qAsConst() to std::as_const()
We've been requiring C++17 since Qt 6.0, and our qAsConst use finally
starts to bother us (QTBUG-99313), so time to port away from it
now.

Since qAsConst has exactly the same semantics as std::as_const (down
to rvalue treatment, constexpr'ness and noexcept'ness), there's really
nothing more to it than a global search-and-replace.

Task-number: QTBUG-99313
Change-Id: I88edd91395849574436299b8badda21bb93bea39
Reviewed-by: hjk <hjk@qt.io>
2022-10-07 13:47:53 +00:00

218 lines
5.8 KiB
C++

// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#include "designmode.h"
#include <coreplugin/icore.h>
#include <coreplugin/idocument.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/coreicons.h>
#include <extensionsystem/pluginmanager.h>
#include <QDebug>
#include <QPointer>
#include <QStackedWidget>
#include <QStringList>
namespace Core {
struct DesignEditorInfo
{
int widgetIndex;
QStringList mimeTypes;
Context context;
QWidget *widget;
};
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([]() -> bool {
m_instance->currentEditorChanged(nullptr);
return true;
});
setObjectName(QLatin1String("DesignMode"));
setEnabled(false);
setContext(Context(Constants::C_DESIGN_MODE));
setWidget(d->m_stackWidget);
setDisplayName(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)
{
setDesignModeIsRequired();
int index = d->m_stackWidget->addWidget(widget);
auto info = new DesignEditorInfo;
info->mimeTypes = mimeTypes;
info->context = context;
info->widgetIndex = index;
info->widget = widget;
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);
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