1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
31 **************************************************************************/
33 #include "designmode.h"
35 #include <coreplugin/icore.h>
36 #include <coreplugin/modemanager.h>
37 #include <coreplugin/editormanager/editormanager.h>
38 #include <coreplugin/editormanager/openeditorsmodel.h>
39 #include <coreplugin/actionmanager/actionmanager.h>
40 #include <coreplugin/actionmanager/command.h>
41 #include <coreplugin/coreconstants.h>
42 #include <coreplugin/mimedatabase.h>
43 #include <coreplugin/icorelistener.h>
44 #include <coreplugin/editormanager/ieditor.h>
45 #include <extensionsystem/pluginmanager.h>
46 #include <utils/qtcassert.h>
48 #include <QtCore/QPair>
49 #include <QtCore/QFileInfo>
50 #include <QtCore/QStringList>
51 #include <QtCore/QDebug>
53 #include <QtGui/QAction>
54 #include <QtGui/QPlainTextEdit>
55 #include <QtGui/QStackedWidget>
67 class DesignModeCoreListener : public Core::ICoreListener
70 DesignModeCoreListener(DesignMode* mode);
71 bool coreAboutToClose();
76 DesignModeCoreListener::DesignModeCoreListener(DesignMode *mode) :
81 bool DesignModeCoreListener::coreAboutToClose()
83 m_mode->currentEditorChanged(0);
87 } // namespace Internal
89 struct DesignEditorInfo {
91 QStringList mimeTypes;
96 struct DesignModePrivate {
97 explicit DesignModePrivate(DesignMode *q, EditorManager *editorManager);
98 Internal::DesignModeCoreListener *m_coreListener;
99 QWeakPointer<Core::IEditor> m_currentEditor;
102 QList<DesignEditorInfo*> m_editors;
104 EditorManager *m_editorManager;
105 QStackedWidget *m_stackWidget;
106 Context m_activeContext;
109 DesignModePrivate::DesignModePrivate(DesignMode *q, EditorManager *editorManager) :
110 m_coreListener(new Internal::DesignModeCoreListener(q)),
112 m_editorManager(editorManager),
113 m_stackWidget(new QStackedWidget)
117 DesignMode::DesignMode(EditorManager *editorManager) :
118 IMode(), d(new DesignModePrivate(this, editorManager))
120 setObjectName(QLatin1String("DesignMode"));
122 ExtensionSystem::PluginManager::instance()->addObject(d->m_coreListener);
124 connect(editorManager, SIGNAL(currentEditorChanged(Core::IEditor*)),
125 this, SLOT(currentEditorChanged(Core::IEditor*)));
127 connect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*,Core::IMode*)),
128 this, SLOT(updateContext(Core::IMode*,Core::IMode*)));
131 DesignMode::~DesignMode()
133 ExtensionSystem::PluginManager::instance()->removeObject(d->m_coreListener);
134 delete d->m_coreListener;
136 qDeleteAll(d->m_editors);
140 Context DesignMode::context() const
142 static Context contexts(Constants::C_DESIGN_MODE);
146 QWidget *DesignMode::widget()
148 return d->m_stackWidget;
151 QString DesignMode::displayName() const
156 QIcon DesignMode::icon() const
158 return QIcon(QLatin1String(":/fancyactionbar/images/mode_Design.png"));
161 int DesignMode::priority() const
163 return Constants::P_MODE_DESIGN;
166 QString DesignMode::id() const
168 return QLatin1String(Constants::MODE_DESIGN);
171 QString DesignMode::type() const
173 return QLatin1String(Constants::MODE_DESIGN_TYPE);
176 QStringList DesignMode::registeredMimeTypes() const
179 foreach(const DesignEditorInfo *i, d->m_editors)
185 * Registers a widget to be displayed when an editor with a file specified in
186 * mimeTypes is opened. This also appends the additionalContext in ICore to
187 * the context, specified here.
189 void DesignMode::registerDesignWidget(QWidget *widget,
190 const QStringList &mimeTypes,
191 const Context &context)
193 int index = d->m_stackWidget->addWidget(widget);
195 DesignEditorInfo *info = new DesignEditorInfo;
196 info->mimeTypes = mimeTypes;
197 info->context = context;
198 info->widgetIndex = index;
199 info->widget = widget;
200 d->m_editors.append(info);
203 void DesignMode::unregisterDesignWidget(QWidget *widget)
205 d->m_stackWidget->removeWidget(widget);
206 foreach(DesignEditorInfo *info, d->m_editors) {
207 if (info->widget == widget) {
208 d->m_editors.removeAll(info);
214 // if editor changes, check if we have valid mimetype registered.
215 void DesignMode::currentEditorChanged(Core::IEditor *editor)
217 if (editor && (d->m_currentEditor.data() == editor))
220 bool mimeEditorAvailable = false;
221 Core::ICore *core = Core::ICore::instance();
223 if (editor && editor->file()) {
224 const QString mimeType = editor->file()->mimeType();
225 if (!mimeType.isEmpty()) {
226 foreach (DesignEditorInfo *editorInfo, d->m_editors) {
227 foreach (const QString &mime, editorInfo->mimeTypes) {
228 if (mime == mimeType) {
229 d->m_stackWidget->setCurrentIndex(editorInfo->widgetIndex);
230 setActiveContext(editorInfo->context);
231 mimeEditorAvailable = true;
236 if (mimeEditorAvailable)
238 } // foreach editorInfo
241 if (d->m_currentEditor)
242 disconnect(d->m_currentEditor.data(), SIGNAL(changed()), this, SLOT(updateActions()));
244 if (!mimeEditorAvailable) {
245 setActiveContext(Context());
246 if (core->modeManager()->currentMode() == this)
247 core->modeManager()->activateMode(Core::Constants::MODE_EDIT);
249 d->m_currentEditor = QWeakPointer<Core::IEditor>();
250 emit actionsUpdated(d->m_currentEditor.data());
252 d->m_currentEditor = QWeakPointer<Core::IEditor>(editor);
254 if (d->m_currentEditor)
255 connect(d->m_currentEditor.data(), SIGNAL(changed()), this, SLOT(updateActions()));
257 emit actionsUpdated(d->m_currentEditor.data());
261 void DesignMode::updateActions()
263 emit actionsUpdated(d->m_currentEditor.data());
266 void DesignMode::updateContext(Core::IMode *newMode, Core::IMode *oldMode)
268 if (newMode == this) {
269 // Apply active context
270 Core::ICore::instance()->updateAdditionalContexts(Context(), d->m_activeContext);
271 } else if (oldMode == this) {
272 // Remove active context
273 Core::ICore::instance()->updateAdditionalContexts(d->m_activeContext, Context());
277 void DesignMode::setActiveContext(const Context &context)
279 if (d->m_activeContext == context)
282 if (ModeManager::instance()->currentMode() == this)
283 Core::ICore::instance()->updateAdditionalContexts(d->m_activeContext, context);
285 d->m_activeContext = context;