Commit 1b86bc50 authored by Friedemann Kleint's avatar Friedemann Kleint

Design mode/Qt Designer: Clean up the widget part of it.

- Remove shared subwindow reparenting from EditorWidget, make EditorWidget
  inherit FancyMainWindow. and use just once instance of it instead of
  per-editor ones.
- Embedded FormEditorStack into EditorWidget as a centralwidget.
- Changed FormWindowEditor's base class from IEditor to SharedTools::FormWindowHost
  (Widget) to be embedded into FormEditorStack (no need to be an IEditor),
  Remove Designer::Internal::FormWindowHost which had little functionality.
- Add Design Mode widget to FormEditorW which has FakeToolBar and EditorWidget
  (single instance) in a vertical layout.
- Removed ProxyAction class handling dock view toggle actions of several EditorWidgets
  (no longer necessary since there is just once instance). Moved "View menu" to bottom.
- Started to make FakeToolBar work as a single instance listening on changing
  xml editors
- Include-file/slot connection clean-up.
parent 9dae1688
......@@ -25,7 +25,6 @@ HEADERS += formeditorplugin.h \
formeditorfactory.h \
formwindoweditor.h \
formwindowfile.h \
formwindowhost.h \
formwizard.h \
qtcreatorintegration.h \
designerconstants.h \
......@@ -46,7 +45,6 @@ SOURCES += formeditorplugin.cpp \
formeditorfactory.cpp \
formwindoweditor.cpp \
formwindowfile.cpp \
formwindowhost.cpp \
formwizard.cpp \
qtcreatorintegration.cpp \
settingspage.cpp \
......
......@@ -29,27 +29,26 @@
#include "designercontext.h"
#include "designerconstants.h"
#include <coreplugin/uniqueidmanager.h>
#include <coreplugin/coreconstants.h>
#include "formeditorw.h"
#include <QWidget>
#include <QtDesigner/QDesignerFormEditorInterface>
#include "qt_private/qdesigner_integration_p.h"
#include <QtGui/QWidget>
#include <QtCore/QDebug>
enum { debug = 0 };
namespace Designer {
namespace Internal {
DesignerContext::DesignerContext(QWidget *widget) : Core::IContext(widget),
DesignerContext::DesignerContext(const QList<int> contexts,
QWidget *widget,
QObject *parent) :
Core::IContext(parent),
m_context(contexts),
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
......@@ -62,11 +61,19 @@ QWidget *DesignerContext::widget()
return m_widget;
}
void DesignerContext::setWidget(QWidget *widget)
QString DesignerContext::contextHelpId() const
{
m_widget = widget;
}
}
QString helpId;
const QDesignerFormEditorInterface *core = FormEditorW::instance()->designerEditor();
// Present from Qt 4.5.1 onwards. This will show the class documentation
// scrolled to the current property.
if (const qdesigner_internal::QDesignerIntegration *integration =
qobject_cast<const qdesigner_internal::QDesignerIntegration*>(core->integration()))
helpId = integration->contextHelpId();
if (debug)
qDebug() << "DesignerContext::contextHelpId" << m_widget << helpId;
return helpId;
}
} // namespace Internal
} // namespace Designer
......@@ -42,19 +42,22 @@ namespace Internal {
class DesignerContext : public Core::IContext
{
Q_DISABLE_COPY(DesignerContext)
public:
DesignerContext(QWidget *widget = 0);
~DesignerContext();
QList<int> context() const;
QWidget *widget();
void setWidget(QWidget *widget);
explicit DesignerContext(const QList<int> contexts,
QWidget *widget,
QObject *parent = 0);
virtual QList<int> context() const;
virtual QWidget *widget();
virtual QString contextHelpId() const;
private:
QList<int> m_context;
const QList<int> m_context;
QWidget *m_widget;
};
}
}
} // namespace Internal
} // namespace Designer
#endif // DESIGNERCONTEXT_H
......@@ -99,4 +99,12 @@ Core::IEditor *DesignerXmlEditorEditable::duplicate(QWidget *parent)
Q_UNUSED(parent);
return 0;
}
namespace Internal {
TextEditor::BaseTextEditorEditable *DesignerXmlEditor::createEditableInterface()
{
return new DesignerXmlEditorEditable(this);
}
}
} // namespace Designer
......@@ -80,7 +80,7 @@ private slots:
void updateEditorInfoBar(Core::IEditor *editor);
protected:
virtual TextEditor::BaseTextEditorEditable *createEditableInterface() { return new DesignerXmlEditorEditable(this); }
virtual TextEditor::BaseTextEditorEditable *createEditableInterface();
private:
};
......
......@@ -29,168 +29,97 @@
#include "editorwidget.h"
#include "formeditorw.h"
#include "formeditorstack.h"
#include <coreplugin/minisplitter.h>
#include <utils/qtcassert.h>
#include <QtCore/QEvent>
#include <QtGui/QVBoxLayout>
#include <QtGui/QTabWidget>
static const char *editorWidgetStateKeyC = "editorWidgetState";
#include <QtGui/QDockWidget>
using namespace Designer::Constants;
namespace Designer {
namespace Internal {
SharedSubWindow::SharedSubWindow(QWidget *shared, QWidget *parent) :
QWidget(parent),
m_shared(shared),
m_layout(new QVBoxLayout)
{
QTC_ASSERT(m_shared, /**/);
m_layout->setContentsMargins(0, 0, 0, 0);
setLayout(m_layout);
}
void SharedSubWindow::activate()
{
// Take the widget off the other parent
QTC_ASSERT(m_shared, return);
QWidget *currentParent = m_shared->parentWidget();
if (currentParent == this)
return;
m_layout->addWidget(m_shared);
m_shared->show();
}
SharedSubWindow::~SharedSubWindow()
{
// Do not destroy the shared sub window if we currently own it
if (m_shared->parent() == this) {
m_shared->hide();
m_shared->setParent(0);
}
}
// ---------- EditorWidget
QHash<QString, QVariant> EditorWidget::m_globalState = QHash<QString, QVariant>();
EditorWidget::EditorWidget(QWidget *formWindow)
: m_mainWindow(new Utils::FancyMainWindow),
m_initialized(false)
EditorWidget::EditorWidget(FormEditorW *few, QWidget *parent) :
Utils::FancyMainWindow(parent),
m_stack(new FormEditorStack)
{
QVBoxLayout *layout = new QVBoxLayout;
layout->setMargin(0);
layout->setSpacing(0);
setLayout(layout);
layout->addWidget(m_mainWindow);
m_mainWindow->setCentralWidget(formWindow);
m_mainWindow->setDocumentMode(true);
m_mainWindow->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::South);
m_mainWindow->setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
m_mainWindow->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
// Get shared sub windows from Form Editor
FormEditorW *few = FormEditorW::instance();
QWidget * const*subs = few->designerSubWindows();
setObjectName(QLatin1String("EditorWidget"));
setCentralWidget(m_stack);
setDocumentMode(true);
setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::South);
setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
// Create shared sub windows
for (int i=0; i < DesignerSubWindowCount; i++) {
m_designerSubWindows[i] = new SharedSubWindow(subs[i]);
m_designerSubWindows[i]->setWindowTitle(subs[i]->windowTitle());
m_designerDockWidgets[i] = m_mainWindow->addDockForWidget(m_designerSubWindows[i]);
QWidget * const*subs = few->designerSubWindows();
for (int i = 0; i < DesignerSubWindowCount; i++) {
QWidget *subWindow = subs[i];
subWindow->setWindowTitle(subs[i]->windowTitle());
m_designerDockWidgets[i] = addDockForWidget(subWindow);
}
resetToDefaultLayout();
}
void EditorWidget::resetToDefaultLayout()
{
m_mainWindow->setTrackingEnabled(false);
QList<QDockWidget *> dockWidgets = m_mainWindow->dockWidgets();
foreach (QDockWidget *dockWidget, dockWidgets) {
setTrackingEnabled(false);
QList<QDockWidget *> dockWidgetList = dockWidgets();
foreach (QDockWidget *dockWidget, dockWidgetList) {
dockWidget->setFloating(false);
m_mainWindow->removeDockWidget(dockWidget);
removeDockWidget(dockWidget);
}
m_mainWindow->addDockWidget(Qt::LeftDockWidgetArea, m_designerDockWidgets[WidgetBoxSubWindow]);
m_mainWindow->addDockWidget(Qt::RightDockWidgetArea, m_designerDockWidgets[ObjectInspectorSubWindow]);
m_mainWindow->addDockWidget(Qt::RightDockWidgetArea, m_designerDockWidgets[PropertyEditorSubWindow]);
m_mainWindow->addDockWidget(Qt::BottomDockWidgetArea, m_designerDockWidgets[ActionEditorSubWindow]);
m_mainWindow->addDockWidget(Qt::BottomDockWidgetArea, m_designerDockWidgets[SignalSlotEditorSubWindow]);
addDockWidget(Qt::LeftDockWidgetArea, m_designerDockWidgets[WidgetBoxSubWindow]);
addDockWidget(Qt::RightDockWidgetArea, m_designerDockWidgets[ObjectInspectorSubWindow]);
addDockWidget(Qt::RightDockWidgetArea, m_designerDockWidgets[PropertyEditorSubWindow]);
addDockWidget(Qt::BottomDockWidgetArea, m_designerDockWidgets[ActionEditorSubWindow]);
addDockWidget(Qt::BottomDockWidgetArea, m_designerDockWidgets[SignalSlotEditorSubWindow]);
m_mainWindow->tabifyDockWidget(m_designerDockWidgets[ActionEditorSubWindow],
m_designerDockWidgets[SignalSlotEditorSubWindow]);
tabifyDockWidget(m_designerDockWidgets[ActionEditorSubWindow],
m_designerDockWidgets[SignalSlotEditorSubWindow]);
foreach (QDockWidget *dockWidget, dockWidgets) {
foreach (QDockWidget *dockWidget, dockWidgetList)
dockWidget->show();
}
m_mainWindow->setTrackingEnabled(true);
setTrackingEnabled(true);
}
void EditorWidget::activate()
QDockWidget* const* EditorWidget::designerDockWidgets() const
{
/*
- 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();
if (!m_initialized) {
// set a default layout, so if something goes wrong with
// restoring the settings below, there is a fallback
// (otherwise we end up with a broken mainwindow layout)
// we can't do it in the constructor, because the sub windows
// don't have their widgets yet there
resetToDefaultLayout();
m_initialized = true;
if (!m_globalState.isEmpty())
m_mainWindow->restoreSettings(m_globalState);
}
return m_designerDockWidgets;
}
if (m_globalState.isEmpty())
m_globalState = m_mainWindow->saveSettings();
Designer::FormWindowEditor *EditorWidget::createFormWindowEditor(DesignerXmlEditorEditable *xmlEditor)
{
return m_stack->createFormWindowEditor(xmlEditor);
}
void EditorWidget::hideEvent(QHideEvent *)
bool EditorWidget::removeFormWindowEditor(Core::IEditor *xmlEditor)
{
m_globalState = m_mainWindow->saveSettings();
return m_stack->removeFormWindowEditor(xmlEditor);
}
void EditorWidget::saveState(QSettings *settings)
bool EditorWidget::setVisibleEditor(Core::IEditor *xmlEditor)
{
settings->beginGroup(editorWidgetStateKeyC);
QHashIterator<QString, QVariant> it(m_globalState);
while (it.hasNext()) {
it.next();
settings->setValue(it.key(), it.value());
}
settings->endGroup();
return m_stack->setVisibleEditor(xmlEditor);
}
void EditorWidget::restoreState(QSettings *settings)
Designer::FormWindowEditor *EditorWidget::formWindowEditorForXmlEditor(const Core::IEditor *xmlEditor) const
{
m_globalState.clear();
settings->beginGroup(editorWidgetStateKeyC);
foreach (const QString &key, settings->childKeys()) {
m_globalState.insert(key, settings->value(key));
}
settings->endGroup();
return m_stack->formWindowEditorForXmlEditor(xmlEditor);
}
FormWindowEditor *EditorWidget::activeFormWindow() const
{
return m_stack->activeFormWindow();
}
void EditorWidget::toolChanged(int i)
Designer::FormWindowEditor *EditorWidget::formWindowEditorForFormWindow(const QDesignerFormWindowInterface *fw) const
{
Q_UNUSED(i)
// TODO: How to activate the right dock window?
// if (m_bottomTab)
// m_bottomTab->setCurrentIndex(i == EditModeSignalsSlotEditor ? SignalSlotEditorTab : ActionEditorTab);
return m_stack->formWindowEditorForFormWindow(fw);
}
} // namespace Internal
......
......@@ -34,72 +34,48 @@
#include <utils/fancymainwindow.h>
#include <QtCore/QPointer>
#include <QtCore/QList>
#include <QtCore/QHash>
#include <QtCore/QVariant>
#include <QtCore/QSettings>
#include <QtGui/QWidget>
#include <QtGui/QVBoxLayout>
#include <QtGui/QDockWidget>
#include <QtGui/QHideEvent>
namespace Designer {
namespace Internal {
/* A widget that shares its embedded sub window with others. For example,
* the designer editors need to share the widget box, etc. */
class SharedSubWindow : public QWidget
{
Q_OBJECT
Q_DISABLE_COPY(SharedSubWindow)
public:
SharedSubWindow(QWidget *shared, QWidget *parent = 0);
virtual ~SharedSubWindow();
public slots:
// Takes the shared widget off the current parent and adds it to its
// layout
void activate();
QT_BEGIN_NAMESPACE
class QDesignerFormWindowInterface;
QT_END_NAMESPACE
private:
QPointer <QWidget> m_shared;
QVBoxLayout *m_layout;
};
namespace Core {
class IEditor;
}
namespace Designer {
class FormWindowEditor;
class DesignerXmlEditorEditable;
namespace Internal {
class FormEditorStack;
class FormEditorW;
/* Form editor splitter used as editor window. Contains the shared designer
* windows. */
class EditorWidget : public QWidget
class EditorWidget : public Utils::FancyMainWindow
{
Q_OBJECT
Q_DISABLE_COPY(EditorWidget)
public:
explicit EditorWidget(QWidget *formWindow);
explicit EditorWidget(FormEditorW *fe, QWidget *parent = 0);
QDockWidget* const* designerDockWidgets() const;
void resetToDefaultLayout();
QDockWidget* const* dockWidgets() const { return m_designerDockWidgets; }
bool isLocked() const { return m_mainWindow->isLocked(); }
void setLocked(bool locked) { m_mainWindow->setLocked(locked); }
static void saveState(QSettings *settings);
static void restoreState(QSettings *settings);
// Form editor stack API
Designer::FormWindowEditor *createFormWindowEditor(DesignerXmlEditorEditable *xmlEditor);
bool removeFormWindowEditor(Core::IEditor *xmlEditor);
bool setVisibleEditor(Core::IEditor *xmlEditor);
Designer::FormWindowEditor *formWindowEditorForXmlEditor(const Core::IEditor *xmlEditor) const;
Designer::FormWindowEditor *formWindowEditorForFormWindow(const QDesignerFormWindowInterface *fw) const;
FormWindowEditor *activeFormWindow() const;
public slots:
void activate();
void toolChanged(int);
protected:
void hideEvent(QHideEvent * e);
void resetToDefaultLayout();
private:
SharedSubWindow* m_designerSubWindows[Designer::Constants::DesignerSubWindowCount];
FormEditorStack *m_stack;
QDockWidget *m_designerDockWidgets[Designer::Constants::DesignerSubWindowCount];
Utils::FancyMainWindow *m_mainWindow;
bool m_initialized;
static QHash<QString, QVariant> m_globalState;
};
} // namespace Internal
......
......@@ -33,7 +33,6 @@
#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>
......@@ -59,7 +58,7 @@
#include <QtGui/QLabel>
#include <QtGui/QToolBar>
using Core::MiniSplitter;
using Core::IEditor;
using Core::EditorManager;
......@@ -69,24 +68,28 @@ enum {
debug = false
};
static inline bool isDesignerXmlEditor(const Core::IEditor *editor)
{
return editor->id() == QLatin1String(Designer::Constants::K_DESIGNER_XML_EDITOR_ID);
}
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) :
FakeToolBar::FakeToolBar(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)
m_goForwardAction(new QAction(QIcon(QLatin1String(":/help/images/next.png")), EditorManager::tr("Go Forward"), parent))
{
Core::ICore *core = Core::ICore::instance();
//setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
m_editorsListModel = core->editorManager()->openedEditorsModel();
// copied from EditorView::EditorView
......@@ -95,7 +98,6 @@ FakeToolBar::FakeToolBar(Core::IEditor *editor, QWidget *toolbar, QWidget *paren
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);
......@@ -141,7 +143,6 @@ FakeToolBar::FakeToolBar(Core::IEditor *editor, QWidget *toolbar, QWidget *paren
toplayout->setMargin(0);
toplayout->setContentsMargins(0,0,0,0);
// toplayout->addWidget(backFwToolBar);
toplayout->addWidget(editorListToolBar);
toplayout->addWidget(toolbar);
toplayout->addWidget(rightToolBar);
......@@ -151,16 +152,26 @@ FakeToolBar::FakeToolBar(Core::IEditor *editor, QWidget *toolbar, QWidget *paren
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*)));
connect(core->editorManager(), SIGNAL(currentEditorChanged(Core::IEditor*)), SLOT(editorChanged(Core::IEditor*)));
updateEditorStatus();
if (Core::IEditor *editor = core->editorManager()->currentEditor())
editorChanged(editor);
}
void FakeToolBar::updateEditorListSelection(Core::IEditor *newSelection)
void FakeToolBar::editorChanged(Core::IEditor *newSelection)
{
if (newSelection == m_editor)
return;
if (m_editor && isDesignerXmlEditor(m_editor))
disconnect(m_editor, SIGNAL(changed()), this, SLOT(updateEditorStatus()));
if (newSelection) {
m_editor = newSelection;
m_editorList->setCurrentIndex(m_editorsListModel->indexOf(newSelection).row());
if (isDesignerXmlEditor(m_editor))
connect(m_editor, SIGNAL(changed()), this, SLOT(updateEditorStatus()));
updateEditorStatus();
}
}
......@@ -170,11 +181,9 @@ void FakeToolBar::close()
// 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);
if (Core::IEditor *editor = core->editorManager()->currentEditor()) {
if (isDesignerXmlEditor(editor) && editor->file() == m_editor->file())
core->editorManager()->closeEditors(QList<Core::IEditor*>() << editor);
}
core->modeManager()->activateMode(Core::Constants::MODE_EDIT);
}
......@@ -182,10 +191,9 @@ void FakeToolBar::close()
void FakeToolBar::listSelectionActivated(int row)
{
Core::EditorManager *em = Core::ICore::instance()->editorManager();
QAbstractItemModel *model = m_editorList->model();
const QAbstractItemModel *model = m_editorList->model();
const QModelIndex modelIndex = model->index(row, 0);
IEditor *editor = model->data(modelIndex, Qt::UserRole).value<IEditor*>();
Core::IEditor *editor = model->data(modelIndex, Qt::UserRole).value<Core::IEditor*>();
if (editor) {
if (editor != em->currentEditor())
em->activateEditor(editor, EditorManager::NoModeSwitch);
......@@ -219,7 +227,7 @@ void FakeToolBar::makeEditorWritable()
void FakeToolBar::updateEditorStatus()
{
if (!m_editor->file())
if (!m_editor || !m_editor->file())
return;
if (m_editor->file()->isReadOnly()) {
......
......@@ -56,12 +56,12 @@ class FakeToolBar : public QWidget
Q_OBJECT
Q_DISABLE_COPY(FakeToolBar)
public:
explicit FakeToolBar(Core::IEditor *editor, QWidget *toolbar, QWidget *parent = 0);
explicit FakeToolBar(QWidget *toolbar, QWidget *parent = 0);
void