From 26283cdb67b81f99605539af44c794b099f4b2b9 Mon Sep 17 00:00:00 2001
From: Marco Bubke <marco.bubke@digia.com>
Date: Thu, 7 Mar 2013 17:04:11 +0100
Subject: [PATCH] QmlDesigner: Add registration of additional views.

Change-Id: I48aff6a1a94ca3c0bcd8b0689333b6acad7d35cd
Reviewed-by: Thomas Hartmann <Thomas.Hartmann@digia.com>
(cherry picked from commit 81341a865928401edacafc248d242a7b14befbbc)
Reviewed-by: Marco Bubke <marco.bubke@digia.com>
---
 .../components/formeditor/formeditorview.cpp  | 11 +++
 .../components/formeditor/formeditorview.h    |  2 +
 .../itemlibrary/itemlibraryview.cpp           | 10 +++
 .../components/itemlibrary/itemlibraryview.h  |  2 +
 .../components/navigator/navigatorview.cpp    | 15 ++++
 .../components/navigator/navigatorview.h      |  2 +
 .../propertyeditor/propertyeditor.cpp         |  9 ++
 .../propertyeditor/propertyeditor.h           |  2 +
 .../stateseditor/stateseditorview.cpp         |  5 ++
 .../stateseditor/stateseditorview.h           |  2 +
 .../designercore/include/abstractview.h       | 25 ++++++
 .../designercore/include/viewmanager.h        | 16 ++--
 .../designercore/model/abstractview.cpp       | 27 ++++++
 .../designercore/model/viewmanager.cpp        | 61 ++++++++++---
 src/plugins/qmldesigner/designmodewidget.cpp  | 90 ++++++++++++-------
 src/plugins/qmldesigner/designmodewidget.h    |  1 -
 16 files changed, 228 insertions(+), 52 deletions(-)

diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp
index b5316e35522..d7559a89823 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp
@@ -37,6 +37,8 @@
 #include "formeditoritem.h"
 #include "formeditorscene.h"
 #include "toolbox.h"
+
+#include <designmodecontext.h>
 #include <rewritertransaction.h>
 #include <modelnode.h>
 #include <itemlibraryinfo.h>
@@ -54,6 +56,7 @@
 #include <nodelistproperty.h>
 #include <commondefines.h>
 
+#include <coreplugin/icore.h>
 
 namespace QmlDesigner {
 
@@ -68,6 +71,9 @@ FormEditorView::FormEditorView(QObject *parent)
       m_currentTool(m_selectionTool),
       m_transactionCounter(0)
 {
+    Internal::FormEditorContext *formEditorContext = new Internal::FormEditorContext(m_formEditorWidget.data());
+    Core::ICore::addContextObject(formEditorContext);
+
     connect(formEditorWidget()->zoomAction(), SIGNAL(zoomLevelChanged(double)), SLOT(updateGraphicsIndicators()));
     connect(formEditorWidget()->showBoundingRectAction(), SIGNAL(toggled(bool)), scene(), SLOT(setShowBoundingRects(bool)));
     connect(formEditorWidget()->selectOnlyContentItemsAction(), SIGNAL(toggled(bool)), this, SLOT(setSelectOnlyContentItemsAction(bool)));
@@ -273,6 +279,11 @@ QWidget *FormEditorView::widget()
     return m_formEditorWidget.data();
 }
 
+WidgetInfo FormEditorView::widgetInfo()
+{
+    return createWidgetInfo(m_formEditorWidget.data(), "FormEditor", WidgetInfo::CentralPane, 0, tr("Form Editor"));
+}
+
 FormEditorWidget *FormEditorView::formEditorWidget()
 {
     return m_formEditorWidget.data();
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.h b/src/plugins/qmldesigner/components/formeditor/formeditorview.h
index 63853dcef51..64a50f6f801 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorview.h
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.h
@@ -86,6 +86,8 @@ public:
 
     // FormEditorView
     QWidget *widget();
+    WidgetInfo widgetInfo();
+
     FormEditorWidget *formEditorWidget();
     AbstractFormEditorTool *currentTool() const;
     FormEditorScene *scene() const;
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp
index 2f63c2d13e3..745420bc7d2 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp
@@ -51,6 +51,16 @@ QWidget *ItemLibraryView::widget()
     return m_widget.data();
 }
 
+bool ItemLibraryView::hasWidget() const
+{
+    return true;
+}
+
+WidgetInfo ItemLibraryView::widgetInfo()
+{
+    return createWidgetInfo(widget(), QLatin1String("Library"), WidgetInfo::LeftPane, 0);
+}
+
 void ItemLibraryView::modelAttached(Model *model)
 {
     AbstractView::modelAttached(model);
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h
index f5ee3ceefd0..013bdfdf2dc 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h
@@ -49,6 +49,8 @@ public:
     ~ItemLibraryView();
 
     QWidget *widget();
+    bool hasWidget() const;
+    WidgetInfo widgetInfo();
 
     // AbstractView
     void modelAttached(Model *model);
diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp
index 37020f84e60..26123262841 100644
--- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp
+++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp
@@ -33,7 +33,9 @@
 #include "modelnodecontextmenu.h"
 
 #include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/icore.h>
 
+#include <designmodecontext.h>
 #include <nodeproperty.h>
 #include <nodelistproperty.h>
 #include <variantproperty.h>
@@ -57,6 +59,9 @@ NavigatorView::NavigatorView(QObject* parent) :
         m_widget(new NavigatorWidget(this)),
         m_treeModel(new NavigatorTreeModel(this))
 {
+    Internal::NavigatorContext *navigatorContext = new Internal::NavigatorContext(m_widget.data());
+    Core::ICore::addContextObject(navigatorContext);
+
     m_widget->setTreeModel(m_treeModel.data());
 
     connect(treeWidget()->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(changeSelection(QItemSelection,QItemSelection)));
@@ -99,6 +104,16 @@ QWidget *NavigatorView::widget()
     return m_widget.data();
 }
 
+bool NavigatorView::hasWidget() const
+{
+    return true;
+}
+
+WidgetInfo NavigatorView::widgetInfo()
+{
+    return createWidgetInfo(m_widget.data(), QLatin1String("Navigator"), WidgetInfo::LeftPane, 0);
+}
+
 void NavigatorView::modelAttached(Model *model)
 {
     QmlModelView::modelAttached(model);
diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.h b/src/plugins/qmldesigner/components/navigator/navigatorview.h
index 48a9f6ac004..0d086284a7d 100644
--- a/src/plugins/qmldesigner/components/navigator/navigatorview.h
+++ b/src/plugins/qmldesigner/components/navigator/navigatorview.h
@@ -57,6 +57,8 @@ public:
     ~NavigatorView();
 
     QWidget *widget();
+    bool hasWidget() const;
+    WidgetInfo widgetInfo();
 
     // AbstractView
     void modelAttached(Model *model);
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp
index 891a598e46b..3df98108b8d 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp
@@ -966,6 +966,15 @@ QWidget *PropertyEditor::widget()
     return m_stackedWidget;
 }
 
+bool PropertyEditor::hasWidget() const
+{
+    return true;
+}
+
+WidgetInfo PropertyEditor::widgetInfo()
+{
+    return createWidgetInfo(m_stackedWidget, QLatin1String("Properties"), WidgetInfo::RightPane, 0);
+}
 
 void PropertyEditor::actualStateChanged(const ModelNode &node)
 {
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h
index 24df1fabd05..8d057ebba4a 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h
@@ -84,6 +84,8 @@ public:
     void setQmlDir(const QString &qmlDirPath);
 
     QWidget *widget();
+    bool hasWidget() const;
+    WidgetInfo widgetInfo();
 
     void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
                               const QList<ModelNode> &lastSelectedNodeList);
diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp
index 7b9aff68292..b7956aa443b 100644
--- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp
+++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp
@@ -65,6 +65,11 @@ QWidget *StatesEditorView::widget()
     return m_statesEditorWidget.data();
 }
 
+WidgetInfo StatesEditorView::widgetInfo()
+{
+    return createWidgetInfo(m_statesEditorWidget.data(), "StatesEditor", WidgetInfo::TopPane, 0, tr("States Editor"));
+}
+
 void StatesEditorView::removeState(int nodeId)
 {
     try {
diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h
index ac8dcfa0060..73dca2487be 100644
--- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h
+++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h
@@ -75,6 +75,8 @@ public:
     void instancesPreviewImageChanged(const QVector<ModelNode> &nodeList);
 
     QWidget *widget();
+    WidgetInfo widgetInfo();
+
 
 public slots:
     void synchonizeCurrentStateFromWidget();
diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h
index 1e670186e76..03aa1f8bf3f 100644
--- a/src/plugins/qmldesigner/designercore/include/abstractview.h
+++ b/src/plugins/qmldesigner/designercore/include/abstractview.h
@@ -58,6 +58,24 @@ class QmlModelView;
 class NodeInstanceView;
 class RewriterView;
 
+struct WidgetInfo {
+    enum PlacementHint {
+        NoPane,
+        LeftPane,
+        RightPane,
+        TopPane, // not used
+        BottomPane, // not used
+        CentralPane // not used
+    };
+
+    QString uniqueId;
+    QString tabName;
+    QWidget *widget;
+    int placementPriority;
+    PlacementHint placementHint;
+};
+
+
 class QMLDESIGNERCORE_EXPORT AbstractView : public QObject
 {
     Q_OBJECT
@@ -180,11 +198,18 @@ public:
 
     void resetView();
 
+    virtual bool hasWidget() const;
     virtual QWidget *widget() = 0;
+    virtual WidgetInfo widgetInfo();
 
 protected:
     void setModel(Model * model);
     void removeModel();
+    static WidgetInfo createWidgetInfo(QWidget *widget = 0,
+                                       const QString &uniqueId = QString(),
+                                       WidgetInfo::PlacementHint placementHint = WidgetInfo::NoPane,
+                                       int placementPriority = 0,
+                                       const QString &tabName = QString());
 
 private: //functions
     QList<ModelNode> toModelNodeList(const QList<Internal::InternalNodePointer> &nodeList) const;
diff --git a/src/plugins/qmldesigner/designercore/include/viewmanager.h b/src/plugins/qmldesigner/designercore/include/viewmanager.h
index 405e9a23861..af07577a044 100644
--- a/src/plugins/qmldesigner/designercore/include/viewmanager.h
+++ b/src/plugins/qmldesigner/designercore/include/viewmanager.h
@@ -54,6 +54,7 @@ class ViewManager
 {
 public:
     ViewManager();
+    ~ViewManager();
 
     void attachRewriterView(TextModifier *textModifier);
     void detachRewriterView();
@@ -69,13 +70,14 @@ public:
     void setNodeInstanceViewQtPath(const QString & qtPath);
 
     void resetPropertyEditorView();
+
     void resisterFormEditorTool(AbstractFormEditorTool *tool); // takes ownership
+    void registerView(AbstractView *view);
+
+    QList<WidgetInfo> widgetInfos();
 
-    QWidget *formEditorWidget();
-    QWidget *propertyEditorWidget();
-    QWidget *itemLibraryWidget();
-    QWidget *navigatorWidget();
-    QWidget *statesEditorWidget();
+    void disableWidgets();
+    void enableWidgets();
 
     void pushFileOnCrambleBar(const QString &fileName);
     void pushInFileComponentOnCrambleBar(const QString &componentId);
@@ -89,8 +91,8 @@ private: // functions
 
     void attachNodeInstanceView();
     void attachItemLibraryView();
-
-
+    void attachAdditionalViews();
+    void detachAdditionalViews();
 
     Model *currentModel() const;
     Model *documentModel() const;
diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp
index 1e4993976c1..6d15f2a521a 100644
--- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp
+++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp
@@ -118,6 +118,23 @@ void AbstractView::removeModel()
     m_model.clear();
 }
 
+WidgetInfo AbstractView::createWidgetInfo(QWidget *widget,
+                                          const QString &uniqueId,
+                                          WidgetInfo::PlacementHint placementHint,
+                                          int placementPriority,
+                                          const QString &tabName)
+{
+    WidgetInfo widgetInfo;
+
+    widgetInfo.widget = widget;
+    widgetInfo.uniqueId = uniqueId;
+    widgetInfo.placementHint = placementHint;
+    widgetInfo.placementPriority = placementPriority;
+    widgetInfo.tabName = tabName;
+
+    return widgetInfo;
+}
+
 /*!
 \name Model related functions
 \{
@@ -367,6 +384,16 @@ void AbstractView::resetView()
     currentModel->attachView(this);
 }
 
+bool AbstractView::hasWidget() const
+{
+    return false;
+}
+
+WidgetInfo AbstractView::widgetInfo()
+{
+    return createWidgetInfo();
+}
+
 QList<ModelNode> AbstractView::allModelNodes() const
 {
    return toModelNodeList(model()->d->allNodes());
diff --git a/src/plugins/qmldesigner/designercore/model/viewmanager.cpp b/src/plugins/qmldesigner/designercore/model/viewmanager.cpp
index d309ea79dea..55222c9dc08 100644
--- a/src/plugins/qmldesigner/designercore/model/viewmanager.cpp
+++ b/src/plugins/qmldesigner/designercore/model/viewmanager.cpp
@@ -24,6 +24,12 @@ ViewManager::ViewManager()
     m_formEditorView.formEditorWidget()->toolBox()->addLeftSideAction(m_componentView.action()); // ugly hack
 }
 
+ViewManager::~ViewManager()
+{
+    foreach (const QWeakPointer<AbstractView> &view, m_additionalViews)
+        delete view.data();
+}
+
 DesignDocument *ViewManager::currentDesignDocument() const
 {
     return QmlDesignerPlugin::instance()->documentManager().currentDesignDocument();
@@ -87,9 +93,15 @@ void ViewManager::resisterFormEditorTool(AbstractFormEditorTool *tool)
     m_formEditorView.registerTool(tool);
 }
 
+void ViewManager::registerView(AbstractView *view)
+{
+    m_additionalViews.append(view);
+}
+
 void ViewManager::detachViewsExceptRewriterAndComponetView()
 {
     switchStateEditorViewToBaseState();
+    detachAdditionalViews();
     currentModel()->detachView(DesignerActionManager::view());
     currentModel()->detachView(&m_formEditorView);
     currentModel()->detachView(&m_navigatorView);
@@ -109,6 +121,18 @@ void ViewManager::attachItemLibraryView()
     currentModel()->attachView(&m_itemLibraryView);
 }
 
+void ViewManager::attachAdditionalViews()
+{
+    foreach (const QWeakPointer<AbstractView> &view, m_additionalViews)
+        currentModel()->attachView(view.data());
+}
+
+void ViewManager::detachAdditionalViews()
+{
+    foreach (const QWeakPointer<AbstractView> &view, m_additionalViews)
+        currentModel()->detachView(view.data());
+}
+
 void ViewManager::attachComponentView()
 {
     documentModel()->attachView(&m_componentView);
@@ -134,6 +158,7 @@ void ViewManager::attachViewsExceptRewriterAndComponetView()
     currentModel()->attachView(&m_statesEditorView);
     currentModel()->attachView(&m_propertyEditorView);
     currentModel()->attachView(DesignerActionManager::view());
+    attachAdditionalViews();
     switchStateEditorViewToSavedState();
 }
 
@@ -152,29 +177,41 @@ void ViewManager::setNodeInstanceViewQtPath(const QString &qtPath)
     m_nodeInstanceView.setPathToQt(qtPath);
 }
 
-QWidget *ViewManager::formEditorWidget()
+static bool widgetInfoLessThan(const WidgetInfo &firstWidgetInfo, const WidgetInfo &secondWidgetInfo)
 {
-    return m_formEditorView.widget();
+    return firstWidgetInfo.placementPriority < secondWidgetInfo.placementPriority;
 }
 
-QWidget *ViewManager::propertyEditorWidget()
+QList<WidgetInfo> ViewManager::widgetInfos()
 {
-    return m_propertyEditorView.widget();
-}
+    QList<WidgetInfo> widgetInfoList;
 
-QWidget *ViewManager::itemLibraryWidget()
-{
-    return m_itemLibraryView.widget();
+    widgetInfoList.append(m_formEditorView.widgetInfo());
+    widgetInfoList.append(m_itemLibraryView.widgetInfo());
+    widgetInfoList.append(m_navigatorView.widgetInfo());
+    widgetInfoList.append(m_propertyEditorView.widgetInfo());
+    widgetInfoList.append(m_statesEditorView.widgetInfo());
+
+    foreach (const QWeakPointer<AbstractView> &abstractView, m_additionalViews) {
+        if (abstractView && abstractView->hasWidget())
+            widgetInfoList.append(abstractView->widgetInfo());
+    }
+
+    qSort(widgetInfoList.begin(), widgetInfoList.end(), widgetInfoLessThan);
+
+    return widgetInfoList;
 }
 
-QWidget *ViewManager::navigatorWidget()
+void ViewManager::disableWidgets()
 {
-    return m_navigatorView.widget();
+    foreach (const WidgetInfo &widgetInfo, widgetInfos())
+        widgetInfo.widget->setEnabled(false);
 }
 
-QWidget *ViewManager::statesEditorWidget()
+void ViewManager::enableWidgets()
 {
-    return m_statesEditorView.widget();
+    foreach (const WidgetInfo &widgetInfo, widgetInfos())
+        widgetInfo.widget->setEnabled(true);
 }
 
 void ViewManager::pushFileOnCrambleBar(const QString &fileName)
diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp
index 46a9f778f47..3c82b3b7189 100644
--- a/src/plugins/qmldesigner/designmodewidget.cpp
+++ b/src/plugins/qmldesigner/designmodewidget.cpp
@@ -30,7 +30,6 @@
 #include "designmodewidget.h"
 #include "qmldesignerconstants.h"
 #include "styledoutputpaneplaceholder.h"
-#include "designmodecontext.h"
 #include "qmldesignerplugin.h"
 
 #include <model.h>
@@ -71,6 +70,7 @@
 #include <QClipboard>
 #include <QLabel>
 #include <QProgressDialog>
+#include <QTabWidget>
 
 using Core::MiniSplitter;
 using Core::IEditor;
@@ -82,9 +82,6 @@ enum {
     debug = false
 };
 
-const char SB_NAVIGATOR[] = "Navigator";
-const char SB_LIBRARY[] = "Library";
-const char SB_PROPERTIES[] = "Properties";
 const char SB_PROJECTS[] = "Projects";
 const char SB_FILESYSTEM[] = "FileSystem";
 const char SB_OPENDOCUMENTS[] = "OpenDocuments";
@@ -232,9 +229,6 @@ void DesignModeWidget::toggleSidebars()
         m_leftSideBar->setVisible(m_showSidebars);
     if (m_rightSideBar)
         m_rightSideBar->setVisible(m_showSidebars);
-
-    viewManager().statesEditorWidget()->setVisible(m_showSidebars);
-
 }
 
 void DesignModeWidget::readSettings()
@@ -268,8 +262,7 @@ void DesignModeWidget::enableWidgets()
     if (debug)
         qDebug() << Q_FUNC_INFO;
     m_warningWidget->setVisible(false);
-    viewManager().formEditorWidget()->setEnabled(true);
-    viewManager().statesEditorWidget()->setEnabled(true);
+    viewManager().enableWidgets();
     m_leftSideBar->setEnabled(true);
     m_rightSideBar->setEnabled(true);
     m_isDisabled = false;
@@ -280,8 +273,7 @@ void DesignModeWidget::disableWidgets()
     if (debug)
         qDebug() << Q_FUNC_INFO;
 
-    viewManager().formEditorWidget()->setEnabled(false);
-    viewManager().statesEditorWidget()->setEnabled(false);
+    viewManager().disableWidgets();
     m_leftSideBar->setEnabled(false);
     m_rightSideBar->setEnabled(false);
     m_isDisabled = true;
@@ -349,6 +341,7 @@ void DesignModeWidget::setup()
         }
     }
 
+
     m_toolBar = Core::EditorManager::createToolBar(this);
 
     m_mainSplitter = new MiniSplitter(this);
@@ -358,30 +351,41 @@ void DesignModeWidget::setup()
     m_warningWidget = new DocumentWarningWidget(this);
     m_warningWidget->setVisible(false);
 
-    Core::SideBarItem *navigatorItem = new NavigatorSideBarItem(viewManager().navigatorWidget(), QLatin1String(SB_NAVIGATOR));
-    Core::SideBarItem *libraryItem = new ItemLibrarySideBarItem(viewManager().itemLibraryWidget(), QLatin1String(SB_LIBRARY));
-    Core::SideBarItem *propertiesItem = new Core::SideBarItem(viewManager().propertyEditorWidget(), QLatin1String(SB_PROPERTIES));
+    QList<Core::SideBarItem*> sideBarItems;
+    QList<Core::SideBarItem*> leftSideBarItems;
+    QList<Core::SideBarItem*> rightSideBarItems;
 
-    // default items
-    m_sideBarItems << navigatorItem << libraryItem << propertiesItem;
+    foreach (const WidgetInfo &widgetInfo, viewManager().widgetInfos()) {
+        if (widgetInfo.placementHint == widgetInfo.LeftPane) {
+            Core::SideBarItem *sideBarItem = new NavigatorSideBarItem(widgetInfo.widget, widgetInfo.uniqueId);
+            sideBarItems.append(sideBarItem);
+            leftSideBarItems.append(sideBarItem);
+        }
+
+        if (widgetInfo.placementHint == widgetInfo.RightPane) {
+            Core::SideBarItem *sideBarItem = new NavigatorSideBarItem(widgetInfo.widget, widgetInfo.uniqueId);
+            sideBarItems.append(sideBarItem);
+            rightSideBarItems.append(sideBarItem);
+        }
+    }
 
     if (projectsExplorer) {
         Core::SideBarItem *projectExplorerItem = new Core::SideBarItem(projectsExplorer, QLatin1String(SB_PROJECTS));
-        m_sideBarItems << projectExplorerItem;
+        sideBarItems.append(projectExplorerItem);
     }
 
     if (fileSystemExplorer) {
         Core::SideBarItem *fileSystemExplorerItem = new Core::SideBarItem(fileSystemExplorer, QLatin1String(SB_FILESYSTEM));
-        m_sideBarItems << fileSystemExplorerItem;
+        sideBarItems.append(fileSystemExplorerItem);
     }
 
     if (openDocumentsWidget) {
         Core::SideBarItem *openDocumentsItem = new Core::SideBarItem(openDocumentsWidget, QLatin1String(SB_OPENDOCUMENTS));
-        m_sideBarItems << openDocumentsItem;
+        sideBarItems.append(openDocumentsItem);
     }
 
-    m_leftSideBar.reset(new Core::SideBar(m_sideBarItems, QList<Core::SideBarItem*>() << navigatorItem << libraryItem));
-    m_rightSideBar.reset(new Core::SideBar(m_sideBarItems, QList<Core::SideBarItem*>() << propertiesItem));
+    m_leftSideBar.reset(new Core::SideBar(sideBarItems, leftSideBarItems));
+    m_rightSideBar.reset(new Core::SideBar(sideBarItems, rightSideBarItems));
 
     connect(m_leftSideBar.data(), SIGNAL(availableItemsChanged()), SLOT(updateAvailableSidebarItemsRight()));
     connect(m_rightSideBar.data(), SIGNAL(availableItemsChanged()), SLOT(updateAvailableSidebarItemsLeft()));
@@ -398,12 +402,9 @@ void DesignModeWidget::setup()
     if (currentDesignDocument())
         setupNavigatorHistory(currentDesignDocument()->textEditor());
 
-    // right area:
-    QWidget *centerWidget = createCenterWidget();
-
     // m_mainSplitter area:
     m_mainSplitter->addWidget(m_leftSideBar.data());
-    m_mainSplitter->addWidget(centerWidget);
+    m_mainSplitter->addWidget(createCenterWidget());
     m_mainSplitter->addWidget(m_rightSideBar.data());
 
     // Finishing touches:
@@ -416,7 +417,7 @@ void DesignModeWidget::setup()
     mainLayout->addWidget(m_mainSplitter);
 
     m_warningWidget->setVisible(false);
-    viewManager().statesEditorWidget()->setEnabled(true);
+    viewManager().enableWidgets();
     m_leftSideBar->setEnabled(true);
     m_rightSideBar->setEnabled(true);
     m_leftSideBar->setCloseWhenEmpty(true);
@@ -514,6 +515,16 @@ void DesignModeWidget::addNavigatorHistoryEntry(const QString &fileName)
     ++m_navigatorHistoryCounter;
 }
 
+static QWidget *createWidgetsInTabWidget(const QList<WidgetInfo> &widgetInfos)
+{
+    QTabWidget *tabWidget = new QTabWidget;
+
+    foreach (const WidgetInfo &widgetInfo, widgetInfos)
+        tabWidget->addTab(widgetInfo.widget, widgetInfo.tabName);
+
+    return tabWidget;
+}
+
 QWidget *DesignModeWidget::createCenterWidget()
 {
     QWidget *centerWidget = new QWidget;
@@ -522,17 +533,32 @@ QWidget *DesignModeWidget::createCenterWidget()
     rightLayout->setMargin(0);
     rightLayout->setSpacing(0);
     rightLayout->addWidget(m_toolBar);
+
+
     //### we now own these here
-    rightLayout->addWidget(viewManager().statesEditorWidget());
+    QList<WidgetInfo> topWidgetInfos;
+    foreach (const WidgetInfo &widgetInfo, viewManager().widgetInfos()) {
+        if (widgetInfo.placementHint == widgetInfo.TopPane)
+            topWidgetInfos.append(widgetInfo);
+    }
 
-    FormEditorContext *formEditorContext = new FormEditorContext(viewManager().formEditorWidget());
-    Core::ICore::addContextObject(formEditorContext);
+    if (topWidgetInfos.count() == 1)
+        rightLayout->addWidget(topWidgetInfos.first().widget);
+    else
+        rightLayout->addWidget(createWidgetsInTabWidget(topWidgetInfos));
 
-    NavigatorContext *navigatorContext = new NavigatorContext(viewManager().navigatorWidget());
-    Core::ICore::addContextObject(navigatorContext);
+    QList<WidgetInfo> centralWidgetInfos;
+    foreach (const WidgetInfo &widgetInfo, viewManager().widgetInfos()) {
+        if (widgetInfo.placementHint == widgetInfo.CentralPane)
+            centralWidgetInfos.append(widgetInfo);
+    }
 
     // editor and output panes
-    m_outputPlaceholderSplitter->addWidget(viewManager().formEditorWidget());
+    if (centralWidgetInfos.count() == 1)
+        m_outputPlaceholderSplitter->addWidget(centralWidgetInfos.first().widget);
+    else
+         m_outputPlaceholderSplitter->addWidget(createWidgetsInTabWidget(centralWidgetInfos));
+
     m_outputPlaceholderSplitter->addWidget(m_outputPanePlaceholder);
     m_outputPlaceholderSplitter->setStretchFactor(0, 10);
     m_outputPlaceholderSplitter->setStretchFactor(1, 0);
diff --git a/src/plugins/qmldesigner/designmodewidget.h b/src/plugins/qmldesigner/designmodewidget.h
index 724f0fa5232..48f4f5045ab 100644
--- a/src/plugins/qmldesigner/designmodewidget.h
+++ b/src/plugins/qmldesigner/designmodewidget.h
@@ -161,7 +161,6 @@ private: // variables
     Core::EditorToolBar *m_toolBar;
     Core::OutputPanePlaceHolder *m_outputPanePlaceholder;
     Core::MiniSplitter *m_outputPlaceholderSplitter;
-    QList<Core::SideBarItem*> m_sideBarItems;
     bool m_isDisabled;
     bool m_showSidebars;
 
-- 
GitLab