Commit df7a19de authored by Lasse Holmstedt's avatar Lasse Holmstedt

Design mode integration

Moved Qt Designer to open from Design Mode. Also, Design mode is now global,
and created in coreplugin. Other plugins can register themselves to it.
parent 57ee6f07
......@@ -63,8 +63,10 @@ const char * const IDE_REVISION_STR = "";
//modes
const char * const MODE_WELCOME = "Welcome";
const char * const MODE_EDIT = "Edit";
const char * const MODE_DESIGN = "Design";
const int P_MODE_WELCOME = 100;
const int P_MODE_EDIT = 90;
const int P_MODE_DESIGN = 89;
const int P_MODE_OUTPUT = 10;
//menubar
......@@ -87,6 +89,7 @@ const char * const C_GLOBAL = "Global Context";
const int C_GLOBAL_ID = 0;
const char * const C_WELCOME_MODE = "Core.WelcomeMode";
const char * const C_EDIT_MODE = "Core.EditMode";
const char * const C_DESIGN_MODE = "Core.DesignMode";
const char * const C_EDITORMANAGER = "Core.EditorManager";
const char * const C_NAVIGATION_PANE = "Core.NavigationPane";
const char * const C_PROBLEM_PANE = "Core.ProblemPane";
......
......@@ -33,12 +33,14 @@
#include "mainwindow.h"
#include "modemanager.h"
#include "fileiconprovider.h"
#include "designmode.h"
#include <extensionsystem/pluginmanager.h>
#include <QtCore/QtPlugin>
#include <QtCore/QDebug>
using namespace Core;
using namespace Core::Internal;
CorePlugin::CorePlugin() :
......@@ -53,6 +55,11 @@ CorePlugin::~CorePlugin()
delete m_editMode;
}
if (m_designMode) {
removeObject(m_designMode);
delete m_designMode;
}
// delete FileIconProvider singleton
delete FileIconProvider::instance();
......@@ -78,6 +85,9 @@ bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage)
EditorManager *editorManager = m_mainWindow->editorManager();
m_editMode = new EditMode(editorManager);
addObject(m_editMode);
m_designMode = new DesignMode(editorManager);
addObject(m_designMode);
}
return success;
}
......
......@@ -33,6 +33,7 @@
#include <extensionsystem/iplugin.h>
namespace Core {
class DesignMode;
namespace Internal {
class EditMode;
......@@ -59,6 +60,7 @@ private:
MainWindow *m_mainWindow;
EditMode *m_editMode;
DesignMode *m_designMode;
};
} // namespace Internal
......
......@@ -80,7 +80,9 @@ SOURCES += mainwindow.cpp \
settingsdatabase.cpp \
eventfilteringmainwindow.cpp \
imode.cpp \
editormanager/systemeditor.cpp
editormanager/systemeditor.cpp \
designmode.cpp
HEADERS += mainwindow.h \
editmode.h \
tabpositionindicator.h \
......@@ -158,7 +160,9 @@ HEADERS += mainwindow.h \
mimedatabase.h \
settingsdatabase.h \
eventfilteringmainwindow.h \
editormanager/systemeditor.h
editormanager/systemeditor.h \
designmode.h
FORMS += dialogs/newdialog.ui \
dialogs/shortcutsettings.ui \
dialogs/saveitemsdialog.ui \
......
......@@ -28,8 +28,6 @@
**************************************************************************/
#include "designmode.h"
#include "qmldesignerconstants.h"
#include "designmodewidget.h"
#include <coreplugin/icore.h>
#include <coreplugin/modemanager.h>
......@@ -39,21 +37,28 @@
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/mimedatabase.h>
#include <extensionsystem/pluginmanager.h>
#include <QAction>
#include <QDebug>
#include <QPlainTextEdit>
#include <QFileInfo>
#include <QtCore/QPair>
#include <QtCore/QFileInfo>
#include <QtGui/QAction>
namespace QmlDesigner {
namespace Internal {
#include <QtGui/QPlainTextEdit>
#include <QtGui/QStackedWidget>
#include <QtCore/QDebug>
namespace Core {
class EditorManager;
enum {
debug = false
};
namespace Internal {
DesignModeCoreListener::DesignModeCoreListener(DesignMode *mode) :
m_mode(mode)
{
......@@ -61,113 +66,33 @@ DesignModeCoreListener::DesignModeCoreListener(DesignMode *mode) :
bool DesignModeCoreListener::coreAboutToClose()
{
// make sure settings are stored before actual program exit
m_mode->currentEditorChanged(0);
return true;
}
DesignMode::DesignMode() :
} // namespace Internal
DesignMode::DesignMode(EditorManager *editorManager) :
IMode(),
m_mainWidget(new DesignModeWidget(this)),
m_coreListener(new DesignModeCoreListener(this)),
m_coreListener(new Internal::DesignModeCoreListener(this)),
m_isActive(false),
m_revertToSavedAction(new QAction(this)),
m_saveAction(new QAction(this)),
m_saveAsAction(new QAction(this)),
m_closeCurrentEditorAction(new QAction(this)),
m_closeAllEditorsAction(new QAction(this)),
m_closeOtherEditorsAction(new QAction(this))
m_editorManager(editorManager),
m_stackWidget(new QStackedWidget)
{
Core::ICore *creatorCore = Core::ICore::instance();
Core::ModeManager *modeManager = creatorCore->modeManager();
connect(modeManager, SIGNAL(currentModeChanged(Core::IMode*)),
this, SLOT(modeChanged(Core::IMode*)));
setEnabled(false);
ExtensionSystem::PluginManager::instance()->addObject(m_coreListener);
Core::ActionManager *actionManager = creatorCore->actionManager();
Core::EditorManager *editorManager = creatorCore->editorManager();
// Undo / Redo
actionManager->registerAction(m_mainWidget->undoAction(), Core::Constants::UNDO, context());
actionManager->registerAction(m_mainWidget->redoAction(), Core::Constants::REDO, context());
// Revert to saved
actionManager->registerAction(m_revertToSavedAction,
Core::Constants::REVERTTOSAVED, context());
connect(m_revertToSavedAction, SIGNAL(triggered()), editorManager, SLOT(revertToSaved()));
//Save
actionManager->registerAction(m_saveAction, Core::Constants::SAVE, context());
connect(m_saveAction, SIGNAL(triggered()), editorManager, SLOT(saveFile()));
//Save As
actionManager->registerAction(m_saveAsAction, Core::Constants::SAVEAS, context());
connect(m_saveAsAction, SIGNAL(triggered()), editorManager, SLOT(saveFileAs()));
//Close Editor
actionManager->registerAction(m_closeCurrentEditorAction, Core::Constants::CLOSE, context());
connect(m_closeCurrentEditorAction, SIGNAL(triggered()), editorManager, SLOT(closeEditor()));
//Close All
actionManager->registerAction(m_closeAllEditorsAction, Core::Constants::CLOSEALL, context());
connect(m_closeAllEditorsAction, SIGNAL(triggered()), editorManager, SLOT(closeAllEditors()));
//Close All Others Action
actionManager->registerAction(m_closeOtherEditorsAction, Core::Constants::CLOSEOTHERS, context());
connect(m_closeOtherEditorsAction, SIGNAL(triggered()), editorManager, SLOT(closeOtherEditors()));
connect(editorManager, SIGNAL(currentEditorChanged(Core::IEditor*)),
this, SLOT(currentEditorChanged(Core::IEditor*)));
connect(editorManager, SIGNAL(editorsClosed(QList<Core::IEditor*>)),
this, SLOT(textEditorsClosed(QList<Core::IEditor*>)));
Core::ActionContainer *editMenu = actionManager->actionContainer(Core::Constants::M_EDIT);
Core::Command *command;
command = actionManager->registerAction(m_mainWidget->deleteAction(),
QmlDesigner::Constants::DELETE, context());
command->setDefaultKeySequence(QKeySequence::Delete);
command->setAttribute(Core::Command::CA_Hide); // don't show delete in other modes
editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE);
command = actionManager->registerAction(m_mainWidget->cutAction(),
Core::Constants::CUT, context());
command->setDefaultKeySequence(QKeySequence::Cut);
editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE);
command = actionManager->registerAction(m_mainWidget->copyAction(),
Core::Constants::COPY, context());
command->setDefaultKeySequence(QKeySequence::Copy);
editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE);
command = actionManager->registerAction(m_mainWidget->pasteAction(),
Core::Constants::PASTE, context());
command->setDefaultKeySequence(QKeySequence::Paste);
editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE);
command = actionManager->registerAction(m_mainWidget->selectAllAction(),
Core::Constants::SELECTALL, context());
command->setDefaultKeySequence(QKeySequence::SelectAll);
editMenu->addAction(command, Core::Constants::G_EDIT_SELECTALL);
// add second shortcut to trigger delete
QAction *deleteAction = new QAction(m_mainWidget);
deleteAction->setShortcut(QKeySequence(QLatin1String("Backspace")));
connect(deleteAction, SIGNAL(triggered()), m_mainWidget->deleteAction(),
SIGNAL(triggered()));
m_mainWidget->addAction(deleteAction);
updateActions();
//updateActions();
}
DesignMode::~DesignMode()
{
delete m_mainWidget;
ExtensionSystem::PluginManager::instance()->removeObject(m_coreListener);
delete m_coreListener;
qDeleteAll(m_editors);
}
QList<int> DesignMode::context() const
......@@ -179,12 +104,12 @@ QList<int> DesignMode::context() const
QWidget *DesignMode::widget()
{
return m_mainWidget;
return m_stackWidget;
}
QString DesignMode::displayName() const
{
return tr(Constants::DESIGN_MODE_NAME);
return tr(Constants::MODE_DESIGN);
}
QIcon DesignMode::icon() const
......@@ -194,38 +119,79 @@ QIcon DesignMode::icon() const
int DesignMode::priority() const
{
return Constants::DESIGN_MODE_PRIORITY;
return Constants::P_MODE_DESIGN;
}
QString DesignMode::id() const
{
return QLatin1String(Constants::DESIGN_MODE_NAME);
return QLatin1String(Constants::MODE_DESIGN);
}
void DesignMode::textEditorsClosed(QList<Core::IEditor*> editors)
void DesignMode::registerDesignWidget(QWidget *widget, const QStringList &mimeTypes, bool preferDesignMode)
{
m_mainWidget->closeEditors(editors);
int index = m_stackWidget->addWidget(widget);
DesignEditorInfo *info = new DesignEditorInfo;
info->preferredMode = preferDesignMode;
info->mimeTypes = mimeTypes;
info->widgetIndex = index;
info->widget = widget;
m_editors.append(info);
}
void DesignMode::modeChanged(Core::IMode *mode)
void DesignMode::unregisterDesignWidget(QWidget *widget)
{
if (debug)
qDebug() << Q_FUNC_INFO << ((mode == this) ? "Design mode" : "other mode");
if (mode == this) {
m_isActive = true;
m_mainWidget->showEditor(m_currentEditor.data());
} else {
if (m_isActive) {
m_isActive = false;
m_mainWidget->showEditor(0);
m_stackWidget->removeWidget(widget);
foreach(DesignEditorInfo *info, m_editors) {
if (info->widget == widget) {
m_editors.removeAll(info);
break;
}
}
}
// if editor changes, check if we have valid mimetype registered.
void DesignMode::currentEditorChanged(Core::IEditor *editor)
{
if (debug)
qDebug() << Q_FUNC_INFO << editor;
bool mimeEditorAvailable = false;
bool modeActivated = false;
Core::ICore *core = Core::ICore::instance();
if (editor && editor->file()) {
MimeType type = core->mimeDatabase()->findByFile(QFileInfo(editor->file()->fileName()));
QString mimeType = editor->file()->mimeType();
if (type && !type.type().isEmpty())
mimeType = type.type();
foreach(DesignEditorInfo *editorInfo, m_editors) {
foreach(QString mime, editorInfo->mimeTypes) {
if (mime == mimeType) {
m_stackWidget->setCurrentIndex(editorInfo->widgetIndex);
mimeEditorAvailable = true;
setEnabled(true);
if (editorInfo->preferredMode && core->modeManager()->currentMode() != this) {
core->modeManager()->activateMode(Constants::MODE_DESIGN);
modeActivated = true;
}
break;
}
}
if (mimeEditorAvailable)
break;
}
}
if (!mimeEditorAvailable)
setEnabled(false);
if ((!mimeEditorAvailable && core->modeManager()->currentMode() == this)
|| !modeActivated)
{
// switch back to edit mode
core->modeManager()->activateMode(Constants::MODE_EDIT);
}
if (m_currentEditor.data() == editor)
return;
......@@ -238,55 +204,12 @@ void DesignMode::currentEditorChanged(Core::IEditor *editor)
if (m_currentEditor)
connect(m_currentEditor.data(), SIGNAL(changed()), this, SLOT(updateActions()));
updateActions();
emit actionsUpdated(m_currentEditor.data());
}
void DesignMode::makeCurrentEditorWritable()
{
Core::ICore *creatorCore = Core::ICore::instance();
if (m_currentEditor)
creatorCore->editorManager()->makeEditorWritable(m_currentEditor.data());
}
// copied from EditorManager::updateActions
void DesignMode::updateActions()
{
Core::ICore *creatorCore = Core::ICore::instance();
Core::EditorManager *editorManager = creatorCore->editorManager();
Core::IEditor *curEditor = m_currentEditor.data();
int openedCount = editorManager->openedEditors().count()
+ editorManager->openedEditorsModel()->restoredEditors().count();
QString fName;
if (curEditor) {
if (!curEditor->file()->fileName().isEmpty()) {
QFileInfo fi(curEditor->file()->fileName());
fName = fi.fileName();
} else {
fName = curEditor->displayName();
}
}
m_saveAction->setEnabled(curEditor != 0 && curEditor->file()->isModified());
m_saveAsAction->setEnabled(curEditor != 0 && curEditor->file()->isSaveAsAllowed());
m_revertToSavedAction->setEnabled(curEditor != 0
&& !curEditor->file()->fileName().isEmpty()
&& curEditor->file()->isModified());
QString quotedName;
if (!fName.isEmpty())
quotedName = '"' + fName + '"';
m_saveAsAction->setText(tr("Save %1 As...").arg(quotedName));
m_saveAction->setText(tr("&Save %1").arg(quotedName));
m_revertToSavedAction->setText(tr("Revert %1 to Saved").arg(quotedName));
m_closeCurrentEditorAction->setEnabled(curEditor != 0);
m_closeCurrentEditorAction->setText(tr("Close %1").arg(quotedName));
m_closeAllEditorsAction->setEnabled(openedCount > 0);
m_closeOtherEditorsAction->setEnabled(openedCount > 1);
m_closeOtherEditorsAction->setText((openedCount > 1 ? tr("Close All Except %1").arg(quotedName) : tr("Close Others")));
emit actionsUpdated(m_currentEditor.data());
}
} // namespace Internal
} // namespace QmlDesigner
} // namespace Core
......@@ -2,7 +2,7 @@
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
......@@ -35,16 +35,19 @@
#include <coreplugin/editormanager/ieditor.h>
#include <QWeakPointer>
#include <QPair>
#include <QStringList>
QT_BEGIN_NAMESPACE
class QAction;
class QStackedWidget;
QT_END_NAMESPACE
namespace QmlDesigner {
namespace Internal {
namespace Core {
class EditorManager;
class DesignMode;
class DesignModeWidget;
namespace Internal {
class DesignModeCoreListener : public Core::ICoreListener
{
......@@ -56,14 +59,25 @@ private:
DesignMode *m_mode;
};
class DesignMode : public Core::IMode
} // namespace Internal
/**
* A global mode for Design pane - used by Bauhaus (QML Designer) and
* Qt Designer. Other plugins can register themselves by registerDesignWidget()
* and giving a list of mimetypes that the editor understands, as well as an instance
* to the main editor widget itself.
*/
class CORE_EXPORT DesignMode : public Core::IMode
{
Q_OBJECT
public:
DesignMode();
DesignMode(EditorManager *editorManager);
~DesignMode();
void registerDesignWidget(QWidget *widget, const QStringList &mimeTypes,
bool preferDesignMode = false);
void unregisterDesignWidget(QWidget *widget);
// IContext
QList<int> context() const;
QWidget *widget();
......@@ -74,30 +88,34 @@ public:
int priority() const;
QString id() const;
signals:
void actionsUpdated(Core::IEditor *editor);
private slots:
void textEditorsClosed(QList<Core::IEditor *> editors);
void modeChanged(Core::IMode *mode);
void currentEditorChanged(Core::IEditor *editor);
void makeCurrentEditorWritable();
void updateActions();
private:
DesignModeWidget *m_mainWidget;
DesignModeCoreListener *m_coreListener;
Internal::DesignModeCoreListener *m_coreListener;
QWeakPointer<Core::IEditor> m_currentEditor;
bool m_isActive;
QAction *m_revertToSavedAction;
QAction *m_saveAction;
QAction *m_saveAsAction;
QAction *m_closeCurrentEditorAction;
QAction *m_closeAllEditorsAction;
QAction *m_closeOtherEditorsAction;
struct DesignEditorInfo {
int widgetIndex;
QStringList mimeTypes;
bool preferredMode;
QWidget *widget;
};
QList<DesignEditorInfo*> m_editors;
EditorManager *m_editorManager;
QStackedWidget *m_stackWidget;
friend class DesignModeCoreListener;
friend class Internal::DesignModeCoreListener;
};
} // namespace Internal
} // namespace QmlDesigner
} // namespace Core
#endif // DESIGNMODE_H
......@@ -230,6 +230,11 @@ EditorManager::EditorManager(ICore *core, QWidget *parent) :
const QList<int> editManagerContext =
QList<int>() << m_d->m_core->uniqueIDManager()->uniqueIdentifier(Constants::C_EDITORMANAGER);
// combined context for edit & design modes
const QList<int> editDesignContext =
QList<int>() << m_d->m_core->uniqueIDManager()->uniqueIdentifier(Constants::C_EDITORMANAGER)
<< m_d->m_core->uniqueIDManager()->uniqueIdentifier(Constants::C_DESIGN_MODE);
ActionManager *am = m_d->m_core->actionManager();
ActionContainer *mfile = am->actionContainer(Constants::M_FILE);
......@@ -284,7 +289,7 @@ EditorManager::EditorManager(ICore *core, QWidget *parent) :
connect(m_d->m_closeOtherEditorsAction, SIGNAL(triggered()), this, SLOT(closeOtherEditors()));
// Goto Previous In History Action
cmd = am->registerAction(m_d->m_gotoPreviousDocHistoryAction, Constants::GOTOPREVINHISTORY, editManagerContext);
cmd = am->registerAction(m_d->m_gotoPreviousDocHistoryAction, Constants::GOTOPREVINHISTORY, editDesignContext);
#ifdef Q_WS_MAC
cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Tab")));
#else
......@@ -294,7 +299,7 @@ EditorManager::EditorManager(ICore *core, QWidget *parent) :
connect(m_d->m_gotoPreviousDocHistoryAction, SIGNAL(triggered()), this, SLOT(gotoPreviousDocHistory()));
// Goto Next In History Action
cmd = am->registerAction(m_d->m_gotoNextDocHistoryAction, Constants::GOTONEXTINHISTORY, editManagerContext);
cmd = am->registerAction(m_d->m_gotoNextDocHistoryAction, Constants::GOTONEXTINHISTORY, editDesignContext);
#ifdef Q_WS_MAC
cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Shift+Tab")));
#else
......@@ -304,7 +309,7 @@ EditorManager::EditorManager(ICore *core, QWidget *parent) :
connect(m_d->m_gotoNextDocHistoryAction, SIGNAL(triggered()), this, SLOT(gotoNextDocHistory()));
// Go back in navigation history
cmd = am->registerAction(m_d->m_goBackAction, Constants::GO_BACK, editManagerContext);
cmd = am->registerAction(m_d->m_goBackAction, Constants::GO_BACK, editDesignContext);
#ifdef Q_WS_MAC
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Left")));
#else
......@@ -314,7 +319,7 @@ EditorManager::EditorManager(ICore *core, QWidget *parent) :
connect(m_d->m_goBackAction, SIGNAL(triggered()), this, SLOT(goBackInNavigationHistory()));
// Go forward in navigation history
cmd = am->registerAction(m_d->m_goForwardAction, Constants::GO_FORWARD, editManagerContext);
cmd = am->registerAction(m_d->m_goForwardAction, Constants::GO_FORWARD, editDesignContext);
#ifdef Q_WS_MAC
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Right")));
#else
......@@ -522,8 +527,6 @@ Core::Internal::EditorView *EditorManager::currentEditorView() const
return currentSplitterOrView()->view();
}
QList<IEditor *> EditorManager::editorsForFileName(const QString &filename) const