Commit 8d9710c0 authored by Marco Bubke's avatar Marco Bubke

Refactoring document handling

The document handling in the qml designer was complicated source
code, which was initially intended for a non creator application.
To integrate new views it has to be changed and cleaned up. This
is the first major step in that direction.

Change-Id: Ie26f0aad7a03946d18bdb4c0759b246c5439d922
Reviewed-by: default avatarTim Jenssen <tim.jenssen@digia.com>
Reviewed-by: default avatarAlessandro Portale <alessandro.portale@digia.com>
parent a4455f37
......@@ -186,6 +186,11 @@ public:
m_designerActionList = designerActionList;
}
QWidget *widget()
{
return 0;
}
protected:
void setupContext()
{
......
......@@ -35,12 +35,13 @@
#include <bindingproperty.h>
#include <nodeproperty.h>
#include <designmodewidget.h>
#include <qmldesignerplugin.h>
namespace QmlDesigner {
static inline DesignDocumentController* designDocumentController()
static inline DesignDocument* currentDesignDocument()
{
return Internal::DesignModeWidget::instance()->currentDesignDocumentController();
return QmlDesignerPlugin::instance()->documentManager().currentDesignDocument();
}
static inline bool checkIfNodeIsAView(const ModelNode &node)
......@@ -103,14 +104,14 @@ static inline bool modelNodeIsComponent(const ModelNode &node)
if (!node.isValid() || !node.metaInfo().isValid())
return false;
if (node.metaInfo().isComponent())
if (node.metaInfo().isFileComponent())
return true;
if (node.nodeSourceType() == ModelNode::NodeWithComponentSource)
return true;
if (checkIfNodeIsAView(node) &&
node.hasNodeProperty("delegate")) {
if (node.nodeProperty("delegate").modelNode().metaInfo().isComponent())
if (node.nodeProperty("delegate").modelNode().metaInfo().isFileComponent())
return true;
if (node.nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource)
return true;
......@@ -156,12 +157,12 @@ static inline bool isFileComponent(const ModelNode &node)
if (!node.isValid() || !node.metaInfo().isValid())
return false;
if (node.metaInfo().isComponent())
if (node.metaInfo().isFileComponent())
return true;
if (checkIfNodeIsAView(node) &&
node.hasNodeProperty("delegate")) {
if (node.nodeProperty("delegate").modelNode().metaInfo().isComponent())
if (node.nodeProperty("delegate").modelNode().metaInfo().isFileComponent())
return true;
}
......@@ -170,21 +171,23 @@ static inline bool isFileComponent(const ModelNode &node)
static inline void openFileForComponent(const ModelNode &node)
{
QmlDesignerPlugin::instance()->viewManager().nextFileIsCalledInternally();
//int width = 0;
//int height = 0;
QHash<QString, QVariant> propertyHash;
if (node.metaInfo().isComponent()) {
if (node.metaInfo().isFileComponent()) {
//getWidthHeight(node, width, height);
getProperties(node, propertyHash);
designDocumentController()->changeToExternalSubComponent(node.metaInfo().componentFileName());
currentDesignDocument()->changeToExternalSubComponent(node.metaInfo().componentFileName());
} else if (checkIfNodeIsAView(node) &&
node.hasNodeProperty("delegate") &&
node.nodeProperty("delegate").modelNode().metaInfo().isComponent()) {
node.nodeProperty("delegate").modelNode().metaInfo().isFileComponent()) {
//getWidthHeight(node, width, height);
getProperties(node, propertyHash);
designDocumentController()->changeToExternalSubComponent(node.nodeProperty("delegate").modelNode().metaInfo().componentFileName());
currentDesignDocument()->changeToExternalSubComponent(node.nodeProperty("delegate").modelNode().metaInfo().componentFileName());
}
ModelNode rootModelNode = designDocumentController()->model()->rewriterView()->rootModelNode();
ModelNode rootModelNode = currentDesignDocument()->rewriterView()->rootModelNode();
applyProperties(rootModelNode, propertyHash);
//rootModelNode.setAuxiliaryData("width", width);
//rootModelNode.setAuxiliaryData("height", height);
......@@ -192,10 +195,11 @@ static inline void openFileForComponent(const ModelNode &node)
static inline void openInlineComponent(const ModelNode &node)
{
if (!node.isValid() || !node.metaInfo().isValid())
return;
if (!designDocumentController())
if (!currentDesignDocument())
return;
QHash<QString, QVariant> propertyHash;
......@@ -203,27 +207,27 @@ static inline void openInlineComponent(const ModelNode &node)
if (node.nodeSourceType() == ModelNode::NodeWithComponentSource) {
//getWidthHeight(node, width, height);
getProperties(node, propertyHash);
designDocumentController()->changeToSubComponent(node);
currentDesignDocument()->changeToSubComponent(node);
} else if (checkIfNodeIsAView(node) &&
node.hasNodeProperty("delegate")) {
if (node.nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource) {
//getWidthHeight(node, width, height);
getProperties(node, propertyHash);
designDocumentController()->changeToSubComponent(node.nodeProperty("delegate").modelNode());
currentDesignDocument()->changeToSubComponent(node.nodeProperty("delegate").modelNode());
}
}
ModelNode rootModelNode = designDocumentController()->model()->rewriterView()->rootModelNode();
ModelNode rootModelNode = currentDesignDocument()->rewriterView()->rootModelNode();
applyProperties(rootModelNode, propertyHash);
//rootModelNode.setAuxiliaryData("width", width);
//rootModelNode.setAuxiliaryData("height", height);
}
namespace ComponentUtils {
void goIntoComponent(const ModelNode &modelNode)
{
if (modelNode.isValid() && modelNodeIsComponent(modelNode)) {
QmlDesignerPlugin::instance()->viewManager().setComponentNode(modelNode);
if (isFileComponent(modelNode))
openFileForComponent(modelNode);
else
......
......@@ -32,7 +32,8 @@ SOURCES += formeditoritem.cpp \
zoomaction.cpp \
formeditorgraphicsview.cpp \
numberseriesaction.cpp \
lineeditaction.cpp
lineeditaction.cpp \
formeditorcrumblebar.cpp
HEADERS += formeditorscene.h \
formeditorwidget.h \
formeditoritem.h \
......@@ -63,5 +64,6 @@ HEADERS += formeditorscene.h \
zoomaction.h \
formeditorgraphicsview.h \
numberseriesaction.h \
lineeditaction.h
lineeditaction.h \
formeditorcrumblebar.h
RESOURCES += formeditor.qrc
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "formeditorcrumblebar.h"
#include "qmldesignerplugin.h"
#include <QVariant>
#include <QtDebug>
namespace QmlDesigner {
FormEditorCrumbleBar::FormEditorCrumbleBar(QObject *parent) :
QObject(parent),
m_isInternalCalled(false),
m_crumblePath(new Utils::CrumblePath)
{
connect(m_crumblePath,
SIGNAL(elementClicked(QVariant)),
this,
SLOT(onCrumblePathElementClicked(QVariant)));
}
void FormEditorCrumbleBar::pushFile(const QString &fileName)
{
if (m_isInternalCalled == false)
crumblePath()->clear();
CrumbleBarInfo crumbleBarInfo;
crumbleBarInfo.fileName = fileName;
crumblePath()->pushElement(fileName.split("/").last(), QVariant::fromValue(crumbleBarInfo));
m_isInternalCalled = false;
}
static DesignDocument *currentDesignDocument()
{
return QmlDesignerPlugin::instance()->documentManager().currentDesignDocument();
}
void FormEditorCrumbleBar::pushInFileComponent(const QString &componentId)
{
CrumbleBarInfo crumbleBarInfo;
crumbleBarInfo.componentId = componentId;
crumbleBarInfo.fileName = currentDesignDocument()->textEditor()->document()->fileName();
CrumbleBarInfo lastElementCrumbleBarInfo = crumblePath()->dataForLastIndex().value<CrumbleBarInfo>();
if (!lastElementCrumbleBarInfo.componentId.isEmpty())
crumblePath()->popElement();
crumblePath()->pushElement(componentId, QVariant::fromValue(crumbleBarInfo));
}
void FormEditorCrumbleBar::nextFileIsCalledInternally()
{
m_isInternalCalled = true;
}
Utils::CrumblePath *FormEditorCrumbleBar::crumblePath()
{
return m_crumblePath;
}
void FormEditorCrumbleBar::onCrumblePathElementClicked(const QVariant &data)
{
CrumbleBarInfo crumbleBarInfo = data.value<CrumbleBarInfo>();
if (crumbleBarInfo == crumblePath()->dataForLastIndex().value<CrumbleBarInfo>())
return;
while (crumbleBarInfo != crumblePath()->dataForLastIndex().value<CrumbleBarInfo>())
crumblePath()->popElement();
if (!crumbleBarInfo.componentId.isEmpty())
crumblePath()->popElement();
crumblePath()->popElement();
m_isInternalCalled = true;
Core::EditorManager::openEditor(crumbleBarInfo.fileName);
if (!crumbleBarInfo.componentId.isEmpty())
currentDesignDocument()->changeToSubComponent(currentDesignDocument()->rewriterView()->modelNodeForId(crumbleBarInfo.componentId));
}
bool operator ==(const CrumbleBarInfo &first, const CrumbleBarInfo &second)
{
return first.fileName == second.fileName && first.componentId == second.componentId;
}
bool operator !=(const CrumbleBarInfo &first, const CrumbleBarInfo &second)
{
return first.fileName != second.fileName || first.componentId != second.componentId;
}
} // namespace QmlDesigner
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef QMLDESIGNER_FORMEDITORCRUMBLEBAR_H
#define QMLDESIGNER_FORMEDITORCRUMBLEBAR_H
#include <QObject>
#include <utils/crumblepath.h>
namespace QmlDesigner {
class FormEditorCrumbleBar : public QObject
{
Q_OBJECT
public:
explicit FormEditorCrumbleBar(QObject *parent = 0);
void pushFile(const QString &fileName);
void pushInFileComponent(const QString &componentId);
void nextFileIsCalledInternally();
Utils::CrumblePath *crumblePath();
private slots:
void onCrumblePathElementClicked(const QVariant &data);
private:
bool m_isInternalCalled;
Utils::CrumblePath *m_crumblePath;
};
class CrumbleBarInfo {
public:
QString fileName;
QString componentId;
};
bool operator ==(const CrumbleBarInfo &first, const CrumbleBarInfo &second);
bool operator !=(const CrumbleBarInfo &first, const CrumbleBarInfo &second);
} // namespace QmlDesigner
Q_DECLARE_METATYPE(QmlDesigner::CrumbleBarInfo)
#endif // QMLDESIGNER_FORMEDITORCRUMBLEBAR_H
......@@ -317,6 +317,9 @@ void FormEditorItem::paintPlaceHolderForInvisbleItem(QPainter *painter) const
void FormEditorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
if (!painter->isActive())
return;
if (!qmlItemNode().isValid())
return;
......
......@@ -65,7 +65,6 @@ FormEditorScene::FormEditorScene(FormEditorWidget *view, FormEditorView *editorV
setupScene();
view->setScene(this);
setItemIndexMethod(QGraphicsScene::NoIndex);
setSceneRect(-canvasWidth()/2., -canvasHeight()/2., canvasWidth(), canvasHeight());
}
FormEditorScene::~FormEditorScene()
......@@ -100,13 +99,13 @@ FormEditorItem* FormEditorScene::itemForQmlItemNode(const QmlItemNode &qmlItemNo
double FormEditorScene::canvasWidth() const
{
DesignerSettings settings = Internal::BauhausPlugin::pluginInstance()->settings();
DesignerSettings settings = QmlDesignerPlugin::instance()->settings();
return settings.canvasWidth;
}
double FormEditorScene::canvasHeight() const
{
DesignerSettings settings = Internal::BauhausPlugin::pluginInstance()->settings();
DesignerSettings settings = QmlDesignerPlugin::instance()->settings();
return settings.canvasHeight;
}
......@@ -217,6 +216,7 @@ FormEditorItem *FormEditorScene::addFormEditorItem(const QmlItemNode &qmlItemNod
m_qmlItemNodeItemHash.insert(qmlItemNode, formEditorItem);
if (qmlItemNode.isRootNode()) {
setSceneRect(-canvasWidth()/2., -canvasHeight()/2., canvasWidth(), canvasHeight());
formLayerItem()->update();
manipulatorLayerItem()->update();
}
......
......@@ -68,9 +68,9 @@ FormEditorView::FormEditorView(QObject *parent)
m_currentTool(m_selectionTool),
m_transactionCounter(0)
{
connect(widget()->zoomAction(), SIGNAL(zoomLevelChanged(double)), SLOT(updateGraphicsIndicators()));
connect(widget()->showBoundingRectAction(), SIGNAL(toggled(bool)), scene(), SLOT(setShowBoundingRects(bool)));
connect(widget()->selectOnlyContentItemsAction(), SIGNAL(toggled(bool)), this, SLOT(setSelectOnlyContentItemsAction(bool)));
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)));
}
......@@ -267,9 +267,13 @@ void FormEditorView::bindingPropertiesChanged(const QList<BindingProperty>& prop
QmlModelView::bindingPropertiesChanged(propertyList, propertyChange);
}
FormEditorWidget *FormEditorView::widget() const
QWidget *FormEditorView::widget()
{
return m_formEditorWidget.data();
}
FormEditorWidget *FormEditorView::formEditorWidget()
{
Q_ASSERT(!m_formEditorWidget.isNull());
return m_formEditorWidget.data();
}
......@@ -453,8 +457,8 @@ void FormEditorView::instanceInformationsChange(const QMultiHash<ModelNode, Info
if (qmlItemNode.isValid() && scene()->hasItemForQmlItemNode(qmlItemNode)) {
scene()->synchronizeTransformation(qmlItemNode);
if (qmlItemNode.isRootModelNode() && informationChangeHash.values(node).contains(Size)) {
widget()->setRootItemRect(qmlItemNode.instanceBoundingRect());
widget()->centerScene();
formEditorWidget()->setRootItemRect(qmlItemNode.instanceBoundingRect());
formEditorWidget()->centerScene();
}
itemNodeList.append(scene()->itemForQmlItemNode(qmlItemNode));
......@@ -588,13 +592,6 @@ void FormEditorView::actualStateChanged(const ModelNode &node)
QmlModelState newQmlModelState(node);
}
Utils::CrumblePath *FormEditorView::crumblePath() const
{
if (widget() && widget()->toolBox())
return widget()->toolBox()->crumblePath();
return 0;
}
void FormEditorView::reset()
{
QTimer::singleShot(200, this, SLOT(delayedReset()));
......
......@@ -61,7 +61,7 @@ class FormEditorView : public QmlModelView
Q_OBJECT
public:
FormEditorView(QObject *parent);
FormEditorView(QObject *parent = 0);
~FormEditorView();
// AbstractView
......@@ -85,7 +85,8 @@ public:
void propertiesRemoved(const QList<AbstractProperty> &propertyList);
// FormEditorView
FormEditorWidget *widget() const;
QWidget *widget();
FormEditorWidget *formEditorWidget();
AbstractFormEditorTool *currentTool() const;
FormEditorScene *scene() const;
......@@ -117,8 +118,6 @@ public:
void actualStateChanged(const ModelNode &node);
Utils::CrumblePath *crumblePath() const;
protected:
void reset();
......
......@@ -241,6 +241,11 @@ void FormEditorWidget::setFocus()
m_graphicsView->setFocus(Qt::OtherFocusReason);
}
FormEditorCrumbleBar *FormEditorWidget::formEditorCrumbleBar() const
{
return toolBox()->formEditorCrumbleBar();
}
ZoomAction *FormEditorWidget::zoomAction() const
{
return m_zoomAction.data();
......@@ -295,13 +300,13 @@ ToolBox *FormEditorWidget::toolBox() const
double FormEditorWidget::spacing() const
{
DesignerSettings settings = Internal::BauhausPlugin::pluginInstance()->settings();
DesignerSettings settings = QmlDesignerPlugin::instance()->settings();
return settings.itemSpacing;
}
double FormEditorWidget::margins() const
{
DesignerSettings settings = Internal::BauhausPlugin::pluginInstance()->settings();
DesignerSettings settings = QmlDesignerPlugin::instance()->settings();
return settings.snapMargin;
}
......
......@@ -32,6 +32,8 @@
#include <QWidget>
#include "formeditorcrumblebar.h"
QT_BEGIN_NAMESPACE
class QActionGroup;
QT_END_NAMESPACE
......@@ -78,6 +80,8 @@ public:
void setFocus();
FormEditorCrumbleBar *formEditorCrumbleBar() const;
protected:
void wheelEvent(QWheelEvent *event);
QActionGroup *toolActionGroup() const;
......
......@@ -106,8 +106,8 @@ void MoveTool::mouseMoveEvent(const QList<QGraphicsItem*> &itemList,
}
}
bool shouldSnapping = view()->widget()->snappingAction()->isChecked();
bool shouldSnappingAndAnchoring = view()->widget()->snappingAndAnchoringAction()->isChecked();
bool shouldSnapping = view()->formEditorWidget()->snappingAction()->isChecked();
bool shouldSnappingAndAnchoring = view()->formEditorWidget()->snappingAndAnchoringAction()->isChecked();
MoveManipulator::Snapping useSnapping = MoveManipulator::NoSnapping;
if (event->modifiers().testFlag(Qt::ControlModifier) != (shouldSnapping || shouldSnappingAndAnchoring)) {
......
......@@ -77,8 +77,8 @@ void ResizeTool::mouseMoveEvent(const QList<QGraphicsItem*> &,
QGraphicsSceneMouseEvent *event)
{
if (m_resizeManipulator.isActive()) {
bool shouldSnapping = view()->widget()->snappingAction()->isChecked();
bool shouldSnappingAndAnchoring = view()->widget()->snappingAndAnchoringAction()->isChecked();
bool shouldSnapping = view()->formEditorWidget()->snappingAction()->isChecked();
bool shouldSnappingAndAnchoring = view()->formEditorWidget()->snappingAndAnchoringAction()->isChecked();
ResizeManipulator::Snapping useSnapping = ResizeManipulator::NoSnapping;
if (event->modifiers().testFlag(Qt::ControlModifier) != (shouldSnapping || shouldSnappingAndAnchoring)) {
......
......@@ -44,19 +44,20 @@ namespace QmlDesigner {
ToolBox::ToolBox(QWidget *parentWidget)
: Utils::StyledBar(parentWidget),
m_leftToolBar(new QToolBar("LeftSidebar", this)),
m_rightToolBar(new QToolBar("RightSidebar", this))
m_rightToolBar(new QToolBar("RightSidebar", this)),
m_formEditorCrumbleBar(new FormEditorCrumbleBar(this))
{
setMaximumHeight(44);
setSingleRow(false);
QFrame *frame = new QFrame(this);
m_crumblePath = new Utils::CrumblePath(frame);
frame->setStyleSheet("background-color: #4e4e4e;");
frame->setFrameShape(QFrame::NoFrame);
QHBoxLayout *layout = new QHBoxLayout(frame);
layout->setMargin(0);
layout->setSpacing(0);
frame->setLayout(layout);
layout->addWidget(m_crumblePath);
qDebug() << __FUNCTION__;
layout->addWidget(m_formEditorCrumbleBar->crumblePath());
frame->setProperty("panelwidget", true);
frame->setProperty("panelwidget_singlerow", false);
QVBoxLayout *verticalLayout = new QVBoxLayout(this);
......@@ -126,9 +127,9 @@ QList<QAction*> ToolBox::actions() const
return QList<QAction*>() << m_leftToolBar->actions() << m_rightToolBar->actions();
}
Utils::CrumblePath *ToolBox::crumblePath() const
FormEditorCrumbleBar *ToolBox::formEditorCrumbleBar() const
{
return m_crumblePath;
return m_formEditorCrumbleBar;
}
} // namespace QmlDesigner
......@@ -32,6 +32,8 @@
#include "utils/styledbar.h"
#include "formeditorcrumblebar.h"
QT_BEGIN_NAMESPACE