OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / coreplugin / designmode.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
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.
18 **
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.
22 **
23 ** Other Usage
24 **
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.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32
33 #include "designmode.h"
34
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>
47
48 #include <QtCore/QPair>
49 #include <QtCore/QFileInfo>
50 #include <QtCore/QStringList>
51 #include <QtCore/QDebug>
52
53 #include <QtGui/QAction>
54 #include <QtGui/QPlainTextEdit>
55 #include <QtGui/QStackedWidget>
56
57 namespace Core {
58
59 class EditorManager;
60
61 enum {
62     debug = false
63 };
64
65 namespace Internal {
66
67 class DesignModeCoreListener : public Core::ICoreListener
68 {
69 public:
70     DesignModeCoreListener(DesignMode* mode);
71     bool coreAboutToClose();
72 private:
73     DesignMode *m_mode;
74 };
75
76 DesignModeCoreListener::DesignModeCoreListener(DesignMode *mode) :
77         m_mode(mode)
78 {
79 }
80
81 bool DesignModeCoreListener::coreAboutToClose()
82 {
83     m_mode->currentEditorChanged(0);
84     return true;
85 }
86
87 } // namespace Internal
88
89 struct DesignEditorInfo {
90     int widgetIndex;
91     QStringList mimeTypes;
92     Context context;
93     QWidget *widget;
94 };
95
96 struct DesignModePrivate {
97     explicit DesignModePrivate(DesignMode *q, EditorManager *editorManager);
98     Internal::DesignModeCoreListener *m_coreListener;
99     QWeakPointer<Core::IEditor> m_currentEditor;
100     bool m_isActive;
101
102     QList<DesignEditorInfo*> m_editors;
103
104     EditorManager *m_editorManager;
105     QStackedWidget *m_stackWidget;
106     Context m_activeContext;
107 };
108
109 DesignModePrivate::DesignModePrivate(DesignMode *q, EditorManager *editorManager) :
110     m_coreListener(new Internal::DesignModeCoreListener(q)),
111     m_isActive(false),
112     m_editorManager(editorManager),
113     m_stackWidget(new QStackedWidget)
114 {
115 }
116
117 DesignMode::DesignMode(EditorManager *editorManager) :
118         IMode(), d(new DesignModePrivate(this, editorManager))
119 {
120     setObjectName(QLatin1String("DesignMode"));
121     setEnabled(false);
122     ExtensionSystem::PluginManager::instance()->addObject(d->m_coreListener);
123
124     connect(editorManager, SIGNAL(currentEditorChanged(Core::IEditor*)),
125             this, SLOT(currentEditorChanged(Core::IEditor*)));
126
127     connect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*,Core::IMode*)),
128             this, SLOT(updateContext(Core::IMode*,Core::IMode*)));
129 }
130
131 DesignMode::~DesignMode()
132 {
133     ExtensionSystem::PluginManager::instance()->removeObject(d->m_coreListener);
134     delete d->m_coreListener;
135
136     qDeleteAll(d->m_editors);
137     delete d;
138 }
139
140 Context DesignMode::context() const
141 {
142     static Context contexts(Constants::C_DESIGN_MODE);
143     return contexts;
144 }
145
146 QWidget *DesignMode::widget()
147 {
148     return d->m_stackWidget;
149 }
150
151 QString DesignMode::displayName() const
152 {
153     return tr("Design");
154 }
155
156 QIcon DesignMode::icon() const
157 {
158     return QIcon(QLatin1String(":/fancyactionbar/images/mode_Design.png"));
159 }
160
161 int DesignMode::priority() const
162 {
163     return Constants::P_MODE_DESIGN;
164 }
165
166 QString DesignMode::id() const
167 {
168     return QLatin1String(Constants::MODE_DESIGN);
169 }
170
171 QString DesignMode::type() const
172 {
173     return QLatin1String(Constants::MODE_DESIGN_TYPE);
174 }
175
176 QStringList DesignMode::registeredMimeTypes() const
177 {
178     QStringList rc;
179     foreach(const DesignEditorInfo *i, d->m_editors)
180         rc += i->mimeTypes;
181     return rc;
182 }
183
184 /**
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.
188   */
189 void DesignMode::registerDesignWidget(QWidget *widget,
190                                       const QStringList &mimeTypes,
191                                       const Context &context)
192 {
193     int index = d->m_stackWidget->addWidget(widget);
194
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);
201 }
202
203 void DesignMode::unregisterDesignWidget(QWidget *widget)
204 {
205     d->m_stackWidget->removeWidget(widget);
206     foreach(DesignEditorInfo *info, d->m_editors) {
207         if (info->widget == widget) {
208             d->m_editors.removeAll(info);
209             break;
210         }
211     }
212 }
213
214 // if editor changes, check if we have valid mimetype registered.
215 void DesignMode::currentEditorChanged(Core::IEditor *editor)
216 {
217     if (editor && (d->m_currentEditor.data() == editor))
218         return;
219
220     bool mimeEditorAvailable = false;
221     Core::ICore *core = Core::ICore::instance();
222
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;
232                         setEnabled(true);
233                         break;
234                     }
235                 } // foreach mime
236                 if (mimeEditorAvailable)
237                     break;
238             } // foreach editorInfo
239         }
240     }
241     if (d->m_currentEditor)
242         disconnect(d->m_currentEditor.data(), SIGNAL(changed()), this, SLOT(updateActions()));
243
244     if (!mimeEditorAvailable) {
245         setActiveContext(Context());
246         if (core->modeManager()->currentMode() == this)
247             core->modeManager()->activateMode(Core::Constants::MODE_EDIT);
248         setEnabled(false);
249         d->m_currentEditor = QWeakPointer<Core::IEditor>();
250         emit actionsUpdated(d->m_currentEditor.data());
251     } else {
252         d->m_currentEditor = QWeakPointer<Core::IEditor>(editor);
253
254         if (d->m_currentEditor)
255             connect(d->m_currentEditor.data(), SIGNAL(changed()), this, SLOT(updateActions()));
256
257         emit actionsUpdated(d->m_currentEditor.data());
258     }
259 }
260
261 void DesignMode::updateActions()
262 {
263     emit actionsUpdated(d->m_currentEditor.data());
264 }
265
266 void DesignMode::updateContext(Core::IMode *newMode, Core::IMode *oldMode)
267 {
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());
274     }
275 }
276
277 void DesignMode::setActiveContext(const Context &context)
278 {
279     if (d->m_activeContext == context)
280         return;
281
282     if (ModeManager::instance()->currentMode() == this)
283         Core::ICore::instance()->updateAdditionalContexts(d->m_activeContext, context);
284
285     d->m_activeContext = context;
286 }
287
288 } // namespace Core