diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h index 0b95a671a832ed56af722619173faa17a8f7d115..964b57f819a9c731bc22addf5e1b4fed3f90dc1f 100644 --- a/src/plugins/coreplugin/coreconstants.h +++ b/src/plugins/coreplugin/coreconstants.h @@ -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"; diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp index 8b9317fb65131c06125586a9597cdec9064e4f76..874cf6ba2ae5acfdf00421297cff2ca3e6872242 100644 --- a/src/plugins/coreplugin/coreplugin.cpp +++ b/src/plugins/coreplugin/coreplugin.cpp @@ -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; } diff --git a/src/plugins/coreplugin/coreplugin.h b/src/plugins/coreplugin/coreplugin.h index 3c03c7b836c72d0f38a9c4d35bc5c8d4e3ade616..087d168fe9dad58e580b49ed36e87e6827b9c27c 100644 --- a/src/plugins/coreplugin/coreplugin.h +++ b/src/plugins/coreplugin/coreplugin.h @@ -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 diff --git a/src/plugins/coreplugin/coreplugin.pro b/src/plugins/coreplugin/coreplugin.pro index 1e1cd45a9e2932607add6ce0a78753308fd0256b..837358f22044cee816ac7c7b59973b1fc05bba89 100644 --- a/src/plugins/coreplugin/coreplugin.pro +++ b/src/plugins/coreplugin/coreplugin.pro @@ -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 \ diff --git a/src/plugins/coreplugin/designmode.cpp b/src/plugins/coreplugin/designmode.cpp new file mode 100644 index 0000000000000000000000000000000000000000..89702fd05fb382927f35c389308482a64e722ef2 --- /dev/null +++ b/src/plugins/coreplugin/designmode.cpp @@ -0,0 +1,215 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "designmode.h" + +#include <coreplugin/icore.h> +#include <coreplugin/modemanager.h> +#include <coreplugin/uniqueidmanager.h> +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/editormanager/openeditorsmodel.h> +#include <coreplugin/actionmanager/actionmanager.h> +#include <coreplugin/actionmanager/command.h> +#include <coreplugin/coreconstants.h> +#include <coreplugin/mimedatabase.h> +#include <extensionsystem/pluginmanager.h> + +#include <QtCore/QPair> +#include <QtCore/QFileInfo> +#include <QtGui/QAction> + +#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) +{ +} + +bool DesignModeCoreListener::coreAboutToClose() +{ + m_mode->currentEditorChanged(0); + return true; +} + +} // namespace Internal + +DesignMode::DesignMode(EditorManager *editorManager) : + IMode(), + m_coreListener(new Internal::DesignModeCoreListener(this)), + m_isActive(false), + m_editorManager(editorManager), + m_stackWidget(new QStackedWidget) +{ + setEnabled(false); + ExtensionSystem::PluginManager::instance()->addObject(m_coreListener); + + connect(editorManager, SIGNAL(currentEditorChanged(Core::IEditor*)), + this, SLOT(currentEditorChanged(Core::IEditor*))); + //updateActions(); +} + +DesignMode::~DesignMode() +{ + ExtensionSystem::PluginManager::instance()->removeObject(m_coreListener); + delete m_coreListener; + + qDeleteAll(m_editors); +} + +QList<int> DesignMode::context() const +{ + static QList<int> contexts = QList<int>() << + Core::UniqueIDManager::instance()->uniqueIdentifier(Constants::C_DESIGN_MODE); + return contexts; +} + +QWidget *DesignMode::widget() +{ + return m_stackWidget; +} + +QString DesignMode::displayName() const +{ + return tr(Constants::MODE_DESIGN); +} + +QIcon DesignMode::icon() const +{ + return QIcon(QLatin1String(":/qmldesigner/images/mode_Design.png")); +} + +int DesignMode::priority() const +{ + return Constants::P_MODE_DESIGN; +} + +QString DesignMode::id() const +{ + return QLatin1String(Constants::MODE_DESIGN); +} + +void DesignMode::registerDesignWidget(QWidget *widget, const QStringList &mimeTypes, bool preferDesignMode) +{ + 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::unregisterDesignWidget(QWidget *widget) +{ + 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) +{ + 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; + + if (m_currentEditor) + disconnect(m_currentEditor.data(), SIGNAL(changed()), this, SLOT(updateActions())); + + m_currentEditor = QWeakPointer<Core::IEditor>(editor); + + if (m_currentEditor) + connect(m_currentEditor.data(), SIGNAL(changed()), this, SLOT(updateActions())); + + emit actionsUpdated(m_currentEditor.data()); +} + +void DesignMode::updateActions() +{ + emit actionsUpdated(m_currentEditor.data()); +} + +} // namespace Core diff --git a/src/plugins/qmldesigner/designmode.h b/src/plugins/coreplugin/designmode.h similarity index 64% rename from src/plugins/qmldesigner/designmode.h rename to src/plugins/coreplugin/designmode.h index 89e407b77a890a4141ae33e0a95c8fb37dc64b88..c52b264a08fa3279105bf78b94d5936c1ff842a4 100644 --- a/src/plugins/qmldesigner/designmode.h +++ b/src/plugins/coreplugin/designmode.h @@ -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 diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 7d6b2b220998ad1393e1a8986735c7e1fd2133e7..fbf2fd5bf0baab1fb33c6fce13667b1e21c1eea9 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -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 { QList<IEditor *> found; @@ -919,6 +922,7 @@ Core::IEditor *EditorManager::activateEditor(Core::Internal::EditorView *view, C if (isVisible()) editor->widget()->setFocus(); } + emit currentEditorChanged(editor); return editor; } @@ -1445,7 +1449,9 @@ void EditorManager::updateActions() QString fName; IEditor *curEditor = currentEditor(); int openedCount = openedEditors().count() + m_d->m_editorModel->restoredEditors().count(); + if (curEditor) { + if (!curEditor->file()->fileName().isEmpty()) { QFileInfo fi(curEditor->file()->fileName()); fName = fi.fileName(); @@ -1453,7 +1459,6 @@ void EditorManager::updateActions() fName = curEditor->displayName(); } - if (curEditor->file()->isModified() && curEditor->file()->isReadOnly()) { // we are about to change a read-only file, warn user showEditorInfoBar(QLatin1String("Core.EditorManager.MakeWritable"), @@ -1472,11 +1477,11 @@ void EditorManager::updateActions() QString quotedName; if (!fName.isEmpty()) quotedName = '"' + fName + '"'; + m_d->m_saveAsAction->setText(tr("Save %1 &As...").arg(quotedName)); m_d->m_saveAction->setText(tr("&Save %1").arg(quotedName)); m_d->m_revertToSavedAction->setText(tr("Revert %1 to Saved").arg(quotedName)); - m_d->m_closeCurrentEditorAction->setEnabled(curEditor != 0); m_d->m_closeCurrentEditorAction->setText(tr("Close %1").arg(quotedName)); m_d->m_closeAllEditorsAction->setEnabled(openedCount > 0); @@ -1700,7 +1705,6 @@ void EditorManager::showEditorInfoBar(const QString &id, const QString &buttonText, QObject *object, const char *member) { - currentEditorView()->showEditorInfoBar(id, infoText, buttonText, object, member); } diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 2dd2429772ce26ae76f5579784f4a1d8795602de..8516d1588258b17a3b6c87e1d87478fc4ad8c232 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -788,7 +788,6 @@ static IFileFactory *findFileFactory(const QList<IFileFactory*> &fileFactories, // opens either an editor or loads a project void MainWindow::openFiles(const QStringList &fileNames) { - bool needToSwitchToEditor = false; QList<IFileFactory*> nonEditorFileFactories = getNonEditorFileFactories(); foreach (const QString &fileName, fileNames) { @@ -797,13 +796,9 @@ void MainWindow::openFiles(const QStringList &fileNames) if (IFileFactory *fileFactory = findFileFactory(nonEditorFileFactories, mimeDatabase(), fi)) { fileFactory->open(absoluteFilePath); } else { - IEditor *editor = editorManager()->openEditor(absoluteFilePath); - if (editor) - needToSwitchToEditor = true; + editorManager()->openEditor(absoluteFilePath); } } - if (needToSwitchToEditor) - editorManager()->ensureEditorManagerVisible(); } void MainWindow::setFocusToEditor() diff --git a/src/plugins/designer/designer.pro b/src/plugins/designer/designer.pro index bf4653357485a54507bd79b3b510e2e321e7fe00..48d9e3db1802848a17941f3b5ca81dc0d5504d38 100644 --- a/src/plugins/designer/designer.pro +++ b/src/plugins/designer/designer.pro @@ -36,7 +36,11 @@ HEADERS += formeditorplugin.h \ formtemplatewizardpage.h \ formwizarddialog.h \ codemodelhelpers.h \ - designer_export.h + designer_export.h \ + designerxmleditor.h \ + designercontext.h \ + faketoolbar.h \ + formeditorstack.h SOURCES += formeditorplugin.cpp \ formeditorfactory.cpp \ @@ -51,8 +55,12 @@ SOURCES += formeditorplugin.cpp \ settingsmanager.cpp \ formtemplatewizardpage.cpp \ formwizarddialog.cpp \ - codemodelhelpers.cpp + codemodelhelpers.cpp \ + designerxmleditor.cpp \ + designercontext.cpp \ + faketoolbar.cpp \ + formeditorstack.cpp RESOURCES += designer.qrc -OTHER_FILES += Designer.pluginspec +OTHER_FILES += Designer.pluginspec Designer.mimetypes.xml diff --git a/src/plugins/designer/designerconstants.h b/src/plugins/designer/designerconstants.h index 2df76db73e8fc151529e71c04ed1aa84a7c2accc..91448fd62148cf6689203a757772453e7d0e28d2 100644 --- a/src/plugins/designer/designerconstants.h +++ b/src/plugins/designer/designerconstants.h @@ -35,6 +35,12 @@ namespace Designer { namespace Constants { +const char * const INFO_READ_ONLY = "DesignerXmlEditor.ReadOnly"; +const char * const K_DESIGNER_XML_EDITOR_ID = "FormEditor.DesignerXmlEditor"; +const char * const C_DESIGNER_XML_EDITOR = "Designer Xml Editor"; +const char * const DESIGNER_XML_EDITOR_ID ="DesignerXmlEditor"; +const char * const C_DESIGNER_XML_DISPLAY_NAME = QT_TRANSLATE_NOOP("Designer", "Xml Editor"); + const char * const SETTINGS_CATEGORY = "P.Designer"; const char * const SETTINGS_TR_CATEGORY = QT_TRANSLATE_NOOP("Designer", "Designer"); const char * const SETTINGS_CPP_SETTINGS_ID = "Class Generation"; diff --git a/src/plugins/designer/designercontext.cpp b/src/plugins/designer/designercontext.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69f0678d8e49f433a0afb73d631ebfc4f29d0438 --- /dev/null +++ b/src/plugins/designer/designercontext.cpp @@ -0,0 +1,72 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "designercontext.h" +#include "designerconstants.h" +#include <coreplugin/uniqueidmanager.h> +#include <coreplugin/coreconstants.h> + +#include <QWidget> + +namespace Designer { +namespace Internal { + +DesignerContext::DesignerContext(QWidget *widget) : Core::IContext(widget), + m_widget(widget) +{ + Core::UniqueIDManager *idMan = Core::UniqueIDManager::instance(); + m_context << idMan->uniqueIdentifier(Designer::Constants::C_FORMEDITOR) + << idMan->uniqueIdentifier(Core::Constants::C_EDITORMANAGER) + << idMan->uniqueIdentifier(Core::Constants::C_DESIGN_MODE); + +} + +DesignerContext::~DesignerContext() +{ + +} + +QList<int> DesignerContext::context() const +{ + return m_context; +} + +QWidget *DesignerContext::widget() +{ + return m_widget; +} + +void DesignerContext::setWidget(QWidget *widget) +{ + m_widget = widget; +} + +} +} + diff --git a/src/plugins/designer/designercontext.h b/src/plugins/designer/designercontext.h new file mode 100644 index 0000000000000000000000000000000000000000..00d798387a58553aafdaceef4ddf531aba9f6181 --- /dev/null +++ b/src/plugins/designer/designercontext.h @@ -0,0 +1,60 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef DESIGNERCONTEXT_H +#define DESIGNERCONTEXT_H + +#include <coreplugin/icontext.h> +#include <QList> + +QT_BEGIN_NAMESPACE +class QWidget; +QT_END_NAMESPACE + +namespace Designer { +namespace Internal { + +class DesignerContext : public Core::IContext +{ +public: + DesignerContext(QWidget *widget = 0); + ~DesignerContext(); + QList<int> context() const; + QWidget *widget(); + void setWidget(QWidget *widget); +private: + QList<int> m_context; + QWidget *m_widget; +}; + +} +} + + +#endif // DESIGNERCONTEXT_H diff --git a/src/plugins/designer/designerxmleditor.cpp b/src/plugins/designer/designerxmleditor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b8d4937092fdb6b19eac8e5640d68c1e30ef06da --- /dev/null +++ b/src/plugins/designer/designerxmleditor.cpp @@ -0,0 +1,98 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "designerxmleditor.h" +#include "designerconstants.h" +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/icore.h> +#include <coreplugin/modemanager.h> +#include <coreplugin/imode.h> +#include <coreplugin/coreconstants.h> +#include <coreplugin/uniqueidmanager.h> +#include <QDebug> + +using namespace Designer::Internal; + +DesignerXmlEditor::DesignerXmlEditor(QWidget *parent) : TextEditor::PlainTextEditor(parent) +{ + setReadOnly(true); + connect(Core::ICore::instance()->editorManager(), SIGNAL(currentEditorChanged(Core::IEditor*)), + SLOT(updateEditorInfoBar(Core::IEditor*))); +} + +DesignerXmlEditor::~DesignerXmlEditor() +{ + +} + +bool DesignerXmlEditor::open(const QString &fileName) +{ + bool res = TextEditor::PlainTextEditor::open(fileName); + QPlainTextEdit::setReadOnly(true); + return res; +} + +void DesignerXmlEditor::updateEditorInfoBar(Core::IEditor *editor) +{ + if (editor == editableInterface()) { + Core::EditorManager::instance()->showEditorInfoBar(Constants::INFO_READ_ONLY, + tr("This file can only be edited in Design Mode."), + "Open Designer", this, SLOT(designerOpened())); + } + if (!editor) + Core::EditorManager::instance()->hideEditorInfoBar(Constants::INFO_READ_ONLY); +} + +void DesignerXmlEditor::designerOpened() +{ + Core::ICore::instance()->modeManager()->activateMode(Core::Constants::MODE_DESIGN); +} + +QString DesignerXmlEditorEditable::id() const +{ + return QLatin1String(Designer::Constants::K_DESIGNER_XML_EDITOR_ID); +} +DesignerXmlEditorEditable::DesignerXmlEditorEditable(DesignerXmlEditor *editor) + : TextEditor::PlainTextEditorEditable(editor) +{ + Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance(); + m_context << uidm->uniqueIdentifier(Designer::Constants::K_DESIGNER_XML_EDITOR_ID); + m_context << uidm->uniqueIdentifier(Designer::Constants::C_DESIGNER_XML_EDITOR); +} + +QList<int> DesignerXmlEditorEditable::context() const +{ + return m_context; +} + +Core::IEditor *DesignerXmlEditorEditable::duplicate(QWidget *parent) +{ + Q_UNUSED(parent); + return 0; +} diff --git a/src/plugins/designer/designerxmleditor.h b/src/plugins/designer/designerxmleditor.h new file mode 100644 index 0000000000000000000000000000000000000000..4c5d410f6db85f0545bf9971e058fa5a6ce851e0 --- /dev/null +++ b/src/plugins/designer/designerxmleditor.h @@ -0,0 +1,89 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef DESIGNERXMLEDITOR_H +#define DESIGNERXMLEDITOR_H + +#include <texteditor/plaintexteditor.h> +#include <texteditor/basetexteditor.h> + +namespace Core { + class IEditor; + class IMode; +} + +namespace Designer { +namespace Internal { + +class DesignerXmlEditor; + +class TEXTEDITOR_EXPORT DesignerXmlEditorEditable : public TextEditor::PlainTextEditorEditable +{ + Q_OBJECT +public: + DesignerXmlEditorEditable(DesignerXmlEditor *editor); + QList<int> context() const; + + bool duplicateSupported() const { return false; } + Core::IEditor *duplicate(QWidget *parent); + virtual QString id() const; + +private: + QList<int> m_context; +}; + +/** + * A stub-like, read-only text editor which displays UI files as text. Could be used as a + * read/write editor too, but due to lack of XML editor, highlighting and other such + * functionality, editing is disabled. + */ +class DesignerXmlEditor : public TextEditor::PlainTextEditor +{ + Q_OBJECT +public: + DesignerXmlEditor(QWidget *parent = 0); + virtual ~DesignerXmlEditor(); + bool open(const QString &fileName = QString()); + +private slots: + void designerOpened(); + void updateEditorInfoBar(Core::IEditor *editor); + +protected: + virtual TextEditor::BaseTextEditorEditable *createEditableInterface() { return new DesignerXmlEditorEditable(this); } + +private: + + +}; + +} // Internal +} // Designer + +#endif // DESIGNERXMLEDITOR_H diff --git a/src/plugins/designer/editorwidget.cpp b/src/plugins/designer/editorwidget.cpp index c12a07610043e2e7c1534ac13f4952b809e4c08b..0b8ad8e08951884609c2d9076abb0cac4f6dc263 100644 --- a/src/plugins/designer/editorwidget.cpp +++ b/src/plugins/designer/editorwidget.cpp @@ -97,6 +97,7 @@ EditorWidget::EditorWidget(QWidget *formWindow) // Get shared sub windows from Form Editor FormEditorW *few = FormEditorW::instance(); QWidget * const*subs = few->designerSubWindows(); + // Create shared sub windows for (int i=0; i < DesignerSubWindowCount; i++) { m_designerSubWindows[i] = new SharedSubWindow(subs[i]); @@ -132,6 +133,13 @@ void EditorWidget::resetToDefaultLayout() void EditorWidget::activate() { + /* + + - now, settings are only changed when form is hidden. + - they should be not restored when a new form is activated - the same settings should be kept. + - only on initial load, settings should be loaded. + + */ for (int i=0; i < DesignerSubWindowCount; i++) m_designerSubWindows[i]->activate(); @@ -143,13 +151,12 @@ void EditorWidget::activate() // don't have their widgets yet there resetToDefaultLayout(); m_initialized = true; + if (!m_globalState.isEmpty()) + m_mainWindow->restoreSettings(m_globalState); } - if (!m_globalState.isEmpty()) - m_mainWindow->restoreSettings(m_globalState); - else { + if (m_globalState.isEmpty()) m_globalState = m_mainWindow->saveSettings(); - } } void EditorWidget::hideEvent(QHideEvent *) diff --git a/src/plugins/designer/editorwidget.h b/src/plugins/designer/editorwidget.h index 4f1312c3b6c9c17745fefa7ada9da0f2dd700125..d611220b6295661e5df8d953752c7e4c8b55637a 100644 --- a/src/plugins/designer/editorwidget.h +++ b/src/plugins/designer/editorwidget.h @@ -77,6 +77,7 @@ class EditorWidget : public QWidget public: explicit EditorWidget(QWidget *formWindow); + void resetToDefaultLayout(); QDockWidget* const* dockWidgets() const { return m_designerDockWidgets; } bool isLocked() const { return m_mainWindow->isLocked(); } diff --git a/src/plugins/designer/faketoolbar.cpp b/src/plugins/designer/faketoolbar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3f3e5e6d59e0a3f525783da76e1e1892d0435d76 --- /dev/null +++ b/src/plugins/designer/faketoolbar.cpp @@ -0,0 +1,242 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "faketoolbar.h" + +#include <designerconstants.h> +#include <coreplugin/coreconstants.h> +#include <coreplugin/editormanager/ieditor.h> +#include <coreplugin/icore.h> +#include <coreplugin/minisplitter.h> +#include <coreplugin/sidebar.h> +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/editormanager/openeditorsmodel.h> +#include <coreplugin/editormanager/ieditor.h> +#include <coreplugin/actionmanager/actionmanager.h> +#include <coreplugin/actionmanager/command.h> +#include <coreplugin/modemanager.h> + +#include <utils/parameteraction.h> +#include <utils/qtcassert.h> + +#include <QtCore/QSettings> +#include <QtCore/QEvent> +#include <QtCore/QDir> +#include <QtGui/QApplication> +#include <QtGui/QPlainTextEdit> +#include <QtGui/QVBoxLayout> +#include <QtGui/QScrollArea> +#include <QtGui/QTabWidget> +#include <QtGui/QToolButton> +#include <QtGui/QMenu> +#include <QtGui/QClipboard> +#include <QtGui/QLabel> +#include <QtGui/QToolBar> + +using Core::MiniSplitter; +using Core::IEditor; +using Core::EditorManager; + +Q_DECLARE_METATYPE(Core::IEditor*) + +enum { + debug = false +}; + +namespace Designer { +namespace Internal { + +/*! + Mimic the look of the text editor toolbar as defined in e.g. EditorView::EditorView + */ +FakeToolBar::FakeToolBar(Core::IEditor *editor, QWidget *toolbar, QWidget *parent) : + QWidget(parent), + m_editorList(new QComboBox), + m_closeButton(new QToolButton), + m_lockButton(new QToolButton), + m_goBackAction(new QAction(QIcon(QLatin1String(":/help/images/previous.png")), EditorManager::tr("Go Back"), parent)), + m_goForwardAction(new QAction(QIcon(QLatin1String(":/help/images/next.png")), EditorManager::tr("Go Forward"), parent)), + m_editor(editor) +{ + Core::ICore *core = Core::ICore::instance(); + + //setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + m_editorsListModel = core->editorManager()->openedEditorsModel(); + + // copied from EditorView::EditorView + m_editorList->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_editorList->setMinimumContentsLength(20); + m_editorList->setModel(m_editorsListModel); + m_editorList->setMaxVisibleItems(40); + m_editorList->setContextMenuPolicy(Qt::CustomContextMenu); + m_editorList->setCurrentIndex(m_editorsListModel->indexOf(m_editor).row()); + + QToolBar *editorListToolBar = new QToolBar; + editorListToolBar->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored); + editorListToolBar->addWidget(m_editorList); + + m_lockButton->setAutoRaise(true); + m_lockButton->setProperty("type", QLatin1String("dockbutton")); + + m_closeButton->setAutoRaise(true); + m_closeButton->setIcon(QIcon(":/core/images/closebutton.png")); + m_closeButton->setProperty("type", QLatin1String("dockbutton")); + +// Core::ActionManager *am = core->actionManager(); +// Core::EditorManager *em = core->editorManager(); + +// TODO back/FW buttons disabled for the time being, as the implementation would require changing editormanager. +// +// QToolBar *backFwToolBar = new QToolBar; +// backFwToolBar->addAction(m_goBackAction); +// backFwToolBar->addAction(m_goForwardAction); +// Core::Command *cmd = am->registerAction(m_goBackAction, Core::Constants::GO_BACK, editor->context()); +//#ifdef Q_WS_MAC +// cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Left"))); +//#else +// cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Left"))); +//#endif +// connect(m_goBackAction, SIGNAL(triggered()), em, SLOT(goBackInNavigationHistory())); +// cmd = am->registerAction(m_goForwardAction, Core::Constants::GO_FORWARD, editor->context()); +//#ifdef Q_WS_MAC +// cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Right"))); +//#else +// cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Right"))); +//#endif +// connect(m_goForwardAction, SIGNAL(triggered()), em, SLOT(goForwardInNavigationHistory())); + + QToolBar *rightToolBar = new QToolBar; + rightToolBar->setLayoutDirection(Qt::RightToLeft); + rightToolBar->addWidget(m_closeButton); + rightToolBar->addWidget(m_lockButton); + + QHBoxLayout *toplayout = new QHBoxLayout(this); + toplayout->setSpacing(0); + toplayout->setMargin(0); + toplayout->setContentsMargins(0,0,0,0); + +// toplayout->addWidget(backFwToolBar); + toplayout->addWidget(editorListToolBar); + toplayout->addWidget(toolbar); + toplayout->addWidget(rightToolBar); + + connect(m_editorList, SIGNAL(activated(int)), this, SLOT(listSelectionActivated(int))); + connect(m_editorList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(listContextMenu(QPoint))); + connect(m_lockButton, SIGNAL(clicked()), this, SLOT(makeEditorWritable())); + connect(m_closeButton, SIGNAL(clicked()), this, SLOT(close())); + + connect(m_editor, SIGNAL(changed()), this, SLOT(updateEditorStatus())); + connect(core->editorManager(), SIGNAL(currentEditorChanged(Core::IEditor*)), SLOT(updateEditorListSelection(Core::IEditor*))); + + updateEditorStatus(); +} + +void FakeToolBar::updateEditorListSelection(Core::IEditor *newSelection) +{ + if (newSelection) { + m_editorList->setCurrentIndex(m_editorsListModel->indexOf(newSelection).row()); + } +} + +void FakeToolBar::close() +{ + // instead of closing & deleting the visual editor, we want to go to edit mode and + // close the xml file instead. + Core::ICore *core = Core::ICore::instance(); + + Core::IEditor *editor = core->editorManager()->currentEditor(); + if (editor && editor->id() == Designer::Constants::K_DESIGNER_XML_EDITOR_ID + && editor->file() == m_editor->file()) + { + core->editorManager()->closeEditors(QList<Core::IEditor*>() << editor); + } + core->modeManager()->activateMode(Core::Constants::MODE_EDIT); +} + +void FakeToolBar::listSelectionActivated(int row) +{ + Core::EditorManager *em = Core::ICore::instance()->editorManager(); + QAbstractItemModel *model = m_editorList->model(); + + const QModelIndex modelIndex = model->index(row, 0); + IEditor *editor = model->data(modelIndex, Qt::UserRole).value<IEditor*>(); + if (editor) { + if (editor != em->currentEditor()) + em->activateEditor(editor, EditorManager::NoModeSwitch); + } else { + QString fileName = model->data(modelIndex, Qt::UserRole + 1).toString(); + QByteArray kind = model->data(modelIndex, Qt::UserRole + 2).toByteArray(); + editor = em->openEditor(fileName, kind, EditorManager::NoModeSwitch); + } + if (editor) { + m_editorList->setCurrentIndex(m_editorsListModel->indexOf(editor).row()); + } +} + +void FakeToolBar::listContextMenu(QPoint pos) +{ + QModelIndex index = m_editorsListModel->index(m_editorList->currentIndex(), 0); + QString fileName = m_editorsListModel->data(index, Qt::UserRole + 1).toString(); + if (fileName.isEmpty()) + return; + QMenu menu; + menu.addAction(tr("Copy full path to clipboard")); + if (menu.exec(m_editorList->mapToGlobal(pos))) { + QApplication::clipboard()->setText(fileName); + } +} + +void FakeToolBar::makeEditorWritable() +{ + Core::ICore::instance()->editorManager()->makeEditorWritable(m_editor); +} + +void FakeToolBar::updateEditorStatus() +{ + if (!m_editor->file()) + return; + + if (m_editor->file()->isReadOnly()) { + m_lockButton->setIcon(m_editorsListModel->lockedIcon()); + m_lockButton->setEnabled(!m_editor->file()->fileName().isEmpty()); + m_lockButton->setToolTip(tr("Make writable")); + } else { + m_lockButton->setIcon(m_editorsListModel->unlockedIcon()); + m_lockButton->setEnabled(false); + m_lockButton->setToolTip(tr("File is writable")); + } + m_editorList->setToolTip( + m_editor->file()->fileName().isEmpty() + ? m_editor->displayName() + : QDir::toNativeSeparators(m_editor->file()->fileName()) + ); +} + +} // Internal +} // Designer diff --git a/src/plugins/designer/faketoolbar.h b/src/plugins/designer/faketoolbar.h new file mode 100644 index 0000000000000000000000000000000000000000..82993b25506782e75c6930107bb99f9fc977fade --- /dev/null +++ b/src/plugins/designer/faketoolbar.h @@ -0,0 +1,84 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef FAKETOOLBAR_H +#define FAKETOOLBAR_H + +#include <QWidget> +#include <QtCore/QPointer> + +namespace Core { + class IEditor; + class OpenEditorsModel; +} + +QT_BEGIN_NAMESPACE +class QComboBox; +class QToolButton; +class QToolBar; +QT_END_NAMESPACE + +namespace Designer { +namespace Internal { + +/** + * Fakes an IEditor-like toolbar for design mode widgets such as Qt Designer and Bauhaus. + * Creates a combobox for open files and lock and close buttons on the right. + */ +class FakeToolBar : public QWidget +{ + Q_OBJECT + Q_DISABLE_COPY(FakeToolBar) +public: + explicit FakeToolBar(Core::IEditor *editor, QWidget *toolbar, QWidget *parent = 0); + + void updateActions(); + +private slots: + void updateEditorListSelection(Core::IEditor *newSelection); + void close(); + void listSelectionActivated(int row); + void listContextMenu(QPoint); + void makeEditorWritable(); + void updateEditorStatus(); + +private: + Core::OpenEditorsModel *m_editorsListModel; + QComboBox *m_editorList; + QToolButton *m_closeButton; + QToolButton *m_lockButton; + QAction *m_goBackAction; + QAction *m_goForwardAction; + QPointer<Core::IEditor> m_editor; +}; + +} +} + +#endif // FAKETOOLBAR_H diff --git a/src/plugins/designer/formeditorfactory.cpp b/src/plugins/designer/formeditorfactory.cpp index 311c6adf95d2acdbbdecc33f7b9b02c53e643c4e..8ed963e0dbf288be1661ebad7f7348cccb399e08 100644 --- a/src/plugins/designer/formeditorfactory.cpp +++ b/src/plugins/designer/formeditorfactory.cpp @@ -31,10 +31,12 @@ #include "formeditorw.h" #include "formwindoweditor.h" #include "designerconstants.h" +#include "designerxmleditor.h" #include <coreplugin/icore.h> #include <coreplugin/fileiconprovider.h> #include <coreplugin/editormanager/editormanager.h> +#include <texteditor/texteditorsettings.h> #include <QtCore/QFileInfo> #include <QtCore/QDebug> @@ -53,12 +55,12 @@ FormEditorFactory::FormEditorFactory() QString FormEditorFactory::id() const { - return QLatin1String(FORMEDITOR_ID); + return QLatin1String(DESIGNER_XML_EDITOR_ID); //FORMEDITOR_ID); } QString FormEditorFactory::displayName() const { - return tr(C_FORMEDITOR_DISPLAY_NAME); + return tr(C_DESIGNER_XML_DISPLAY_NAME); } Core::IFile *FormEditorFactory::open(const QString &fileName) @@ -69,7 +71,9 @@ Core::IFile *FormEditorFactory::open(const QString &fileName) Core::IEditor *FormEditorFactory::createEditor(QWidget *parent) { - return FormEditorW::instance()->createFormWindowEditor(parent); + DesignerXmlEditor *xmlEditor = new DesignerXmlEditor(parent); + TextEditor::TextEditorSettings::instance()->initializeEditor(xmlEditor); + return xmlEditor->editableInterface(); } QStringList FormEditorFactory::mimeTypes() const diff --git a/src/plugins/designer/formeditorplugin.cpp b/src/plugins/designer/formeditorplugin.cpp index 04c7b33fd5ad8ddee5ea04aff8c6f32cb2678150..16090fcd2436bc804972299f0bca8b673f11091f 100644 --- a/src/plugins/designer/formeditorplugin.cpp +++ b/src/plugins/designer/formeditorplugin.cpp @@ -31,6 +31,7 @@ #include "formeditorfactory.h" #include "formeditorw.h" #include "formwizard.h" +#include "formeditorstack.h" #ifdef CPP_ENABLED # include "formclasswizard.h" @@ -39,12 +40,24 @@ #endif #include "designerconstants.h" +#include "formwindoweditor.h" +#include "designerxmleditor.h" +#include "formwindowfile.h" + +#include <QDesignerFormWindowInterface> #include <coreplugin/icore.h> #include <coreplugin/mimedatabase.h> #include <coreplugin/coreconstants.h> #include <coreplugin/uniqueidmanager.h> - +#include <extensionsystem/pluginmanager.h> +#include <coreplugin/editormanager/ieditor.h> +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/modemanager.h> +#include <coreplugin/designmode.h> +#include <texteditor/basetextdocument.h> + +#include <QtCore/QPointer> #include <QtCore/QCoreApplication> #include <QtCore/QtPlugin> #include <QtCore/QDebug> @@ -52,6 +65,8 @@ #include <QtCore/QLibraryInfo> #include <QtCore/QTranslator> +#include <QtGui/QTextDocument> + #ifdef CPP_ENABLED # include <QtGui/QAction> # include <QtGui/QWizard> @@ -86,9 +101,6 @@ bool FormEditorPlugin::initialize(const QStringList &arguments, QString *error) initializeTemplates(); - const int uid = core->uniqueIDManager()->uniqueIdentifier(QLatin1String(C_FORMEDITOR)); - const QList<int> context = QList<int>() << uid; - addAutoReleasedObject(new FormEditorFactory); // Ensure that loading designer translations is done before FormEditorW is instantiated @@ -113,6 +125,8 @@ bool FormEditorPlugin::initialize(const QStringList &arguments, QString *error) const QByteArray output = proc.readAll(); if (output.contains("KDE: 4.2.0")) FormEditorW::ensureInitStage(FormEditorW::FullyInitialized); + else + FormEditorW::ensureInitStage(FormEditorW::RegisterPlugins); } else { FormEditorW::ensureInitStage(FormEditorW::RegisterPlugins); } @@ -123,6 +137,7 @@ bool FormEditorPlugin::initialize(const QStringList &arguments, QString *error) void FormEditorPlugin::extensionsInitialized() { + // 4) test and make sure everything works (undo, saving, editors, opening/closing multiple files, dirtiness etc) } //////////////////////////////////////////////////// diff --git a/src/plugins/designer/formeditorplugin.h b/src/plugins/designer/formeditorplugin.h index e0fa5e9507ad82379ac2cca707f06d2d58bdcf90..972f92f2eec9a45b2d165bb3302e98b3a99979e8 100644 --- a/src/plugins/designer/formeditorplugin.h +++ b/src/plugins/designer/formeditorplugin.h @@ -31,9 +31,19 @@ #define FORMEDITORPLUGIN_H #include <extensionsystem/iplugin.h> +#include <QtCore/QPointer> + +namespace Core { + class DesignMode; + class IMode; + class IEditor; +} namespace Designer { +class FormWindowEditor; namespace Internal { +class FormEditorStack; + class FormEditorPlugin : public ExtensionSystem::IPlugin { @@ -48,7 +58,10 @@ public: void extensionsInitialized(); private: + void initializeTemplates(); + + //Core::IMode *m_prevMode; }; } // namespace Internal diff --git a/src/plugins/designer/formeditorstack.cpp b/src/plugins/designer/formeditorstack.cpp new file mode 100644 index 0000000000000000000000000000000000000000..77a24bf263c442ae8f9acda755639adc9fc89c4b --- /dev/null +++ b/src/plugins/designer/formeditorstack.cpp @@ -0,0 +1,142 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "formeditorstack.h" +#include "designerxmleditor.h" +#include <QDesignerFormWindowInterface> +#include <texteditor/basetextdocument.h> +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/editormanager/ieditor.h> +#include <coreplugin/icore.h> +#include "formwindoweditor.h" +#include "formeditorw.h" +#include "designerconstants.h" + +#include <QtCore/QStringList> + +namespace Designer { +namespace Internal { + + +FormEditorStack::FormEditorStack() : activeEditor(0) +{ + +} + +FormEditorStack::~FormEditorStack() +{ + qDeleteAll(m_formEditors); +} + +Designer::FormWindowEditor *FormEditorStack::createFormWindowEditor(DesignerXmlEditorEditable *xmlEditor) +{ + FormXmlData *data = new FormXmlData; + data->formEditor = FormEditorW::instance()->createFormWindowEditor(this); + data->formEditor->setFile(xmlEditor->file()); + data->xmlEditor = xmlEditor; + data->widgetIndex = addWidget(data->formEditor->widget()); + m_formEditors.append(data); + + setFormEditorData(data->formEditor, xmlEditor->contents()); + + TextEditor::BaseTextDocument *document = qobject_cast<TextEditor::BaseTextDocument*>(xmlEditor->file()); + connect(document, SIGNAL(reloaded()), SLOT(reloadDocument())); + + return data->formEditor; +} + +bool FormEditorStack::removeFormWindowEditor(Core::IEditor *xmlEditor) +{ + for(int i = 0; i < m_formEditors.length(); ++i) { + if (m_formEditors[i]->xmlEditor == xmlEditor) { + disconnect(m_formEditors[i]->formEditor->formWindow(), SIGNAL(changed()), this, SLOT(formChanged())); + removeWidget(m_formEditors[i]->formEditor->widget()); + delete m_formEditors[i]->formEditor; + m_formEditors.removeAt(i); + return true; + } + } + return false; +} + +bool FormEditorStack::setVisibleEditor(Core::IEditor *xmlEditor) +{ + for(int i = 0; i < m_formEditors.length(); ++i) { + if (m_formEditors[i]->xmlEditor == xmlEditor) { + setCurrentIndex(m_formEditors[i]->widgetIndex); + activeEditor = m_formEditors[i]; + return true; + } + } + return false; +} + +Designer::FormWindowEditor *FormEditorStack::formWindowEditorForXmlEditor(Core::IEditor *xmlEditor) +{ + foreach(FormXmlData *data, m_formEditors) { + if (data->xmlEditor == xmlEditor) + return data->formEditor; + } + return 0; +} + + +void FormEditorStack::reloadDocument() +{ + if (activeEditor) { + setFormEditorData(activeEditor->formEditor, activeEditor->xmlEditor->contents()); + } +} + +void FormEditorStack::setFormEditorData(Designer::FormWindowEditor *formEditor, const QString &contents) +{ + disconnect(formEditor->formWindow(), SIGNAL(changed()), this, SLOT(formChanged())); + formEditor->createNew(contents); + connect(formEditor->formWindow(), SIGNAL(changed()), SLOT(formChanged())); +} + +void FormEditorStack::formChanged() +{ + Core::ICore *core = Core::ICore::instance(); + + if (core->editorManager()->currentEditor() && activeEditor + && core->editorManager()->currentEditor() == activeEditor->xmlEditor) + { + TextEditor::BaseTextDocument *doc = qobject_cast<TextEditor::BaseTextDocument*>(activeEditor->xmlEditor->file()); + Q_ASSERT(doc); + if (doc) { + doc->document()->setPlainText(activeEditor->formEditor->contents()); + } + } + +} + + +} // Internal +} // Designer diff --git a/src/plugins/designer/formeditorstack.h b/src/plugins/designer/formeditorstack.h new file mode 100644 index 0000000000000000000000000000000000000000..7e7b16f893c508170b6afbd877059191a907634e --- /dev/null +++ b/src/plugins/designer/formeditorstack.h @@ -0,0 +1,87 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef FORMEDITORSTACK_H +#define FORMEDITORSTACK_H + +#include <QtGui/QStackedWidget> +#include <QtCore/QList> +#include <QtCore/QString> + +namespace Core { + class IEditor; +} + +namespace Designer { +class FormWindowEditor; + +namespace Internal { +class DesignerXmlEditorEditable; + +/** + * A wrapper for Qt Designer form editors, so that they can be used in Design mode. + * FormEditorW owns an instance of this class, and creates new form editors when + * needed. + */ +class FormEditorStack : public QStackedWidget +{ + Q_OBJECT + Q_DISABLE_COPY(FormEditorStack); +public: + FormEditorStack(); + ~FormEditorStack(); + Designer::FormWindowEditor *createFormWindowEditor(DesignerXmlEditorEditable *xmlEditor); + bool removeFormWindowEditor(Core::IEditor *xmlEditor); + bool setVisibleEditor(Core::IEditor *xmlEditor); + Designer::FormWindowEditor *formWindowEditorForXmlEditor(Core::IEditor *xmlEditor); + +private slots: + void formChanged(); + void reloadDocument(); + +private: + void setFormEditorData(Designer::FormWindowEditor *formEditor, const QString &contents); + + struct FormXmlData; + QList<FormXmlData*> m_formEditors; + + FormXmlData *activeEditor; + + struct FormXmlData { + DesignerXmlEditorEditable *xmlEditor; + Designer::FormWindowEditor *formEditor; + int widgetIndex; + }; + +}; + +} +} + +#endif // FORMEDITORSTACK_H diff --git a/src/plugins/designer/formeditorw.cpp b/src/plugins/designer/formeditorw.cpp index ebcbae38a0b8d74869a1424dd172f5a8146675a2..2e95abf9217c3390dbba8b258e266b5a63f0ae4e 100644 --- a/src/plugins/designer/formeditorw.cpp +++ b/src/plugins/designer/formeditorw.cpp @@ -34,7 +34,13 @@ #include "settingspage.h" #include "editorwidget.h" #include "qtcreatorintegration.h" +#include "designerxmleditor.h" +#include "designercontext.h" +#include "formeditorstack.h" +#include <texteditor/basetextdocument.h> +#include <coreplugin/modemanager.h> +#include <coreplugin/designmode.h> #include <coreplugin/coreconstants.h> #include <coreplugin/icore.h> #include <coreplugin/uniqueidmanager.h> @@ -198,7 +204,10 @@ FormEditorW::FormEditorW() : m_actionPreview(0), m_actionGroupPreviewInStyle(0), m_actionAboutPlugins(0), - m_shortcutMapper(new QSignalMapper(this)) + m_shortcutMapper(new QSignalMapper(this)), + m_context(0), + m_stack(new FormEditorStack), + m_designMode(0) { if (Designer::Constants::Internal::debug) qDebug() << Q_FUNC_INFO; @@ -217,9 +226,7 @@ FormEditorW::FormEditorW() : m_fwm = qobject_cast<qdesigner_internal::QDesignerFormWindowManager*>(m_formeditor->formWindowManager()); QTC_ASSERT(m_fwm, return); - const int uid = m_core->uniqueIDManager()->uniqueIdentifier(QLatin1String(C_FORMEDITOR)); - m_context << uid; - + m_context = new DesignerContext(); setupActions(); foreach (QDesignerOptionsPageInterface *designerPage, m_formeditor->optionsPages()) { @@ -239,6 +246,12 @@ FormEditorW::~FormEditorW() { saveSettings(m_core->settings()); + if (m_initStage == FullyInitialized) { + m_designMode->unregisterDesignWidget(m_stack); + delete m_stack; + m_stack = 0; + } + for (int i = 0; i < Designer::Constants::DesignerSubWindowCount; ++i) delete m_designerSubWindows[i]; @@ -247,7 +260,10 @@ FormEditorW::~FormEditorW() ExtensionSystem::PluginManager::instance()->removeObject(settingsPage); delete settingsPage; } - delete m_integration; + delete m_integration; + + + m_self = 0; } @@ -287,6 +303,18 @@ void FormEditorW::fullInit() delete initTime; } + connect(m_core->editorManager()->instance(), SIGNAL(currentEditorChanged(Core::IEditor*)), + SLOT(checkToActivateEditor(Core::IEditor*))); + connect(m_core->modeManager(), SIGNAL(currentModeChanged(Core::IMode*)), + SLOT(syncOnModeChange(Core::IMode*))); + connect(m_core->editorManager()->instance(), SIGNAL(editorsClosed(QList<Core::IEditor*>)), + SLOT(closeFormEditorsForXmlEditors(QList<Core::IEditor*>))); + + m_designMode = ExtensionSystem::PluginManager::instance()->getObject<Core::DesignMode>(); + QStringList mimeTypes; + mimeTypes << FORM_MIMETYPE; + m_designMode->registerDesignWidget(m_stack, mimeTypes); + m_initStage = FullyInitialized; } @@ -343,6 +371,24 @@ void FormEditorW::deleteInstance() delete m_self; } +void FormEditorW::checkToActivateEditor(Core::IEditor *editor) +{ + Core::ModeManager *mm = Core::ICore::instance()->modeManager(); + if (editor && editor->id() == Constants::K_DESIGNER_XML_EDITOR_ID) { + mm->activateMode(Core::Constants::MODE_DESIGN); + } +} + +void FormEditorW::syncOnModeChange(Core::IMode *mode) +{ + Core::ICore *core = Core::ICore::instance(); + if (mode->id() == Core::Constants::MODE_DESIGN + && core->editorManager()->currentEditor()->id() == Designer::Constants::K_DESIGNER_XML_EDITOR_ID ) + { + m_stack->setVisibleEditor(core->editorManager()->currentEditor()); + } +} + void FormEditorW::setupActions() { Core::ActionManager *am = m_core->actionManager(); @@ -360,19 +406,19 @@ void FormEditorW::setupActions() mtools->addMenu(mformtools); //overridden actions - bindShortcut(am->registerAction(m_fwm->actionUndo(), Core::Constants::UNDO, m_context), m_fwm->actionUndo()); - bindShortcut(am->registerAction(m_fwm->actionRedo(), Core::Constants::REDO, m_context), m_fwm->actionRedo()); - bindShortcut(am->registerAction(m_fwm->actionCut(), Core::Constants::CUT, m_context), m_fwm->actionCut()); - bindShortcut(am->registerAction(m_fwm->actionCopy(), Core::Constants::COPY, m_context), m_fwm->actionCopy()); - bindShortcut(am->registerAction(m_fwm->actionPaste(), Core::Constants::PASTE, m_context), m_fwm->actionPaste()); - bindShortcut(am->registerAction(m_fwm->actionSelectAll(), Core::Constants::SELECTALL, m_context), m_fwm->actionSelectAll()); + bindShortcut(am->registerAction(m_fwm->actionUndo(), Core::Constants::UNDO, m_context->context()), m_fwm->actionUndo()); + bindShortcut(am->registerAction(m_fwm->actionRedo(), Core::Constants::REDO, m_context->context()), m_fwm->actionRedo()); + bindShortcut(am->registerAction(m_fwm->actionCut(), Core::Constants::CUT, m_context->context()), m_fwm->actionCut()); + bindShortcut(am->registerAction(m_fwm->actionCopy(), Core::Constants::COPY, m_context->context()), m_fwm->actionCopy()); + bindShortcut(am->registerAction(m_fwm->actionPaste(), Core::Constants::PASTE, m_context->context()), m_fwm->actionPaste()); + bindShortcut(am->registerAction(m_fwm->actionSelectAll(), Core::Constants::SELECTALL, m_context->context()), m_fwm->actionSelectAll()); m_actionPrint = new QAction(this); - bindShortcut(am->registerAction(m_actionPrint, Core::Constants::PRINT, m_context), m_actionPrint); + bindShortcut(am->registerAction(m_actionPrint, Core::Constants::PRINT, m_context->context()), m_actionPrint); connect(m_actionPrint, SIGNAL(triggered()), this, SLOT(print())); //'delete' action - command = am->registerAction(m_fwm->actionDelete(), QLatin1String("FormEditor.Edit.Delete"), m_context); + command = am->registerAction(m_fwm->actionDelete(), QLatin1String("FormEditor.Edit.Delete"), m_context->context()); command->setDefaultKeySequence(QKeySequence::Delete); bindShortcut(command, m_fwm->actionDelete()); command->setAttribute(Core::Command::CA_Hide); @@ -451,7 +497,7 @@ void FormEditorW::setupActions() addToolAction(m_fwm->actionSimplifyLayout(), am, globalcontext, m_toolActionIds.back(), mformtools); - createSeparator(this, am, m_context, mformtools, QLatin1String("FormEditor.Menu.Tools.Separator1")); + createSeparator(this, am, m_context->context(), mformtools, QLatin1String("FormEditor.Menu.Tools.Separator1")); addToolAction(m_fwm->actionLower(), am, globalcontext, QLatin1String("FormEditor.Lower"), mformtools); @@ -512,7 +558,7 @@ void FormEditorW::setupActions() mformtools->addMenu(createPreviewStyleMenu(am, m_actionGroupPreviewInStyle)); // Form settings - createSeparator(this, am, m_context, medit, QLatin1String("FormEditor.Edit.Separator2"), Core::Constants::G_EDIT_OTHER); + createSeparator(this, am, m_context->context(), medit, QLatin1String("FormEditor.Edit.Separator2"), Core::Constants::G_EDIT_OTHER); createSeparator(this, am, globalcontext, mformtools, QLatin1String("FormEditor.Menu.Tools.Separator3")); QAction *actionFormSettings = m_fwm->actionShowFormWindowSettingsDialog(); @@ -576,7 +622,7 @@ Core::ActionContainer *FormEditorW::createPreviewStyleMenu(Core::ActionManager * name += dot; } name += data.toString(); - Core::Command *command = am->registerAction(a, name, m_context); + Core::Command *command = am->registerAction(a, name, m_context->context()); bindShortcut(command, a); if (isDeviceProfile) { command->setAttribute(Core::Command::CA_UpdateText); @@ -661,12 +707,17 @@ FormWindowEditor *FormEditorW::createFormWindowEditor(QWidget* parentWidget) { m_fwm->closeAllPreviews(); QDesignerFormWindowInterface *form = m_fwm->createFormWindow(0); + connect(form, SIGNAL(toolChanged(int)), this, SLOT(toolChanged(int))); qdesigner_internal::FormWindowBase::setupDefaultAction(form); - FormWindowEditor *fww = new FormWindowEditor(m_context, form, parentWidget); + + FormWindowEditor *fww = new FormWindowEditor(form, parentWidget); // Store a pointer to all form windows so we can unselect // all other formwindows except the active one. m_formWindows.append(fww); + + fww->setContext(m_context->context()); + connect(fww, SIGNAL(destroyed()), this, SLOT(editorDestroyed())); return fww; } @@ -705,10 +756,20 @@ void FormEditorW::currentEditorChanged(Core::IEditor *editor) qDebug() << Q_FUNC_INFO << editor << " of " << m_fwm->formWindowCount(); // Deactivate Designer if a non-form is being edited - if (editor && editor->id() == QLatin1String(Constants::FORMEDITOR_ID)) { - FormWindowEditor *fw = qobject_cast<FormWindowEditor *>(editor); - QTC_ASSERT(fw, return); + if (editor && editor->id() == QLatin1String(Constants::K_DESIGNER_XML_EDITOR_ID)) { + DesignerXmlEditorEditable *xmlEditor = qobject_cast<DesignerXmlEditorEditable *>(editor); + FormWindowEditor *fw = m_stack->formWindowEditorForXmlEditor(xmlEditor); + QTC_ASSERT(xmlEditor, return); + if (!fw) + fw = m_stack->createFormWindowEditor(xmlEditor); + + // change context when activating another editor + m_core->removeContextObject(m_context); + m_context->setWidget(fw->widget()); + m_core->addContextObject(m_context); + fw->activate(); + m_fwm->setActiveFormWindow(fw->formWindow()); m_actionGroupEditMode->setVisible(true); m_modeActionSeparator->setVisible(true); @@ -810,6 +871,13 @@ void FormEditorW::resetToDefaultLayout() fwe->resetToDefaultLayout(); } +void FormEditorW::closeFormEditorsForXmlEditors(QList<Core::IEditor*> editors) +{ + foreach(Core::IEditor *editor, editors) { + m_stack->removeFormWindowEditor(editor); + } +} + void FormEditorW::print() { // Printing code courtesy of designer_actions.cpp @@ -864,3 +932,4 @@ void FormEditorW::print() m_core->printer()->setFullPage(oldFullPage); m_core->printer()->setOrientation(oldOrientation); } + diff --git a/src/plugins/designer/formeditorw.h b/src/plugins/designer/formeditorw.h index b3293b520742e3345633834aaa6c2a62827e1593..70cfea7dce905eeb97a66d1b1bda446fd990cb7e 100644 --- a/src/plugins/designer/formeditorw.h +++ b/src/plugins/designer/formeditorw.h @@ -67,6 +67,8 @@ class ActionContainer; class ICore; class IEditor; class Command; +class IMode; +class DesignMode; } namespace Designer { @@ -74,7 +76,9 @@ class FormWindowEditor; namespace Internal { +class FormEditorStack; class SettingsPage; +class DesignerContext; class ProxyAction : public QAction { @@ -144,6 +148,9 @@ private slots: void editorDestroyed(); void updateShortcut(QObject *command); + void syncOnModeChange(Core::IMode *mode); + void checkToActivateEditor(Core::IEditor *editor); + void closeFormEditorsForXmlEditors(QList<Core::IEditor*> editors); private: FormEditorW(); @@ -199,12 +206,15 @@ private: QActionGroup *m_actionGroupPreviewInStyle; QAction *m_actionAboutPlugins; QAction *m_modeActionSeparator; + QSignalMapper *m_shortcutMapper; - QList<int> m_context; - + DesignerContext *m_context; EditorList m_formWindows; + QStringList m_toolActionIds; - QSignalMapper *m_shortcutMapper; + QPointer<FormEditorStack> m_stack; + Core::DesignMode *m_designMode; + QMap<Core::Command *, QAction *> m_commandToDesignerAction; }; diff --git a/src/plugins/designer/formwindoweditor.cpp b/src/plugins/designer/formwindoweditor.cpp index 48e211312726520f5c6f75c66311c837327d2b97..7915619525947cd0117000c3a3e3632b788ac7e4 100644 --- a/src/plugins/designer/formwindoweditor.cpp +++ b/src/plugins/designer/formwindoweditor.cpp @@ -33,6 +33,7 @@ #include "formwindoweditor.h" #include "formwindowfile.h" #include "formwindowhost.h" +#include "faketoolbar.h" #include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectnodes.h> @@ -41,6 +42,8 @@ #include <projectexplorer/session.h> #include <utils/qtcassert.h> +#include <coreplugin/icore.h> +#include <coreplugin/editormanager/editormanager.h> #include <QtDesigner/QDesignerFormWindowInterface> #include <QtDesigner/QDesignerFormEditorInterface> @@ -99,38 +102,60 @@ void QrcFilesVisitor::visitFolderNode(FolderNode *folderNode) } -FormWindowEditor::FormWindowEditor(const QList<int> &context, - QDesignerFormWindowInterface *form, +FormWindowEditor::FormWindowEditor(QDesignerFormWindowInterface *form, QObject *parent) : Core::IEditor(parent), - m_context(context), m_formWindow(form), - m_file(new FormWindowFile(form, this)), + m_file(0), m_host(new FormWindowHost(form)), m_editorWidget(new EditorWidget(m_host)), m_toolBar(0), m_sessionNode(0), - m_sessionWatcher(0) + m_sessionWatcher(0), + m_fakeToolBar(new FakeToolBar(this, toolBar())) { + m_containerWidget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout(m_containerWidget); + m_containerWidget->setLayout(layout); + + layout->addWidget(m_fakeToolBar); + layout->addWidget(m_editorWidget); + layout->setStretch(0,0); + layout->setStretch(1,1); + layout->setSpacing(0); + layout->setMargin(0); + layout->setContentsMargins(0,0,0,0); + if (Designer::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << form << parent; - connect(m_file, SIGNAL(reload(QString)), this, SLOT(slotOpen(QString))); - connect(m_file, SIGNAL(setDisplayName(QString)), this, SLOT(slotSetDisplayName(QString))); - connect(m_file, SIGNAL(changed()), this, SIGNAL(changed())); - connect(m_file, SIGNAL(changed()), this, SLOT(updateResources())); - connect(this, SIGNAL(opened(QString)), m_file, SLOT(setFileName(QString))); - connect(m_host, SIGNAL(changed()), this, SIGNAL(changed())); connect(form, SIGNAL(toolChanged(int)), m_editorWidget, SLOT(toolChanged(int))); + m_editorWidget->activate(); } +void FormWindowEditor::setFile(Core::IFile *file) +{ + if (m_file) { + disconnect(m_file, SIGNAL(changed()), this, SIGNAL(changed())); + disconnect(m_file, SIGNAL(changed()), this, SLOT(updateResources())); + } + + m_file = file; + + if (m_file) { + connect(m_file, SIGNAL(changed()), this, SIGNAL(changed())); + connect(m_file, SIGNAL(changed()), this, SLOT(updateResources())); + } +} + FormWindowEditor::~FormWindowEditor() { // Close: Delete the Designer form window via embedding widget delete m_toolBar; + delete m_fakeToolBar; delete m_host; delete m_editorWidget; if (Designer::Constants::Internal::debug) @@ -141,6 +166,11 @@ FormWindowEditor::~FormWindowEditor() } } +void FormWindowEditor::setContext(QList<int> context) +{ + m_context = context; +} + bool FormWindowEditor::createNew(const QString &contents) { if (Designer::Constants::Internal::debug) @@ -302,7 +332,7 @@ QList<int> FormWindowEditor::context() const QWidget *FormWindowEditor::widget() { - return m_editorWidget; + return m_containerWidget; } @@ -321,11 +351,6 @@ void FormWindowEditor::updateFormWindowSelectionHandles(bool state) m_host->updateFormWindowSelectionHandles(state); } -void FormWindowEditor::setSuggestedFileName(const QString &fileName) -{ - m_file->setSuggestedFileName(fileName); -} - void FormWindowEditor::activate() { m_editorWidget->activate(); diff --git a/src/plugins/designer/formwindoweditor.h b/src/plugins/designer/formwindoweditor.h index fb964a5b2f8bf4b9838e6e31cce5b9e10f853077..ed9b7a67ab081e70efe613b76ef049b00713e6b9 100644 --- a/src/plugins/designer/formwindoweditor.h +++ b/src/plugins/designer/formwindoweditor.h @@ -35,6 +35,7 @@ #include <coreplugin/editormanager/ieditor.h> #include <QtCore/QStringList> +#include <QtCore/QPointer> QT_BEGIN_NAMESPACE class QDesignerFormWindowInterface; @@ -54,6 +55,7 @@ namespace Internal { class FormWindowFile; class FormWindowHost; class EditorWidget; +class FakeToolBar; } // Master class maintaining a form window editor, @@ -63,8 +65,7 @@ class DESIGNER_EXPORT FormWindowEditor : public Core::IEditor { Q_OBJECT public: - FormWindowEditor(const QList<int> &context, - QDesignerFormWindowInterface *form, + FormWindowEditor(QDesignerFormWindowInterface *form, QObject *parent = 0); ~FormWindowEditor(); @@ -82,6 +83,7 @@ public: bool restoreState(const QByteArray &state); virtual bool isTemporary() const { return false; } + void setContext(QList<int> ctx); // ContextInterface virtual QList<int> context() const; virtual QWidget *widget(); @@ -90,12 +92,12 @@ public: QDesignerFormWindowInterface *formWindow() const; QWidget *integrationContainer(); void updateFormWindowSelectionHandles(bool state); - void setSuggestedFileName(const QString &fileName); QDockWidget* const* dockWidgets() const; bool isLocked() const; void setLocked(bool locked); - QString contents() const; + QString contents() const;\ + void setFile(Core::IFile *file); signals: // Internal @@ -111,18 +113,20 @@ private slots: void updateResources(); private: + QWidget *m_containerWidget; QString m_displayName; - const QList<int> m_context; + QList<int> m_context; QDesignerFormWindowInterface *m_formWindow; - Internal::FormWindowFile *m_file; + QPointer<Core::IFile> m_file; Internal::FormWindowHost *m_host; Internal::EditorWidget *m_editorWidget; QToolBar *m_toolBar; QStringList m_originalUiQrcPaths; ProjectExplorer::SessionNode *m_sessionNode; ProjectExplorer::NodesWatcher *m_sessionWatcher; + Internal::FakeToolBar *m_fakeToolBar; }; -} // namespace Internal +} // namespace Designer #endif // FORMWINDOWEDITOR_H diff --git a/src/plugins/locator/basefilefilter.cpp b/src/plugins/locator/basefilefilter.cpp index 40000c7549b3b617082e29fb02cd40478fefa43f..8bf1e3996b9bb285689fb92e4bd6c1786faae4b6 100644 --- a/src/plugins/locator/basefilefilter.cpp +++ b/src/plugins/locator/basefilefilter.cpp @@ -95,7 +95,6 @@ void BaseFileFilter::accept(Locator::FilterEntry selection) const { Core::EditorManager *em = Core::EditorManager::instance(); em->openEditor(selection.internalData.toString()); - em->ensureEditorManagerVisible(); } void BaseFileFilter::generateFileNames() diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp index b522f1459421cd055abf7a3c6b40d9499da92bbc..0a46ccfe79cc72b18733fac1e0247c6109344e44 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.cpp +++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp @@ -266,7 +266,6 @@ void FolderNavigationWidget::openItem(const QModelIndex &srcIndex) // Open file. Core::EditorManager *editorManager = Core::EditorManager::instance(); editorManager->openEditor(m_fileSystemModel->filePath(srcIndex)); - editorManager->ensureEditorManagerVisible(); } void FolderNavigationWidget::setCurrentTitle(const QString &dirName, const QString &fullPath) diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp index 682dd18d8d2df5138b54f8b8affef08692edb82e..90e7401fe0ed44d9f44e616cc57c1061f2a594d0 100644 --- a/src/plugins/projectexplorer/projecttreewidget.cpp +++ b/src/plugins/projectexplorer/projecttreewidget.cpp @@ -337,7 +337,6 @@ void ProjectTreeWidget::openItem(const QModelIndex &mainIndex) if (node->nodeType() == FileNodeType) { Core::EditorManager *editorManager = Core::EditorManager::instance(); editorManager->openEditor(node->path()); - editorManager->ensureEditorManagerVisible(); } } diff --git a/src/plugins/qmldesigner/designmode.cpp b/src/plugins/qmldesigner/designmode.cpp deleted file mode 100644 index 4b824d3e4bc3fc0a2cf372db7d48baaae2776d68..0000000000000000000000000000000000000000 --- a/src/plugins/qmldesigner/designmode.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#include "designmode.h" -#include "qmldesignerconstants.h" -#include "designmodewidget.h" - -#include <coreplugin/icore.h> -#include <coreplugin/modemanager.h> -#include <coreplugin/uniqueidmanager.h> -#include <coreplugin/editormanager/editormanager.h> -#include <coreplugin/editormanager/openeditorsmodel.h> -#include <coreplugin/actionmanager/actionmanager.h> -#include <coreplugin/actionmanager/command.h> -#include <coreplugin/coreconstants.h> - -#include <extensionsystem/pluginmanager.h> - -#include <QAction> -#include <QDebug> -#include <QPlainTextEdit> -#include <QFileInfo> - -namespace QmlDesigner { -namespace Internal { - -enum { - debug = false -}; - -DesignModeCoreListener::DesignModeCoreListener(DesignMode *mode) : - m_mode(mode) -{ -} - -bool DesignModeCoreListener::coreAboutToClose() -{ - // make sure settings are stored before actual program exit - m_mode->currentEditorChanged(0); - return true; -} - -DesignMode::DesignMode() : - IMode(), - m_mainWidget(new DesignModeWidget(this)), - m_coreListener(new 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)) -{ - Core::ICore *creatorCore = Core::ICore::instance(); - Core::ModeManager *modeManager = creatorCore->modeManager(); - - connect(modeManager, SIGNAL(currentModeChanged(Core::IMode*)), - this, SLOT(modeChanged(Core::IMode*))); - - 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(); -} - -DesignMode::~DesignMode() -{ - delete m_mainWidget; - ExtensionSystem::PluginManager::instance()->removeObject(m_coreListener); - delete m_coreListener; -} - -QList<int> DesignMode::context() const -{ - static QList<int> contexts = QList<int>() << - Core::UniqueIDManager::instance()->uniqueIdentifier(Constants::C_DESIGN_MODE); - return contexts; -} - -QWidget *DesignMode::widget() -{ - return m_mainWidget; -} - -QString DesignMode::displayName() const -{ - return tr(Constants::DESIGN_MODE_NAME); -} - -QIcon DesignMode::icon() const -{ - return QIcon(QLatin1String(":/qmldesigner/images/mode_Design.png")); -} - -int DesignMode::priority() const -{ - return Constants::DESIGN_MODE_PRIORITY; -} - -QString DesignMode::id() const -{ - return QLatin1String(Constants::DESIGN_MODE_NAME); -} - -void DesignMode::textEditorsClosed(QList<Core::IEditor*> editors) -{ - m_mainWidget->closeEditors(editors); -} - -void DesignMode::modeChanged(Core::IMode *mode) -{ - 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); - } - } -} - -void DesignMode::currentEditorChanged(Core::IEditor *editor) -{ - if (debug) - qDebug() << Q_FUNC_INFO << editor; - - if (m_currentEditor.data() == editor) - return; - - if (m_currentEditor) - disconnect(m_currentEditor.data(), SIGNAL(changed()), this, SLOT(updateActions())); - - m_currentEditor = QWeakPointer<Core::IEditor>(editor); - - if (m_currentEditor) - connect(m_currentEditor.data(), SIGNAL(changed()), this, SLOT(updateActions())); - - updateActions(); -} - -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"))); -} - -} // namespace Internal -} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designmodecontext.cpp b/src/plugins/qmldesigner/designmodecontext.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3b15329b364e5c841682f01bf48c8adff460b5de --- /dev/null +++ b/src/plugins/qmldesigner/designmodecontext.cpp @@ -0,0 +1,61 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "designmodecontext.h" +#include "qmldesignerconstants.h" +#include <coreplugin/uniqueidmanager.h> +#include <QWidget> + +namespace QmlDesigner { +namespace Internal { + +DesignModeContext::DesignModeContext(QWidget *widget) : IContext(widget), + m_widget(widget) +{ + m_context << Core::UniqueIDManager::instance()->uniqueIdentifier(Constants::C_FORMEDITOR); +} + +DesignModeContext::~DesignModeContext() +{ + +} + +QList<int> DesignModeContext::context() const +{ + return m_context; +} + +QWidget *DesignModeContext::widget() +{ + return m_widget; +} + +} +} + diff --git a/src/plugins/qmldesigner/designmodecontext.h b/src/plugins/qmldesigner/designmodecontext.h new file mode 100644 index 0000000000000000000000000000000000000000..e35f3aa1fd9b71454056f0cc54596e6700b5714a --- /dev/null +++ b/src/plugins/qmldesigner/designmodecontext.h @@ -0,0 +1,62 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef DESIGNMODECONTEXT_H +#define DESIGNMODECONTEXT_H + +#include <coreplugin/icontext.h> +#include <QList> + +QT_BEGIN_NAMESPACE +class QWidget; +QT_END_NAMESPACE + +namespace QmlDesigner { +namespace Internal { + +/** + * Bauhaus Design mode context object + */ +class DesignModeContext : public Core::IContext +{ +public: + DesignModeContext(QWidget *widget); + ~DesignModeContext(); + + QList<int> context() const; + QWidget *widget(); +private: + QList<int> m_context; + QWidget *m_widget; +}; + +} +} + +#endif // DESIGNMODECONTEXT_H diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index 6da38ce63ade251fa1364a27ec71716474db9df0..99e0acb31b904678e110d8bbecadd31a69bc7ac5 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -28,7 +28,6 @@ **************************************************************************/ #include "designmodewidget.h" -#include "designmode.h" #include "qmldesignerconstants.h" #include <model.h> @@ -471,9 +470,8 @@ ModelNode DocumentWidget::nodeForPosition(int cursorPos) const } // ---------- DesignModeWidget -DesignModeWidget::DesignModeWidget(DesignMode *designMode, QWidget *parent) : +DesignModeWidget::DesignModeWidget(QWidget *parent) : QWidget(parent), - m_designMode(designMode), m_documentWidgetStack(new QStackedWidget), m_currentDocumentWidget(0), m_currentTextEdit(0), @@ -603,11 +601,6 @@ QAction *DesignModeWidget::selectAllAction() const return m_selectAllAction; } -DesignMode *DesignModeWidget::designMode() const -{ - return m_designMode; -} - void DesignModeWidget::undo() { if (m_currentDocumentWidget) diff --git a/src/plugins/qmldesigner/designmodewidget.h b/src/plugins/qmldesigner/designmodewidget.h index 68ce3af9a62166fe56a03fed4d1ab74e9915939f..e64cb46bffd89eefd9d49be8b5dca4f62fd64a0a 100644 --- a/src/plugins/qmldesigner/designmodewidget.h +++ b/src/plugins/qmldesigner/designmodewidget.h @@ -161,7 +161,7 @@ class DesignModeWidget : public QWidget Q_OBJECT Q_DISABLE_COPY(DesignModeWidget) public: - explicit DesignModeWidget(DesignMode *designMode, QWidget *parent = 0); + explicit DesignModeWidget(QWidget *parent = 0); ~DesignModeWidget(); // void syncWithTextEdit(bool sync); @@ -176,8 +176,6 @@ public: QAction *pasteAction() const; QAction *selectAllAction() const; - DesignMode *designMode() const; - private slots: void undo(); void redo(); @@ -193,8 +191,6 @@ private slots: private: void setCurrentDocumentWidget(DocumentWidget *newDocumentWidget); - DesignMode *m_designMode; - QStackedWidget *m_documentWidgetStack; QHash<QPlainTextEdit*,DocumentWidget*> m_documentHash; DocumentWidget *m_currentDocumentWidget; diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 1c27e94cb617e6cd5b73c35575fe094f937a3c46..d21112375fc019d932e5a693e2627972bdced870 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -39,7 +39,7 @@ const char * const DELETE = "QmlDesigner.Delete"; // context const char * const C_DESIGN_MODE = "QmlDesigner::DesignMode"; -const char * const C_FORMEDITOR = "QmlDesigner::FormEditor"; +const char * const C_FORMEDITOR = "QmlDesigner::QmlFormEditor"; // actions const char * const SWITCH_TEXT_DESIGN = "QmlDesigner.SwitchTextDesign"; diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index fbf5bcc49e4ed2eb804e46cfba1747a25e286571..dd67918caba7cab40cbd29625838b39612f96a2e 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -29,11 +29,13 @@ #include "exception.h" #include "qmldesignerplugin.h" -#include "designmode.h" #include "qmldesignerconstants.h" #include "pluginmanager.h" +#include "designmodewidget.h" #include "settingspage.h" +#include "designmodecontext.h" +#include <coreplugin/designmode.h> #include <qmljseditor/qmljseditorconstants.h> #include <coreplugin/modemanager.h> @@ -46,13 +48,21 @@ #include <coreplugin/mimedatabase.h> #include <coreplugin/coreconstants.h> #include <coreplugin/uniqueidmanager.h> +#include <coreplugin/editormanager/openeditorsmodel.h> +#include <coreplugin/actionmanager/actionmanager.h> +#include <coreplugin/modemanager.h> +#include <extensionsystem/pluginmanager.h> + #include <utils/qtcassert.h> #include <integrationcore.h> -#include <QtCore/QDebug> +#include <QtGui/QAction> + +#include <QtCore/QFileInfo> #include <QtCore/QCoreApplication> #include <QtCore/qplugin.h> +#include <QtCore/QDebug> namespace QmlDesigner { namespace Internal { @@ -60,7 +70,15 @@ namespace Internal { BauhausPlugin *BauhausPlugin::m_pluginInstance = 0; BauhausPlugin::BauhausPlugin() : - m_designerCore(0) + m_designerCore(0), + m_designMode(0), + 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)) { // Exceptions should never ever assert: they are handled in a number of // places where it is actually VALID AND EXPECTED BEHAVIOUR to get an @@ -77,6 +95,7 @@ BauhausPlugin::BauhausPlugin() : BauhausPlugin::~BauhausPlugin() { delete m_designerCore; + Core::ICore::instance()->removeContextObject(m_context); } //////////////////////////////////////////////////// @@ -91,7 +110,7 @@ bool BauhausPlugin::initialize(const QStringList & /*arguments*/, QString *error const int uid = core->uniqueIDManager()->uniqueIdentifier(QLatin1String(QmlDesigner::Constants::C_FORMEDITOR)); const QList<int> context = QList<int>() << uid; - const QList<int> switchContext = QList<int() << uid + const QList<int> switchContext = QList<int>() << uid << core->uniqueIDManager()->uniqueIdentifier(QmlJSEditor::Constants::C_QMLJSEDITOR_ID); Core::ActionManager *am = core->actionManager(); @@ -103,7 +122,6 @@ bool BauhausPlugin::initialize(const QStringList & /*arguments*/, QString *error connect(switchAction, SIGNAL(triggered()), this, SLOT(switchTextDesign())); m_designerCore = new QmlDesigner::IntegrationCore; - m_pluginInstance = this; #ifdef Q_OS_MAC @@ -115,7 +133,8 @@ bool BauhausPlugin::initialize(const QStringList & /*arguments*/, QString *error m_designerCore->pluginManager()->setPluginPaths(QStringList() << pluginPath); - addAutoReleasedObject(new DesignMode); + createDesignModeWidget(); + addAutoReleasedObject(new SettingsPage); error_message->clear(); @@ -123,8 +142,157 @@ bool BauhausPlugin::initialize(const QStringList & /*arguments*/, QString *error return true; } +void BauhausPlugin::createDesignModeWidget() +{ + Core::ICore *creatorCore = Core::ICore::instance(); + Core::ActionManager *actionManager = creatorCore->actionManager(); + m_editorManager = creatorCore->editorManager(); + Core::ActionContainer *editMenu = actionManager->actionContainer(Core::Constants::M_EDIT); + + m_mainWidget = new DesignModeWidget; + + m_context = new DesignModeContext(m_mainWidget); + creatorCore->addContextObject(m_context); + + // Revert to saved + actionManager->registerAction(m_revertToSavedAction, + Core::Constants::REVERTTOSAVED, m_context->context()); + connect(m_revertToSavedAction, SIGNAL(triggered()), m_editorManager, SLOT(revertToSaved())); + + //Save + actionManager->registerAction(m_saveAction, Core::Constants::SAVE, m_context->context()); + connect(m_saveAction, SIGNAL(triggered()), m_editorManager, SLOT(saveFile())); + + //Save As + actionManager->registerAction(m_saveAsAction, Core::Constants::SAVEAS, m_context->context()); + connect(m_saveAsAction, SIGNAL(triggered()), m_editorManager, SLOT(saveFileAs())); + + //Close Editor + actionManager->registerAction(m_closeCurrentEditorAction, Core::Constants::CLOSE, m_context->context()); + connect(m_closeCurrentEditorAction, SIGNAL(triggered()), m_editorManager, SLOT(closeEditor())); + + //Close All + actionManager->registerAction(m_closeAllEditorsAction, Core::Constants::CLOSEALL, m_context->context()); + connect(m_closeAllEditorsAction, SIGNAL(triggered()), m_editorManager, SLOT(closeAllEditors())); + + //Close All Others Action + actionManager->registerAction(m_closeOtherEditorsAction, Core::Constants::CLOSEOTHERS, m_context->context()); + connect(m_closeOtherEditorsAction, SIGNAL(triggered()), m_editorManager, SLOT(closeOtherEditors())); + + // Undo / Redo + actionManager->registerAction(m_mainWidget->undoAction(), Core::Constants::UNDO, m_context->context()); + actionManager->registerAction(m_mainWidget->redoAction(), Core::Constants::REDO, m_context->context()); + + Core::Command *command; + command = actionManager->registerAction(m_mainWidget->deleteAction(), + QmlDesigner::Constants::DELETE, m_context->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, m_context->context()); + command->setDefaultKeySequence(QKeySequence::Cut); + editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE); + + command = actionManager->registerAction(m_mainWidget->copyAction(), + Core::Constants::COPY, m_context->context()); + command->setDefaultKeySequence(QKeySequence::Copy); + editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE); + + command = actionManager->registerAction(m_mainWidget->pasteAction(), + Core::Constants::PASTE, m_context->context()); + command->setDefaultKeySequence(QKeySequence::Paste); + editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE); + + command = actionManager->registerAction(m_mainWidget->selectAllAction(), + Core::Constants::SELECTALL, m_context->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); + + Core::ModeManager *modeManager = creatorCore->modeManager(); + + connect(modeManager, SIGNAL(currentModeChanged(Core::IMode*)), + this, SLOT(modeChanged(Core::IMode*))); + + connect(m_editorManager, SIGNAL(editorsClosed(QList<Core::IEditor*>)), + this, SLOT(textEditorsClosed(QList<Core::IEditor*>))); + +} + +void BauhausPlugin::modeChanged(Core::IMode *mode) +{ + if (mode == m_designMode) { + m_isActive = true; + m_mainWidget->showEditor(m_editorManager->currentEditor()); + } else { + if (m_isActive) { + m_isActive = false; + + m_mainWidget->showEditor(0); + } + } +} + +void BauhausPlugin::textEditorsClosed(QList<Core::IEditor*> editors) +{ + m_mainWidget->closeEditors(editors); +} + +// copied from EditorManager::updateActions +void BauhausPlugin::updateActions(Core::IEditor* editor) +{ + Core::IEditor *curEditor = editor; + int openedCount = m_editorManager->openedEditors().count() + + m_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"))); +} + void BauhausPlugin::extensionsInitialized() { + m_designMode = ExtensionSystem::PluginManager::instance()->getObject<Core::DesignMode>(); + + m_mimeTypes << "application/x-qml" << "application/javascript" + << "application/x-javascript" << "text/javascript"; + + m_designMode->registerDesignWidget(m_mainWidget, m_mimeTypes); + connect(m_designMode, SIGNAL(actionsUpdated(Core::IEditor*)), SLOT(updateActions(Core::IEditor*))); } BauhausPlugin *BauhausPlugin::pluginInstance() @@ -135,18 +303,15 @@ BauhausPlugin *BauhausPlugin::pluginInstance() void BauhausPlugin::switchTextDesign() { Core::ModeManager *modeManager = Core::ModeManager::instance(); + Core::EditorManager *editorManager = Core::EditorManager::instance(); + Core::IEditor *editor = editorManager->currentEditor(); - if (modeManager->currentMode() == Core::Constants::MODE_EDIT) { - - } else if (modeManager->currentMode() == Core::Constants::MODE_DESIGN) { - - } - Core::IEditor *editor = editorManager->currentEditor(); - QString otherFile = correspondingHeaderOrSource(editor->file()->fileName()); - if (!otherFile.isEmpty()) { - editorManager->openEditor(otherFile); - editorManager->ensureEditorManagerVisible(); + if (modeManager->currentMode()->id() == Core::Constants::MODE_EDIT) { + if (editor->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID) + modeManager->activateMode(Core::Constants::MODE_DESIGN); + } else if (modeManager->currentMode()->id() == Core::Constants::MODE_DESIGN) { + modeManager->activateMode(Core::Constants::MODE_EDIT); } } diff --git a/src/plugins/qmldesigner/qmldesignerplugin.h b/src/plugins/qmldesigner/qmldesignerplugin.h index 2146573b78a0b69ac42a0aed24bbd4237dd5e5f6..6e4c7c16b20bcb61a6c472ab12a1fa59733a17b6 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.h +++ b/src/plugins/qmldesigner/qmldesignerplugin.h @@ -34,11 +34,21 @@ #include <extensionsystem/iplugin.h> +#include <QWeakPointer> +#include <QStringList> + +QT_BEGIN_NAMESPACE +class QAction; +QT_END_NAMESPACE + namespace Core { class IWizard; class ICore; class IEditorFactory; class IEditor; + class IMode; + class DesignMode; + class EditorManager; } namespace QmlDesigner { @@ -48,6 +58,9 @@ namespace QmlDesigner { namespace QmlDesigner { namespace Internal { +class DesignModeWidget; +class DesignModeContext; + class BauhausPlugin : public ExtensionSystem::IPlugin { Q_OBJECT @@ -66,12 +79,32 @@ public: void setSettings(const DesignerSettings &s); private slots: + void switchTextDesign(); + void modeChanged(Core::IMode *mode); + void textEditorsClosed(QList<Core::IEditor *> editors); + void updateActions(Core::IEditor* editor); private: + void createDesignModeWidget(); + + QStringList m_mimeTypes; + DesignModeWidget *m_mainWidget; + QmlDesigner::IntegrationCore *m_designerCore; static BauhausPlugin *m_pluginInstance; DesignerSettings m_settings; + DesignModeContext *m_context; + Core::DesignMode *m_designMode; + Core::EditorManager *m_editorManager; + bool m_isActive; + + QAction *m_revertToSavedAction; + QAction *m_saveAction; + QAction *m_saveAsAction; + QAction *m_closeCurrentEditorAction; + QAction *m_closeAllEditorsAction; + QAction *m_closeOtherEditorsAction; }; } // namespace Internal diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pro b/src/plugins/qmldesigner/qmldesignerplugin.pro index 814f1952e64475366f3584b915d56c228d8a9d23..a4f53b8142645f0e5aed54af7b29dab6ab6265ec 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.pro +++ b/src/plugins/qmldesigner/qmldesignerplugin.pro @@ -17,17 +17,17 @@ include(components/resources/resources.pri) HEADERS += qmldesignerconstants.h \ qmldesignerplugin.h \ - designmode.h \ designmodewidget.h \ application.h \ designersettings.h \ - settingspage.h + settingspage.h \ + designmodecontext.h SOURCES += qmldesignerplugin.cpp \ - designmode.cpp \ designmodewidget.cpp \ application.cpp \ designersettings.cpp \ - settingspage.cpp + settingspage.cpp \ + designmodecontext.cpp FORMS += settingspage.ui OTHER_FILES += QmlDesigner.pluginspec diff --git a/src/plugins/qmlprojectmanager/qmlprojectruncontrol.cpp b/src/plugins/qmlprojectmanager/qmlprojectruncontrol.cpp index b947d6a8604be5ff245ef7a9937662a5358964b3..86fc0fdbdb9f4e2b76b83e0e55f29ccb3dc62fc2 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectruncontrol.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectruncontrol.cpp @@ -36,6 +36,7 @@ #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/applicationlauncher.h> #include <utils/qtcassert.h> +#include <debugger/debuggerconstants.h> #include <debugger/debuggerconstants.h> #include <debugger/debuggeruiswitcher.h> diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index e24d73edd2606482f27db59672db96d5cfed5755..66deae43cfb442ce5e75e7f8ebfa6a8247d32550 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -299,7 +299,7 @@ public: // EditorInterface Core::IFile * file(); bool createNew(const QString &contents); - bool open(const QString &fileName = QString()); + virtual bool open(const QString &fileName = QString()); QByteArray saveState() const; bool restoreState(const QByteArray &state); QString displayName() const; diff --git a/src/plugins/texteditor/plaintexteditor.h b/src/plugins/texteditor/plaintexteditor.h index 5c570b0c2500c3a82fd3c6a21432ea92dac2f582..ea03210e4c37432d3cf598cbdc66814f2a15a064 100644 --- a/src/plugins/texteditor/plaintexteditor.h +++ b/src/plugins/texteditor/plaintexteditor.h @@ -46,8 +46,9 @@ public: bool duplicateSupported() const { return true; } Core::IEditor *duplicate(QWidget *parent); - QString id() const; bool isTemporary() const { return false; } + virtual QString id() const; + private: QList<int> m_context; }; @@ -60,7 +61,7 @@ public: PlainTextEditor(QWidget *parent); protected: - BaseTextEditorEditable *createEditableInterface() { return new PlainTextEditorEditable(this); } + virtual BaseTextEditorEditable *createEditableInterface() { return new PlainTextEditorEditable(this); } // Indent a text block based on previous line. virtual void indentBlock(QTextDocument *doc, QTextBlock block, QChar typedChar); };