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: Tim Jenssen <tim.jenssen@digia.com>
Reviewed-by: Alessandro Portale <alessandro.portale@digia.com>
This commit is contained in:
Marco Bubke
2013-01-23 12:31:22 +01:00
parent a4455f3711
commit 8d9710c074
62 changed files with 2668 additions and 1944 deletions

View File

@@ -186,6 +186,11 @@ public:
m_designerActionList = designerActionList; m_designerActionList = designerActionList;
} }
QWidget *widget()
{
return 0;
}
protected: protected:
void setupContext() void setupContext()
{ {

View File

@@ -35,12 +35,13 @@
#include <bindingproperty.h> #include <bindingproperty.h>
#include <nodeproperty.h> #include <nodeproperty.h>
#include <designmodewidget.h> #include <designmodewidget.h>
#include <qmldesignerplugin.h>
namespace QmlDesigner { 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) static inline bool checkIfNodeIsAView(const ModelNode &node)
@@ -103,14 +104,14 @@ static inline bool modelNodeIsComponent(const ModelNode &node)
if (!node.isValid() || !node.metaInfo().isValid()) if (!node.isValid() || !node.metaInfo().isValid())
return false; return false;
if (node.metaInfo().isComponent()) if (node.metaInfo().isFileComponent())
return true; return true;
if (node.nodeSourceType() == ModelNode::NodeWithComponentSource) if (node.nodeSourceType() == ModelNode::NodeWithComponentSource)
return true; return true;
if (checkIfNodeIsAView(node) && if (checkIfNodeIsAView(node) &&
node.hasNodeProperty("delegate")) { node.hasNodeProperty("delegate")) {
if (node.nodeProperty("delegate").modelNode().metaInfo().isComponent()) if (node.nodeProperty("delegate").modelNode().metaInfo().isFileComponent())
return true; return true;
if (node.nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource) if (node.nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource)
return true; return true;
@@ -156,12 +157,12 @@ static inline bool isFileComponent(const ModelNode &node)
if (!node.isValid() || !node.metaInfo().isValid()) if (!node.isValid() || !node.metaInfo().isValid())
return false; return false;
if (node.metaInfo().isComponent()) if (node.metaInfo().isFileComponent())
return true; return true;
if (checkIfNodeIsAView(node) && if (checkIfNodeIsAView(node) &&
node.hasNodeProperty("delegate")) { node.hasNodeProperty("delegate")) {
if (node.nodeProperty("delegate").modelNode().metaInfo().isComponent()) if (node.nodeProperty("delegate").modelNode().metaInfo().isFileComponent())
return true; return true;
} }
@@ -170,21 +171,23 @@ static inline bool isFileComponent(const ModelNode &node)
static inline void openFileForComponent(const ModelNode &node) static inline void openFileForComponent(const ModelNode &node)
{ {
QmlDesignerPlugin::instance()->viewManager().nextFileIsCalledInternally();
//int width = 0; //int width = 0;
//int height = 0; //int height = 0;
QHash<QString, QVariant> propertyHash; QHash<QString, QVariant> propertyHash;
if (node.metaInfo().isComponent()) { if (node.metaInfo().isFileComponent()) {
//getWidthHeight(node, width, height); //getWidthHeight(node, width, height);
getProperties(node, propertyHash); getProperties(node, propertyHash);
designDocumentController()->changeToExternalSubComponent(node.metaInfo().componentFileName()); currentDesignDocument()->changeToExternalSubComponent(node.metaInfo().componentFileName());
} else if (checkIfNodeIsAView(node) && } else if (checkIfNodeIsAView(node) &&
node.hasNodeProperty("delegate") && node.hasNodeProperty("delegate") &&
node.nodeProperty("delegate").modelNode().metaInfo().isComponent()) { node.nodeProperty("delegate").modelNode().metaInfo().isFileComponent()) {
//getWidthHeight(node, width, height); //getWidthHeight(node, width, height);
getProperties(node, propertyHash); 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); applyProperties(rootModelNode, propertyHash);
//rootModelNode.setAuxiliaryData("width", width); //rootModelNode.setAuxiliaryData("width", width);
//rootModelNode.setAuxiliaryData("height", height); //rootModelNode.setAuxiliaryData("height", height);
@@ -192,10 +195,11 @@ static inline void openFileForComponent(const ModelNode &node)
static inline void openInlineComponent(const ModelNode &node) static inline void openInlineComponent(const ModelNode &node)
{ {
if (!node.isValid() || !node.metaInfo().isValid()) if (!node.isValid() || !node.metaInfo().isValid())
return; return;
if (!designDocumentController()) if (!currentDesignDocument())
return; return;
QHash<QString, QVariant> propertyHash; QHash<QString, QVariant> propertyHash;
@@ -203,27 +207,27 @@ static inline void openInlineComponent(const ModelNode &node)
if (node.nodeSourceType() == ModelNode::NodeWithComponentSource) { if (node.nodeSourceType() == ModelNode::NodeWithComponentSource) {
//getWidthHeight(node, width, height); //getWidthHeight(node, width, height);
getProperties(node, propertyHash); getProperties(node, propertyHash);
designDocumentController()->changeToSubComponent(node); currentDesignDocument()->changeToSubComponent(node);
} else if (checkIfNodeIsAView(node) && } else if (checkIfNodeIsAView(node) &&
node.hasNodeProperty("delegate")) { node.hasNodeProperty("delegate")) {
if (node.nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource) { if (node.nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource) {
//getWidthHeight(node, width, height); //getWidthHeight(node, width, height);
getProperties(node, propertyHash); 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); applyProperties(rootModelNode, propertyHash);
//rootModelNode.setAuxiliaryData("width", width); //rootModelNode.setAuxiliaryData("width", width);
//rootModelNode.setAuxiliaryData("height", height); //rootModelNode.setAuxiliaryData("height", height);
} }
namespace ComponentUtils { namespace ComponentUtils {
void goIntoComponent(const ModelNode &modelNode) void goIntoComponent(const ModelNode &modelNode)
{ {
if (modelNode.isValid() && modelNodeIsComponent(modelNode)) { if (modelNode.isValid() && modelNodeIsComponent(modelNode)) {
QmlDesignerPlugin::instance()->viewManager().setComponentNode(modelNode);
if (isFileComponent(modelNode)) if (isFileComponent(modelNode))
openFileForComponent(modelNode); openFileForComponent(modelNode);
else else

View File

@@ -32,7 +32,8 @@ SOURCES += formeditoritem.cpp \
zoomaction.cpp \ zoomaction.cpp \
formeditorgraphicsview.cpp \ formeditorgraphicsview.cpp \
numberseriesaction.cpp \ numberseriesaction.cpp \
lineeditaction.cpp lineeditaction.cpp \
formeditorcrumblebar.cpp
HEADERS += formeditorscene.h \ HEADERS += formeditorscene.h \
formeditorwidget.h \ formeditorwidget.h \
formeditoritem.h \ formeditoritem.h \
@@ -63,5 +64,6 @@ HEADERS += formeditorscene.h \
zoomaction.h \ zoomaction.h \
formeditorgraphicsview.h \ formeditorgraphicsview.h \
numberseriesaction.h \ numberseriesaction.h \
lineeditaction.h lineeditaction.h \
formeditorcrumblebar.h
RESOURCES += formeditor.qrc RESOURCES += formeditor.qrc

View File

@@ -0,0 +1,123 @@
/****************************************************************************
**
** 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

View File

@@ -0,0 +1,73 @@
/****************************************************************************
**
** 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

View File

@@ -317,6 +317,9 @@ void FormEditorItem::paintPlaceHolderForInvisbleItem(QPainter *painter) const
void FormEditorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) void FormEditorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{ {
if (!painter->isActive())
return;
if (!qmlItemNode().isValid()) if (!qmlItemNode().isValid())
return; return;

View File

@@ -65,7 +65,6 @@ FormEditorScene::FormEditorScene(FormEditorWidget *view, FormEditorView *editorV
setupScene(); setupScene();
view->setScene(this); view->setScene(this);
setItemIndexMethod(QGraphicsScene::NoIndex); setItemIndexMethod(QGraphicsScene::NoIndex);
setSceneRect(-canvasWidth()/2., -canvasHeight()/2., canvasWidth(), canvasHeight());
} }
FormEditorScene::~FormEditorScene() FormEditorScene::~FormEditorScene()
@@ -100,13 +99,13 @@ FormEditorItem* FormEditorScene::itemForQmlItemNode(const QmlItemNode &qmlItemNo
double FormEditorScene::canvasWidth() const double FormEditorScene::canvasWidth() const
{ {
DesignerSettings settings = Internal::BauhausPlugin::pluginInstance()->settings(); DesignerSettings settings = QmlDesignerPlugin::instance()->settings();
return settings.canvasWidth; return settings.canvasWidth;
} }
double FormEditorScene::canvasHeight() const double FormEditorScene::canvasHeight() const
{ {
DesignerSettings settings = Internal::BauhausPlugin::pluginInstance()->settings(); DesignerSettings settings = QmlDesignerPlugin::instance()->settings();
return settings.canvasHeight; return settings.canvasHeight;
} }
@@ -217,6 +216,7 @@ FormEditorItem *FormEditorScene::addFormEditorItem(const QmlItemNode &qmlItemNod
m_qmlItemNodeItemHash.insert(qmlItemNode, formEditorItem); m_qmlItemNodeItemHash.insert(qmlItemNode, formEditorItem);
if (qmlItemNode.isRootNode()) { if (qmlItemNode.isRootNode()) {
setSceneRect(-canvasWidth()/2., -canvasHeight()/2., canvasWidth(), canvasHeight());
formLayerItem()->update(); formLayerItem()->update();
manipulatorLayerItem()->update(); manipulatorLayerItem()->update();
} }

View File

@@ -68,9 +68,9 @@ FormEditorView::FormEditorView(QObject *parent)
m_currentTool(m_selectionTool), m_currentTool(m_selectionTool),
m_transactionCounter(0) m_transactionCounter(0)
{ {
connect(widget()->zoomAction(), SIGNAL(zoomLevelChanged(double)), SLOT(updateGraphicsIndicators())); connect(formEditorWidget()->zoomAction(), SIGNAL(zoomLevelChanged(double)), SLOT(updateGraphicsIndicators()));
connect(widget()->showBoundingRectAction(), SIGNAL(toggled(bool)), scene(), SLOT(setShowBoundingRects(bool))); connect(formEditorWidget()->showBoundingRectAction(), SIGNAL(toggled(bool)), scene(), SLOT(setShowBoundingRects(bool)));
connect(widget()->selectOnlyContentItemsAction(), SIGNAL(toggled(bool)), this, SLOT(setSelectOnlyContentItemsAction(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); 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(); return m_formEditorWidget.data();
} }
@@ -453,8 +457,8 @@ void FormEditorView::instanceInformationsChange(const QMultiHash<ModelNode, Info
if (qmlItemNode.isValid() && scene()->hasItemForQmlItemNode(qmlItemNode)) { if (qmlItemNode.isValid() && scene()->hasItemForQmlItemNode(qmlItemNode)) {
scene()->synchronizeTransformation(qmlItemNode); scene()->synchronizeTransformation(qmlItemNode);
if (qmlItemNode.isRootModelNode() && informationChangeHash.values(node).contains(Size)) { if (qmlItemNode.isRootModelNode() && informationChangeHash.values(node).contains(Size)) {
widget()->setRootItemRect(qmlItemNode.instanceBoundingRect()); formEditorWidget()->setRootItemRect(qmlItemNode.instanceBoundingRect());
widget()->centerScene(); formEditorWidget()->centerScene();
} }
itemNodeList.append(scene()->itemForQmlItemNode(qmlItemNode)); itemNodeList.append(scene()->itemForQmlItemNode(qmlItemNode));
@@ -588,13 +592,6 @@ void FormEditorView::actualStateChanged(const ModelNode &node)
QmlModelState newQmlModelState(node); QmlModelState newQmlModelState(node);
} }
Utils::CrumblePath *FormEditorView::crumblePath() const
{
if (widget() && widget()->toolBox())
return widget()->toolBox()->crumblePath();
return 0;
}
void FormEditorView::reset() void FormEditorView::reset()
{ {
QTimer::singleShot(200, this, SLOT(delayedReset())); QTimer::singleShot(200, this, SLOT(delayedReset()));

View File

@@ -61,7 +61,7 @@ class FormEditorView : public QmlModelView
Q_OBJECT Q_OBJECT
public: public:
FormEditorView(QObject *parent); FormEditorView(QObject *parent = 0);
~FormEditorView(); ~FormEditorView();
// AbstractView // AbstractView
@@ -85,7 +85,8 @@ public:
void propertiesRemoved(const QList<AbstractProperty> &propertyList); void propertiesRemoved(const QList<AbstractProperty> &propertyList);
// FormEditorView // FormEditorView
FormEditorWidget *widget() const; QWidget *widget();
FormEditorWidget *formEditorWidget();
AbstractFormEditorTool *currentTool() const; AbstractFormEditorTool *currentTool() const;
FormEditorScene *scene() const; FormEditorScene *scene() const;
@@ -117,8 +118,6 @@ public:
void actualStateChanged(const ModelNode &node); void actualStateChanged(const ModelNode &node);
Utils::CrumblePath *crumblePath() const;
protected: protected:
void reset(); void reset();

View File

@@ -241,6 +241,11 @@ void FormEditorWidget::setFocus()
m_graphicsView->setFocus(Qt::OtherFocusReason); m_graphicsView->setFocus(Qt::OtherFocusReason);
} }
FormEditorCrumbleBar *FormEditorWidget::formEditorCrumbleBar() const
{
return toolBox()->formEditorCrumbleBar();
}
ZoomAction *FormEditorWidget::zoomAction() const ZoomAction *FormEditorWidget::zoomAction() const
{ {
return m_zoomAction.data(); return m_zoomAction.data();
@@ -295,13 +300,13 @@ ToolBox *FormEditorWidget::toolBox() const
double FormEditorWidget::spacing() const double FormEditorWidget::spacing() const
{ {
DesignerSettings settings = Internal::BauhausPlugin::pluginInstance()->settings(); DesignerSettings settings = QmlDesignerPlugin::instance()->settings();
return settings.itemSpacing; return settings.itemSpacing;
} }
double FormEditorWidget::margins() const double FormEditorWidget::margins() const
{ {
DesignerSettings settings = Internal::BauhausPlugin::pluginInstance()->settings(); DesignerSettings settings = QmlDesignerPlugin::instance()->settings();
return settings.snapMargin; return settings.snapMargin;
} }

View File

@@ -32,6 +32,8 @@
#include <QWidget> #include <QWidget>
#include "formeditorcrumblebar.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QActionGroup; class QActionGroup;
QT_END_NAMESPACE QT_END_NAMESPACE
@@ -78,6 +80,8 @@ public:
void setFocus(); void setFocus();
FormEditorCrumbleBar *formEditorCrumbleBar() const;
protected: protected:
void wheelEvent(QWheelEvent *event); void wheelEvent(QWheelEvent *event);
QActionGroup *toolActionGroup() const; QActionGroup *toolActionGroup() const;

View File

@@ -106,8 +106,8 @@ void MoveTool::mouseMoveEvent(const QList<QGraphicsItem*> &itemList,
} }
} }
bool shouldSnapping = view()->widget()->snappingAction()->isChecked(); bool shouldSnapping = view()->formEditorWidget()->snappingAction()->isChecked();
bool shouldSnappingAndAnchoring = view()->widget()->snappingAndAnchoringAction()->isChecked(); bool shouldSnappingAndAnchoring = view()->formEditorWidget()->snappingAndAnchoringAction()->isChecked();
MoveManipulator::Snapping useSnapping = MoveManipulator::NoSnapping; MoveManipulator::Snapping useSnapping = MoveManipulator::NoSnapping;
if (event->modifiers().testFlag(Qt::ControlModifier) != (shouldSnapping || shouldSnappingAndAnchoring)) { if (event->modifiers().testFlag(Qt::ControlModifier) != (shouldSnapping || shouldSnappingAndAnchoring)) {

View File

@@ -77,8 +77,8 @@ void ResizeTool::mouseMoveEvent(const QList<QGraphicsItem*> &,
QGraphicsSceneMouseEvent *event) QGraphicsSceneMouseEvent *event)
{ {
if (m_resizeManipulator.isActive()) { if (m_resizeManipulator.isActive()) {
bool shouldSnapping = view()->widget()->snappingAction()->isChecked(); bool shouldSnapping = view()->formEditorWidget()->snappingAction()->isChecked();
bool shouldSnappingAndAnchoring = view()->widget()->snappingAndAnchoringAction()->isChecked(); bool shouldSnappingAndAnchoring = view()->formEditorWidget()->snappingAndAnchoringAction()->isChecked();
ResizeManipulator::Snapping useSnapping = ResizeManipulator::NoSnapping; ResizeManipulator::Snapping useSnapping = ResizeManipulator::NoSnapping;
if (event->modifiers().testFlag(Qt::ControlModifier) != (shouldSnapping || shouldSnappingAndAnchoring)) { if (event->modifiers().testFlag(Qt::ControlModifier) != (shouldSnapping || shouldSnappingAndAnchoring)) {

View File

@@ -44,19 +44,20 @@ namespace QmlDesigner {
ToolBox::ToolBox(QWidget *parentWidget) ToolBox::ToolBox(QWidget *parentWidget)
: Utils::StyledBar(parentWidget), : Utils::StyledBar(parentWidget),
m_leftToolBar(new QToolBar("LeftSidebar", this)), 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); setMaximumHeight(44);
setSingleRow(false); setSingleRow(false);
QFrame *frame = new QFrame(this); QFrame *frame = new QFrame(this);
m_crumblePath = new Utils::CrumblePath(frame);
frame->setStyleSheet("background-color: #4e4e4e;"); frame->setStyleSheet("background-color: #4e4e4e;");
frame->setFrameShape(QFrame::NoFrame); frame->setFrameShape(QFrame::NoFrame);
QHBoxLayout *layout = new QHBoxLayout(frame); QHBoxLayout *layout = new QHBoxLayout(frame);
layout->setMargin(0); layout->setMargin(0);
layout->setSpacing(0); layout->setSpacing(0);
frame->setLayout(layout); frame->setLayout(layout);
layout->addWidget(m_crumblePath); qDebug() << __FUNCTION__;
layout->addWidget(m_formEditorCrumbleBar->crumblePath());
frame->setProperty("panelwidget", true); frame->setProperty("panelwidget", true);
frame->setProperty("panelwidget_singlerow", false); frame->setProperty("panelwidget_singlerow", false);
QVBoxLayout *verticalLayout = new QVBoxLayout(this); QVBoxLayout *verticalLayout = new QVBoxLayout(this);
@@ -126,9 +127,9 @@ QList<QAction*> ToolBox::actions() const
return QList<QAction*>() << m_leftToolBar->actions() << m_rightToolBar->actions(); 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 } // namespace QmlDesigner

View File

@@ -32,6 +32,8 @@
#include "utils/styledbar.h" #include "utils/styledbar.h"
#include "formeditorcrumblebar.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QToolBar; class QToolBar;
QT_END_NAMESPACE QT_END_NAMESPACE
@@ -51,13 +53,12 @@ public:
void addLeftSideAction(QAction *action); void addLeftSideAction(QAction *action);
void addRightSideAction(QAction *action); void addRightSideAction(QAction *action);
QList<QAction*> actions() const; QList<QAction*> actions() const;
Utils::CrumblePath *crumblePath() const; FormEditorCrumbleBar *formEditorCrumbleBar() const;
private: private:
QToolBar *m_leftToolBar; QToolBar *m_leftToolBar;
QToolBar *m_rightToolBar; QToolBar *m_rightToolBar;
Utils::CrumblePath *m_crumblePath; FormEditorCrumbleBar *m_formEditorCrumbleBar;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -32,7 +32,8 @@
#include <QComboBox> #include <QComboBox>
#include "componentview.h" #include "componentview.h"
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QDebug> #include <qmldesignerplugin.h>
#include <modelnode.h>
namespace QmlDesigner { namespace QmlDesigner {
@@ -42,9 +43,9 @@ ComponentAction::ComponentAction(ComponentView *componentView)
{ {
} }
void ComponentAction::setCurrentIndex(int i) void ComponentAction::setCurrentIndex(int index)
{ {
emit currentIndexChanged(i); emit currentIndexChanged(index);
} }
QWidget *ComponentAction::createWidget(QWidget *parent) QWidget *ComponentAction::createWidget(QWidget *parent)
@@ -59,9 +60,21 @@ QWidget *ComponentAction::createWidget(QWidget *parent)
return comboBox; return comboBox;
} }
static const QString fileNameOfCurrentDocument()
{
return QmlDesignerPlugin::instance()->documentManager().currentDesignDocument()->textEditor()->document()->fileName();
}
void ComponentAction::emitCurrentComponentChanged(int index) void ComponentAction::emitCurrentComponentChanged(int index)
{ {
emit currentComponentChanged(m_componentView->modelNode(index)); ModelNode componentNode = m_componentView->modelNode(index);
if ( index > 0)
QmlDesignerPlugin::instance()->viewManager().pushInFileComponentOnCrambleBar(componentNode.id());
else
QmlDesignerPlugin::instance()->viewManager().pushFileOnCrambleBar(fileNameOfCurrentDocument());
emit currentComponentChanged(componentNode);
} }
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -48,16 +48,17 @@ class ComponentAction : public QWidgetAction
Q_OBJECT Q_OBJECT
public: public:
ComponentAction(ComponentView *componentView); ComponentAction(ComponentView *componentView);
void setCurrentIndex(int); void setCurrentIndex(int index);
protected: protected:
QWidget *createWidget(QWidget *parent); QWidget *createWidget(QWidget *parent);
signals: signals:
void currentComponentChanged(const ModelNode &node); void currentComponentChanged(const ModelNode &node);
void currentIndexChanged(int); void currentIndexChanged(int index);
private slots: public slots:
void emitCurrentComponentChanged(int index); void emitCurrentComponentChanged(int index);
private: private:

View File

@@ -34,6 +34,7 @@
#include <nodemetainfo.h> #include <nodemetainfo.h>
#include <nodeabstractproperty.h> #include <nodeabstractproperty.h>
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QAbstractItemView>
// silence gcc warnings about unused parameters // silence gcc warnings about unused parameters
@@ -46,8 +47,6 @@ ComponentView::ComponentView(QObject *parent)
{ {
} }
void ComponentView::nodeAboutToBeRemoved(const ModelNode &removedNode) void ComponentView::nodeAboutToBeRemoved(const ModelNode &removedNode)
{ {
removeSingleNodeFromList(removedNode); removeSingleNodeFromList(removedNode);
@@ -74,6 +73,11 @@ void ComponentView::setComponentNode(const ModelNode &node)
m_componentAction->setCurrentIndex(indexForNode(node)); m_componentAction->setCurrentIndex(indexForNode(node));
} }
QWidget *ComponentView::widget()
{
return 0;
}
void ComponentView::appendWholeDocumentAsComponent() void ComponentView::appendWholeDocumentAsComponent()
{ {
QStandardItem *item = new QStandardItem(tr("whole document")); QStandardItem *item = new QStandardItem(tr("whole document"));
@@ -110,7 +114,6 @@ void ComponentView::modelAttached(Model *model)
AbstractView::modelAttached(model); AbstractView::modelAttached(model);
Q_ASSERT(model->masterModel());
appendWholeDocumentAsComponent(); appendWholeDocumentAsComponent();
searchForComponentAndAddToList(rootModelNode()); searchForComponentAndAddToList(rootModelNode());

View File

@@ -37,6 +37,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QStandardItemModel; class QStandardItemModel;
class QComboBox;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace QmlDesigner { namespace QmlDesigner {
@@ -53,7 +54,7 @@ public:
ModelNodeRole = Qt::UserRole ModelNodeRole = Qt::UserRole
}; };
ComponentView(QObject *parent); ComponentView(QObject *parent = 0);
void modelAttached(Model *model); void modelAttached(Model *model);
void modelAboutToBeDetached(Model *model); void modelAboutToBeDetached(Model *model);
@@ -106,6 +107,8 @@ public:
void setComponentNode(const ModelNode &node); void setComponentNode(const ModelNode &node);
QWidget *widget();
signals: signals:
void componentListChanged(const QStringList &componentList); void componentListChanged(const QStringList &componentList);
@@ -118,6 +121,7 @@ private: //functions
int indexForNode(const ModelNode &node); int indexForNode(const ModelNode &node);
private: private:
QList<QComboBox*> m_comboBoxList;
QStandardItemModel *m_standardItemModel; QStandardItemModel *m_standardItemModel;
ComponentAction *m_componentAction; ComponentAction *m_componentAction;
}; };

View File

@@ -0,0 +1,793 @@
/****************************************************************************
**
** 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 "designdocument.h"
#include "designdocumentview.h"
#include "xuifiledialog.h"
#include "componentview.h"
#include <itemlibrarywidget.h>
#include <formeditorwidget.h>
#include <toolbox.h>
#include <metainfo.h>
#include <invalidargumentexception.h>
#include <componentaction.h>
#include <designeractionmanager.h>
#include <qmlobjectnode.h>
#include <rewritingexception.h>
#include <nodelistproperty.h>
#include <variantproperty.h>
#include <rewritingexception.h>
#include <modelnodeoperations.h>
#include <qmldesignerplugin.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/project.h>
#include <projectexplorer/target.h>
#include <qmlprojectmanager/qmlprojectrunconfiguration.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtsupportconstants.h>
#include <qtsupport/qtversionmanager.h>
#include <utils/crumblepath.h>
#include <utils/fileutils.h>
#include <QCoreApplication>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QUrl>
#include <QProcess>
#include <QTemporaryFile>
#include <QDebug>
#include <QEvent>
#include <QBoxLayout>
#include <QComboBox>
#include <QErrorMessage>
#include <QFileDialog>
#include <QLabel>
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QMessageBox>
#include <QUndoStack>
#include <QPlainTextEdit>
#include <QApplication>
enum {
debug = false
};
namespace QmlDesigner {
bool DesignDocument::s_clearCrumblePath = true;
bool DesignDocument::s_pushCrumblePath = true;
/**
\class QmlDesigner::DesignDocument
DesignDocument acts as a facade to a model representing a qml document,
and the different views/widgets accessing it.
*/
DesignDocument::DesignDocument(QObject *parent) :
QObject(parent),
m_documentModel(Model::create("QtQuick.Item", 1, 0)),
m_inFileComponentModel(Model::create("QtQuick.Item", 1, 0)),
m_currentModel(m_documentModel),
m_subComponentManager(new SubComponentManager(m_documentModel.data(), this)),
m_rewriterView (new RewriterView(RewriterView::Amend, m_documentModel.data())),
m_documentLoaded(false),
m_qtVersionId(-1)
{
updateActiveQtVersion();
}
DesignDocument::~DesignDocument()
{
delete m_documentModel.data();
delete m_inFileComponentModel.data();
delete rewriterView();
delete m_inFileComponentTextModifier.data();
delete m_documentTextModifier.data();
}
Model *DesignDocument::currentModel() const
{
return m_currentModel.data();
}
Model *DesignDocument::documentModel() const
{
return m_documentModel.data();
}
void DesignDocument::changeToDocumentModel()
{
viewManager().detachRewriterView();
viewManager().detachViewsExceptRewriterAndComponetView();
m_currentModel = m_documentModel;
viewManager().attachRewriterView(m_documentTextModifier.data());
viewManager().attachViewsExceptRewriterAndComponetView();
}
void DesignDocument::changeToInFileComponentModel()
{
viewManager().detachRewriterView();
viewManager().detachViewsExceptRewriterAndComponetView();
m_currentModel = m_inFileComponentModel;
viewManager().attachRewriterView(m_inFileComponentTextModifier.data());
viewManager().attachViewsExceptRewriterAndComponetView();
}
QWidget *DesignDocument::centralWidget() const
{
return qobject_cast<QWidget*>(parent());
}
QString DesignDocument::pathToQt() const
{
QtSupport::BaseQtVersion *activeQtVersion = QtSupport::QtVersionManager::instance()->version(m_qtVersionId);
if (activeQtVersion && (activeQtVersion->qtVersion() >= QtSupport::QtVersionNumber(4, 7, 1))
&& (activeQtVersion->type() == QLatin1String(QtSupport::Constants::DESKTOPQT)
|| activeQtVersion->type() == QLatin1String(QtSupport::Constants::SIMULATORQT)))
return activeQtVersion->qmakeProperty("QT_INSTALL_DATA");
return QString();
}
const ViewManager &DesignDocument::viewManager() const
{
return QmlDesignerPlugin::instance()->viewManager();
}
ViewManager &DesignDocument::viewManager()
{
return QmlDesignerPlugin::instance()->viewManager();
}
static ComponentTextModifier *createComponentTextModifier(TextModifier *originalModifier,
RewriterView *rewriterView,
const QString &componentText,
const ModelNode &componentNode)
{
bool explicitComponent = componentText.contains("Component");
ModelNode rootModelNode = rewriterView->rootModelNode();
int componentStartOffset;
int componentEndOffset;
int rootStartOffset = rewriterView->nodeOffset(rootModelNode);
if (explicitComponent) { //the component is explciit we have to find the first definition inside
componentStartOffset = rewriterView->firstDefinitionInsideOffset(componentNode);
componentEndOffset = componentStartOffset + rewriterView->firstDefinitionInsideLength(componentNode);
} else { //the component is implicit
componentStartOffset = rewriterView->nodeOffset(componentNode);
componentEndOffset = componentStartOffset + rewriterView->nodeLength(componentNode);
}
return new ComponentTextModifier (originalModifier, componentStartOffset, componentEndOffset, rootStartOffset);
}
bool DesignDocument::loadSubComponent(const ModelNode &componentNode)
{
QString componentText = rewriterView()->extractText(QList<ModelNode>() << componentNode).value(componentNode);
if (componentText.isEmpty())
return false;
if (!componentNode.isRootNode()) {
Q_ASSERT(m_currentModel == m_documentModel);
//change to subcomponent model
if (m_inFileComponentTextModifier)
delete m_inFileComponentTextModifier.data();
m_inFileComponentTextModifier = createComponentTextModifier(m_documentTextModifier.data(), rewriterView(), componentText, componentNode);
changeToInFileComponentModel();
}
return true;
}
/*!
Returns any errors that happened when parsing the latest qml file.
*/
QList<RewriterView::Error> DesignDocument::qmlSyntaxErrors() const
{
return m_rewriterView->errors();
}
bool DesignDocument::hasQmlSyntaxErrors() const
{
return !m_currentModel->rewriterView()->errors().isEmpty();
}
QString DesignDocument::displayName() const
{
return fileName();
}
QString DesignDocument::simplfiedDisplayName() const
{
if (rootModelNode().id().isEmpty()) {
return rootModelNode().id();
} else {
return rootModelNode().simplifiedTypeName();
}
QStringList list = displayName().split(QLatin1Char('/'));
return list.last();
}
void DesignDocument::updateFileName(const QString & /*oldFileName*/, const QString &newFileName)
{
if (m_documentModel)
m_documentModel->setFileUrl(QUrl::fromLocalFile(newFileName));
if (m_inFileComponentModel)
m_inFileComponentModel->setFileUrl(QUrl::fromLocalFile(newFileName));
viewManager().setItemLibraryViewResourcePath(QFileInfo(newFileName).absolutePath());
emit displayNameChanged(displayName());
}
QString DesignDocument::fileName() const
{
return editor()->document()->fileName();
}
int DesignDocument::qtVersionId() const
{
return m_qtVersionId;
}
bool DesignDocument::isDocumentLoaded() const
{
return m_documentLoaded;
}
void DesignDocument::resetToDocumentModel()
{
m_currentModel = m_documentModel;
m_rewriterView->setTextModifier(m_documentTextModifier.data());
}
QList<RewriterView::Error> DesignDocument::loadDocument(QPlainTextEdit *edit)
{
Q_CHECK_PTR(edit);
connect(edit, SIGNAL(undoAvailable(bool)),
this, SIGNAL(undoAvailable(bool)));
connect(edit, SIGNAL(redoAvailable(bool)),
this, SIGNAL(redoAvailable(bool)));
connect(edit, SIGNAL(modificationChanged(bool)),
this, SIGNAL(dirtyStateChanged(bool)));
m_documentTextModifier = new BaseTextEditModifier(dynamic_cast<TextEditor::BaseTextEditorWidget*>(plainTextEdit()));
m_inFileComponentTextModifier.clear();
//masterModel = Model::create(textModifier, searchPath, errors);
updateFileName(QString(), fileName());
m_subComponentManager->update(QUrl::fromLocalFile(fileName()), m_currentModel->imports());
activateCurrentModel(m_documentTextModifier.data());
return rewriterView()->errors();
}
void DesignDocument::changeCurrentModelTo(const ModelNode &node)
{
if (QmlDesignerPlugin::instance()->currentDesignDocument() != this)
return;
if (rootModelNode() == node) {
changeToDocumentModel();
} else {
changeToSubComponent(node);
}
// s_clearCrumblePath = false;
// while (m_formEditorView->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>().modelNode.isValid() &&
// !m_formEditorView->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>().modelNode.isRootNode())
// m_formEditorView->crumblePath()->popElement();
// if (node.isRootNode() && m_formEditorView->crumblePath()->dataForLastIndex().isValid())
// m_formEditorView->crumblePath()->popElement();
// s_clearCrumblePath = true;
}
void DesignDocument::changeToSubComponent(const ModelNode &componentNode)
{
Q_ASSERT(m_documentModel);
QWeakPointer<Model> oldModel = m_currentModel;
Q_ASSERT(oldModel.data());
if (m_currentModel == m_inFileComponentModel) {
changeToDocumentModel();
}
bool subComponentLoaded = loadSubComponent(componentNode);
if (subComponentLoaded) {
Q_ASSERT(m_documentModel);
Q_ASSERT(m_currentModel);
activateCurrentModel(m_inFileComponentTextModifier.data());
}
}
void DesignDocument::changeToExternalSubComponent(const QString &fileName)
{
Core::EditorManager::openEditor(fileName);
}
void DesignDocument::goIntoComponent()
{
if (!m_currentModel)
return;
QList<ModelNode> selectedNodes;
if (rewriterView())
selectedNodes = rewriterView()->selectedModelNodes();
s_clearCrumblePath = false;
if (selectedNodes.count() == 1) {
qDebug() << __FUNCTION__ << selectedNodes.first();
viewManager().setComponentNode(selectedNodes.first());
ModelNodeOperations::goIntoComponent(selectedNodes.first());
}
s_clearCrumblePath = true;
}
void DesignDocument::activateCurrentModel(TextModifier *textModifier)
{
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
Q_ASSERT(m_documentModel);
Q_ASSERT(m_currentModel);
if (!plainTextEdit()->parent()) // hack to prevent changing owner of external text edit
m_stackedWidget->addWidget(plainTextEdit());
viewManager().attachRewriterView(textModifier);
// if (s_clearCrumblePath)
// m_formEditorView->crumblePath()->clear();
// if (s_pushCrumblePath &&
// !differentCrumbleBarOnTop(m_formEditorView.data(), createCrumbleBarInfo().value<CrumbleBarInfo>()))
// m_formEditorView->crumblePath()->pushElement(simplfiedDisplayName(), createCrumbleBarInfo());
m_documentLoaded = true;
m_subComponentManager->update(QUrl::fromLocalFile(fileName()), m_currentModel->imports());
Q_ASSERT(m_documentModel);
QApplication::restoreOverrideCursor();
}
void DesignDocument::activateCurrentModel()
{
if (currentModel() == documentModel())
activateCurrentModel(m_documentTextModifier.data());
else
activateCurrentModel(m_inFileComponentTextModifier.data());
}
void DesignDocument::activateDocumentModel()
{
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
Q_ASSERT(m_documentModel);
Q_ASSERT(m_currentModel);
if (!plainTextEdit()->parent()) // hack to prevent changing owner of external text edit
m_stackedWidget->addWidget(plainTextEdit());
m_currentModel = m_documentModel;
m_documentLoaded = true;
m_subComponentManager->update(QUrl::fromLocalFile(fileName()), m_currentModel->imports());
Q_ASSERT(m_documentModel);
QApplication::restoreOverrideCursor();
}
bool DesignDocument::isUndoAvailable() const
{
if (plainTextEdit())
return plainTextEdit()->document()->isUndoAvailable();
return false;
}
bool DesignDocument::isRedoAvailable() const
{
if (plainTextEdit())
return plainTextEdit()->document()->isRedoAvailable();
return false;
}
void DesignDocument::close()
{
m_documentLoaded = false;
emit designDocumentClosed();
}
void DesignDocument::deleteSelected()
{
if (!m_currentModel)
return;
try {
RewriterTransaction transaction(rewriterView());
QList<ModelNode> toDelete = rewriterView()->selectedModelNodes();
foreach (ModelNode node, toDelete) {
if (node.isValid() && !node.isRootNode() && QmlObjectNode(node).isValid())
QmlObjectNode(node).destroy();
}
} catch (RewritingException &e) {
QMessageBox::warning(0, tr("Error"), e.description());
}
}
void DesignDocument::copySelected()
{
QScopedPointer<Model> copyModel(Model::create("QtQuick.Rectangle", 1, 0, currentModel()));
copyModel->setFileUrl(currentModel()->fileUrl());
copyModel->changeImports(currentModel()->imports(), QList<Import>());
Q_ASSERT(copyModel);
DesignDocumentView view;
m_currentModel->attachView(&view);
if (view.selectedModelNodes().isEmpty())
return;
QList<ModelNode> selectedNodes(view.selectedModelNodes());
foreach (const ModelNode &node, selectedNodes) {
foreach (const ModelNode &node2, selectedNodes) {
if (node.isAncestorOf(node2))
selectedNodes.removeAll(node2);
}
}
if (selectedNodes.count() == 1) {
ModelNode selectedNode(selectedNodes.first());
if (!selectedNode.isValid())
return;
m_currentModel->detachView(&view);
copyModel->attachView(&view);
view.replaceModel(selectedNode);
Q_ASSERT(view.rootModelNode().isValid());
Q_ASSERT(view.rootModelNode().type() != "empty");
view.toClipboard();
} else { //multi items selected
m_currentModel->detachView(&view);
copyModel->attachView(&view);
foreach (ModelNode node, view.rootModelNode().allDirectSubModelNodes()) {
node.destroy();
}
view.changeRootNodeType("QtQuick.Rectangle", 1, 0);
view.rootModelNode().setId("designer__Selection");
foreach (const ModelNode &selectedNode, selectedNodes) {
ModelNode newNode(view.insertModel(selectedNode));
view.rootModelNode().nodeListProperty("data").reparentHere(newNode);
}
view.toClipboard();
}
}
void DesignDocument::cutSelected()
{
copySelected();
deleteSelected();
}
static void scatterItem(ModelNode pastedNode, const ModelNode targetNode, int offset = -2000)
{
bool scatter = false;
foreach (const ModelNode &childNode, targetNode.allDirectSubModelNodes()) {
if ((childNode.variantProperty("x").value() == pastedNode.variantProperty("x").value()) &&
(childNode.variantProperty("y").value() == pastedNode.variantProperty("y").value()))
scatter = true;
}
if (!scatter)
return;
if (offset == -2000) {
double x = pastedNode.variantProperty("x").value().toDouble();
double y = pastedNode.variantProperty("y").value().toDouble();
double targetWidth = 20;
double targetHeight = 20;
x = x + double(qrand()) / RAND_MAX * targetWidth - targetWidth / 2;
y = y + double(qrand()) / RAND_MAX * targetHeight - targetHeight / 2;
pastedNode.variantProperty("x") = int(x);
pastedNode.variantProperty("y") = int(y);
} else {
double x = pastedNode.variantProperty("x").value().toDouble();
double y = pastedNode.variantProperty("y").value().toDouble();
x = x + offset;
y = y + offset;
pastedNode.variantProperty("x") = int(x);
pastedNode.variantProperty("y") = int(y);
}
}
void DesignDocument::paste()
{
QScopedPointer<Model> pasteModel(Model::create("empty", 1, 0, currentModel()));
pasteModel->setFileUrl(currentModel()->fileUrl());
pasteModel->changeImports(currentModel()->imports(), QList<Import>());
Q_ASSERT(pasteModel);
if (!pasteModel)
return;
DesignDocumentView view;
pasteModel->attachView(&view);
view.fromClipboard();
ModelNode rootNode(view.rootModelNode());
if (rootNode.type() == "empty")
return;
if (rootNode.id() == "designer__Selection") {
QList<ModelNode> selectedNodes = rootNode.allDirectSubModelNodes();
qDebug() << rootNode;
qDebug() << selectedNodes;
pasteModel->detachView(&view);
m_currentModel->attachView(&view);
ModelNode targetNode;
if (!view.selectedModelNodes().isEmpty())
targetNode = view.selectedModelNodes().first();
//In case we copy and paste a selection we paste in the parent item
if ((view.selectedModelNodes().count() == selectedNodes.count()) && targetNode.isValid() && targetNode.parentProperty().isValid())
targetNode = targetNode.parentProperty().parentModelNode();
if (!targetNode.isValid())
targetNode = view.rootModelNode();
foreach (const ModelNode &node, selectedNodes) {
foreach (const ModelNode &node2, selectedNodes) {
if (node.isAncestorOf(node2))
selectedNodes.removeAll(node2);
}
}
QList<ModelNode> pastedNodeList;
try {
RewriterTransaction transaction(rewriterView());
int offset = double(qrand()) / RAND_MAX * 20 - 10;
foreach (const ModelNode &node, selectedNodes) {
QString defaultProperty(targetNode.metaInfo().defaultPropertyName());
ModelNode pastedNode(view.insertModel(node));
pastedNodeList.append(pastedNode);
scatterItem(pastedNode, targetNode, offset);
targetNode.nodeListProperty(defaultProperty).reparentHere(pastedNode);
}
view.setSelectedModelNodes(pastedNodeList);
} catch (RewritingException &e) {
qWarning() << e.description(); //silent error
}
} else {
try {
RewriterTransaction transaction(rewriterView());
pasteModel->detachView(&view);
m_currentModel->attachView(&view);
ModelNode pastedNode(view.insertModel(rootNode));
ModelNode targetNode;
if (!view.selectedModelNodes().isEmpty())
targetNode = view.selectedModelNodes().first();
if (!targetNode.isValid())
targetNode = view.rootModelNode();
if (targetNode.parentProperty().isValid() &&
(pastedNode.simplifiedTypeName() == targetNode.simplifiedTypeName()) &&
(pastedNode.variantProperty("width").value() == targetNode.variantProperty("width").value()) &&
(pastedNode.variantProperty("height").value() == targetNode.variantProperty("height").value()))
targetNode = targetNode.parentProperty().parentModelNode();
QString defaultProperty(targetNode.metaInfo().defaultPropertyName());
scatterItem(pastedNode, targetNode);
if (targetNode.nodeListProperty(defaultProperty).isValid())
targetNode.nodeListProperty(defaultProperty).reparentHere(pastedNode);
transaction.commit();
NodeMetaInfo::clearCache();
view.setSelectedModelNodes(QList<ModelNode>() << pastedNode);
} catch (RewritingException &e) {
qWarning() << e.description(); //silent error
}
}
}
void DesignDocument::selectAll()
{
if (!m_currentModel)
return;
DesignDocumentView view;
m_currentModel->attachView(&view);
QList<ModelNode> allNodesExceptRootNode(view.allModelNodes());
allNodesExceptRootNode.removeOne(view.rootModelNode());
view.setSelectedModelNodes(allNodesExceptRootNode);
}
RewriterView *DesignDocument::rewriterView() const
{
return m_rewriterView.data();
}
void DesignDocument::setEditor(Core::IEditor *editor)
{
m_textEditor = editor;
connect(editor->document(),
SIGNAL(fileNameChanged(QString,QString)),
SLOT(updateFileName(QString,QString)));
}
Core::IEditor *DesignDocument::editor() const
{
return m_textEditor.data();
}
TextEditor::ITextEditor *DesignDocument::textEditor() const
{
return qobject_cast<TextEditor::ITextEditor*>(editor());
}
QPlainTextEdit *DesignDocument::plainTextEdit() const
{
if (editor())
return qobject_cast<QPlainTextEdit*>(editor()->widget());
return 0;
}
ModelNode DesignDocument::rootModelNode() const
{
return rewriterView()->rootModelNode();
}
void DesignDocument::undo()
{
if (rewriterView() && !rewriterView()->modificationGroupActive())
plainTextEdit()->undo();
viewManager().resetPropertyEditorView();
}
void DesignDocument::redo()
{
if (rewriterView() && !rewriterView()->modificationGroupActive())
plainTextEdit()->redo();
viewManager().resetPropertyEditorView();
}
static inline QtSupport::BaseQtVersion *getActiveQtVersion(DesignDocument *controller)
{
ProjectExplorer::ProjectExplorerPlugin *projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance();
ProjectExplorer::Project *currentProject = projectExplorer->currentProject();
if (!currentProject)
return 0;
controller->disconnect(controller, SLOT(updateActiveQtVersion()));
controller->connect(projectExplorer, SIGNAL(currentProjectChanged(ProjectExplorer::Project*)), controller, SLOT(updateActiveQtVersion()));
controller->connect(currentProject, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)), controller, SLOT(updateActiveQtVersion()));
ProjectExplorer::Target *target = currentProject->activeTarget();
if (!target)
return 0;
controller->connect(target, SIGNAL(kitChanged()), controller, SLOT(updateActiveQtVersion()));
return QtSupport::QtKitInformation::qtVersion(target->kit());
}
void DesignDocument::updateActiveQtVersion()
{
QtSupport::BaseQtVersion *newQtVersion = getActiveQtVersion(this);
if (!newQtVersion ) {
m_qtVersionId = -1;
return;
}
if (m_qtVersionId == newQtVersion->uniqueId())
return;
m_qtVersionId = newQtVersion->uniqueId();
viewManager().setNodeInstanceViewQtPath(pathToQt());
}
QString DesignDocument::contextHelpId() const
{
DesignDocumentView view;
m_currentModel->attachView(&view);
QList<ModelNode> nodes = view.selectedModelNodes();
QString helpId;
if (!nodes.isEmpty()) {
helpId = nodes.first().type();
helpId.replace("QtQuick", "QML");
}
return helpId;
}
} // namespace QmlDesigner

View File

@@ -27,8 +27,8 @@
** **
****************************************************************************/ ****************************************************************************/
#ifndef DesignDocumentController_h #ifndef DesignDocument_h
#define DesignDocumentController_h #define DesignDocument_h
#include "rewriterview.h" #include "rewriterview.h"
@@ -44,6 +44,7 @@
#include <componenttextmodifier.h> #include <componenttextmodifier.h>
#include <subcomponentmanager.h> #include <subcomponentmanager.h>
#include <model/viewlogger.h> #include <model/viewlogger.h>
#include <viewmanager.h>
#include <QObject> #include <QObject>
#include <QString> #include <QString>
@@ -66,49 +67,44 @@ class TextModifier;
class QmlObjectNode; class QmlObjectNode;
struct CrumbleBarInfo; struct CrumbleBarInfo;
class DesignDocumentController: public QObject class DesignDocument: public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
DesignDocumentController(QObject *parent); DesignDocument(QObject *parent = 0);
~DesignDocumentController(); ~DesignDocument();
QString displayName() const; QString displayName() const;
QString simplfiedDisplayName() const; QString simplfiedDisplayName() const;
QString fileName() const; QList<RewriterView::Error> loadDocument(QPlainTextEdit *edit);
void setFileName(const QString &m_fileName); void activateCurrentModel(TextModifier *textModifier);
void activateCurrentModel();
QList<RewriterView::Error> loadMaster(QPlainTextEdit *edit); void activateDocumentModel();
QList<RewriterView::Error> loadMaster(const QByteArray &qml);
void loadCurrentModel();
void close(); void close();
bool isDirty() const;
bool isUndoAvailable() const; bool isUndoAvailable() const;
bool isRedoAvailable() const; bool isRedoAvailable() const;
Model *model() const; Model *currentModel() const;
Model *masterModel() const; Model *documentModel() const;
QString contextHelpId() const;
QList<RewriterView::Error> qmlSyntaxErrors() const;
bool hasQmlSyntaxErrors() const;
RewriterView *rewriterView() const; RewriterView *rewriterView() const;
bool isModelSyncBlocked() const; void setEditor(Core::IEditor *editor);
void blockModelSync(bool block); Core::IEditor *editor() const;
QString contextHelpId() const; TextEditor::ITextEditor *textEditor() const;
QList<RewriterView::Error> qmlErrors() const; QPlainTextEdit *plainTextEdit() const;
QString fileName() const;
int qtVersionId() const; // maybe that is not working, because the id should be not cached!!!
bool isDocumentLoaded() const;
void setItemLibraryView(ItemLibraryView* m_itemLibraryView); void resetToDocumentModel();
void setNavigator(NavigatorView* navigatorView);
void setPropertyEditorView(PropertyEditor *propertyEditor);
void setStatesEditorView(StatesEditorView* m_statesEditorView);
void setFormEditorView(FormEditorView *m_formEditorView);
void setNodeInstanceView(NodeInstanceView *m_nodeInstanceView);
void setComponentView(ComponentView *m_componentView);
void setCrumbleBarInfo(const CrumbleBarInfo &crumbleBarInfo);
static void setBlockCrumbleBar(bool);
signals: signals:
void displayNameChanged(const QString &newFileName); void displayNameChanged(const QString &newFileName);
@@ -122,8 +118,6 @@ signals:
void fileToOpen(const QString &path); void fileToOpen(const QString &path);
public slots: public slots:
bool save(QWidget *parent = 0);
void saveAs(QWidget *parent = 0);
void deleteSelected(); void deleteSelected();
void copySelected(); void copySelected();
void cutSelected(); void cutSelected();
@@ -131,68 +125,46 @@ public slots:
void selectAll(); void selectAll();
void undo(); void undo();
void redo(); void redo();
void activeQtVersionChanged(); void updateActiveQtVersion();
void changeCurrentModelTo(const ModelNode &node); void changeCurrentModelTo(const ModelNode &node);
void changeToSubComponent(const ModelNode &node); void changeToSubComponent(const ModelNode &node);
void changeToExternalSubComponent(const QString &m_fileName); void changeToExternalSubComponent(const QString &m_oldFileName);
void goIntoComponent(); void goIntoComponent();
#ifdef ENABLE_TEXT_VIEW
void showText();
void showForm();
#endif // ENABLE_TEXT_VIEW
private slots: private slots:
void doRealSaveAs(const QString &m_fileName); void updateFileName(const QString &oldFileName, const QString &newFileName);
private: // functions private: // functions
void detachNodeInstanceView(); void changeToDocumentModel();
void attachNodeInstanceView(); void changeToInFileComponentModel();
void changeToMasterModel();
QVariant createCrumbleBarInfo();
QWidget *centralWidget() const; QWidget *centralWidget() const;
QString pathToQt() const; QString pathToQt() const;
const ViewManager &viewManager() const;
ViewManager &viewManager();
ModelNode rootModelNode() const;
bool loadSubComponent(const ModelNode &componentNode);
private: // variables private: // variables
QWeakPointer<FormEditorView> m_formEditorView;
QWeakPointer<ItemLibraryView> m_itemLibraryView;
QWeakPointer<NavigatorView> m_navigator;
QWeakPointer<PropertyEditor> m_propertyEditorView;
QWeakPointer<StatesEditorView> m_statesEditorView;
QWeakPointer<QStackedWidget> m_stackedWidget; QWeakPointer<QStackedWidget> m_stackedWidget;
QWeakPointer<NodeInstanceView> m_nodeInstanceView; QWeakPointer<Model> m_documentModel;
QWeakPointer<ComponentView> m_componentView; QWeakPointer<Model> m_inFileComponentModel;
QWeakPointer<Model> m_currentModel;
QWeakPointer<Model> m_model; QWeakPointer<Core::IEditor> m_textEditor;
QWeakPointer<Model> m_subComponentModel; QWeakPointer<BaseTextEditModifier> m_documentTextModifier;
QWeakPointer<Model> m_masterModel; QWeakPointer<ComponentTextModifier> m_inFileComponentTextModifier;
QWeakPointer<QPlainTextEdit> m_textEdit;
QWeakPointer<RewriterView> m_rewriterView;
BaseTextEditModifier *m_textModifier;
ComponentTextModifier *m_componentTextModifier;
QWeakPointer<SubComponentManager> m_subComponentManager; QWeakPointer<SubComponentManager> m_subComponentManager;
QWeakPointer<Internal::ViewLogger> m_viewLogger;
ModelNode m_componentNode;
QString m_fileName; QWeakPointer<RewriterView> m_rewriterView;
QUrl m_searchPath;
bool m_documentLoaded; bool m_documentLoaded;
bool m_syncBlocked; int m_qtVersionId;
int m_qt_versionId;
static bool s_clearCrumblePath;
static bool s_pushCrumblePath;
};
struct CrumbleBarInfo {
ModelNode modelNode;
QString fileName;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner
Q_DECLARE_METATYPE(QmlDesigner::CrumbleBarInfo)
#endif // DesignDocumentController_h #endif // DesignDocument_h

View File

@@ -1,943 +0,0 @@
/****************************************************************************
**
** 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 "designdocumentcontroller.h"
#include "designdocumentcontrollerview.h"
#include "xuifiledialog.h"
#include "componentview.h"
#include <itemlibrarywidget.h>
#include <formeditorwidget.h>
#include <toolbox.h>
#include <metainfo.h>
#include <invalidargumentexception.h>
#include <componentaction.h>
#include <designeractionmanager.h>
#include <qmlobjectnode.h>
#include <rewritingexception.h>
#include <nodelistproperty.h>
#include <variantproperty.h>
#include <rewritingexception.h>
#include <modelnodeoperations.h>
#include <designmodewidget.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/project.h>
#include <projectexplorer/target.h>
#include <qmlprojectmanager/qmlprojectrunconfiguration.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtsupportconstants.h>
#include <qtsupport/qtversionmanager.h>
#include <utils/crumblepath.h>
#include <utils/fileutils.h>
#include <QCoreApplication>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QUrl>
#include <QProcess>
#include <QTemporaryFile>
#include <QDebug>
#include <QEvent>
#include <QBoxLayout>
#include <QComboBox>
#include <QErrorMessage>
#include <QFileDialog>
#include <QLabel>
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QMessageBox>
#include <QUndoStack>
#include <QPlainTextEdit>
#include <QApplication>
enum {
debug = false
};
namespace QmlDesigner {
bool DesignDocumentController::s_clearCrumblePath = true;
bool DesignDocumentController::s_pushCrumblePath = true;
/**
\class QmlDesigner::DesignDocumentController
DesignDocumentController acts as a facade to a model representing a qml document,
and the different views/widgets accessing it.
*/
DesignDocumentController::DesignDocumentController(QObject *parent) :
QObject(parent)
{
m_documentLoaded = false;
m_syncBlocked = false;
ProjectExplorer::ProjectExplorerPlugin *projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance();
connect(projectExplorer, SIGNAL(currentProjectChanged(ProjectExplorer::Project*)), this, SLOT(activeQtVersionChanged()));
activeQtVersionChanged();
}
DesignDocumentController::~DesignDocumentController()
{
delete m_model.data();
delete m_subComponentModel.data();
delete m_rewriterView.data();
if (m_componentTextModifier) //componentTextModifier might not be created
delete m_componentTextModifier;
}
Model *DesignDocumentController::model() const
{
return m_model.data();
}
Model *DesignDocumentController::masterModel() const
{
return m_masterModel.data();
}
void DesignDocumentController::detachNodeInstanceView()
{
if (m_nodeInstanceView)
model()->detachView(m_nodeInstanceView.data());
}
void DesignDocumentController::attachNodeInstanceView()
{
if (m_nodeInstanceView)
model()->attachView(m_nodeInstanceView.data());
if (m_formEditorView)
m_formEditorView->resetView();
}
void DesignDocumentController::changeToMasterModel()
{
m_model->detachView(m_rewriterView.data());
m_rewriterView->setTextModifier(m_textModifier);
m_model = m_masterModel;
m_model->attachView(m_rewriterView.data());
m_componentNode = m_rewriterView->rootModelNode();
}
QVariant DesignDocumentController::createCrumbleBarInfo()
{
CrumbleBarInfo info;
info.fileName = fileName();
info.modelNode = m_componentNode;
return QVariant::fromValue<CrumbleBarInfo>(info);
}
QWidget *DesignDocumentController::centralWidget() const
{
return qobject_cast<QWidget*>(parent());
}
QString DesignDocumentController::pathToQt() const
{
QtSupport::BaseQtVersion *activeQtVersion = QtSupport::QtVersionManager::instance()->version(m_qt_versionId);
if (activeQtVersion && (activeQtVersion->qtVersion().majorVersion > 3)
&& (activeQtVersion->type() == QLatin1String(QtSupport::Constants::DESKTOPQT)
|| activeQtVersion->type() == QLatin1String(QtSupport::Constants::SIMULATORQT)))
return activeQtVersion->qmakeProperty("QT_INSTALL_DATA");
return QString();
}
/*!
Returns whether the model is automatically updated if the text editor changes.
*/
bool DesignDocumentController::isModelSyncBlocked() const
{
return m_syncBlocked;
}
/*!
Switches whether the model (and therefore the views) are updated if the text editor
changes.
If the synchronization is enabled again, the model is automatically resynchronized
with the current state of the text editor.
*/
void DesignDocumentController::blockModelSync(bool block)
{
if (m_syncBlocked == block)
return;
m_syncBlocked = block;
if (m_textModifier) {
if (m_syncBlocked) {
detachNodeInstanceView();
m_textModifier->deactivateChangeSignals();
} else {
activeQtVersionChanged();
changeToMasterModel();
QmlModelState state;
//We go back to base state (and back again) to avoid side effects from text editing.
if (m_statesEditorView && m_statesEditorView->model()) {
state = m_statesEditorView->currentState();
m_statesEditorView->setCurrentState(m_statesEditorView->baseState());
}
m_textModifier->reactivateChangeSignals();
if (state.isValid() && m_statesEditorView)
m_statesEditorView->setCurrentState(state);
attachNodeInstanceView();
if (m_propertyEditorView)
m_propertyEditorView->resetView();
if (m_formEditorView)
m_formEditorView->resetView();
}
}
}
/*!
Returns any errors that happened when parsing the latest qml file.
*/
QList<RewriterView::Error> DesignDocumentController::qmlErrors() const
{
return m_rewriterView->errors();
}
void DesignDocumentController::setItemLibraryView(ItemLibraryView* itemLibraryView)
{
m_itemLibraryView = itemLibraryView;
}
void DesignDocumentController::setNavigator(NavigatorView* navigatorView)
{
m_navigator = navigatorView;
}
void DesignDocumentController::setPropertyEditorView(PropertyEditor *propertyEditor)
{
m_propertyEditorView = propertyEditor;
}
void DesignDocumentController::setStatesEditorView(StatesEditorView* statesEditorView)
{
m_statesEditorView = statesEditorView;
}
void DesignDocumentController::setFormEditorView(FormEditorView *formEditorView)
{
m_formEditorView = formEditorView;
}
void DesignDocumentController::setNodeInstanceView(NodeInstanceView *nodeInstanceView)
{
m_nodeInstanceView = nodeInstanceView;
}
void DesignDocumentController::setComponentView(ComponentView *componentView)
{
m_componentView = componentView;
connect(componentView->action(), SIGNAL(currentComponentChanged(ModelNode)), SLOT(changeCurrentModelTo(ModelNode)));
}
static inline bool compareCrumbleBarInfo(const CrumbleBarInfo &crumbleBarInfo1, const CrumbleBarInfo &crumbleBarInfo2)
{
return crumbleBarInfo1.fileName == crumbleBarInfo2.fileName && crumbleBarInfo1.modelNode == crumbleBarInfo2.modelNode;
}
void DesignDocumentController::setCrumbleBarInfo(const CrumbleBarInfo &crumbleBarInfo)
{
s_clearCrumblePath = false;
s_pushCrumblePath = false;
while (!compareCrumbleBarInfo(m_formEditorView->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>(), crumbleBarInfo))
m_formEditorView->crumblePath()->popElement();
Core::EditorManager::openEditor(crumbleBarInfo.fileName);
s_pushCrumblePath = true;
Internal::DesignModeWidget::instance()->currentDesignDocumentController()->changeToSubComponent(crumbleBarInfo.modelNode);
s_clearCrumblePath = true;
}
void DesignDocumentController::setBlockCrumbleBar(bool b)
{
s_clearCrumblePath = !b;
s_pushCrumblePath = !b;
}
QString DesignDocumentController::displayName() const
{
if (fileName().isEmpty())
return tr("-New Form-");
else
return fileName();
}
QString DesignDocumentController::simplfiedDisplayName() const
{
if (!m_componentNode.isRootNode()) {
if (m_componentNode.id().isEmpty()) {
if (m_formEditorView->rootModelNode().id().isEmpty())
return m_formEditorView->rootModelNode().simplifiedTypeName();
return m_formEditorView->rootModelNode().id();
}
return m_componentNode.id();
}
QStringList list = displayName().split(QLatin1Char('/'));
return list.last();
}
QString DesignDocumentController::fileName() const
{
return m_fileName;
}
void DesignDocumentController::setFileName(const QString &fileName)
{
m_fileName = fileName;
if (QFileInfo(fileName).exists())
m_searchPath = QUrl::fromLocalFile(fileName);
else
m_searchPath = QUrl(fileName);
if (m_model)
m_model->setFileUrl(m_searchPath);
if (m_itemLibraryView)
m_itemLibraryView->widget()->setResourcePath(QFileInfo(fileName).absolutePath());
emit displayNameChanged(displayName());
}
QList<RewriterView::Error> DesignDocumentController::loadMaster(QPlainTextEdit *edit)
{
Q_CHECK_PTR(edit);
m_textEdit = edit;
connect(edit, SIGNAL(undoAvailable(bool)),
this, SIGNAL(undoAvailable(bool)));
connect(edit, SIGNAL(redoAvailable(bool)),
this, SIGNAL(redoAvailable(bool)));
connect(edit, SIGNAL(modificationChanged(bool)),
this, SIGNAL(dirtyStateChanged(bool)));
m_textModifier = new BaseTextEditModifier(dynamic_cast<TextEditor::BaseTextEditorWidget*>(m_textEdit.data()));
m_componentTextModifier = 0;
//masterModel = Model::create(textModifier, searchPath, errors);
m_masterModel = Model::create("QtQuick.Rectangle", 1, 0);
#if defined(VIEWLOGGER)
m_viewLogger = new Internal::ViewLogger(m_model.data());
m_masterModel->attachView(m_viewLogger.data());
#endif
m_masterModel->setFileUrl(m_searchPath);
m_subComponentModel = Model::create("QtQuick.Rectangle", 1, 0);
m_subComponentModel->setFileUrl(m_searchPath);
m_rewriterView = new RewriterView(RewriterView::Amend, m_masterModel.data());
m_rewriterView->setTextModifier( m_textModifier);
connect(m_rewriterView.data(), SIGNAL(errorsChanged(QList<RewriterView::Error>)),
this, SIGNAL(qmlErrorsChanged(QList<RewriterView::Error>)));
m_masterModel->attachView(m_rewriterView.data());
m_model = m_masterModel;
m_componentNode = m_rewriterView->rootModelNode();
m_subComponentManager = new SubComponentManager(m_masterModel.data(), this);
m_subComponentManager->update(m_searchPath, m_model->imports());
loadCurrentModel();
m_masterModel->attachView(m_componentView.data());
return m_rewriterView->errors();
}
void DesignDocumentController::changeCurrentModelTo(const ModelNode &node)
{
if (m_componentNode == node)
return;
if (Internal::DesignModeWidget::instance()->currentDesignDocumentController() != this)
return;
s_clearCrumblePath = false;
while (m_formEditorView->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>().modelNode.isValid() &&
!m_formEditorView->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>().modelNode.isRootNode())
m_formEditorView->crumblePath()->popElement();
if (node.isRootNode() && m_formEditorView->crumblePath()->dataForLastIndex().isValid())
m_formEditorView->crumblePath()->popElement();
changeToSubComponent(node);
s_clearCrumblePath = true;
}
void DesignDocumentController::changeToSubComponent(const ModelNode &componentNode)
{
Q_ASSERT(m_masterModel);
QWeakPointer<Model> oldModel = m_model;
Q_ASSERT(oldModel.data());
if (m_model == m_subComponentModel)
changeToMasterModel();
QString componentText = m_rewriterView->extractText(QList<ModelNode>() << componentNode).value(componentNode);
if (componentText.isEmpty())
return;
bool explicitComponent = false;
if (componentText.contains("Component")) { //explicit component
explicitComponent = true;
}
m_componentNode = componentNode;
if (!componentNode.isRootNode()) {
Q_ASSERT(m_model == m_masterModel);
Q_ASSERT(componentNode.isValid());
//change to subcomponent model
ModelNode rootModelNode = componentNode.view()->rootModelNode();
Q_ASSERT(rootModelNode.isValid());
if (m_componentTextModifier)
delete m_componentTextModifier;
int componentStartOffset;
int componentEndOffset;
int rootStartOffset = m_rewriterView->nodeOffset(rootModelNode);
if (explicitComponent) { //the component is explciit we have to find the first definition inside
componentStartOffset = m_rewriterView->firstDefinitionInsideOffset(componentNode);
componentEndOffset = componentStartOffset + m_rewriterView->firstDefinitionInsideLength(componentNode);
} else { //the component is implicit
componentStartOffset = m_rewriterView->nodeOffset(componentNode);
componentEndOffset = componentStartOffset + m_rewriterView->nodeLength(componentNode);
}
m_componentTextModifier = new ComponentTextModifier (m_textModifier, componentStartOffset, componentEndOffset, rootStartOffset);
m_model->detachView(m_rewriterView.data());
m_rewriterView->setTextModifier(m_componentTextModifier);
m_subComponentModel->attachView(m_rewriterView.data());
Q_ASSERT(m_rewriterView->rootModelNode().isValid());
m_model = m_subComponentModel;
}
Q_ASSERT(m_masterModel);
Q_ASSERT(m_model);
loadCurrentModel();
m_componentView->setComponentNode(componentNode);
}
void DesignDocumentController::changeToExternalSubComponent(const QString &fileName)
{
s_clearCrumblePath = false;
Core::EditorManager::openEditor(fileName);
s_clearCrumblePath = true;
}
void DesignDocumentController::goIntoComponent()
{
if (!m_model)
return;
QList<ModelNode> selectedNodes;
if (m_formEditorView)
selectedNodes = m_formEditorView->selectedModelNodes();
s_clearCrumblePath = false;
if (selectedNodes.count() == 1)
ModelNodeOperations::goIntoComponent(selectedNodes.first());
s_clearCrumblePath = true;
}
void DesignDocumentController::loadCurrentModel()
{
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
Q_ASSERT(m_masterModel);
Q_ASSERT(m_model);
m_model->setMasterModel(m_masterModel.data());
m_masterModel->attachView(m_componentView.data());
m_nodeInstanceView->setPathToQt(pathToQt());
m_model->attachView(m_nodeInstanceView.data());
m_model->attachView(m_navigator.data());
m_itemLibraryView->widget()->setResourcePath(QFileInfo(m_fileName).absolutePath());
m_model->attachView(m_formEditorView.data());
m_model->attachView(m_itemLibraryView.data());
if (!m_textEdit->parent()) // hack to prevent changing owner of external text edit
m_stackedWidget->addWidget(m_textEdit.data());
// Will call setCurrentState (formEditorView etc has to be constructed first)
m_model->attachView(m_statesEditorView.data());
m_model->attachView(m_propertyEditorView.data());
m_model->attachView(DesignerActionManager::view());
if (s_clearCrumblePath)
m_formEditorView->crumblePath()->clear();
if (s_pushCrumblePath &&
!compareCrumbleBarInfo(m_formEditorView->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>(),
createCrumbleBarInfo().value<CrumbleBarInfo>()))
m_formEditorView->crumblePath()->pushElement(simplfiedDisplayName(), createCrumbleBarInfo());
m_documentLoaded = true;
m_subComponentManager->update(m_searchPath, m_model->imports());
Q_ASSERT(m_masterModel);
QApplication::restoreOverrideCursor();
}
QList<RewriterView::Error> DesignDocumentController::loadMaster(const QByteArray &qml)
{
QPlainTextEdit *textEdit = new QPlainTextEdit;
textEdit->setReadOnly(true);
textEdit->setPlainText(QString(qml));
return loadMaster(textEdit);
}
void DesignDocumentController::saveAs(QWidget *parent)
{
QFileInfo oldFileInfo(m_fileName);
XUIFileDialog::runSaveFileDialog(oldFileInfo.path(), parent, this, SLOT(doRealSaveAs(QString)));
}
void DesignDocumentController::doRealSaveAs(const QString &fileName)
{
if (fileName.isNull())
return;
QFileInfo fileInfo(fileName);
if (fileInfo.exists() && !fileInfo.isWritable()) {
QMessageBox msgBox(centralWidget());
msgBox.setIcon(QMessageBox::Warning);
msgBox.setText(tr("Cannot save to file \"%1\": permission denied.").arg(fileInfo.baseName()));
msgBox.exec();
return;
} else if (!fileInfo.exists() && !fileInfo.dir().exists()) {
QMessageBox msgBox(centralWidget());
msgBox.setIcon(QMessageBox::Warning);
msgBox.setText(tr("Parent folder \"%1\" for file \"%2\" does not exist.")
.arg(fileInfo.dir().dirName())
.arg(fileInfo.baseName()));
msgBox.exec();
return;
}
setFileName(fileName);
save(centralWidget());
}
bool DesignDocumentController::isDirty() const
{
if (m_textEdit)
return m_textEdit->document()->isModified();
else
return false;
}
bool DesignDocumentController::isUndoAvailable() const
{
if (m_textEdit)
return m_textEdit->document()->isUndoAvailable();
return false;
}
bool DesignDocumentController::isRedoAvailable() const
{
if (m_textEdit)
return m_textEdit->document()->isRedoAvailable();
return false;
}
void DesignDocumentController::close()
{
m_documentLoaded = false;
emit designDocumentClosed();
}
void DesignDocumentController::deleteSelected()
{
if (!m_model)
return;
try {
if (m_formEditorView) {
RewriterTransaction transaction(m_formEditorView.data());
QList<ModelNode> toDelete = m_formEditorView->selectedModelNodes();
foreach (ModelNode node, toDelete) {
if (node.isValid() && !node.isRootNode() && QmlObjectNode(node).isValid())
QmlObjectNode(node).destroy();
}
}
} catch (RewritingException &e) {
QMessageBox::warning(0, tr("Error"), e.description());
}
}
void DesignDocumentController::copySelected()
{
QScopedPointer<Model> copyModel(Model::create("QtQuick.Rectangle", 1, 0, model()));
copyModel->setFileUrl(model()->fileUrl());
copyModel->changeImports(model()->imports(), QList<Import>());
Q_ASSERT(copyModel);
DesignDocumentControllerView view;
m_model->attachView(&view);
if (view.selectedModelNodes().isEmpty())
return;
QList<ModelNode> selectedNodes(view.selectedModelNodes());
foreach (const ModelNode &node, selectedNodes) {
foreach (const ModelNode &node2, selectedNodes) {
if (node.isAncestorOf(node2))
selectedNodes.removeAll(node2);
}
}
if (selectedNodes.count() == 1) {
ModelNode selectedNode(selectedNodes.first());
if (!selectedNode.isValid())
return;
m_model->detachView(&view);
copyModel->attachView(&view);
view.replaceModel(selectedNode);
Q_ASSERT(view.rootModelNode().isValid());
Q_ASSERT(view.rootModelNode().type() != "empty");
view.toClipboard();
} else { //multi items selected
m_model->detachView(&view);
copyModel->attachView(&view);
foreach (ModelNode node, view.rootModelNode().allDirectSubModelNodes()) {
node.destroy();
}
view.changeRootNodeType("QtQuick.Rectangle", 1, 0);
view.rootModelNode().setId("designer__Selection");
foreach (const ModelNode &selectedNode, selectedNodes) {
ModelNode newNode(view.insertModel(selectedNode));
view.rootModelNode().nodeListProperty("data").reparentHere(newNode);
}
view.toClipboard();
}
}
void DesignDocumentController::cutSelected()
{
copySelected();
deleteSelected();
}
static void scatterItem(ModelNode pastedNode, const ModelNode targetNode, int offset = -2000)
{
bool scatter = false;
foreach (const ModelNode &childNode, targetNode.allDirectSubModelNodes()) {
if ((childNode.variantProperty("x").value() == pastedNode.variantProperty("x").value()) &&
(childNode.variantProperty("y").value() == pastedNode.variantProperty("y").value()))
scatter = true;
}
if (!scatter)
return;
if (offset == -2000) {
double x = pastedNode.variantProperty("x").value().toDouble();
double y = pastedNode.variantProperty("y").value().toDouble();
double targetWidth = 20;
double targetHeight = 20;
x = x + double(qrand()) / RAND_MAX * targetWidth - targetWidth / 2;
y = y + double(qrand()) / RAND_MAX * targetHeight - targetHeight / 2;
pastedNode.variantProperty("x") = int(x);
pastedNode.variantProperty("y") = int(y);
} else {
double x = pastedNode.variantProperty("x").value().toDouble();
double y = pastedNode.variantProperty("y").value().toDouble();
x = x + offset;
y = y + offset;
pastedNode.variantProperty("x") = int(x);
pastedNode.variantProperty("y") = int(y);
}
}
void DesignDocumentController::paste()
{
QScopedPointer<Model> pasteModel(Model::create("empty", 1, 0, model()));
pasteModel->setFileUrl(model()->fileUrl());
pasteModel->changeImports(model()->imports(), QList<Import>());
Q_ASSERT(pasteModel);
if (!pasteModel)
return;
DesignDocumentControllerView view;
pasteModel->attachView(&view);
view.fromClipboard();
ModelNode rootNode(view.rootModelNode());
if (rootNode.type() == "empty")
return;
if (rootNode.id() == "designer__Selection") {
QList<ModelNode> selectedNodes = rootNode.allDirectSubModelNodes();
qDebug() << rootNode;
qDebug() << selectedNodes;
pasteModel->detachView(&view);
m_model->attachView(&view);
ModelNode targetNode;
if (!view.selectedModelNodes().isEmpty())
targetNode = view.selectedModelNodes().first();
//In case we copy and paste a selection we paste in the parent item
if ((view.selectedModelNodes().count() == selectedNodes.count()) && targetNode.isValid() && targetNode.parentProperty().isValid())
targetNode = targetNode.parentProperty().parentModelNode();
if (!targetNode.isValid())
targetNode = view.rootModelNode();
foreach (const ModelNode &node, selectedNodes) {
foreach (const ModelNode &node2, selectedNodes) {
if (node.isAncestorOf(node2))
selectedNodes.removeAll(node2);
}
}
QList<ModelNode> pastedNodeList;
try {
RewriterTransaction transaction(m_formEditorView.data());
int offset = double(qrand()) / RAND_MAX * 20 - 10;
foreach (const ModelNode &node, selectedNodes) {
QString defaultProperty(targetNode.metaInfo().defaultPropertyName());
ModelNode pastedNode(view.insertModel(node));
pastedNodeList.append(pastedNode);
scatterItem(pastedNode, targetNode, offset);
targetNode.nodeListProperty(defaultProperty).reparentHere(pastedNode);
}
view.setSelectedModelNodes(pastedNodeList);
} catch (RewritingException &e) {
qWarning() << e.description(); //silent error
}
} else {
try {
RewriterTransaction transaction(m_formEditorView.data());
pasteModel->detachView(&view);
m_model->attachView(&view);
ModelNode pastedNode(view.insertModel(rootNode));
ModelNode targetNode;
if (!view.selectedModelNodes().isEmpty())
targetNode = view.selectedModelNodes().first();
if (!targetNode.isValid())
targetNode = view.rootModelNode();
if (targetNode.parentProperty().isValid() &&
(pastedNode.simplifiedTypeName() == targetNode.simplifiedTypeName()) &&
(pastedNode.variantProperty("width").value() == targetNode.variantProperty("width").value()) &&
(pastedNode.variantProperty("height").value() == targetNode.variantProperty("height").value()))
targetNode = targetNode.parentProperty().parentModelNode();
QString defaultProperty(targetNode.metaInfo().defaultPropertyName());
scatterItem(pastedNode, targetNode);
if (targetNode.nodeListProperty(defaultProperty).isValid())
targetNode.nodeListProperty(defaultProperty).reparentHere(pastedNode);
transaction.commit();
NodeMetaInfo::clearCache();
view.setSelectedModelNodes(QList<ModelNode>() << pastedNode);
} catch (RewritingException &e) {
qWarning() << e.description(); //silent error
}
}
}
void DesignDocumentController::selectAll()
{
if (!m_model)
return;
DesignDocumentControllerView view;
m_model->attachView(&view);
QList<ModelNode> allNodesExceptRootNode(view.allModelNodes());
allNodesExceptRootNode.removeOne(view.rootModelNode());
view.setSelectedModelNodes(allNodesExceptRootNode);
}
RewriterView *DesignDocumentController::rewriterView() const
{
return m_rewriterView.data();
}
void DesignDocumentController::undo()
{
if (m_rewriterView && !m_rewriterView->modificationGroupActive())
m_textEdit->undo();
m_propertyEditorView->resetView();
}
void DesignDocumentController::redo()
{
if (m_rewriterView && !m_rewriterView->modificationGroupActive())
m_textEdit->redo();
m_propertyEditorView->resetView();
}
static inline QtSupport::BaseQtVersion *getActiveQtVersion(DesignDocumentController *controller)
{
ProjectExplorer::ProjectExplorerPlugin *projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance();
ProjectExplorer::Project *currentProject = projectExplorer->currentProject();
if (!currentProject)
return 0;
controller->disconnect(controller, SLOT(activeQtVersionChanged()));
controller->connect(projectExplorer, SIGNAL(currentProjectChanged(ProjectExplorer::Project*)), controller, SLOT(activeQtVersionChanged()));
controller->connect(currentProject, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)), controller, SLOT(activeQtVersionChanged()));
ProjectExplorer::Target *target = currentProject->activeTarget();
if (!target)
return 0;
controller->connect(target, SIGNAL(kitChanged()), controller, SLOT(activeQtVersionChanged()));
return QtSupport::QtKitInformation::qtVersion(target->kit());
}
void DesignDocumentController::activeQtVersionChanged()
{
QtSupport::BaseQtVersion *newQtVersion = getActiveQtVersion(this);
if (!newQtVersion ) {
m_qt_versionId = -1;
return;
}
if (m_qt_versionId == newQtVersion->uniqueId())
return;
m_qt_versionId = newQtVersion->uniqueId();
if (m_nodeInstanceView)
m_nodeInstanceView->setPathToQt(pathToQt());
}
#ifdef ENABLE_TEXT_VIEW
void DesignDocumentController::showText()
{
m_stackedWidget->setCurrentWidget(m_textEdit.data());
}
#endif // ENABLE_TEXT_VIEW
#ifdef ENABLE_TEXT_VIEW
void DesignDocumentController::showForm()
{
m_stackedWidget->setCurrentWidget(m_formEditorView->widget());
}
#endif // ENABLE_TEXT_VIEW
bool DesignDocumentController::save(QWidget *parent)
{
// qDebug() << "Saving document to file \"" << fileName << "\"...";
//
if (m_fileName.isEmpty()) {
saveAs(parent);
return true;
}
Utils::FileSaver saver(m_fileName, QIODevice::Text);
if (m_model)
saver.write(m_textEdit->toPlainText().toLatin1());
if (!saver.finalize(parent ? parent : m_stackedWidget.data()))
return false;
if (m_model)
m_textEdit->setPlainText(m_textEdit->toPlainText()); // clear undo/redo history
return true;
}
QString DesignDocumentController::contextHelpId() const
{
DesignDocumentControllerView view;
m_model->attachView(&view);
QList<ModelNode> nodes = view.selectedModelNodes();
QString helpId;
if (!nodes.isEmpty()) {
helpId = nodes.first().type();
helpId.replace("QtQuick", "QML");
}
return helpId;
}
} // namespace QmlDesigner

View File

@@ -27,7 +27,7 @@
** **
****************************************************************************/ ****************************************************************************/
#include "designdocumentcontrollerview.h" #include "designdocumentview.h"
#include <rewriterview.h> #include <rewriterview.h>
#include <basetexteditmodifier.h> #include <basetexteditmodifier.h>
#include <metainfo.h> #include <metainfo.h>
@@ -40,79 +40,88 @@
namespace QmlDesigner { namespace QmlDesigner {
void DesignDocumentControllerView::nodeCreated(const ModelNode & /*createdNode*/) {} DesignDocumentView::DesignDocumentView(QObject *parent)
void DesignDocumentControllerView::nodeAboutToBeRemoved(const ModelNode & /*removedNode*/) {} : AbstractView(parent), m_modelMerger(this)
void DesignDocumentControllerView::nodeRemoved(const ModelNode & /*removedNode*/, const NodeAbstractProperty & /*parentProperty*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {} {
void DesignDocumentControllerView::nodeAboutToBeReparented(const ModelNode & /*node*/, const NodeAbstractProperty & /*newPropertyParent*/, const NodeAbstractProperty & /*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {} }
void DesignDocumentControllerView::nodeReparented(const ModelNode & /*node*/, const NodeAbstractProperty & /*newPropertyParent*/, const NodeAbstractProperty & /*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {}
void DesignDocumentControllerView::nodeIdChanged(const ModelNode& /*node*/, const QString& /*newId*/, const QString& /*oldId*/) {}
void DesignDocumentControllerView::propertiesAboutToBeRemoved(const QList<AbstractProperty>& /*propertyList*/) {}
void DesignDocumentControllerView::propertiesRemoved(const QList<AbstractProperty>& /*propertyList*/) {}
void DesignDocumentControllerView::variantPropertiesChanged(const QList<VariantProperty>& /*propertyList*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {}
void DesignDocumentControllerView::bindingPropertiesChanged(const QList<BindingProperty>& /*propertyList*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {}
void DesignDocumentControllerView::rootNodeTypeChanged(const QString & /*type*/, int /*majorVersion*/, int /*minorVersion*/) {}
void DesignDocumentControllerView::selectedNodesChanged(const QList<ModelNode> & /*selectedNodeList*/, DesignDocumentView::~DesignDocumentView()
{
}
void DesignDocumentView::nodeCreated(const ModelNode & /*createdNode*/) {}
void DesignDocumentView::nodeAboutToBeRemoved(const ModelNode & /*removedNode*/) {}
void DesignDocumentView::nodeRemoved(const ModelNode & /*removedNode*/, const NodeAbstractProperty & /*parentProperty*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {}
void DesignDocumentView::nodeAboutToBeReparented(const ModelNode & /*node*/, const NodeAbstractProperty & /*newPropertyParent*/, const NodeAbstractProperty & /*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {}
void DesignDocumentView::nodeReparented(const ModelNode & /*node*/, const NodeAbstractProperty & /*newPropertyParent*/, const NodeAbstractProperty & /*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {}
void DesignDocumentView::nodeIdChanged(const ModelNode& /*node*/, const QString& /*newId*/, const QString& /*oldId*/) {}
void DesignDocumentView::propertiesAboutToBeRemoved(const QList<AbstractProperty>& /*propertyList*/) {}
void DesignDocumentView::propertiesRemoved(const QList<AbstractProperty>& /*propertyList*/) {}
void DesignDocumentView::variantPropertiesChanged(const QList<VariantProperty>& /*propertyList*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {}
void DesignDocumentView::bindingPropertiesChanged(const QList<BindingProperty>& /*propertyList*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {}
void DesignDocumentView::rootNodeTypeChanged(const QString & /*type*/, int /*majorVersion*/, int /*minorVersion*/) {}
void DesignDocumentView::selectedNodesChanged(const QList<ModelNode> & /*selectedNodeList*/,
const QList<ModelNode> & /*lastSelectedNodeList*/) {} const QList<ModelNode> & /*lastSelectedNodeList*/) {}
void DesignDocumentControllerView::nodeOrderChanged(const NodeListProperty & /*listProperty*/, const ModelNode & /*movedNode*/, int /*oldIndex*/) {} void DesignDocumentView::nodeOrderChanged(const NodeListProperty & /*listProperty*/, const ModelNode & /*movedNode*/, int /*oldIndex*/) {}
void DesignDocumentControllerView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStringList &/*scriptFunctionList*/) void DesignDocumentView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStringList &/*scriptFunctionList*/)
{ {
} }
void DesignDocumentControllerView::instancePropertyChange(const QList<QPair<ModelNode, QString> > &/*propertyList*/) void DesignDocumentView::instancePropertyChange(const QList<QPair<ModelNode, QString> > &/*propertyList*/)
{ {
} }
void DesignDocumentControllerView::instancesCompleted(const QVector<ModelNode> &/*completedNodeList*/) void DesignDocumentView::instancesCompleted(const QVector<ModelNode> &/*completedNodeList*/)
{ {
} }
void DesignDocumentControllerView::instanceInformationsChange(const QMultiHash<ModelNode, InformationName> &/*informationChangeHash*/) void DesignDocumentView::instanceInformationsChange(const QMultiHash<ModelNode, InformationName> &/*informationChangeHash*/)
{ {
} }
void DesignDocumentControllerView::instancesRenderImageChanged(const QVector<ModelNode> &/*nodeList*/) void DesignDocumentView::instancesRenderImageChanged(const QVector<ModelNode> &/*nodeList*/)
{ {
} }
void DesignDocumentControllerView::instancesPreviewImageChanged(const QVector<ModelNode> &/*nodeList*/) void DesignDocumentView::instancesPreviewImageChanged(const QVector<ModelNode> &/*nodeList*/)
{ {
} }
void DesignDocumentControllerView::instancesChildrenChanged(const QVector<ModelNode> &/*nodeList*/) void DesignDocumentView::instancesChildrenChanged(const QVector<ModelNode> &/*nodeList*/)
{ {
} }
void DesignDocumentControllerView::instancesToken(const QString &/*tokenName*/, int /*tokenNumber*/, const QVector<ModelNode> &/*nodeVector*/) void DesignDocumentView::instancesToken(const QString &/*tokenName*/, int /*tokenNumber*/, const QVector<ModelNode> &/*nodeVector*/)
{ {
} }
void DesignDocumentControllerView::nodeSourceChanged(const ModelNode &, const QString & /*newNodeSource*/) void DesignDocumentView::nodeSourceChanged(const ModelNode &, const QString & /*newNodeSource*/)
{ {
} }
void DesignDocumentControllerView::rewriterBeginTransaction() void DesignDocumentView::rewriterBeginTransaction()
{ {
} }
void DesignDocumentControllerView::rewriterEndTransaction() void DesignDocumentView::rewriterEndTransaction()
{ {
} }
void DesignDocumentControllerView::actualStateChanged(const ModelNode &/*node*/) void DesignDocumentView::actualStateChanged(const ModelNode &/*node*/)
{ {
} }
void DesignDocumentControllerView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/) void DesignDocumentView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/)
{ {
} }
@@ -131,7 +140,7 @@ static QByteArray stringListToArray(const QStringList &stringList)
return str.toLatin1(); return str.toLatin1();
} }
void DesignDocumentControllerView::toClipboard() const void DesignDocumentView::toClipboard() const
{ {
QClipboard *clipboard = QApplication::clipboard(); QClipboard *clipboard = QApplication::clipboard();
@@ -146,7 +155,7 @@ void DesignDocumentControllerView::toClipboard() const
clipboard->setMimeData(data); clipboard->setMimeData(data);
} }
void DesignDocumentControllerView::fromClipboard() void DesignDocumentView::fromClipboard()
{ {
QClipboard *clipboard = QApplication::clipboard(); QClipboard *clipboard = QApplication::clipboard();
fromText(clipboard->text()); fromText(clipboard->text());
@@ -158,7 +167,7 @@ void DesignDocumentControllerView::fromClipboard()
} }
QString DesignDocumentControllerView::toText() const QString DesignDocumentView::toText() const
{ {
QScopedPointer<Model> outputModel(Model::create("QtQuick.Rectangle", 1, 0, model())); QScopedPointer<Model> outputModel(Model::create("QtQuick.Rectangle", 1, 0, model()));
outputModel->setFileUrl(model()->fileUrl()); outputModel->setFileUrl(model()->fileUrl());
@@ -178,7 +187,7 @@ QString DesignDocumentControllerView::toText() const
QScopedPointer<RewriterView> rewriterView(new RewriterView(RewriterView::Amend, 0)); QScopedPointer<RewriterView> rewriterView(new RewriterView(RewriterView::Amend, 0));
rewriterView->setCheckSemanticErrors(false); rewriterView->setCheckSemanticErrors(false);
rewriterView->setTextModifier(&modifier); rewriterView->setTextModifier(&modifier);
outputModel->attachView(rewriterView.data()); outputModel->setRewriterView(rewriterView.data());
ModelMerger merger(rewriterView.data()); ModelMerger merger(rewriterView.data());
@@ -190,7 +199,7 @@ QString DesignDocumentControllerView::toText() const
return rewriterView->extractText(QList<ModelNode>() << rewriterNode).value(rewriterNode); return rewriterView->extractText(QList<ModelNode>() << rewriterNode).value(rewriterNode);
} }
void DesignDocumentControllerView::fromText(QString text) void DesignDocumentView::fromText(QString text)
{ {
QScopedPointer<Model> inputModel(Model::create("QtQuick.Rectangle", 1, 0, model())); QScopedPointer<Model> inputModel(Model::create("QtQuick.Rectangle", 1, 0, model()));
inputModel->setFileUrl(model()->fileUrl()); inputModel->setFileUrl(model()->fileUrl());
@@ -205,7 +214,7 @@ void DesignDocumentControllerView::fromText(QString text)
QScopedPointer<RewriterView> rewriterView(new RewriterView(RewriterView::Amend, 0)); QScopedPointer<RewriterView> rewriterView(new RewriterView(RewriterView::Amend, 0));
rewriterView->setCheckSemanticErrors(false); rewriterView->setCheckSemanticErrors(false);
rewriterView->setTextModifier(&modifier); rewriterView->setTextModifier(&modifier);
inputModel->attachView(rewriterView.data()); inputModel->setRewriterView(rewriterView.data());
if (rewriterView->errors().isEmpty() && rewriterView->rootModelNode().isValid()) { if (rewriterView->errors().isEmpty() && rewriterView->rootModelNode().isValid()) {
ModelMerger merger(this); ModelMerger merger(this);
@@ -213,4 +222,9 @@ void DesignDocumentControllerView::fromText(QString text)
} }
} }
QWidget *DesignDocumentView::widget()
{
return 0;
}
}// namespace QmlDesigner }// namespace QmlDesigner

View File

@@ -27,20 +27,20 @@
** **
****************************************************************************/ ****************************************************************************/
#ifndef DESIGNDOCUMENTCONTROLLERVIEW_H #ifndef DesignDocumentVIEW_H
#define DESIGNDOCUMENTCONTROLLERVIEW_H #define DesignDocumentVIEW_H
#include <abstractview.h> #include <abstractview.h>
#include <modelmerger.h> #include <modelmerger.h>
namespace QmlDesigner { namespace QmlDesigner {
class DesignDocumentControllerView : public AbstractView class DesignDocumentView : public AbstractView
{ {
Q_OBJECT Q_OBJECT
public: public:
DesignDocumentControllerView(QObject *parent = 0) DesignDocumentView(QObject *parent = 0);
: AbstractView(parent), m_modelMerger(this) {} ~DesignDocumentView();
virtual void nodeCreated(const ModelNode &createdNode); virtual void nodeCreated(const ModelNode &createdNode);
virtual void nodeAboutToBeRemoved(const ModelNode &removedNode); virtual void nodeAboutToBeRemoved(const ModelNode &removedNode);
@@ -87,10 +87,12 @@ public:
QString toText() const; QString toText() const;
void fromText(QString text); void fromText(QString text);
QWidget *widget();
private: private:
ModelMerger m_modelMerger; ModelMerger m_modelMerger;
}; };
}// namespace QmlDesigner }// namespace QmlDesigner
#endif // DESIGNDOCUMENTCONTROLLERVIEW_H #endif // DesignDocumentVIEW_H

View File

@@ -1,8 +1,8 @@
VPATH += $$PWD VPATH += $$PWD
INCLUDEPATH += $$PWD INCLUDEPATH += $$PWD
SOURCES += \ SOURCES += \
designdocumentcontroller.cpp \ designdocument.cpp \
designdocumentcontrollerview.cpp \ designdocumentview.cpp \
utilitypanelcontroller.cpp \ utilitypanelcontroller.cpp \
stackedutilitypanelcontroller.cpp \ stackedutilitypanelcontroller.cpp \
componentaction.cpp \ componentaction.cpp \
@@ -10,8 +10,8 @@ SOURCES += \
xuifiledialog.cpp xuifiledialog.cpp
HEADERS += \ HEADERS += \
designdocumentcontrollerview.h \ designdocumentview.h \
designdocumentcontroller.h \ designdocument.h \
utilitypanelcontroller.h \ utilitypanelcontroller.h \
stackedutilitypanelcontroller.h \ stackedutilitypanelcontroller.h \
componentaction.h \ componentaction.h \

View File

@@ -29,7 +29,7 @@
#include <QStackedWidget> #include <QStackedWidget>
#include "designdocumentcontroller.h" #include "designdocument.h"
#include "stackedutilitypanelcontroller.h" #include "stackedutilitypanelcontroller.h"
namespace QmlDesigner { namespace QmlDesigner {
@@ -43,12 +43,12 @@ StackedUtilityPanelController::StackedUtilityPanelController(QObject* parent):
m_stackedWidget->setFrameStyle(QFrame::NoFrame); m_stackedWidget->setFrameStyle(QFrame::NoFrame);
} }
void StackedUtilityPanelController::show(DesignDocumentController* designDocumentController) void StackedUtilityPanelController::show(DesignDocument* DesignDocument)
{ {
if (!designDocumentController) if (!DesignDocument)
return; return;
QWidget* page = stackedPageWidget(designDocumentController); QWidget* page = stackedPageWidget(DesignDocument);
if (!m_stackedWidget->children().contains(page)) if (!m_stackedWidget->children().contains(page))
m_stackedWidget->addWidget(page); m_stackedWidget->addWidget(page);
@@ -57,9 +57,9 @@ void StackedUtilityPanelController::show(DesignDocumentController* designDocumen
page->show(); page->show();
} }
void StackedUtilityPanelController::close(DesignDocumentController* designDocumentController) void StackedUtilityPanelController::close(DesignDocument* DesignDocument)
{ {
QWidget* page = stackedPageWidget(designDocumentController); QWidget* page = stackedPageWidget(DesignDocument);
if (m_stackedWidget->children().contains(page)) { if (m_stackedWidget->children().contains(page)) {
page->hide(); page->hide();

View File

@@ -34,7 +34,7 @@
namespace QmlDesigner { namespace QmlDesigner {
class DesignDocumentController; class DesignDocument;
class StackedUtilityPanelController : public UtilityPanelController class StackedUtilityPanelController : public UtilityPanelController
{ {
@@ -44,12 +44,12 @@ public:
StackedUtilityPanelController(QObject* parent = 0); StackedUtilityPanelController(QObject* parent = 0);
public slots: public slots:
void show(DesignDocumentController* designDocumentController); void show(DesignDocument* DesignDocument);
void close(DesignDocumentController* designDocumentController); void close(DesignDocument* DesignDocument);
protected: protected:
virtual QWidget* contentWidget() const; virtual QWidget* contentWidget() const;
virtual QWidget* stackedPageWidget(DesignDocumentController* designDocumentController) const = 0; virtual QWidget* stackedPageWidget(DesignDocument* DesignDocument) const = 0;
private: private:
class QStackedWidget* m_stackedWidget; class QStackedWidget* m_stackedWidget;

View File

@@ -33,7 +33,7 @@
namespace QmlDesigner { namespace QmlDesigner {
ItemLibraryView::ItemLibraryView(QObject* parent) : AbstractView(parent), m_widget(new ItemLibraryWidget) ItemLibraryView::ItemLibraryView(QObject* parent) : AbstractView(parent)
{ {
} }
@@ -43,8 +43,11 @@ ItemLibraryView::~ItemLibraryView()
} }
ItemLibraryWidget *ItemLibraryView::widget() QWidget *ItemLibraryView::widget()
{ {
if (m_widget.isNull())
m_widget = new ItemLibraryWidget;
return m_widget.data(); return m_widget.data();
} }
@@ -191,6 +194,14 @@ void ItemLibraryView::actualStateChanged(const ModelNode &/*node*/)
{ {
} }
void ItemLibraryView::setResourcePath(const QString &resourcePath)
{
if (m_widget.isNull())
m_widget = new ItemLibraryWidget;
m_widget->setResourcePath(resourcePath);
}
void ItemLibraryView::updateImports() void ItemLibraryView::updateImports()
{ {
m_widget->updateModel(); m_widget->updateModel();

View File

@@ -48,7 +48,7 @@ public:
ItemLibraryView(QObject* parent = 0); ItemLibraryView(QObject* parent = 0);
~ItemLibraryView(); ~ItemLibraryView();
ItemLibraryWidget *widget(); QWidget *widget();
// AbstractView // AbstractView
void modelAttached(Model *model); void modelAttached(Model *model);
@@ -90,6 +90,8 @@ public:
void actualStateChanged(const ModelNode &node); void actualStateChanged(const ModelNode &node);
void setResourcePath(const QString &resourcePath);
protected: protected:
void updateImports(); void updateImports();

View File

@@ -94,7 +94,7 @@ NavigatorView::~NavigatorView()
delete m_widget.data(); delete m_widget.data();
} }
NavigatorWidget *NavigatorView::widget() QWidget *NavigatorView::widget()
{ {
return m_widget.data(); return m_widget.data();
} }
@@ -270,7 +270,7 @@ void NavigatorView::changeToComponent(const QModelIndex &index)
{ {
if (index.isValid() && m_treeModel->data(index, Qt::UserRole).isValid()) { if (index.isValid() && m_treeModel->data(index, Qt::UserRole).isValid()) {
ModelNode doubleClickNode = m_treeModel->nodeForIndex(index); ModelNode doubleClickNode = m_treeModel->nodeForIndex(index);
if (doubleClickNode.metaInfo().isComponent()) if (doubleClickNode.metaInfo().isFileComponent())
Core::EditorManager::openEditor(doubleClickNode.metaInfo().componentFileName()); Core::EditorManager::openEditor(doubleClickNode.metaInfo().componentFileName());
} }
} }

View File

@@ -56,7 +56,7 @@ public:
NavigatorView(QObject* parent = 0); NavigatorView(QObject* parent = 0);
~NavigatorView(); ~NavigatorView();
NavigatorWidget *widget(); QWidget *widget();
// AbstractView // AbstractView
void modelAttached(Model *model); void modelAttached(Model *model);

View File

@@ -991,7 +991,6 @@ void PropertyEditor::select(const ModelNode &node)
QWidget *PropertyEditor::widget() QWidget *PropertyEditor::widget()
{ {
delayedResetView();
return m_stackedWidget; return m_stackedWidget;
} }

View File

@@ -53,17 +53,15 @@ namespace QmlDesigner {
StatesEditorView::StatesEditorView(QObject *parent) : StatesEditorView::StatesEditorView(QObject *parent) :
QmlModelView(parent), QmlModelView(parent),
m_statesEditorModel(new StatesEditorModel(this)), m_statesEditorModel(new StatesEditorModel(this)),
m_statesEditorWidget(new StatesEditorWidget(this, m_statesEditorModel.data())),
m_lastIndex(-1) m_lastIndex(-1)
{ {
Q_ASSERT(m_statesEditorModel); Q_ASSERT(m_statesEditorModel);
// base state // base state
} }
StatesEditorWidget *StatesEditorView::widget() QWidget *StatesEditorView::widget()
{ {
if (m_statesEditorWidget.isNull())
m_statesEditorWidget = new StatesEditorWidget(this, m_statesEditorModel.data());
return m_statesEditorWidget.data(); return m_statesEditorWidget.data();
} }

View File

@@ -76,7 +76,7 @@ public:
void instancesPreviewImageChanged(const QVector<ModelNode> &nodeList); void instancesPreviewImageChanged(const QVector<ModelNode> &nodeList);
StatesEditorWidget *widget(); QWidget *widget();
public slots: public slots:
void synchonizeCurrentStateFromWidget(); void synchonizeCurrentStateFromWidget();
@@ -84,6 +84,7 @@ public slots:
void removeState(int nodeId); void removeState(int nodeId);
private: private:
StatesEditorWidget *statesEditorWidget() const;
void resetModel(); void resetModel();
void addState(); void addState();
void duplicateCurrentState(); void duplicateCurrentState();

View File

@@ -75,7 +75,8 @@ SOURCES += $$PWD/model/abstractview.cpp \
$$PWD/model/rewriteactioncompressor.cpp \ $$PWD/model/rewriteactioncompressor.cpp \
$$PWD/model/qmltextgenerator.cpp \ $$PWD/model/qmltextgenerator.cpp \
$$PWD/model/modelmerger.cpp \ $$PWD/model/modelmerger.cpp \
$$PWD/exceptions/rewritingexception.cpp $$PWD/exceptions/rewritingexception.cpp \
$$PWD/model/viewmanager.cpp
HEADERS += $$PWD/include/qmldesignercorelib_global.h \ HEADERS += $$PWD/include/qmldesignercorelib_global.h \
$$PWD/include/abstractview.h \ $$PWD/include/abstractview.h \
@@ -145,7 +146,8 @@ HEADERS += $$PWD/include/qmldesignercorelib_global.h \
$$PWD/include/modelmerger.h \ $$PWD/include/modelmerger.h \
$$PWD/include/mathutils.h \ $$PWD/include/mathutils.h \
$$PWD/include/customnotifications.h \ $$PWD/include/customnotifications.h \
$$PWD/include/rewritingexception.h $$PWD/include/rewritingexception.h \
$$PWD/include/viewmanager.h
contains(CONFIG, plugin) { contains(CONFIG, plugin) {
# If core.pri has been included in the qmldesigner plugin # If core.pri has been included in the qmldesigner plugin

View File

@@ -50,7 +50,7 @@ void QmlWarningDialog::okButtonPressed()
bool QmlWarningDialog::warningsEnabled() const bool QmlWarningDialog::warningsEnabled() const
{ {
#ifndef QMLDESIGNER_TEST #ifndef QMLDESIGNER_TEST
DesignerSettings settings = BauhausPlugin::pluginInstance()->settings(); DesignerSettings settings = QmlDesignerPlugin::instance()->settings();
return settings.warningsInDesigner; return settings.warningsInDesigner;
#else #else
return false; return false;
@@ -60,9 +60,9 @@ bool QmlWarningDialog::warningsEnabled() const
void QmlWarningDialog::checkBoxToggled(bool b) void QmlWarningDialog::checkBoxToggled(bool b)
{ {
#ifndef QMLDESIGNER_TEST #ifndef QMLDESIGNER_TEST
DesignerSettings settings = BauhausPlugin::pluginInstance()->settings(); DesignerSettings settings = QmlDesignerPlugin::instance()->settings();
settings.warningsInDesigner = b; settings.warningsInDesigner = b;
BauhausPlugin::pluginInstance()->setSettings(settings); QmlDesignerPlugin::instance()->setSettings(settings);
#else #else
Q_UNUSED(b); Q_UNUSED(b);
#endif #endif

View File

@@ -77,6 +77,7 @@ public:
virtual ~AbstractView(); virtual ~AbstractView();
Model* model() const; Model* model() const;
bool isAttached() const;
RewriterTransaction beginRewriterTransaction(); RewriterTransaction beginRewriterTransaction();
@@ -104,7 +105,7 @@ public:
ModelNode modelNodeForInternalId(qint32 internalId); ModelNode modelNodeForInternalId(qint32 internalId);
bool hasModelNodeForInternalId(qint32 internalId) const; bool hasModelNodeForInternalId(qint32 internalId) const;
QList<ModelNode> allModelNodes(); QList<ModelNode> allModelNodes() const;
void emitCustomNotification(const QString &identifier); void emitCustomNotification(const QString &identifier);
void emitCustomNotification(const QString &identifier, const QList<ModelNode> &nodeList); void emitCustomNotification(const QString &identifier, const QList<ModelNode> &nodeList);
@@ -179,6 +180,8 @@ public:
void resetView(); void resetView();
virtual QWidget *widget() = 0;
protected: protected:
void setModel(Model * model); void setModel(Model * model);
void removeModel(); void removeModel();

View File

@@ -58,6 +58,7 @@ class ModelState;
class NodeAnchors; class NodeAnchors;
class AbstractProperty; class AbstractProperty;
class RewriterView; class RewriterView;
class NodeInstanceView;
typedef QList<QPair<QString, QVariant> > PropertyListType; typedef QList<QPair<QString, QVariant> > PropertyListType;
@@ -80,9 +81,6 @@ public:
static Model *create(QString type, int major = 1, int minor = 1, Model *metaInfoPropxyModel = 0); static Model *create(QString type, int major = 1, int minor = 1, Model *metaInfoPropxyModel = 0);
Model *masterModel() const;
void setMasterModel(Model *model);
QUrl fileUrl() const; QUrl fileUrl() const;
void setFileUrl(const QUrl &url); void setFileUrl(const QUrl &url);
@@ -103,6 +101,10 @@ public:
QString pathForImport(const Import &import); QString pathForImport(const Import &import);
RewriterView *rewriterView() const; RewriterView *rewriterView() const;
void setRewriterView(RewriterView *rewriterView);
NodeInstanceView *nodeInstanceView() const;
void setNodeInstanceView(NodeInstanceView *nodeInstanceView);
Model *metaInfoProxyModel(); Model *metaInfoProxyModel();

View File

@@ -143,6 +143,8 @@ public:
void sendToken(const QString &token, int number, const QVector<ModelNode> &nodeVector); void sendToken(const QString &token, int number, const QVector<ModelNode> &nodeVector);
QWidget *widget();
signals: signals:
void qmlPuppetCrashed(); void qmlPuppetCrashed();

View File

@@ -68,7 +68,7 @@ public:
NodeMetaInfo &operator=(const NodeMetaInfo &other); NodeMetaInfo &operator=(const NodeMetaInfo &other);
bool isValid() const; bool isValid() const;
bool isComponent() const; bool isFileComponent() const;
bool hasProperty(const QString &propertyName) const; bool hasProperty(const QString &propertyName) const;
QStringList propertyNames() const; QStringList propertyNames() const;
QStringList directPropertyNames() const; QStringList directPropertyNames() const;

View File

@@ -163,6 +163,9 @@ public:
void setTextModifier(TextModifier *textModifier); void setTextModifier(TextModifier *textModifier);
QString textModifierContent() const; QString textModifierContent() const;
void reactivateTextMofifierChangeSignals();
void deactivateTextMofifierChangeSignals();
Internal::ModelNodePositionStorage *positionStorage() const Internal::ModelNodePositionStorage *positionStorage() const
{ return m_positionStorage; } { return m_positionStorage; }
@@ -182,6 +185,7 @@ public:
int firstDefinitionInsideOffset(const ModelNode &node) const; int firstDefinitionInsideOffset(const ModelNode &node) const;
int firstDefinitionInsideLength(const ModelNode &node) const; int firstDefinitionInsideLength(const ModelNode &node) const;
bool modificationGroupActive(); bool modificationGroupActive();
ModelNode nodeAtTextCursorPosition(int cursorPosition) const;
bool renameId(const QString& oldId, const QString& newId); bool renameId(const QString& oldId, const QString& newId);
@@ -198,6 +202,8 @@ public:
QString pathForImport(const Import &import); QString pathForImport(const Import &import);
QWidget *widget();
signals: signals:
void errorsChanged(const QList<RewriterView::Error> &errors); void errorsChanged(const QList<RewriterView::Error> &errors);

View File

@@ -0,0 +1,115 @@
/****************************************************************************
**
** 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_VIEWMANAGER_H
#define QMLDESIGNER_VIEWMANAGER_H
#include "abstractview.h"
#include <rewriterview.h>
#include <nodeinstanceview.h>
#include <itemlibraryview.h>
#include <navigatorview.h>
#include <stateseditorview.h>
#include <formeditorview.h>
#include <propertyeditor.h>
#include <componentview.h>
#include <model/viewlogger.h>
namespace QmlDesigner {
class DesignDocument;
namespace Internal {
class DesignModeWidget;
}
class ViewManager
{
public:
ViewManager();
void attachRewriterView(TextModifier *textModifier);
void detachRewriterView();
void attachComponentView();
void detachComponentView();
void attachViewsExceptRewriterAndComponetView();
void detachViewsExceptRewriterAndComponetView();
void setItemLibraryViewResourcePath(const QString &resourcePath);
void setComponentNode(const ModelNode &componentNode);
void setNodeInstanceViewQtPath(const QString & qtPath);
void resetPropertyEditorView();
QWidget *formEditorWidget();
QWidget *propertyEditorWidget();
QWidget *itemLibraryWidget();
QWidget *navigatorWidget();
QWidget *statesEditorWidget();
void pushFileOnCrambleBar(const QString &fileName);
void pushInFileComponentOnCrambleBar(const QString &componentId);
void nextFileIsCalledInternally();
private: // functions
Q_DISABLE_COPY(ViewManager)
void attachNodeInstanceView();
void attachItemLibraryView();
Model *currentModel() const;
Model *documentModel() const;
DesignDocument *currentDesignDocument() const;
QString pathToQt() const;
void switchStateEditorViewToBaseState();
void switchStateEditorViewToSavedState();
private: // variables
QmlModelState m_savedState;
Internal::ViewLogger m_viewLogger;
ComponentView m_componentView;
FormEditorView m_formEditorView;
ItemLibraryView m_itemLibraryView;
NavigatorView m_navigatorView;
PropertyEditor m_propertyEditorView;
StatesEditorView m_statesEditorView;
NodeInstanceView m_nodeInstanceView;
QList<QWeakPointer<AbstractView> > m_additionalViews;
};
} // namespace QmlDesigner
#endif // QMLDESIGNER_VIEWMANAGER_H

View File

@@ -1219,4 +1219,9 @@ void NodeInstanceView::sendToken(const QString &token, int number, const QVector
nodeInstanceServer()->token(TokenCommand(token, number, instanceIdVector)); nodeInstanceServer()->token(TokenCommand(token, number, instanceIdVector));
} }
QWidget *NodeInstanceView::widget()
{
return 0;
}
} }

View File

@@ -327,29 +327,10 @@ public:
~NodeMetaInfoPrivate() {} ~NodeMetaInfoPrivate() {}
bool isValid() const; bool isValid() const;
bool isFileComponent() const;
bool isComponent() const QStringList properties() const;
{ QStringList localProperties() const;
return m_isComponent; QString defaultPropertyName() const;
}
QStringList properties() const
{
return m_properties;
}
QStringList localProperties() const
{
return m_localProperties;
}
QString defaultPropertyName() const
{
if (!m_defaultPropertyName.isEmpty())
return m_defaultPropertyName;
return QLatin1String("data");
}
QString propertyType(const QString &propertyName) const; QString propertyType(const QString &propertyName) const;
void setupPrototypes(); void setupPrototypes();
@@ -364,17 +345,10 @@ public:
bool cleverCheckType(const QString &otherType) const; bool cleverCheckType(const QString &otherType) const;
QVariant::Type variantTypeId(const QString &properyName) const; QVariant::Type variantTypeId(const QString &properyName) const;
int majorVersion() const int majorVersion() const;
{ return m_majorVersion; } int minorVersion() const;
QString qualfiedTypeName() const;
int minorVersion() const Model *model() const;
{ return m_minorVersion; }
QString qualfiedTypeName() const
{ return m_qualfiedTypeName; }
Model *model() const
{ return m_model; }
QString cppPackageName() const; QString cppPackageName() const;
@@ -384,20 +358,11 @@ public:
static Pointer create(Model *model, const QString &type, int maj = -1, int min = -1); static Pointer create(Model *model, const QString &type, int maj = -1, int min = -1);
QSet<QString> &prototypeCachePositives() QSet<QString> &prototypeCachePositives();
{ QSet<QString> &prototypeCacheNegatives();
return m_prototypeCachePositives;
}
QSet<QString> &prototypeCacheNegatives() static void clearCache();
{
return m_prototypeCacheNegatives;
}
static void clearCache()
{
m_nodeMetaInfoCache.clear();
}
private: private:
NodeMetaInfoPrivate(Model *model, QString type, int maj = -1, int min = -1); NodeMetaInfoPrivate(Model *model, QString type, int maj = -1, int min = -1);
@@ -415,7 +380,7 @@ private:
int m_majorVersion; int m_majorVersion;
int m_minorVersion; int m_minorVersion;
bool m_isValid; bool m_isValid;
bool m_isComponent; bool m_isFileComponent;
QStringList m_properties; QStringList m_properties;
QStringList m_propertyTypes; QStringList m_propertyTypes;
QStringList m_localProperties; QStringList m_localProperties;
@@ -434,6 +399,42 @@ private:
QHash<QString, NodeMetaInfoPrivate::Pointer> NodeMetaInfoPrivate::m_nodeMetaInfoCache; QHash<QString, NodeMetaInfoPrivate::Pointer> NodeMetaInfoPrivate::m_nodeMetaInfoCache;
bool NodeMetaInfoPrivate::isFileComponent() const
{
return m_isFileComponent;
}
QStringList NodeMetaInfoPrivate::properties() const
{
return m_properties;
}
QStringList NodeMetaInfoPrivate::localProperties() const
{
return m_localProperties;
}
QSet<QString> &NodeMetaInfoPrivate::prototypeCachePositives()
{
return m_prototypeCachePositives;
}
QSet<QString> &NodeMetaInfoPrivate::prototypeCacheNegatives()
{
return m_prototypeCacheNegatives;
}
void NodeMetaInfoPrivate::clearCache()
{
m_nodeMetaInfoCache.clear();
}
QString NodeMetaInfoPrivate::defaultPropertyName() const
{
if (!m_defaultPropertyName.isEmpty())
return m_defaultPropertyName;
return QLatin1String("data");
}
static inline QString stringIdentifier( const QString &type, int maj, int min) static inline QString stringIdentifier( const QString &type, int maj, int min)
{ {
@@ -463,7 +464,7 @@ NodeMetaInfoPrivate::NodeMetaInfoPrivate() : m_isValid(false)
NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, QString type, int maj, int min) : NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, QString type, int maj, int min) :
m_qualfiedTypeName(type), m_majorVersion(maj), m_qualfiedTypeName(type), m_majorVersion(maj),
m_minorVersion(min), m_isValid(false), m_isComponent(false), m_minorVersion(min), m_isValid(false), m_isFileComponent(false),
m_model(model) m_model(model)
{ {
if (context()) { if (context()) {
@@ -493,7 +494,7 @@ NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, QString type, int maj, in
return; return;
} }
} else { } else {
m_isComponent = true; m_isFileComponent = true;
} }
setupPropertyInfo(getTypes(objectValue, context())); setupPropertyInfo(getTypes(objectValue, context()));
setupLocalPropertyInfo(getTypes(objectValue, context(), true)); setupLocalPropertyInfo(getTypes(objectValue, context(), true));
@@ -731,7 +732,7 @@ bool NodeMetaInfoPrivate::cleverCheckType(const QString &otherType) const
if (otherType == qualfiedTypeName()) if (otherType == qualfiedTypeName())
return true; return true;
if (isComponent()) if (isFileComponent())
return false; return false;
QStringList split = otherType.split('.'); QStringList split = otherType.split('.');
@@ -793,6 +794,26 @@ QVariant::Type NodeMetaInfoPrivate::variantTypeId(const QString &properyName) co
return QVariant::nameToType(typeName.toLatin1().data()); return QVariant::nameToType(typeName.toLatin1().data());
} }
int NodeMetaInfoPrivate::majorVersion() const
{
return m_majorVersion;
}
int NodeMetaInfoPrivate::minorVersion() const
{
return m_minorVersion;
}
QString NodeMetaInfoPrivate::qualfiedTypeName() const
{
return m_qualfiedTypeName;
}
Model *NodeMetaInfoPrivate::model() const
{
return m_model;
}
QStringList NodeMetaInfoPrivate::keysForEnum(const QString &enumName) const QStringList NodeMetaInfoPrivate::keysForEnum(const QString &enumName) const
{ {
@@ -807,7 +828,7 @@ QStringList NodeMetaInfoPrivate::keysForEnum(const QString &enumName) const
QString NodeMetaInfoPrivate::cppPackageName() const QString NodeMetaInfoPrivate::cppPackageName() const
{ {
if (!isComponent()) { if (!isFileComponent()) {
if (const CppComponentValue *qmlObject = getCppComponentValue()) if (const CppComponentValue *qmlObject = getCppComponentValue())
return qmlObject->moduleName(); return qmlObject->moduleName();
} }
@@ -816,7 +837,7 @@ QString NodeMetaInfoPrivate::cppPackageName() const
QString NodeMetaInfoPrivate::componentSource() const QString NodeMetaInfoPrivate::componentSource() const
{ {
if (isComponent()) { if (isFileComponent()) {
const ASTObjectValue * astObjectValue = value_cast<ASTObjectValue>(getObjectValue()); const ASTObjectValue * astObjectValue = value_cast<ASTObjectValue>(getObjectValue());
if (astObjectValue) if (astObjectValue)
return astObjectValue->document()->source().mid(astObjectValue->typeName()->identifierToken.begin(), return astObjectValue->document()->source().mid(astObjectValue->typeName()->identifierToken.begin(),
@@ -827,7 +848,7 @@ QString NodeMetaInfoPrivate::componentSource() const
QString NodeMetaInfoPrivate::componentFileName() const QString NodeMetaInfoPrivate::componentFileName() const
{ {
if (isComponent()) { if (isFileComponent()) {
const ASTObjectValue * astObjectValue = value_cast<ASTObjectValue>(getObjectValue()); const ASTObjectValue * astObjectValue = value_cast<ASTObjectValue>(getObjectValue());
if (astObjectValue) { if (astObjectValue) {
QString fileName; QString fileName;
@@ -890,7 +911,7 @@ QString NodeMetaInfoPrivate::propertyType(const QString &propertyName) const
void NodeMetaInfoPrivate::setupPrototypes() void NodeMetaInfoPrivate::setupPrototypes()
{ {
QList<const ObjectValue *> objects; QList<const ObjectValue *> objects;
if (m_isComponent) if (m_isFileComponent)
objects = PrototypeIterator(getObjectValue(), context()).all(); objects = PrototypeIterator(getObjectValue(), context()).all();
else else
objects = PrototypeIterator(getCppComponentValue(), context()).all(); objects = PrototypeIterator(getCppComponentValue(), context()).all();
@@ -927,7 +948,7 @@ QList<TypeDescription> NodeMetaInfoPrivate::prototypes() const
const QmlJS::CppComponentValue *NodeMetaInfoPrivate::getNearestCppComponentValue() const const QmlJS::CppComponentValue *NodeMetaInfoPrivate::getNearestCppComponentValue() const
{ {
if (m_isComponent) if (m_isFileComponent)
return findQmlPrototype(getObjectValue(), context()); return findQmlPrototype(getObjectValue(), context());
return getCppComponentValue(); return getCppComponentValue();
} }
@@ -973,9 +994,9 @@ bool NodeMetaInfo::isValid() const
return m_privateData->isValid(); return m_privateData->isValid();
} }
bool NodeMetaInfo::isComponent() const bool NodeMetaInfo::isFileComponent() const
{ {
return m_privateData->isComponent(); return m_privateData->isFileComponent();
} }
bool NodeMetaInfo::hasProperty(const QString &propertyName) const bool NodeMetaInfo::hasProperty(const QString &propertyName) const

View File

@@ -132,6 +132,11 @@ Model* AbstractView::model() const
return m_model.data(); return m_model.data();
} }
bool AbstractView::isAttached() const
{
return model();
}
/*! /*!
\brief is called if a view is being attached to a model \brief is called if a view is being attached to a model
\param model which is being attached \param model which is being attached
@@ -362,7 +367,7 @@ void AbstractView::resetView()
currentModel->attachView(this); currentModel->attachView(this);
} }
QList<ModelNode> AbstractView::allModelNodes() QList<ModelNode> AbstractView::allModelNodes() const
{ {
return toModelNodeList(model()->d->allNodes()); return toModelNodeList(model()->d->allNodes());
} }

View File

@@ -1525,12 +1525,13 @@ void ModelPrivate::setRewriterView(RewriterView *rewriterView)
Q_ASSERT(!(rewriterView && m_rewriterView)); Q_ASSERT(!(rewriterView && m_rewriterView));
if (m_rewriterView)
m_rewriterView->modelAboutToBeDetached(model());
m_rewriterView = rewriterView; m_rewriterView = rewriterView;
if (rewriterView) if (rewriterView)
rewriterView->modelAttached(model()); rewriterView->modelAttached(model());
else if (m_rewriterView)
m_rewriterView->modelAboutToBeDetached(model());
} }
RewriterView *ModelPrivate::rewriterView() const RewriterView *ModelPrivate::rewriterView() const
@@ -1730,6 +1731,21 @@ RewriterView *Model::rewriterView() const
return d->rewriterView(); return d->rewriterView();
} }
void Model::setRewriterView(RewriterView *rewriterView)
{
d->setRewriterView(rewriterView);
}
NodeInstanceView *Model::nodeInstanceView() const
{
return d->nodeInstanceView();
}
void Model::setNodeInstanceView(NodeInstanceView *nodeInstanceView)
{
d->setNodeInstanceView(nodeInstanceView);
}
/*! /*!
\brief Returns the model that is used for metainfo \brief Returns the model that is used for metainfo
\return Return itself if not other metaInfoProxyModel does exist \return Return itself if not other metaInfoProxyModel does exist
@@ -1755,16 +1771,6 @@ Model *Model::create(const QString &rootType)
} }
#endif #endif
Model *Model::masterModel() const
{
return d->m_masterModel.data();
}
void Model::setMasterModel(Model *model)
{
d->m_masterModel = model;
}
/*! /*!
\brief Returns the URL against which relative URLs within the model should be resolved. \brief Returns the URL against which relative URLs within the model should be resolved.
\return The base URL. \return The base URL.
@@ -1834,13 +1840,11 @@ void Model::attachView(AbstractView *view)
// Internal::WriteLocker locker(d); // Internal::WriteLocker locker(d);
RewriterView *rewriterView = qobject_cast<RewriterView*>(view); RewriterView *rewriterView = qobject_cast<RewriterView*>(view);
if (rewriterView) { if (rewriterView) {
d->setRewriterView(rewriterView);
return; return;
} }
NodeInstanceView *nodeInstanceView = qobject_cast<NodeInstanceView*>(view); NodeInstanceView *nodeInstanceView = qobject_cast<NodeInstanceView*>(view);
if (nodeInstanceView) { if (nodeInstanceView) {
d->setNodeInstanceView(nodeInstanceView);
return; return;
} }
@@ -1862,13 +1866,11 @@ void Model::detachView(AbstractView *view, ViewNotification emitDetachNotify)
RewriterView *rewriterView = qobject_cast<RewriterView*>(view); RewriterView *rewriterView = qobject_cast<RewriterView*>(view);
if (rewriterView) { if (rewriterView) {
d->setRewriterView(0);
return; return;
} }
NodeInstanceView *nodeInstanceView = qobject_cast<NodeInstanceView*>(view); NodeInstanceView *nodeInstanceView = qobject_cast<NodeInstanceView*>(view);
if (nodeInstanceView) { if (nodeInstanceView) {
d->setNodeInstanceView(0);
return; return;
} }

View File

@@ -212,6 +212,8 @@ public:
void setRewriterView(RewriterView *rewriterView); void setRewriterView(RewriterView *rewriterView);
RewriterView *rewriterView() const; RewriterView *rewriterView() const;
void setNodeInstanceView(NodeInstanceView *nodeInstanceView); void setNodeInstanceView(NodeInstanceView *nodeInstanceView);
NodeInstanceView *nodeInstanceView() const; NodeInstanceView *nodeInstanceView() const;
@@ -229,7 +231,6 @@ private: //functions
private: private:
Model *m_q; Model *m_q;
MetaInfo m_metaInfo; MetaInfo m_metaInfo;
QList<Import> m_imports; QList<Import> m_imports;
QList<QWeakPointer<AbstractView> > m_viewList; QList<QWeakPointer<AbstractView> > m_viewList;
QList<InternalNodePointer> m_selectedNodeList; QList<InternalNodePointer> m_selectedNodeList;
@@ -237,17 +238,11 @@ private:
QHash<qint32, InternalNodePointer> m_internalIdNodeHash; QHash<qint32, InternalNodePointer> m_internalIdNodeHash;
QSet<InternalNodePointer> m_nodeSet; QSet<InternalNodePointer> m_nodeSet;
InternalNodePointer m_acutalStateNode; InternalNodePointer m_acutalStateNode;
InternalNodePointer m_rootInternalNode; InternalNodePointer m_rootInternalNode;
QUrl m_fileUrl; QUrl m_fileUrl;
QWeakPointer<Model> m_masterModel;
QWeakPointer<RewriterView> m_rewriterView; QWeakPointer<RewriterView> m_rewriterView;
QWeakPointer<NodeInstanceView> m_nodeInstanceView; QWeakPointer<NodeInstanceView> m_nodeInstanceView;
QWeakPointer<Model> m_metaInfoProxyModel; QWeakPointer<Model> m_metaInfoProxyModel;
bool m_writeLock; bool m_writeLock;
qint32 m_internalIdCounter; qint32 m_internalIdCounter;
}; };

View File

@@ -229,7 +229,7 @@ QmlItemNode QmlModelView::createQmlItemNode(const ItemLibraryEntry &itemLibraryE
QScopedPointer<RewriterView> rewriterView(new RewriterView(RewriterView::Amend, 0)); QScopedPointer<RewriterView> rewriterView(new RewriterView(RewriterView::Amend, 0));
rewriterView->setCheckSemanticErrors(false); rewriterView->setCheckSemanticErrors(false);
rewriterView->setTextModifier(&modifier); rewriterView->setTextModifier(&modifier);
inputModel->attachView(rewriterView.data()); inputModel->setRewriterView(rewriterView.data());
if (rewriterView->errors().isEmpty() && rewriterView->rootModelNode().isValid()) { if (rewriterView->errors().isEmpty() && rewriterView->rootModelNode().isValid()) {
ModelNode rootModelNode = rewriterView->rootModelNode(); ModelNode rootModelNode = rewriterView->rootModelNode();

View File

@@ -472,6 +472,16 @@ QString RewriterView::textModifierContent() const
return QString(); return QString();
} }
void RewriterView::reactivateTextMofifierChangeSignals()
{
textModifier()->reactivateChangeSignals();
}
void RewriterView::deactivateTextMofifierChangeSignals()
{
textModifier()->deactivateChangeSignals();
}
void RewriterView::applyModificationGroupChanges() void RewriterView::applyModificationGroupChanges()
{ {
Q_ASSERT(transactionLevel == 0); Q_ASSERT(transactionLevel == 0);
@@ -615,6 +625,31 @@ bool RewriterView::modificationGroupActive()
return m_modificationGroupActive; return m_modificationGroupActive;
} }
static bool isInNodeDefinition(int nodeTextOffset, int nodeTextLength, int cursorPosition)
{
return (nodeTextOffset <= cursorPosition) && (nodeTextOffset + nodeTextLength > cursorPosition);
}
ModelNode RewriterView::nodeAtTextCursorPosition(int cursorPosition) const
{
const QList<ModelNode> allNodes = allModelNodes();
ModelNode nearestNode;
int nearestNodeTextOffset = -1;
foreach (const ModelNode &currentNode, allNodes) {
const int nodeTextOffset = nodeOffset(currentNode);
const int nodeTextLength = nodeLength(currentNode);
if (isInNodeDefinition(nodeTextOffset, nodeTextLength, cursorPosition)
&& (nodeTextOffset > nearestNodeTextOffset)) {
nearestNode = currentNode;
nearestNodeTextOffset = nodeTextOffset;
}
}
return nearestNode;
}
bool RewriterView::renameId(const QString& oldId, const QString& newId) bool RewriterView::renameId(const QString& oldId, const QString& newId)
{ {
if (textModifier()) if (textModifier())
@@ -698,6 +733,10 @@ QString RewriterView::pathForImport(const Import &import)
return QString(); return QString();
} }
QWidget *RewriterView::widget()
{
return 0;
}
void RewriterView::qmlTextChanged() void RewriterView::qmlTextChanged()
{ {

View File

@@ -285,5 +285,10 @@ void ViewLogger::actualStateChanged(const ModelNode &node)
{ {
m_output << time() << indent("actualStateChanged:") << node << endl; m_output << time() << indent("actualStateChanged:") << node << endl;
} }
QWidget *ViewLogger::widget()
{
return 0;
}
} // namespace Internal } // namespace Internal
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -42,7 +42,7 @@ class ViewLogger : public QmlDesigner::AbstractView
{ {
Q_OBJECT Q_OBJECT
public: public:
ViewLogger(QObject *parent); ViewLogger(QObject *parent = 0);
void modelAttached(Model *model); void modelAttached(Model *model);
void modelAboutToBeDetached(Model *model); void modelAboutToBeDetached(Model *model);
@@ -87,6 +87,8 @@ public:
void actualStateChanged(const ModelNode &node); void actualStateChanged(const ModelNode &node);
QWidget *widget();
protected: protected:
QString time() const; QString time() const;

View File

@@ -0,0 +1,194 @@
#include "viewmanager.h"
#include "designdocument.h"
#include "componentaction.h"
#include "itemlibrarywidget.h"
#include "designmodewidget.h"
#include "formeditorwidget.h"
#include "toolbox.h"
#include "designeractionmanager.h"
#include <qmldesigner/qmldesignerplugin.h>
#include <utils/crumblepath.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtversionmanager.h>
#include <qtsupport/qtsupportconstants.h>
namespace QmlDesigner {
ViewManager::ViewManager()
{
//QObject::connect(&m_nodeInstanceView, SIGNAL(qmlPuppetCrashed()), designModeWidget, SLOT(qmlPuppetCrashed()));
//QObject::connect(m_formEditorView.crumblePath(), SIGNAL(elementClicked(QVariant)), designModeWidget, SLOT(onCrumblePathElementClicked(QVariant)));
m_formEditorView.formEditorWidget()->toolBox()->addLeftSideAction(m_componentView.action()); // ugly hack
}
DesignDocument *ViewManager::currentDesignDocument() const
{
return QmlDesignerPlugin::instance()->documentManager().currentDesignDocument();
}
QString ViewManager::pathToQt() const
{
QtSupport::BaseQtVersion *activeQtVersion = QtSupport::QtVersionManager::instance()->version(currentDesignDocument()->qtVersionId());
if (activeQtVersion && (activeQtVersion->qtVersion() >= QtSupport::QtVersionNumber(4, 7, 1))
&& (activeQtVersion->type() == QLatin1String(QtSupport::Constants::DESKTOPQT)
|| activeQtVersion->type() == QLatin1String(QtSupport::Constants::SIMULATORQT)))
return activeQtVersion->qmakeProperty("QT_INSTALL_DATA");
return QString();
}
void ViewManager::attachNodeInstanceView()
{
setNodeInstanceViewQtPath(pathToQt());
currentModel()->setNodeInstanceView(&m_nodeInstanceView);
}
void ViewManager::attachRewriterView(TextModifier *textModifier)
{
if (currentDesignDocument()->rewriterView()) {
currentDesignDocument()->rewriterView()->setTextModifier(textModifier);
currentDesignDocument()->rewriterView()->reactivateTextMofifierChangeSignals();
currentModel()->setRewriterView(currentDesignDocument()->rewriterView());
}
}
void ViewManager::detachRewriterView()
{
if (currentDesignDocument()->rewriterView()) {
currentDesignDocument()->rewriterView()->deactivateTextMofifierChangeSignals();
currentModel()->setRewriterView(0);
}
}
void ViewManager::switchStateEditorViewToBaseState()
{
if (m_statesEditorView.isAttached()) {
m_savedState = m_statesEditorView.currentState();
m_statesEditorView.setCurrentState(m_statesEditorView.baseState());
}
}
void ViewManager::switchStateEditorViewToSavedState()
{
if (m_savedState.isValid() && m_statesEditorView.isAttached())
m_statesEditorView.setCurrentState(m_savedState);
}
void ViewManager::resetPropertyEditorView()
{
m_propertyEditorView.resetView();
}
void ViewManager::detachViewsExceptRewriterAndComponetView()
{
switchStateEditorViewToBaseState();
currentModel()->detachView(DesignerActionManager::view());
currentModel()->detachView(&m_formEditorView);
currentModel()->detachView(&m_navigatorView);
currentModel()->detachView(&m_itemLibraryView);
currentModel()->detachView(&m_statesEditorView);
currentModel()->detachView(&m_propertyEditorView);
currentModel()->setNodeInstanceView(0);
}
void ViewManager::attachItemLibraryView()
{
setItemLibraryViewResourcePath(QFileInfo(currentDesignDocument()->fileName()).absolutePath());
currentModel()->attachView(&m_itemLibraryView);
}
void ViewManager::attachComponentView()
{
documentModel()->attachView(&m_componentView);
QObject::connect(m_componentView.action(), SIGNAL(currentComponentChanged(ModelNode)), currentDesignDocument(), SLOT(changeCurrentModelTo(ModelNode)));
}
void ViewManager::detachComponentView()
{
QObject::disconnect(m_componentView.action(), SIGNAL(currentComponentChanged(ModelNode)), currentDesignDocument(), SLOT(changeCurrentModelTo(ModelNode)));
documentModel()->detachView(&m_componentView);
}
void ViewManager::attachViewsExceptRewriterAndComponetView()
{
attachNodeInstanceView();
currentModel()->attachView(&m_formEditorView);
currentModel()->attachView(&m_navigatorView);
attachItemLibraryView();
currentModel()->attachView(&m_statesEditorView);
currentModel()->attachView(&m_propertyEditorView);
currentModel()->attachView(DesignerActionManager::view());
switchStateEditorViewToSavedState();
}
void ViewManager::setItemLibraryViewResourcePath(const QString &resourcePath)
{
m_itemLibraryView.setResourcePath(resourcePath);
}
void ViewManager::setComponentNode(const ModelNode &componentNode)
{
qDebug() << __FUNCTION__ << componentNode;
m_componentView.setComponentNode(componentNode);
}
void ViewManager::setNodeInstanceViewQtPath(const QString &qtPath)
{
m_nodeInstanceView.setPathToQt(qtPath);
}
QWidget *ViewManager::formEditorWidget()
{
return m_formEditorView.widget();
}
QWidget *ViewManager::propertyEditorWidget()
{
return m_propertyEditorView.widget();
}
QWidget *ViewManager::itemLibraryWidget()
{
return m_itemLibraryView.widget();
}
QWidget *ViewManager::navigatorWidget()
{
return m_navigatorView.widget();
}
QWidget *ViewManager::statesEditorWidget()
{
return m_statesEditorView.widget();
}
void ViewManager::pushFileOnCrambleBar(const QString &fileName)
{
m_formEditorView.formEditorWidget()->formEditorCrumbleBar()->pushFile(fileName);
}
void ViewManager::pushInFileComponentOnCrambleBar(const QString &componentId)
{
m_formEditorView.formEditorWidget()->formEditorCrumbleBar()->pushInFileComponent(componentId);
}
void ViewManager::nextFileIsCalledInternally()
{
m_formEditorView.formEditorWidget()->formEditorCrumbleBar()->nextFileIsCalledInternally();
}
Model *ViewManager::currentModel() const
{
return currentDesignDocument()->currentModel();
}
Model *ViewManager::documentModel() const
{
return currentDesignDocument()->documentModel();
}
} // namespace QmlDesigner

View File

@@ -31,14 +31,13 @@
#include "qmldesignerconstants.h" #include "qmldesignerconstants.h"
#include "styledoutputpaneplaceholder.h" #include "styledoutputpaneplaceholder.h"
#include "designmodecontext.h" #include "designmodecontext.h"
#include "qmldesignerplugin.h"
#include <model.h> #include <model.h>
#include <rewriterview.h> #include <rewriterview.h>
#include <formeditorwidget.h>
#include <stateseditorwidget.h>
#include <itemlibrarywidget.h>
#include <componentaction.h> #include <componentaction.h>
#include <toolbox.h> #include <toolbox.h>
#include <itemlibrarywidget.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/designmode.h> #include <coreplugin/designmode.h>
@@ -93,8 +92,6 @@ const char SB_OPENDOCUMENTS[] = "OpenDocuments";
namespace QmlDesigner { namespace QmlDesigner {
namespace Internal { namespace Internal {
DesignModeWidget *DesignModeWidget::s_instance = 0;
DocumentWarningWidget::DocumentWarningWidget(DesignModeWidget *parent) : DocumentWarningWidget::DocumentWarningWidget(DesignModeWidget *parent) :
Utils::FakeToolTip(parent), Utils::FakeToolTip(parent),
m_errorMessage(new QLabel(tr("Placeholder"), this)), m_errorMessage(new QLabel(tr("Placeholder"), this)),
@@ -137,13 +134,13 @@ void DocumentWarningWidget::setError(const RewriterView::Error &error)
class ItemLibrarySideBarItem : public Core::SideBarItem class ItemLibrarySideBarItem : public Core::SideBarItem
{ {
public: public:
explicit ItemLibrarySideBarItem(ItemLibraryWidget *widget, const QString &id); explicit ItemLibrarySideBarItem(QWidget *widget, const QString &id);
virtual ~ItemLibrarySideBarItem(); virtual ~ItemLibrarySideBarItem();
virtual QList<QToolButton *> createToolBarWidgets(); virtual QList<QToolButton *> createToolBarWidgets();
}; };
ItemLibrarySideBarItem::ItemLibrarySideBarItem(ItemLibraryWidget *widget, const QString &id) : Core::SideBarItem(widget, id) {} ItemLibrarySideBarItem::ItemLibrarySideBarItem(QWidget *widget, const QString &id) : Core::SideBarItem(widget, id) {}
ItemLibrarySideBarItem::~ItemLibrarySideBarItem() ItemLibrarySideBarItem::~ItemLibrarySideBarItem()
{ {
@@ -158,13 +155,13 @@ QList<QToolButton *> ItemLibrarySideBarItem::createToolBarWidgets()
class NavigatorSideBarItem : public Core::SideBarItem class NavigatorSideBarItem : public Core::SideBarItem
{ {
public: public:
explicit NavigatorSideBarItem(NavigatorWidget *widget, const QString &id); explicit NavigatorSideBarItem(QWidget *widget, const QString &id);
virtual ~NavigatorSideBarItem(); virtual ~NavigatorSideBarItem();
virtual QList<QToolButton *> createToolBarWidgets(); virtual QList<QToolButton *> createToolBarWidgets();
}; };
NavigatorSideBarItem::NavigatorSideBarItem(NavigatorWidget *widget, const QString &id) : Core::SideBarItem(widget, id) {} NavigatorSideBarItem::NavigatorSideBarItem(QWidget *widget, const QString &id) : Core::SideBarItem(widget, id) {}
NavigatorSideBarItem::~NavigatorSideBarItem() NavigatorSideBarItem::~NavigatorSideBarItem()
{ {
@@ -185,7 +182,6 @@ void DocumentWarningWidget::goToError()
// ---------- DesignModeWidget // ---------- DesignModeWidget
DesignModeWidget::DesignModeWidget(QWidget *parent) : DesignModeWidget::DesignModeWidget(QWidget *parent) :
QWidget(parent), QWidget(parent),
m_syncWithTextEdit(false),
m_mainSplitter(0), m_mainSplitter(0),
m_leftSideBar(0), m_leftSideBar(0),
m_rightSideBar(0), m_rightSideBar(0),
@@ -196,41 +192,10 @@ DesignModeWidget::DesignModeWidget(QWidget *parent) :
m_navigatorHistoryCounter(-1), m_navigatorHistoryCounter(-1),
m_keepNavigatorHistory(false) m_keepNavigatorHistory(false)
{ {
s_instance = this;
m_undoAction = new QAction(tr("&Undo"), this);
connect(m_undoAction, SIGNAL(triggered()), this, SLOT(undo()));
m_redoAction = new QAction(tr("&Redo"), this);
connect(m_redoAction, SIGNAL(triggered()), this, SLOT(redo()));
m_deleteAction = new Utils::ParameterAction(tr("Delete"), tr("Delete \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
connect(m_deleteAction, SIGNAL(triggered()), this, SLOT(deleteSelected()));
m_cutAction = new Utils::ParameterAction(tr("Cu&t"), tr("Cut \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
connect(m_cutAction, SIGNAL(triggered()), this, SLOT(cutSelected()));
m_copyAction = new Utils::ParameterAction(tr("&Copy"), tr("Copy \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
connect(m_copyAction, SIGNAL(triggered()), this, SLOT(copySelected()));
m_pasteAction = new Utils::ParameterAction(tr("&Paste"), tr("Paste \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
connect(m_pasteAction, SIGNAL(triggered()), this, SLOT(paste()));
m_selectAllAction = new Utils::ParameterAction(tr("Select &All"), tr("Select All \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
connect(m_selectAllAction, SIGNAL(triggered()), this, SLOT(selectAll()));
m_hideSidebarsAction = new QAction(tr("Toggle Full Screen"), this);
connect(m_hideSidebarsAction, SIGNAL(triggered()), this, SLOT(toggleSidebars()));
m_restoreDefaultViewAction = new QAction(tr("&Restore Default View"), this);
m_goIntoComponentAction = new QAction(tr("&Go into Component"), this);
connect(m_restoreDefaultViewAction, SIGNAL(triggered()), SLOT(restoreDefaultView()));
connect(m_goIntoComponentAction, SIGNAL(triggered()), SLOT(goIntoComponent()));
m_toggleLeftSidebarAction = new QAction(tr("Toggle &Left Sidebar"), this);
connect(m_toggleLeftSidebarAction, SIGNAL(triggered()), SLOT(toggleLeftSidebar()));
m_toggleRightSidebarAction = new QAction(tr("Toggle &Right Sidebar"), this);
connect(m_toggleRightSidebarAction, SIGNAL(triggered()), SLOT(toggleRightSidebar()));
m_outputPlaceholderSplitter = new Core::MiniSplitter; m_outputPlaceholderSplitter = new Core::MiniSplitter;
m_outputPanePlaceholder = new StyledOutputpanePlaceHolder(Core::DesignMode::instance(), m_outputPlaceholderSplitter); m_outputPanePlaceholder = new StyledOutputpanePlaceHolder(Core::DesignMode::instance(), m_outputPlaceholderSplitter);
} }
DesignModeWidget::~DesignModeWidget()
{
s_instance = 0;
}
void DesignModeWidget::restoreDefaultView() void DesignModeWidget::restoreDefaultView()
{ {
QSettings *settings = Core::ICore::settings(); QSettings *settings = Core::ICore::settings();
@@ -265,19 +230,17 @@ void DesignModeWidget::toggleSidebars()
m_leftSideBar->setVisible(m_showSidebars); m_leftSideBar->setVisible(m_showSidebars);
if (m_rightSideBar) if (m_rightSideBar)
m_rightSideBar->setVisible(m_showSidebars); m_rightSideBar->setVisible(m_showSidebars);
if (!m_statesEditorView.isNull())
m_statesEditorView->widget()->setVisible(m_showSidebars); viewManager().statesEditorWidget()->setVisible(m_showSidebars);
} }
void DesignModeWidget::showEditor(Core::IEditor *editor) void DesignModeWidget::showEditor(Core::IEditor *editor)
{ {
if (m_textEditor && editor) if (textEditor()
if (m_textEditor->document()->fileName() != editor->document()->fileName()) { && editor
if (!m_keepNavigatorHistory) && textEditor()->document()->fileName() != editor->document()->fileName())
addNavigatorHistoryEntry(editor->document()->fileName()); setupNavigatorHistory(editor);
setupNavigatorHistory();
}
// //
// Prevent recursive calls to function by explicitly managing initialization status // Prevent recursive calls to function by explicitly managing initialization status
@@ -291,132 +254,16 @@ void DesignModeWidget::showEditor(Core::IEditor *editor)
setup(); setup();
} }
QString fileName;
QPlainTextEdit *textEdit = 0;
TextEditor::ITextEditor *textEditor = 0;
if (editor) { if (textEditor())
fileName = editor->document()->fileName(); m_fakeToolBar->addEditor(textEditor());
textEdit = qobject_cast<QPlainTextEdit*>(editor->widget());
textEditor = qobject_cast<TextEditor::ITextEditor*>(editor);
if (textEditor)
m_fakeToolBar->addEditor(textEditor);
}
if (debug)
qDebug() << Q_FUNC_INFO << fileName;
if (textEdit)
m_currentTextEdit = textEdit;
if (textEditor)
m_textEditor = textEditor;
DesignDocumentController *document = 0;
if (textEdit && textEditor && fileName.endsWith(QLatin1String(".qml"))) {
if (m_documentHash.contains(textEdit)) {
document = m_documentHash.value(textEdit).data();
} else {
DesignDocumentController *newDocument = new DesignDocumentController(this);
newDocument->setNodeInstanceView(m_nodeInstanceView.data());
newDocument->setPropertyEditorView(m_propertyEditorView.data());
newDocument->setNavigator(m_navigatorView.data());
newDocument->setStatesEditorView(m_statesEditorView.data());
newDocument->setItemLibraryView(m_itemLibraryView.data());
newDocument->setFormEditorView(m_formEditorView.data());
newDocument->setComponentView(m_componentView.data());
newDocument->setFileName(fileName); setCurrentDesignDocument(currentDesignDocument());
document = newDocument;
m_documentHash.insert(textEdit, document);
}
}
setCurrentDocument(document);
m_initStatus = Initialized; m_initStatus = Initialized;
} }
void DesignModeWidget::closeEditors(QList<Core::IEditor*> editors)
{
foreach (Core::IEditor* editor, editors) {
if (QPlainTextEdit *textEdit = qobject_cast<QPlainTextEdit*>(editor->widget())) {
if (m_currentTextEdit.data() == textEdit)
setCurrentDocument(0);
if (m_documentHash.contains(textEdit)) {
if (debug)
qDebug() << Q_FUNC_INFO << editor->document()->fileName();
DesignDocumentController *document = m_documentHash.take(textEdit).data();
delete document;
}
}
}
}
QAction *DesignModeWidget::undoAction() const
{
return m_undoAction;
}
QAction *DesignModeWidget::redoAction() const
{
return m_redoAction;
}
QAction *DesignModeWidget::deleteAction() const
{
return m_deleteAction;
}
QAction *DesignModeWidget::cutAction() const
{
return m_cutAction;
}
QAction *DesignModeWidget::copyAction() const
{
return m_copyAction;
}
QAction *DesignModeWidget::pasteAction() const
{
return m_pasteAction;
}
QAction *DesignModeWidget::selectAllAction() const
{
return m_selectAllAction;
}
QAction *DesignModeWidget::hideSidebarsAction() const
{
return m_hideSidebarsAction;
}
QAction *DesignModeWidget::toggleLeftSidebarAction() const
{
return m_toggleLeftSidebarAction;
}
QAction *DesignModeWidget::toggleRightSidebarAction() const
{
return m_toggleRightSidebarAction;
}
QAction *DesignModeWidget::restoreDefaultViewAction() const
{
return m_restoreDefaultViewAction;
}
QAction *DesignModeWidget::goIntoComponentAction() const
{
return m_goIntoComponentAction;
}
void DesignModeWidget::readSettings() void DesignModeWidget::readSettings()
{ {
QSettings *settings = Core::ICore::settings(); QSettings *settings = Core::ICore::settings();
@@ -443,98 +290,25 @@ void DesignModeWidget::saveSettings()
settings->endGroup(); settings->endGroup();
} }
void DesignModeWidget::undo() void DesignModeWidget::enableWidgets()
{
if (m_currentDesignDocumentController)
m_currentDesignDocumentController->undo();
}
void DesignModeWidget::redo()
{
if (m_currentDesignDocumentController)
m_currentDesignDocumentController->redo();
}
void DesignModeWidget::deleteSelected()
{
if (m_currentDesignDocumentController)
m_currentDesignDocumentController->deleteSelected();
}
void DesignModeWidget::cutSelected()
{
if (m_currentDesignDocumentController)
m_currentDesignDocumentController->cutSelected();
}
void DesignModeWidget::copySelected()
{
if (m_currentDesignDocumentController)
m_currentDesignDocumentController->copySelected();
}
void DesignModeWidget::paste()
{
if (m_currentDesignDocumentController)
m_currentDesignDocumentController->paste();
}
void DesignModeWidget::selectAll()
{
if (m_currentDesignDocumentController)
m_currentDesignDocumentController->selectAll();
}
void DesignModeWidget::closeCurrentEditor()
{
}
void DesignModeWidget::undoAvailable(bool isAvailable)
{
DesignDocumentController *documentController = qobject_cast<DesignDocumentController*>(sender());
if (m_currentDesignDocumentController &&
m_currentDesignDocumentController.data() == documentController) {
m_undoAction->setEnabled(isAvailable);
}
}
void DesignModeWidget::redoAvailable(bool isAvailable)
{
DesignDocumentController *documentController = qobject_cast<DesignDocumentController*>(sender());
if (m_currentDesignDocumentController &&
m_currentDesignDocumentController.data() == documentController) {
m_redoAction->setEnabled(isAvailable);
}
}
void DesignModeWidget::goIntoComponent()
{
if (m_currentDesignDocumentController)
m_currentDesignDocumentController->goIntoComponent();
}
void DesignModeWidget::enable()
{ {
if (debug) if (debug)
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
m_warningWidget->setVisible(false); m_warningWidget->setVisible(false);
m_formEditorView->widget()->setEnabled(true); viewManager().formEditorWidget()->setEnabled(true);
m_statesEditorView->widget()->setEnabled(true); viewManager().statesEditorWidget()->setEnabled(true);
m_leftSideBar->setEnabled(true); m_leftSideBar->setEnabled(true);
m_rightSideBar->setEnabled(true); m_rightSideBar->setEnabled(true);
m_isDisabled = false; m_isDisabled = false;
} }
void DesignModeWidget::disable(const QList<RewriterView::Error> &errors) void DesignModeWidget::disableWidgets()
{ {
if (debug) if (debug)
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
Q_ASSERT(!errors.isEmpty());
m_warningWidget->setError(errors.first()); viewManager().formEditorWidget()->setEnabled(false);
m_warningWidget->setVisible(true); viewManager().statesEditorWidget()->setEnabled(false);
m_warningWidget->move(width() / 2, height() / 2);
m_formEditorView->widget()->setEnabled(false);
m_statesEditorView->widget()->setEnabled(false);
m_leftSideBar->setEnabled(false); m_leftSideBar->setEnabled(false);
m_rightSideBar->setEnabled(false); m_rightSideBar->setEnabled(false);
m_isDisabled = true; m_isDisabled = true;
@@ -545,112 +319,27 @@ void DesignModeWidget::updateErrorStatus(const QList<RewriterView::Error> &error
if (debug) if (debug)
qDebug() << Q_FUNC_INFO << errors.count(); qDebug() << Q_FUNC_INFO << errors.count();
if (m_isDisabled && errors.isEmpty()) if (m_isDisabled && errors.isEmpty()) {
enable(); enableWidgets();
else if (!errors.isEmpty()) } else if (!errors.isEmpty()) {
disable(errors); disableWidgets();
} showErrorMessage(errors);
void DesignModeWidget::setAutoSynchronization(bool sync)
{
if (debug)
qDebug() << Q_FUNC_INFO << sync;
RewriterView *rewriter = m_currentDesignDocumentController->rewriterView();
m_currentDesignDocumentController->blockModelSync(!sync);
if (sync) {
if (rewriter && m_currentDesignDocumentController->model())
rewriter->setSelectedModelNodes(QList<ModelNode>());
// text editor -> visual editor
if (!m_currentDesignDocumentController->model()) {
m_currentDesignDocumentController->loadMaster(m_currentTextEdit.data());
} else {
m_currentDesignDocumentController->loadCurrentModel();
m_componentView->resetView();
}
QList<RewriterView::Error> errors = m_currentDesignDocumentController->qmlErrors();
if (errors.isEmpty()) {
// set selection to text cursor
const int cursorPos = m_currentTextEdit->textCursor().position();
ModelNode node = nodeForPosition(cursorPos);
if (rewriter && node.isValid())
rewriter->setSelectedModelNodes(QList<ModelNode>() << node);
enable();
} else {
disable(errors);
}
connect(m_currentDesignDocumentController.data(), SIGNAL(qmlErrorsChanged(QList<RewriterView::Error>)),
this, SLOT(updateErrorStatus(QList<RewriterView::Error>)));
} else {
if (m_currentDesignDocumentController->model() && m_currentDesignDocumentController->qmlErrors().isEmpty()) {
RewriterView *rewriter = m_currentDesignDocumentController->rewriterView();
// visual editor -> text editor
ModelNode selectedNode;
if (!rewriter->selectedModelNodes().isEmpty())
selectedNode = rewriter->selectedModelNodes().first();
if (selectedNode.isValid()) {
const int nodeOffset = rewriter->nodeOffset(selectedNode);
if (nodeOffset > 0) {
const ModelNode currentSelectedNode
= nodeForPosition(m_currentTextEdit->textCursor().position());
if (currentSelectedNode != selectedNode) {
int line, column;
m_textEditor->convertPosition(nodeOffset, &line, &column);
m_textEditor->gotoLine(line, column);
}
}
}
}
disconnect(m_currentDesignDocumentController.data(), SIGNAL(qmlErrorsChanged(QList<RewriterView::Error>)),
this, SLOT(updateErrorStatus(QList<RewriterView::Error>)));
} }
} }
void DesignModeWidget::setCurrentDocument(DesignDocumentController *newDesignDocumentController) TextEditor::ITextEditor *DesignModeWidget::textEditor() const
{
return currentDesignDocument()->textEditor();
}
void DesignModeWidget::setCurrentDesignDocument(DesignDocument *newDesignDocument)
{ {
if (debug) if (debug)
qDebug() << Q_FUNC_INFO << newDesignDocumentController; qDebug() << Q_FUNC_INFO << newDesignDocument;
if (m_currentDesignDocumentController.data() == newDesignDocumentController) //viewManager().setDesignDocument(newDesignDocument);
return;
if (m_currentDesignDocumentController) {
setAutoSynchronization(false);
saveSettings();
}
if (currentDesignDocumentController()) {
disconnect(currentDesignDocumentController(), SIGNAL(undoAvailable(bool)),
this, SLOT(undoAvailable(bool)));
disconnect(currentDesignDocumentController(), SIGNAL(redoAvailable(bool)),
this, SLOT(redoAvailable(bool)));
}
m_currentDesignDocumentController = newDesignDocumentController;
if (currentDesignDocumentController()) {
connect(currentDesignDocumentController(), SIGNAL(undoAvailable(bool)),
this, SLOT(undoAvailable(bool)));
connect(currentDesignDocumentController(), SIGNAL(redoAvailable(bool)),
this, SLOT(redoAvailable(bool)));
}
if (m_currentDesignDocumentController) {
setAutoSynchronization(true);
m_undoAction->setEnabled(m_currentDesignDocumentController->isUndoAvailable());
m_redoAction->setEnabled(m_currentDesignDocumentController->isRedoAvailable());
} else {
//detach all views
m_undoAction->setEnabled(false);
m_redoAction->setEnabled(false);
}
} }
void DesignModeWidget::setup() void DesignModeWidget::setup()
@@ -687,20 +376,6 @@ void DesignModeWidget::setup()
} }
} }
m_nodeInstanceView = new NodeInstanceView(this);
connect(m_nodeInstanceView.data(), SIGNAL(qmlPuppetCrashed()), this, SLOT(qmlPuppetCrashed()));
// Sidebar takes ownership
m_navigatorView = new NavigatorView;
m_propertyEditorView = new PropertyEditor(this);
m_itemLibraryView = new ItemLibraryView(this);
m_statesEditorView = new StatesEditorView(this);
m_formEditorView = new FormEditorView(this);
connect(m_formEditorView->crumblePath(), SIGNAL(elementClicked(QVariant)), this, SLOT(onCrumblePathElementClicked(QVariant)));
m_componentView = new ComponentView(this);
m_formEditorView->widget()->toolBox()->addLeftSideAction(m_componentView->action());
m_fakeToolBar = Core::EditorManager::createToolBar(this); m_fakeToolBar = Core::EditorManager::createToolBar(this);
m_mainSplitter = new MiniSplitter(this); m_mainSplitter = new MiniSplitter(this);
@@ -710,9 +385,9 @@ void DesignModeWidget::setup()
m_warningWidget = new DocumentWarningWidget(this); m_warningWidget = new DocumentWarningWidget(this);
m_warningWidget->setVisible(false); m_warningWidget->setVisible(false);
Core::SideBarItem *navigatorItem = new NavigatorSideBarItem(m_navigatorView->widget(), QLatin1String(SB_NAVIGATOR)); Core::SideBarItem *navigatorItem = new NavigatorSideBarItem(viewManager().navigatorWidget(), QLatin1String(SB_NAVIGATOR));
Core::SideBarItem *libraryItem = new ItemLibrarySideBarItem(m_itemLibraryView->widget(), QLatin1String(SB_LIBRARY)); Core::SideBarItem *libraryItem = new ItemLibrarySideBarItem(viewManager().itemLibraryWidget(), QLatin1String(SB_LIBRARY));
Core::SideBarItem *propertiesItem = new Core::SideBarItem(m_propertyEditorView->widget(), QLatin1String(SB_PROPERTIES)); Core::SideBarItem *propertiesItem = new Core::SideBarItem(viewManager().propertyEditorWidget(), QLatin1String(SB_PROPERTIES));
// default items // default items
m_sideBarItems << navigatorItem << libraryItem << propertiesItem; m_sideBarItems << navigatorItem << libraryItem << propertiesItem;
@@ -748,7 +423,9 @@ void DesignModeWidget::setup()
connect(m_fakeToolBar, SIGNAL(closeClicked()), this, SLOT(closeCurrentEditor())); connect(m_fakeToolBar, SIGNAL(closeClicked()), this, SLOT(closeCurrentEditor()));
connect(m_fakeToolBar, SIGNAL(goForwardClicked()), this, SLOT(onGoForwardClicked())); connect(m_fakeToolBar, SIGNAL(goForwardClicked()), this, SLOT(onGoForwardClicked()));
connect(m_fakeToolBar, SIGNAL(goBackClicked()), this, SLOT(onGoBackClicked())); connect(m_fakeToolBar, SIGNAL(goBackClicked()), this, SLOT(onGoBackClicked()));
setupNavigatorHistory();
if (currentDesignDocument())
setupNavigatorHistory(currentDesignDocument()->textEditor());
// right area: // right area:
QWidget *centerWidget = new QWidget; QWidget *centerWidget = new QWidget;
@@ -758,16 +435,16 @@ void DesignModeWidget::setup()
rightLayout->setSpacing(0); rightLayout->setSpacing(0);
rightLayout->addWidget(m_fakeToolBar); rightLayout->addWidget(m_fakeToolBar);
//### we now own these here //### we now own these here
rightLayout->addWidget(m_statesEditorView->widget()); rightLayout->addWidget(viewManager().statesEditorWidget());
FormEditorContext *formEditorContext = new FormEditorContext(m_formEditorView->widget()); FormEditorContext *formEditorContext = new FormEditorContext(viewManager().formEditorWidget());
Core::ICore::addContextObject(formEditorContext); Core::ICore::addContextObject(formEditorContext);
NavigatorContext *navigatorContext = new NavigatorContext(m_navigatorView->widget()); NavigatorContext *navigatorContext = new NavigatorContext(viewManager().navigatorWidget());
Core::ICore::addContextObject(navigatorContext); Core::ICore::addContextObject(navigatorContext);
// editor and output panes // editor and output panes
m_outputPlaceholderSplitter->addWidget(m_formEditorView->widget()); m_outputPlaceholderSplitter->addWidget(viewManager().formEditorWidget());
m_outputPlaceholderSplitter->addWidget(m_outputPanePlaceholder); m_outputPlaceholderSplitter->addWidget(m_outputPanePlaceholder);
m_outputPlaceholderSplitter->setStretchFactor(0, 10); m_outputPlaceholderSplitter->setStretchFactor(0, 10);
m_outputPlaceholderSplitter->setStretchFactor(1, 0); m_outputPlaceholderSplitter->setStretchFactor(1, 0);
@@ -791,7 +468,7 @@ void DesignModeWidget::setup()
mainLayout->addWidget(m_mainSplitter); mainLayout->addWidget(m_mainSplitter);
m_warningWidget->setVisible(false); m_warningWidget->setVisible(false);
m_statesEditorView->widget()->setEnabled(true); viewManager().statesEditorWidget()->setEnabled(true);
m_leftSideBar->setEnabled(true); m_leftSideBar->setEnabled(true);
m_rightSideBar->setEnabled(true); m_rightSideBar->setEnabled(true);
m_leftSideBar->setCloseWhenEmpty(true); m_leftSideBar->setCloseWhenEmpty(true);
@@ -800,7 +477,6 @@ void DesignModeWidget::setup()
readSettings(); readSettings();
show(); show();
QApplication::processEvents();
} }
void DesignModeWidget::updateAvailableSidebarItemsRight() void DesignModeWidget::updateAvailableSidebarItemsRight()
@@ -827,8 +503,10 @@ void DesignModeWidget::qmlPuppetCrashed()
{ {
QList<RewriterView::Error> errorList; QList<RewriterView::Error> errorList;
RewriterView::Error error(tr("Qt Quick emulation layer crashed")); RewriterView::Error error(tr("Qt Quick emulation layer crashed"));
errorList << error; errorList.append(error);
disable(errorList);
disableWidgets();
showErrorMessage(errorList);
} }
void DesignModeWidget::onGoBackClicked() void DesignModeWidget::onGoBackClicked()
@@ -851,17 +529,16 @@ void DesignModeWidget::onGoForwardClicked()
} }
} }
void DesignModeWidget::onCrumblePathElementClicked(const QVariant &data) DesignDocument *DesignModeWidget::currentDesignDocument() const
{ {
currentDesignDocumentController()->setCrumbleBarInfo(data.value<CrumbleBarInfo>()); return QmlDesignerPlugin::instance()->documentManager().currentDesignDocument();
} }
DesignModeWidget *DesignModeWidget::instance() ViewManager &DesignModeWidget::viewManager()
{ {
return s_instance; return QmlDesignerPlugin::instance()->viewManager();
} }
void DesignModeWidget::resizeEvent(QResizeEvent *event) void DesignModeWidget::resizeEvent(QResizeEvent *event)
{ {
if (m_warningWidget) if (m_warningWidget)
@@ -869,35 +546,11 @@ void DesignModeWidget::resizeEvent(QResizeEvent *event)
QWidget::resizeEvent(event); QWidget::resizeEvent(event);
} }
void DesignModeWidget::setupNavigatorHistory(Core::IEditor *editor)
bool DesignModeWidget::isInNodeDefinition(int nodeOffset, int nodeLength, int cursorPos) const {
return (nodeOffset <= cursorPos) && (nodeOffset + nodeLength > cursorPos);
}
ModelNode DesignModeWidget::nodeForPosition(int cursorPos) const
{ {
RewriterView *rewriter = m_currentDesignDocumentController->rewriterView(); if (!m_keepNavigatorHistory)
QList<ModelNode> nodes = rewriter->allModelNodes(); addNavigatorHistoryEntry(editor->document()->fileName());
ModelNode bestNode;
int bestNodeOffset = -1;
foreach (const ModelNode &node, nodes) {
const int nodeOffset = rewriter->nodeOffset(node);
const int nodeLength = rewriter->nodeLength(node);
if (isInNodeDefinition(nodeOffset, nodeLength, cursorPos)
&& (nodeOffset > bestNodeOffset)) {
bestNode = node;
bestNodeOffset = nodeOffset;
}
}
return bestNode;
}
void DesignModeWidget::setupNavigatorHistory()
{
const bool canGoBack = m_navigatorHistoryCounter > 0; const bool canGoBack = m_navigatorHistoryCounter > 0;
const bool canGoForward = m_navigatorHistoryCounter < (m_navigatorHistory.size() - 1); const bool canGoForward = m_navigatorHistoryCounter < (m_navigatorHistory.size() - 1);
m_fakeToolBar->setCanGoBack(canGoBack); m_fakeToolBar->setCanGoBack(canGoBack);
@@ -914,13 +567,30 @@ void DesignModeWidget::addNavigatorHistoryEntry(const QString &fileName)
++m_navigatorHistoryCounter; ++m_navigatorHistoryCounter;
} }
void DesignModeWidget::showErrorMessage(const QList<RewriterView::Error> &errors)
{
Q_ASSERT(!errors.isEmpty());
m_warningWidget->setError(errors.first());
m_warningWidget->setVisible(true);
m_warningWidget->move(width() / 2, height() / 2);
}
QString DesignModeWidget::contextHelpId() const QString DesignModeWidget::contextHelpId() const
{ {
if (m_currentDesignDocumentController) if (currentDesignDocument())
return m_currentDesignDocumentController->contextHelpId(); return currentDesignDocument()->contextHelpId();
return QString(); return QString();
} }
void DesignModeWidget::initialize()
{
if (m_initStatus == NotInitialized) {
m_initStatus = Initializing;
setup();
}
m_initStatus = Initialized;
}
} // namespace Internal } // namespace Internal
} // namespace Designer } // namespace Designer

View File

@@ -35,7 +35,7 @@
#include <utils/faketooltip.h> #include <utils/faketooltip.h>
#include <texteditor/itexteditor.h> #include <texteditor/itexteditor.h>
#include <designdocumentcontroller.h> #include <designdocument.h>
#include <itemlibraryview.h> #include <itemlibraryview.h>
#include <navigatorwidget.h> #include <navigatorwidget.h>
#include <navigatorview.h> #include <navigatorview.h>
@@ -103,54 +103,34 @@ class DesignModeWidget : public QWidget
public: public:
explicit DesignModeWidget(QWidget *parent = 0); explicit DesignModeWidget(QWidget *parent = 0);
~DesignModeWidget();
void showEditor(Core::IEditor *editor); void showEditor(Core::IEditor *editor);
void closeEditors(const QList<Core::IEditor*> editors); void closeEditors(const QList<Core::IEditor*> editors);
QString contextHelpId() const; QString contextHelpId() const;
QAction *undoAction() const; void initialize();
QAction *redoAction() const;
QAction *deleteAction() const;
QAction *cutAction() const;
QAction *copyAction() const;
QAction *pasteAction() const;
QAction *selectAllAction() const;
QAction *hideSidebarsAction() const;
QAction *toggleLeftSidebarAction() const;
QAction *toggleRightSidebarAction() const;
QAction *restoreDefaultViewAction() const;
QAction *goIntoComponentAction() const;
void readSettings(); void readSettings();
void saveSettings(); void saveSettings();
void setAutoSynchronization(bool sync);
TextEditor::ITextEditor *textEditor() const {return m_textEditor.data(); } TextEditor::ITextEditor *textEditor() const;
static DesignModeWidget *instance(); DesignDocument *currentDesignDocument() const;
DesignDocumentController *currentDesignDocumentController() const {return m_currentDesignDocumentController.data(); } ViewManager &viewManager();
private slots: void enableWidgets();
void undo(); void disableWidgets();
void redo(); void showErrorMessage(const QList<RewriterView::Error> &errors);
void deleteSelected();
void cutSelected(); public slots:
void copySelected(); void updateErrorStatus(const QList<RewriterView::Error> &errors);
void paste(); void restoreDefaultView();
void selectAll();
void closeCurrentEditor();
void toggleSidebars(); void toggleSidebars();
void toggleLeftSidebar(); void toggleLeftSidebar();
void toggleRightSidebar(); void toggleRightSidebar();
void restoreDefaultView();
void undoAvailable(bool isAvailable);
void redoAvailable(bool isAvailable);
void goIntoComponent();
void enable(); private slots:
void disable(const QList<RewriterView::Error> &errors);
void updateErrorStatus(const QList<RewriterView::Error> &errors);
void updateAvailableSidebarItemsLeft(); void updateAvailableSidebarItemsLeft();
void updateAvailableSidebarItemsRight(); void updateAvailableSidebarItemsRight();
@@ -160,49 +140,20 @@ private slots:
void onGoBackClicked(); void onGoBackClicked();
void onGoForwardClicked(); void onGoForwardClicked();
void onCrumblePathElementClicked(const QVariant &data);
protected: protected:
void resizeEvent(QResizeEvent *event); void resizeEvent(QResizeEvent *event);
private: private: // functions
void setCurrentDocument(DesignDocumentController *newDesignDocumentController); enum InitializeStatus { NotInitialized, Initializing, Initialized };
//QStackedWidget *m_documentWidgetStack;
QHash<QPlainTextEdit*,QWeakPointer<DesignDocumentController> > m_documentHash;
QWeakPointer<DesignDocumentController> m_currentDesignDocumentController;
QWeakPointer<QPlainTextEdit> m_currentTextEdit;
QAction *m_undoAction;
QAction *m_redoAction;
QAction *m_deleteAction;
QAction *m_cutAction;
QAction *m_copyAction;
QAction *m_pasteAction;
QAction *m_selectAllAction;
QAction *m_hideSidebarsAction;
QAction *m_restoreDefaultViewAction;
QAction *m_toggleLeftSidebarAction;
QAction *m_toggleRightSidebarAction;
QAction *m_goIntoComponentAction;
QWeakPointer<ItemLibraryView> m_itemLibraryView;
QWeakPointer<NavigatorView> m_navigatorView;
QWeakPointer<PropertyEditor> m_propertyEditorView;
QWeakPointer<StatesEditorView> m_statesEditorView;
QWeakPointer<FormEditorView> m_formEditorView;
QWeakPointer<ComponentView> m_componentView;
QWeakPointer<NodeInstanceView> m_nodeInstanceView;
bool m_syncWithTextEdit;
void setCurrentDesignDocument(DesignDocument *newDesignDocument);
void setup(); void setup();
bool isInNodeDefinition(int nodeOffset, int nodeLength, int cursorPos) const; bool isInNodeDefinition(int nodeOffset, int nodeLength, int cursorPos) const;
QmlDesigner::ModelNode nodeForPosition(int cursorPos) const; QmlDesigner::ModelNode nodeForPosition(int cursorPos) const;
void setupNavigatorHistory(); void setupNavigatorHistory(Core::IEditor *editor);
void addNavigatorHistoryEntry(const QString &fileName); void addNavigatorHistoryEntry(const QString &fileName);
QWeakPointer<TextEditor::ITextEditor> m_textEditor; private: // variables
QSplitter *m_mainSplitter; QSplitter *m_mainSplitter;
Core::SideBar *m_leftSideBar; Core::SideBar *m_leftSideBar;
Core::SideBar *m_rightSideBar; Core::SideBar *m_rightSideBar;
@@ -213,15 +164,12 @@ private:
bool m_isDisabled; bool m_isDisabled;
bool m_showSidebars; bool m_showSidebars;
enum InitializeStatus { NotInitialized, Initializing, Initialized };
InitializeStatus m_initStatus; InitializeStatus m_initStatus;
DocumentWarningWidget *m_warningWidget; DocumentWarningWidget *m_warningWidget;
QStringList m_navigatorHistory; QStringList m_navigatorHistory;
int m_navigatorHistoryCounter; int m_navigatorHistoryCounter;
bool m_keepNavigatorHistory; bool m_keepNavigatorHistory;
static DesignModeWidget *s_instance;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -0,0 +1,80 @@
/****************************************************************************
**
** 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 "documentmanager.h"
#include <coreplugin/designmode.h>
#include <coreplugin/modemanager.h>
#include <qmljseditor/qmljseditorconstants.h>
namespace QmlDesigner {
DocumentManager::DocumentManager()
: QObject()
{
}
DocumentManager::~DocumentManager()
{
foreach (const QWeakPointer<DesignDocument> &designDocument, m_designDocumentHash)
delete designDocument.data();
}
void DocumentManager::setCurrentDesignDocument(Core::IEditor *editor)
{
if (editor) {
m_currentDesignDocument = m_designDocumentHash.value(editor);
if (m_currentDesignDocument == 0) {
m_currentDesignDocument = new DesignDocument;
m_designDocumentHash.insert(editor, m_currentDesignDocument);
m_currentDesignDocument->setEditor(editor);
}
} else {
m_currentDesignDocument->resetToDocumentModel();
m_currentDesignDocument.clear();
}
}
DesignDocument *DocumentManager::currentDesignDocument() const
{
return m_currentDesignDocument.data();
}
bool DocumentManager::hasCurrentDesignDocument() const
{
return m_currentDesignDocument.data();
}
void DocumentManager::removeEditors(QList<Core::IEditor *> editors)
{
foreach (Core::IEditor *editor, editors)
delete m_designDocumentHash.take(editor).data();
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,65 @@
/****************************************************************************
**
** 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_DOCUMENTMANAGER_H
#define QMLDESIGNER_DOCUMENTMANAGER_H
#include <QObject>
#include <QList>
#include <designdocument.h>
namespace Core {
class IEditor;
}
namespace QmlDesigner {
class DocumentManager : public QObject
{
Q_OBJECT
public:
DocumentManager();
~DocumentManager();
void setCurrentDesignDocument(Core::IEditor*editor);
DesignDocument *currentDesignDocument() const;
bool hasCurrentDesignDocument() const;
void removeEditors(QList<Core::IEditor*> editors);
private:
QHash<Core::IEditor *,QWeakPointer<DesignDocument> > m_designDocumentHash;
QWeakPointer<DesignDocument> m_currentDesignDocument;
};
} // namespace QmlDesigner
#endif // QMLDESIGNER_DOCUMENTMANAGER_H

View File

@@ -52,6 +52,8 @@
#include <coreplugin/mimedatabase.h> #include <coreplugin/mimedatabase.h>
#include <coreplugin/modemanager.h> #include <coreplugin/modemanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
@@ -66,9 +68,18 @@
#include <QProcessEnvironment> #include <QProcessEnvironment>
namespace QmlDesigner { namespace QmlDesigner {
namespace Internal {
BauhausPlugin *BauhausPlugin::m_pluginInstance = 0; QmlDesignerPlugin *QmlDesignerPlugin::m_instance = 0;
static bool isQmlFile(Core::IEditor *editor)
{
return editor && editor->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID;
}
static bool isInDesignerMode()
{
return Core::ModeManager::currentMode() == Core::DesignMode::instance();
}
bool shouldAssertInException() bool shouldAssertInException()
{ {
@@ -76,15 +87,8 @@ bool shouldAssertInException()
return !processEnvironment.value("QMLDESIGNER_ASSERT_ON_EXCEPTION").isEmpty(); return !processEnvironment.value("QMLDESIGNER_ASSERT_ON_EXCEPTION").isEmpty();
} }
BauhausPlugin::BauhausPlugin() : QmlDesignerPlugin::QmlDesignerPlugin() :
m_designMode(0), m_isActive(false)
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 // Exceptions should never ever assert: they are handled in a number of
@@ -101,9 +105,11 @@ BauhausPlugin::BauhausPlugin() :
Exception::setShouldAssert(shouldAssertInException()); Exception::setShouldAssert(shouldAssertInException());
} }
BauhausPlugin::~BauhausPlugin() QmlDesignerPlugin::~QmlDesignerPlugin()
{ {
Core::ICore::removeContextObject(m_context); Core::ICore::removeContextObject(m_context);
m_context = 0;
m_instance = 0;
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@@ -111,7 +117,7 @@ BauhausPlugin::~BauhausPlugin()
// INHERITED FROM ExtensionSystem::Plugin // INHERITED FROM ExtensionSystem::Plugin
// //
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
bool BauhausPlugin::initialize(const QStringList & /*arguments*/, QString *errorMessage/* = 0*/) // =0; bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *errorMessage/* = 0*/) // =0;
{ {
const Core::Context switchContext(QmlDesigner::Constants::C_QMLDESIGNER, const Core::Context switchContext(QmlDesigner::Constants::C_QMLDESIGNER,
QmlJSEditor::Constants::C_QMLJSEDITOR_ID); QmlJSEditor::Constants::C_QMLJSEDITOR_ID);
@@ -121,7 +127,7 @@ bool BauhausPlugin::initialize(const QStringList & /*arguments*/, QString *error
switchAction, QmlDesigner::Constants::SWITCH_TEXT_DESIGN, switchContext); switchAction, QmlDesigner::Constants::SWITCH_TEXT_DESIGN, switchContext);
command->setDefaultKeySequence(QKeySequence(Qt::Key_F4)); command->setDefaultKeySequence(QKeySequence(Qt::Key_F4));
m_pluginInstance = this; m_instance = this;
const QString pluginPath = Utils::HostOsInfo::isMacHost() const QString pluginPath = Utils::HostOsInfo::isMacHost()
? QString(QCoreApplication::applicationDirPath() + "/../PlugIns/QmlDesigner") ? QString(QCoreApplication::applicationDirPath() + "/../PlugIns/QmlDesigner")
@@ -132,7 +138,7 @@ bool BauhausPlugin::initialize(const QStringList & /*arguments*/, QString *error
createDesignModeWidget(); createDesignModeWidget();
connect(switchAction, SIGNAL(triggered()), this, SLOT(switchTextDesign())); connect(switchAction, SIGNAL(triggered()), this, SLOT(switchTextDesign()));
addAutoReleasedObject(new SettingsPage); addAutoReleasedObject(new Internal::SettingsPage);
m_settings.fromSettings(Core::ICore::settings()); m_settings.fromSettings(Core::ICore::settings());
@@ -142,240 +148,295 @@ bool BauhausPlugin::initialize(const QStringList & /*arguments*/, QString *error
return true; return true;
} }
void BauhausPlugin::createDesignModeWidget() void QmlDesignerPlugin::createDesignModeWidget()
{ {
m_editorManager = Core::ICore::editorManager(); m_mainWidget = new Internal::DesignModeWidget;
Core::ActionContainer *editMenu = Core::ActionManager::actionContainer(Core::Constants::M_EDIT);
m_mainWidget = new DesignModeWidget; m_context = new Internal::DesignModeContext(m_mainWidget);
m_context = new DesignModeContext(m_mainWidget);
Core::ICore::addContextObject(m_context); Core::ICore::addContextObject(m_context);
Core::Context qmlDesignerMainContext(Constants::C_QMLDESIGNER); Core::Context qmlDesignerMainContext(Constants::C_QMLDESIGNER);
Core::Context qmlDesignerFormEditorContext(Constants::C_QMLFORMEDITOR); Core::Context qmlDesignerFormEditorContext(Constants::C_QMLFORMEDITOR);
Core::Context qmlDesignerNavigatorContext(Constants::C_QMLNAVIGATOR); Core::Context qmlDesignerNavigatorContext(Constants::C_QMLNAVIGATOR);
// Revert to saved m_context->context().add(qmlDesignerMainContext);
Core::ActionManager::registerAction(m_revertToSavedAction, m_context->context().add(qmlDesignerFormEditorContext);
Core::Constants::REVERTTOSAVED, qmlDesignerMainContext); m_context->context().add(qmlDesignerNavigatorContext);
connect(m_revertToSavedAction, SIGNAL(triggered()), m_editorManager, SLOT(revertToSaved())); m_context->context().add(ProjectExplorer::Constants::LANG_QMLJS);
//Save m_shortCutManager.registerActions();
Core::ActionManager::registerAction(m_saveAction, Core::Constants::SAVE, qmlDesignerMainContext);
connect(m_saveAction, SIGNAL(triggered()), m_editorManager, SLOT(saveDocument()));
//Save As connect(Core::ICore::editorManager(),
Core::ActionManager::registerAction(m_saveAsAction, Core::Constants::SAVEAS, qmlDesignerMainContext); SIGNAL(currentEditorChanged(Core::IEditor*)),
connect(m_saveAsAction, SIGNAL(triggered()), m_editorManager, SLOT(saveDocumentAs())); this,
SLOT(onCurrentEditorChanged(Core::IEditor*)));
//Close Editor connect(Core::ICore::editorManager(),
Core::ActionManager::registerAction(m_closeCurrentEditorAction, Core::Constants::CLOSE, qmlDesignerMainContext); SIGNAL(editorsClosed(QList<Core::IEditor*>)),
connect(m_closeCurrentEditorAction, SIGNAL(triggered()), m_editorManager, SLOT(closeEditor())); this,
SLOT(onTextEditorsClosed(QList<Core::IEditor*>)));
//Close All // connect(Core::ICore::editorManager(), SIGNAL(currentEditorChanged(Core::IEditor*)),
Core::ActionManager::registerAction(m_closeAllEditorsAction, Core::Constants::CLOSEALL, qmlDesignerMainContext); // &m_documentManager, SLOT(currentTextEditorChanged(Core::IEditor*)));
connect(m_closeAllEditorsAction, SIGNAL(triggered()), m_editorManager, SLOT(closeAllEditors()));
//Close All Others Action // connect(Core::ICore::instance(), SIGNAL(contextChanged(Core::IContext*,Core::Context)),
Core::ActionManager::registerAction(m_closeOtherEditorsAction, Core::Constants::CLOSEOTHERS, qmlDesignerMainContext); // this, SLOT(contextChanged(Core::IContext*,Core::Context)));
connect(m_closeOtherEditorsAction, SIGNAL(triggered()), m_editorManager, SLOT(closeOtherEditors()));
// Undo / Redo connect(Core::ModeManager::instance(),
Core::ActionManager::registerAction(m_mainWidget->undoAction(), Core::Constants::UNDO, qmlDesignerMainContext); SIGNAL(currentModeChanged(Core::IMode*,Core::IMode*)),
Core::ActionManager::registerAction(m_mainWidget->redoAction(), Core::Constants::REDO, qmlDesignerMainContext); SLOT(onCurrentModeChanged(Core::IMode*,Core::IMode*)));
Core::Command *command;
//GoIntoComponent
command = Core::ActionManager::registerAction(m_mainWidget->goIntoComponentAction(),
Constants::GO_INTO_COMPONENT, qmlDesignerMainContext);
command->setDefaultKeySequence(QKeySequence(Qt::Key_F2));
//Edit Menu
command = Core::ActionManager::registerAction(m_mainWidget->deleteAction(),
QmlDesigner::Constants::DELETE, qmlDesignerFormEditorContext);
command = Core::ActionManager::registerAction(m_mainWidget->deleteAction(),
QmlDesigner::Constants::DELETE, qmlDesignerNavigatorContext);
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 = Core::ActionManager::registerAction(m_mainWidget->cutAction(),
Core::Constants::CUT, qmlDesignerFormEditorContext);
command = Core::ActionManager::registerAction(m_mainWidget->cutAction(),
Core::Constants::CUT, qmlDesignerNavigatorContext);
command->setDefaultKeySequence(QKeySequence::Cut);
editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE);
command = Core::ActionManager::registerAction(m_mainWidget->copyAction(),
Core::Constants::COPY, qmlDesignerFormEditorContext);
command = Core::ActionManager::registerAction(m_mainWidget->copyAction(),
Core::Constants::COPY, qmlDesignerNavigatorContext);
command->setDefaultKeySequence(QKeySequence::Copy);
editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE);
command = Core::ActionManager::registerAction(m_mainWidget->pasteAction(),
Core::Constants::PASTE, qmlDesignerFormEditorContext);
command = Core::ActionManager::registerAction(m_mainWidget->pasteAction(),
Core::Constants::PASTE, qmlDesignerNavigatorContext);
command->setDefaultKeySequence(QKeySequence::Paste);
editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE);
command = Core::ActionManager::registerAction(m_mainWidget->selectAllAction(),
Core::Constants::SELECTALL, qmlDesignerFormEditorContext);
command = Core::ActionManager::registerAction(m_mainWidget->selectAllAction(),
Core::Constants::SELECTALL, qmlDesignerNavigatorContext);
command->setDefaultKeySequence(QKeySequence::SelectAll);
editMenu->addAction(command, Core::Constants::G_EDIT_SELECTALL);
Core::ActionContainer *viewsMenu = Core::ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS);
command = Core::ActionManager::registerAction(m_mainWidget->toggleLeftSidebarAction(),
Constants::TOGGLE_LEFT_SIDEBAR, qmlDesignerMainContext);
command->setAttribute(Core::Command::CA_Hide);
command->setDefaultKeySequence(QKeySequence("Ctrl+Alt+0"));
viewsMenu->addAction(command);
command = Core::ActionManager::registerAction(m_mainWidget->toggleRightSidebarAction(),
Constants::TOGGLE_RIGHT_SIDEBAR, qmlDesignerMainContext);
command->setAttribute(Core::Command::CA_Hide);
command->setDefaultKeySequence(QKeySequence("Ctrl+Alt+Shift+0"));
viewsMenu->addAction(command);
command = Core::ActionManager::registerAction(m_mainWidget->restoreDefaultViewAction(),
Constants::RESTORE_DEFAULT_VIEW, qmlDesignerMainContext);
command->setAttribute(Core::Command::CA_Hide);
viewsMenu->addAction(command);
command = Core::ActionManager::registerAction(m_mainWidget->hideSidebarsAction(),
Core::Constants::TOGGLE_SIDEBAR, qmlDesignerMainContext);
if (Utils::HostOsInfo::isMacHost()) {
// 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);
}
connect(m_editorManager, SIGNAL(currentEditorChanged(Core::IEditor*)),
this, SLOT(updateEditor(Core::IEditor*)));
connect(m_editorManager, SIGNAL(editorsClosed(QList<Core::IEditor*>)),
this, SLOT(textEditorsClosed(QList<Core::IEditor*>)));
connect(Core::ICore::instance(), SIGNAL(contextChanged(Core::IContext*,Core::Context)),
this, SLOT(contextChanged(Core::IContext*,Core::Context)));
} }
void BauhausPlugin::updateEditor(Core::IEditor *editor) void QmlDesignerPlugin::showDesigner()
{ {
if (editor && editor->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID Q_ASSERT(!m_documentManager.hasCurrentDesignDocument());
&& Core::ModeManager::currentMode() == m_designMode)
m_shortCutManager.disconnectUndoActions(currentDesignDocument());
m_documentManager.setCurrentDesignDocument(Core::EditorManager::currentEditor());
m_shortCutManager.connectUndoActions(currentDesignDocument());
m_mainWidget->initialize();
if (m_documentManager.hasCurrentDesignDocument()) {
activateAutoSynchronization();
m_viewManager.pushFileOnCrambleBar(m_documentManager.currentDesignDocument()->fileName());
}
m_shortCutManager.updateUndoActions(currentDesignDocument());
}
void QmlDesignerPlugin::hideDesigner()
{
if (currentDesignDocument()->currentModel()
&& !currentDesignDocument()->hasQmlSyntaxErrors())
jumpTextCursorToSelectedModelNode();
if (m_documentManager.hasCurrentDesignDocument()) {
deactivateAutoSynchronization();
m_mainWidget->saveSettings();
}
m_shortCutManager.disconnectUndoActions(currentDesignDocument());
m_documentManager.setCurrentDesignDocument(0);
m_shortCutManager.updateUndoActions(0);
}
void QmlDesignerPlugin::changeEditor()
{
if (m_documentManager.hasCurrentDesignDocument()) {
deactivateAutoSynchronization();
m_mainWidget->saveSettings();
}
m_shortCutManager.disconnectUndoActions(currentDesignDocument());
m_documentManager.setCurrentDesignDocument(Core::EditorManager::currentEditor());
m_mainWidget->initialize();
m_shortCutManager.connectUndoActions(currentDesignDocument());
if (m_documentManager.hasCurrentDesignDocument()) {
m_viewManager.pushFileOnCrambleBar(m_documentManager.currentDesignDocument()->fileName());
activateAutoSynchronization();
}
m_shortCutManager.updateUndoActions(currentDesignDocument());
}
void QmlDesignerPlugin::jumpTextCursorToSelectedModelNode()
{
// visual editor -> text editor
ModelNode selectedNode;
if (!currentDesignDocument()->rewriterView()->selectedModelNodes().isEmpty())
selectedNode = currentDesignDocument()->rewriterView()->selectedModelNodes().first();
if (selectedNode.isValid()) {
const int nodeOffset = currentDesignDocument()->rewriterView()->nodeOffset(selectedNode);
if (nodeOffset > 0) {
const ModelNode currentSelectedNode
= currentDesignDocument()->rewriterView()->nodeAtTextCursorPosition(currentDesignDocument()->plainTextEdit()->textCursor().position());
if (currentSelectedNode != selectedNode) {
int line, column;
currentDesignDocument()->textEditor()->convertPosition(nodeOffset, &line, &column);
currentDesignDocument()->textEditor()->gotoLine(line, column);
}
}
}
}
void QmlDesignerPlugin::selectModelNodeUnderTextCursor()
{
const int cursorPos = currentDesignDocument()->plainTextEdit()->textCursor().position();
ModelNode node = currentDesignDocument()->rewriterView()->nodeAtTextCursorPosition(cursorPos);
if (currentDesignDocument()->rewriterView() && node.isValid()) {
currentDesignDocument()->rewriterView()->setSelectedModelNodes(QList<ModelNode>() << node);
}
}
void QmlDesignerPlugin::activateAutoSynchronization()
{
// text editor -> visual editor
if (!currentDesignDocument()->isDocumentLoaded()) {
currentDesignDocument()->loadDocument(currentDesignDocument()->plainTextEdit());
} else {
currentDesignDocument()->activateCurrentModel();
}
resetModelSelection();
QList<RewriterView::Error> errors = currentDesignDocument()->qmlSyntaxErrors();
if (errors.isEmpty()) {
viewManager().attachComponentView();
viewManager().attachViewsExceptRewriterAndComponetView();
selectModelNodeUnderTextCursor();
m_mainWidget->enableWidgets();
} else {
m_mainWidget->disableWidgets();
m_mainWidget->showErrorMessage(errors);
}
connect(currentDesignDocument()->rewriterView(),
SIGNAL(errorsChanged(QList<RewriterView::Error>)),
m_mainWidget,
SLOT(updateErrorStatus(QList<RewriterView::Error>)));
}
void QmlDesignerPlugin::deactivateAutoSynchronization()
{
viewManager().detachViewsExceptRewriterAndComponetView();
viewManager().detachComponentView();
disconnect(currentDesignDocument()->rewriterView(),
SIGNAL(errorsChanged(QList<RewriterView::Error>)),
m_mainWidget,
SLOT(updateErrorStatus(QList<RewriterView::Error>)));
}
void QmlDesignerPlugin::resetModelSelection()
{
if (currentDesignDocument()->rewriterView() && currentDesignDocument()->currentModel())
currentDesignDocument()->rewriterView()->setSelectedModelNodes(QList<ModelNode>());
}
void QmlDesignerPlugin::onCurrentEditorChanged(Core::IEditor *editor)
{
if (editor
&& editor->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID
&& isInDesignerMode())
{ {
m_mainWidget->showEditor(editor); m_shortCutManager.updateActions(editor);
changeEditor();
} }
} }
void BauhausPlugin::contextChanged(Core::IContext *context, const Core::Context &additionalContexts) static bool isDesignerMode(Core::IMode *mode)
{ {
Q_UNUSED(context) return mode == Core::DesignMode::instance();
foreach (Core::Id id, additionalContexts) {
if (m_context->context().contains(id)) {
m_isActive = true;
m_mainWidget->showEditor(Core::EditorManager::currentEditor());
return;
}
}
if (m_isActive) {
m_isActive = false;
m_mainWidget->showEditor(0);
}
} }
void BauhausPlugin::textEditorsClosed(QList<Core::IEditor*> editors) void QmlDesignerPlugin::onCurrentModeChanged(Core::IMode *newMode, Core::IMode *oldMode)
{ {
m_mainWidget->closeEditors(editors); if ((currentDesignDocument()
&& Core::EditorManager::currentEditor() == currentDesignDocument()->editor())
&& isDesignerMode(newMode))
return;
if (!isDesignerMode(newMode) && isDesignerMode(oldMode))
hideDesigner();
else if (Core::EditorManager::currentEditor()
&& isDesignerMode(newMode)
&& isQmlFile(Core::EditorManager::currentEditor()))
showDesigner();
else if (currentDesignDocument())
hideDesigner();
} }
// copied from EditorManager::updateActions DesignDocument *QmlDesignerPlugin::currentDesignDocument() const
void BauhausPlugin::updateActions(Core::IEditor* editor)
{ {
Core::IEditor *curEditor = editor; return m_documentManager.currentDesignDocument();
int openedCount = m_editorManager->openedEditors().count()
+ m_editorManager->openedEditorsModel()->restoredEditors().count();
QString fName;
if (curEditor) {
if (!curEditor->document()->fileName().isEmpty()) {
QFileInfo fi(curEditor->document()->fileName());
fName = fi.fileName();
} else {
fName = curEditor->displayName();
}
}
m_saveAction->setEnabled(curEditor != 0 && curEditor->document()->isModified());
m_saveAsAction->setEnabled(curEditor != 0 && curEditor->document()->isSaveAsAllowed());
m_revertToSavedAction->setEnabled(curEditor != 0
&& !curEditor->document()->fileName().isEmpty()
&& curEditor->document()->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() Internal::DesignModeWidget *QmlDesignerPlugin::mainWidget() const
{ {
m_designMode = Core::DesignMode::instance(); return m_mainWidget;
m_mimeTypes << "application/x-qml";
m_designMode->registerDesignWidget(m_mainWidget, m_mimeTypes, m_context->context());
connect(m_designMode, SIGNAL(actionsUpdated(Core::IEditor*)), SLOT(updateActions(Core::IEditor*)));
} }
BauhausPlugin *BauhausPlugin::pluginInstance() void QmlDesignerPlugin::onTextEditorsClosed(QList<Core::IEditor*> editors)
{ {
return m_pluginInstance; if (m_documentManager.hasCurrentDesignDocument()
&& editors.contains(m_documentManager.currentDesignDocument()->textEditor()))
hideDesigner();
m_documentManager.removeEditors(editors);
} }
void BauhausPlugin::switchTextDesign() void QmlDesignerPlugin::extensionsInitialized()
{
QStringList mimeTypes;
mimeTypes.append("application/x-qml");
Core::DesignMode::instance()->registerDesignWidget(m_mainWidget, mimeTypes, m_context->context());
connect(Core::DesignMode::instance(),
SIGNAL(actionsUpdated(Core::IEditor*)),
&m_shortCutManager,
SLOT(updateActions(Core::IEditor*)));
}
QmlDesignerPlugin *QmlDesignerPlugin::instance()
{
return m_instance;
}
DocumentManager &QmlDesignerPlugin::documentManager()
{
return m_documentManager;
}
const DocumentManager &QmlDesignerPlugin::documentManager() const
{
return m_documentManager;
}
ViewManager &QmlDesignerPlugin::viewManager()
{
return m_viewManager;
}
const ViewManager &QmlDesignerPlugin::viewManager() const
{
return m_viewManager;
}
void QmlDesignerPlugin::switchTextDesign()
{ {
if (Core::ModeManager::currentMode()->id() == Core::Constants::MODE_EDIT) { if (Core::ModeManager::currentMode()->id() == Core::Constants::MODE_EDIT) {
Core::IEditor *editor = Core::EditorManager::currentEditor(); Core::IEditor *editor = Core::EditorManager::currentEditor();
if (editor->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID) { if (editor->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID)
Core::ModeManager::activateMode(Core::Constants::MODE_DESIGN); Core::ModeManager::activateMode(Core::Constants::MODE_DESIGN);
m_mainWidget->setFocus();
}
} else if (Core::ModeManager::currentMode()->id() == Core::Constants::MODE_DESIGN) { } else if (Core::ModeManager::currentMode()->id() == Core::Constants::MODE_DESIGN) {
Core::ModeManager::activateMode(Core::Constants::MODE_EDIT); Core::ModeManager::activateMode(Core::Constants::MODE_EDIT);
} }
} }
DesignerSettings BauhausPlugin::settings() DesignerSettings QmlDesignerPlugin::settings()
{ {
m_settings.fromSettings(Core::ICore::settings()); m_settings.fromSettings(Core::ICore::settings());
return m_settings; return m_settings;
} }
void BauhausPlugin::setSettings(const DesignerSettings &s) void QmlDesignerPlugin::setSettings(const DesignerSettings &s)
{ {
if (s != m_settings) { if (s != m_settings) {
m_settings = s; m_settings = s;
@@ -383,7 +444,6 @@ void BauhausPlugin::setSettings(const DesignerSettings &s)
} }
} }
}
} }
Q_EXPORT_PLUGIN(QmlDesigner::Internal::BauhausPlugin) Q_EXPORT_PLUGIN(QmlDesigner::QmlDesignerPlugin)

View File

@@ -35,6 +35,10 @@
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
#include "documentmanager.h"
#include "viewmanager.h"
#include "shortcutmanager.h"
#include <QWeakPointer> #include <QWeakPointer>
#include <QStringList> #include <QStringList>
@@ -51,60 +55,70 @@ namespace Core {
} }
namespace QmlDesigner { namespace QmlDesigner {
namespace Internal {
namespace Internal {
class DesignModeWidget; class DesignModeWidget;
class DesignModeContext; class DesignModeContext;
}
class BauhausPlugin : public ExtensionSystem::IPlugin class QmlDesignerPlugin : public ExtensionSystem::IPlugin
{ {
Q_OBJECT Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "QmlDesigner.json") Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "QmlDesigner.json")
public: public:
BauhausPlugin(); QmlDesignerPlugin();
virtual ~BauhausPlugin(); virtual ~QmlDesignerPlugin();
//Plugin //Plugin
virtual bool initialize(const QStringList &arguments, QString *errorMessage = 0); virtual bool initialize(const QStringList &arguments, QString *errorMessage = 0);
virtual void extensionsInitialized(); virtual void extensionsInitialized();
static BauhausPlugin *pluginInstance(); static QmlDesignerPlugin *instance();
DocumentManager &documentManager();
const DocumentManager &documentManager() const;
ViewManager &viewManager();
const ViewManager &viewManager() const;
DesignerSettings settings(); DesignerSettings settings();
void setSettings(const DesignerSettings &s); void setSettings(const DesignerSettings &s);
DesignDocument *currentDesignDocument() const;
Internal::DesignModeWidget *mainWidget() const;
private slots: private slots:
void switchTextDesign(); void switchTextDesign();
void textEditorsClosed(QList<Core::IEditor *> editors); void onTextEditorsClosed(QList<Core::IEditor *> editors);
void updateActions(Core::IEditor* editor); void onCurrentEditorChanged(Core::IEditor *editor);
void updateEditor(Core::IEditor *editor); void onCurrentModeChanged(Core::IMode *mode, Core::IMode *oldMode);
void contextChanged(Core::IContext *context, const Core::Context &additionalContexts);
private: private: // functions
void createDesignModeWidget(); void createDesignModeWidget();
void showDesigner();
void hideDesigner();
void changeEditor();
void jumpTextCursorToSelectedModelNode();
void selectModelNodeUnderTextCursor();
void activateAutoSynchronization();
void deactivateAutoSynchronization();
void resetModelSelection();
QStringList m_mimeTypes; private: // variables
DesignModeWidget *m_mainWidget; ViewManager m_viewManager;
DocumentManager m_documentManager;
ShortCutManager m_shortCutManager;
Internal::DesignModeWidget *m_mainWidget;
QmlDesigner::PluginManager m_pluginManager; QmlDesigner::PluginManager m_pluginManager;
static BauhausPlugin *m_pluginInstance; static QmlDesignerPlugin *m_instance;
DesignerSettings m_settings; DesignerSettings m_settings;
DesignModeContext *m_context; Internal::DesignModeContext *m_context;
Core::DesignMode *m_designMode;
Core::EditorManager *m_editorManager;
bool m_isActive; bool m_isActive;
QAction *m_revertToSavedAction;
QAction *m_saveAction;
QAction *m_saveAsAction;
QAction *m_closeCurrentEditorAction;
QAction *m_closeAllEditorsAction;
QAction *m_closeOtherEditorsAction;
}; };
} // namespace Internal
} // namespace QmlDesigner } // namespace QmlDesigner
#endif // QMLDESIGNERPLUGIN_H #endif // QMLDESIGNERPLUGIN_H

View File

@@ -1,16 +1,20 @@
HEADERS += $$PWD/qmldesignerconstants.h \ HEADERS += $$PWD/qmldesignerconstants.h \
$$PWD/shortcutmanager.h \
$$PWD/qmldesignerplugin.h \ $$PWD/qmldesignerplugin.h \
$$PWD/designmodewidget.h \ $$PWD/designmodewidget.h \
$$PWD/designersettings.h \ $$PWD/designersettings.h \
$$PWD/settingspage.h \ $$PWD/settingspage.h \
$$PWD/designmodecontext.h \ $$PWD/designmodecontext.h \
$$PWD/documentmanager.h \
$$PWD/styledoutputpaneplaceholder.h $$PWD/styledoutputpaneplaceholder.h
SOURCES += $$PWD/qmldesignerplugin.cpp \ SOURCES += $$PWD/qmldesignerplugin.cpp \
$$PWD/shortcutmanager.cpp \
$$PWD/designmodewidget.cpp \ $$PWD/designmodewidget.cpp \
$$PWD/designersettings.cpp \ $$PWD/designersettings.cpp \
$$PWD/settingspage.cpp \ $$PWD/settingspage.cpp \
$$PWD/designmodecontext.cpp \ $$PWD/designmodecontext.cpp \
$$PWD/documentmanager.cpp \
$$PWD/styledoutputpaneplaceholder.cpp $$PWD/styledoutputpaneplaceholder.cpp
FORMS += $$PWD/settingspage.ui FORMS += $$PWD/settingspage.ui

View File

@@ -95,7 +95,7 @@ SettingsPage::SettingsPage() :
QWidget *SettingsPage::createPage(QWidget *parent) QWidget *SettingsPage::createPage(QWidget *parent)
{ {
m_widget = new SettingsPageWidget(parent); m_widget = new SettingsPageWidget(parent);
m_widget->setSettings(BauhausPlugin::pluginInstance()->settings()); m_widget->setSettings(QmlDesignerPlugin::instance()->settings());
if (m_searchKeywords.isEmpty()) if (m_searchKeywords.isEmpty())
m_searchKeywords = m_widget->searchKeywords(); m_searchKeywords = m_widget->searchKeywords();
return m_widget; return m_widget;
@@ -105,7 +105,7 @@ void SettingsPage::apply()
{ {
if (!m_widget) // page was never shown if (!m_widget) // page was never shown
return; return;
BauhausPlugin::pluginInstance()->setSettings(m_widget->settings()); QmlDesignerPlugin::instance()->setSettings(m_widget->settings());
} }
bool SettingsPage::matches(const QString &s) const bool SettingsPage::matches(const QString &s) const

View File

@@ -0,0 +1,326 @@
#include "shortcutmanager.h"
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/icore.h>
#include <coreplugin/editormanager/openeditorsmodel.h>
#include <coreplugin/coreconstants.h>
#include <utils/hostosinfo.h>
#include "qmldesignerconstants.h"
#include "designdocument.h"
#include "qmldesignerplugin.h"
#include "designmodewidget.h"
namespace QmlDesigner {
ShortCutManager::ShortCutManager()
: QObject(),
m_revertToSavedAction(0),
m_saveAction(0),
m_saveAsAction(0),
m_closeCurrentEditorAction(0),
m_closeAllEditorsAction(0),
m_closeOtherEditorsAction(0),
m_undoAction(tr("&Undo"), 0),
m_redoAction(tr("&Redo"), 0),
m_deleteAction(tr("Delete"), tr("Delete \"%1\""), Utils::ParameterAction::EnabledWithParameter),
m_cutAction(tr("Cu&t"), tr("Cut \"%1\""), Utils::ParameterAction::EnabledWithParameter),
m_copyAction(tr("&Copy"), tr("Copy \"%1\""), Utils::ParameterAction::EnabledWithParameter),
m_pasteAction(tr("&Paste"), tr("Paste \"%1\""), Utils::ParameterAction::EnabledWithParameter),
m_selectAllAction(tr("Select &All"), tr("Select All \"%1\""), Utils::ParameterAction::EnabledWithParameter),
m_hideSidebarsAction(tr("Toggle Full Screen"), 0),
m_restoreDefaultViewAction(tr("&Restore Default View"), 0),
m_toggleLeftSidebarAction(tr("Toggle &Left Sidebar"), 0),
m_toggleRightSidebarAction(tr("Toggle &Right Sidebar"), 0),
m_goIntoComponentAction (tr("&Go into Component"), 0)
{
}
void ShortCutManager::registerActions()
{
Core::ActionContainer *editMenu = Core::ActionManager::actionContainer(Core::Constants::M_EDIT);
Core::Context qmlDesignerMainContext(Constants::C_QMLDESIGNER);
Core::Context qmlDesignerFormEditorContext(Constants::C_QMLFORMEDITOR);
Core::Context qmlDesignerNavigatorContext(Constants::C_QMLNAVIGATOR);
connect(&m_undoAction, SIGNAL(triggered()), this, SLOT(undo()));
connect(&m_redoAction, SIGNAL(triggered()), this, SLOT(redo()));
connect(&m_deleteAction, SIGNAL(triggered()), this, SLOT(deleteSelected()));
connect(&m_cutAction, SIGNAL(triggered()), this, SLOT(cutSelected()));
connect(&m_copyAction, SIGNAL(triggered()), this, SLOT(copySelected()));
connect(&m_pasteAction, SIGNAL(triggered()), this, SLOT(paste()));
connect(&m_selectAllAction, SIGNAL(triggered()), this, SLOT(selectAll()));
connect(&m_hideSidebarsAction, SIGNAL(triggered()), this, SLOT(toggleSidebars()));
connect(&m_restoreDefaultViewAction,
SIGNAL(triggered()),
QmlDesignerPlugin::instance()->mainWidget(),
SLOT(restoreDefaultView()));
connect(&m_goIntoComponentAction, SIGNAL(triggered()), SLOT(goIntoComponent()));
connect(&m_toggleLeftSidebarAction,
SIGNAL(triggered()),
QmlDesignerPlugin::instance()->mainWidget(),
SLOT(toggleLeftSidebar()));
connect(&m_toggleRightSidebarAction,
SIGNAL(triggered()),
QmlDesignerPlugin::instance()->mainWidget(),
SLOT(toggleRightSidebar()));
// Revert to saved
Core::ActionManager::registerAction(&m_revertToSavedAction,Core::Constants::REVERTTOSAVED, qmlDesignerMainContext);
connect(&m_revertToSavedAction, SIGNAL(triggered()), Core::ICore::editorManager(), SLOT(revertToSaved()));
//Save
Core::ActionManager::registerAction(&m_saveAction, Core::Constants::SAVE, qmlDesignerMainContext);
connect(&m_saveAction, SIGNAL(triggered()), Core::ICore::editorManager(), SLOT(saveDocument()));
//Save As
Core::ActionManager::registerAction(&m_saveAsAction, Core::Constants::SAVEAS, qmlDesignerMainContext);
connect(&m_saveAsAction, SIGNAL(triggered()), Core::ICore::editorManager(), SLOT(saveDocumentAs()));
//Close Editor
Core::ActionManager::registerAction(&m_closeCurrentEditorAction, Core::Constants::CLOSE, qmlDesignerMainContext);
connect(&m_closeCurrentEditorAction, SIGNAL(triggered()), Core::ICore::editorManager(), SLOT(closeEditor()));
//Close All
Core::ActionManager::registerAction(&m_closeAllEditorsAction, Core::Constants::CLOSEALL, qmlDesignerMainContext);
connect(&m_closeAllEditorsAction, SIGNAL(triggered()), Core::ICore::editorManager(), SLOT(closeAllEditors()));
//Close All Others Action
Core::ActionManager::registerAction(&m_closeOtherEditorsAction, Core::Constants::CLOSEOTHERS, qmlDesignerMainContext);
connect(&m_closeOtherEditorsAction, SIGNAL(triggered()), Core::ICore::editorManager(), SLOT(closeOtherEditors()));
// Undo / Redo
Core::ActionManager::registerAction(&m_undoAction, Core::Constants::UNDO, qmlDesignerMainContext);
Core::ActionManager::registerAction(&m_redoAction, Core::Constants::REDO, qmlDesignerMainContext);
Core::Command *command;
//GoIntoComponent
command = Core::ActionManager::registerAction(&m_goIntoComponentAction,
Constants::GO_INTO_COMPONENT, qmlDesignerMainContext);
command->setDefaultKeySequence(QKeySequence(Qt::Key_F2));
//Edit Menu
command = Core::ActionManager::registerAction(&m_deleteAction, QmlDesigner::Constants::DELETE, qmlDesignerFormEditorContext);
command = Core::ActionManager::registerAction(&m_deleteAction, QmlDesigner::Constants::DELETE, qmlDesignerNavigatorContext);
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 = Core::ActionManager::registerAction(&m_cutAction, Core::Constants::CUT, qmlDesignerFormEditorContext);
command = Core::ActionManager::registerAction(&m_cutAction, Core::Constants::CUT, qmlDesignerNavigatorContext);
command->setDefaultKeySequence(QKeySequence::Cut);
editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE);
command = Core::ActionManager::registerAction(&m_copyAction, Core::Constants::COPY, qmlDesignerFormEditorContext);
command = Core::ActionManager::registerAction(&m_copyAction, Core::Constants::COPY, qmlDesignerNavigatorContext);
command->setDefaultKeySequence(QKeySequence::Copy);
editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE);
command = Core::ActionManager::registerAction(&m_pasteAction, Core::Constants::PASTE, qmlDesignerFormEditorContext);
command = Core::ActionManager::registerAction(&m_pasteAction, Core::Constants::PASTE, qmlDesignerNavigatorContext);
command->setDefaultKeySequence(QKeySequence::Paste);
editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE);
command = Core::ActionManager::registerAction(&m_selectAllAction, Core::Constants::SELECTALL, qmlDesignerFormEditorContext);
command = Core::ActionManager::registerAction(&m_selectAllAction, Core::Constants::SELECTALL, qmlDesignerNavigatorContext);
command->setDefaultKeySequence(QKeySequence::SelectAll);
editMenu->addAction(command, Core::Constants::G_EDIT_SELECTALL);
Core::ActionContainer *viewsMenu = Core::ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS);
command = Core::ActionManager::registerAction(&m_toggleLeftSidebarAction, Constants::TOGGLE_LEFT_SIDEBAR, qmlDesignerMainContext);
command->setAttribute(Core::Command::CA_Hide);
command->setDefaultKeySequence(QKeySequence("Ctrl+Alt+0"));
viewsMenu->addAction(command);
command = Core::ActionManager::registerAction(&m_toggleRightSidebarAction, Constants::TOGGLE_RIGHT_SIDEBAR, qmlDesignerMainContext);
command->setAttribute(Core::Command::CA_Hide);
command->setDefaultKeySequence(QKeySequence("Ctrl+Alt+Shift+0"));
viewsMenu->addAction(command);
command = Core::ActionManager::registerAction(&m_restoreDefaultViewAction, Constants::RESTORE_DEFAULT_VIEW, qmlDesignerMainContext);
command->setAttribute(Core::Command::CA_Hide);
viewsMenu->addAction(command);
command = Core::ActionManager::registerAction(&m_hideSidebarsAction, Core::Constants::TOGGLE_SIDEBAR, qmlDesignerMainContext);
if (Utils::HostOsInfo::isMacHost()) {
// add second shortcut to trigger delete
QAction *deleteAction = new QAction(this);
deleteAction->setShortcut(QKeySequence(QLatin1String("Backspace")));
connect(deleteAction,
SIGNAL(triggered()),
&m_deleteAction,
SIGNAL(triggered()));
}
}
void ShortCutManager::updateActions(Core::IEditor* editor)
{
Core::IEditor *currentEditor = editor;
int openedCount = Core::ICore::editorManager()->openedEditors().count()
+ Core::ICore::editorManager()->openedEditorsModel()->restoredEditors().count();
QString fileName;
if (currentEditor) {
if (!currentEditor->document()->fileName().isEmpty()) {
QFileInfo fileInfo(currentEditor->document()->fileName());
fileName = fileInfo.fileName();
} else {
fileName = currentEditor->displayName();
}
}
m_saveAction.setEnabled(currentEditor != 0 && currentEditor->document()->isModified());
m_saveAsAction.setEnabled(currentEditor != 0 && currentEditor->document()->isSaveAsAllowed());
m_revertToSavedAction.setEnabled(currentEditor != 0
&& !currentEditor->document()->fileName().isEmpty()
&& currentEditor->document()->isModified());
QString quotedName;
if (!fileName.isEmpty())
quotedName = '"' + fileName + '"';
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(currentEditor != 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 ShortCutManager::undo()
{
if (currentDesignDocument())
currentDesignDocument()->undo();
}
void ShortCutManager::redo()
{
if (currentDesignDocument())
currentDesignDocument()->redo();
}
void ShortCutManager::deleteSelected()
{
if (currentDesignDocument())
currentDesignDocument()->deleteSelected();
}
void ShortCutManager::cutSelected()
{
if (currentDesignDocument())
currentDesignDocument()->cutSelected();
}
void ShortCutManager::copySelected()
{
if (currentDesignDocument())
currentDesignDocument()->copySelected();
}
void ShortCutManager::paste()
{
if (currentDesignDocument())
currentDesignDocument()->paste();
}
void ShortCutManager::selectAll()
{
if (currentDesignDocument())
currentDesignDocument()->selectAll();
}
void ShortCutManager::toggleSidebars()
{
QmlDesignerPlugin::instance()->mainWidget()->toggleSidebars();
}
void ShortCutManager::toggleLeftSidebar()
{
QmlDesignerPlugin::instance()->mainWidget()->toggleLeftSidebar();
}
void ShortCutManager::toggleRightSidebar()
{
QmlDesignerPlugin::instance()->mainWidget()->toggleRightSidebar();
}
void ShortCutManager::connectUndoActions(DesignDocument *designDocument)
{
if (designDocument) {
connect(designDocument, SIGNAL(undoAvailable(bool)), this, SLOT(undoAvailable(bool)));
connect(designDocument, SIGNAL(redoAvailable(bool)), this, SLOT(redoAvailable(bool)));
}
}
void ShortCutManager::disconnectUndoActions(DesignDocument *designDocument)
{
if (currentDesignDocument()) {
disconnect(designDocument, SIGNAL(undoAvailable(bool)), this, SLOT(undoAvailable(bool)));
disconnect(designDocument, SIGNAL(redoAvailable(bool)), this, SLOT(redoAvailable(bool)));
}
}
void ShortCutManager::updateUndoActions(DesignDocument *designDocument)
{
if (designDocument) {
m_undoAction.setEnabled(designDocument->isUndoAvailable());
m_redoAction.setEnabled(designDocument->isRedoAvailable());
} else {
m_undoAction.setEnabled(false);
m_redoAction.setEnabled(false);
}
}
DesignDocument *ShortCutManager::currentDesignDocument() const
{
return QmlDesignerPlugin::instance()->currentDesignDocument();
}
void ShortCutManager::undoAvailable(bool isAvailable)
{
DesignDocument *documentController = qobject_cast<DesignDocument*>(sender());
if (currentDesignDocument() &&
currentDesignDocument() == documentController) {
m_undoAction.setEnabled(isAvailable);
}
}
void ShortCutManager::redoAvailable(bool isAvailable)
{
DesignDocument *documentController = qobject_cast<DesignDocument*>(sender());
if (currentDesignDocument() &&
currentDesignDocument() == documentController) {
m_redoAction.setEnabled(isAvailable);
}
}
void ShortCutManager::goIntoComponent()
{
if (currentDesignDocument())
currentDesignDocument()->goIntoComponent();
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,72 @@
#ifndef QMLDESIGNER_SHORTCUTMANAGER_H
#define QMLDESIGNER_SHORTCUTMANAGER_H
#include <QObject>
#include <QAction>
#include <utils/parameteraction.h>
namespace Core {
class IEditor;
}
namespace QmlDesigner {
class DesignDocument;
class ShortCutManager : public QObject
{
Q_OBJECT
public:
ShortCutManager();
void registerActions();
void connectUndoActions(DesignDocument *designDocument);
void disconnectUndoActions(DesignDocument *designDocument);
void updateUndoActions(DesignDocument *designDocument);
DesignDocument *currentDesignDocument() const;
public slots:
void updateActions(Core::IEditor* editor);
private slots:
void undo();
void redo();
void deleteSelected();
void cutSelected();
void copySelected();
void paste();
void selectAll();
void toggleSidebars();
void toggleLeftSidebar();
void toggleRightSidebar();
void undoAvailable(bool isAvailable);
void redoAvailable(bool isAvailable);
void goIntoComponent();
private:
QAction m_revertToSavedAction;
QAction m_saveAction;
QAction m_saveAsAction;
QAction m_closeCurrentEditorAction;
QAction m_closeAllEditorsAction;
QAction m_closeOtherEditorsAction;
QAction m_undoAction;
QAction m_redoAction;
Utils::ParameterAction m_deleteAction;
Utils::ParameterAction m_cutAction;
Utils::ParameterAction m_copyAction;
Utils::ParameterAction m_pasteAction;
Utils::ParameterAction m_selectAllAction;
QAction m_hideSidebarsAction;
QAction m_restoreDefaultViewAction;
QAction m_toggleLeftSidebarAction;
QAction m_toggleRightSidebarAction;
QAction m_goIntoComponentAction;
};
} // namespace QmlDesigner
#endif // QMLDESIGNER_SHORTCUTMANAGER_H