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;
}
QWidget *widget()
{
return 0;
}
protected:
void setupContext()
{

View File

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

View File

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

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 *)
{
if (!painter->isActive())
return;
if (!qmlItemNode().isValid())
return;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -32,7 +32,8 @@
#include <QComboBox>
#include "componentview.h"
#include <QStandardItemModel>
#include <QDebug>
#include <qmldesignerplugin.h>
#include <modelnode.h>
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)
@@ -59,9 +60,21 @@ QWidget *ComponentAction::createWidget(QWidget *parent)
return comboBox;
}
static const QString fileNameOfCurrentDocument()
{
return QmlDesignerPlugin::instance()->documentManager().currentDesignDocument()->textEditor()->document()->fileName();
}
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

View File

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

View File

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

View File

@@ -37,6 +37,7 @@
QT_BEGIN_NAMESPACE
class QStandardItemModel;
class QComboBox;
QT_END_NAMESPACE
namespace QmlDesigner {
@@ -53,7 +54,7 @@ public:
ModelNodeRole = Qt::UserRole
};
ComponentView(QObject *parent);
ComponentView(QObject *parent = 0);
void modelAttached(Model *model);
void modelAboutToBeDetached(Model *model);
@@ -106,6 +107,8 @@ public:
void setComponentNode(const ModelNode &node);
QWidget *widget();
signals:
void componentListChanged(const QStringList &componentList);
@@ -118,6 +121,7 @@ private: //functions
int indexForNode(const ModelNode &node);
private:
QList<QComboBox*> m_comboBoxList;
QStandardItemModel *m_standardItemModel;
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
#define DesignDocumentController_h
#ifndef DesignDocument_h
#define DesignDocument_h
#include "rewriterview.h"
@@ -44,6 +44,7 @@
#include <componenttextmodifier.h>
#include <subcomponentmanager.h>
#include <model/viewlogger.h>
#include <viewmanager.h>
#include <QObject>
#include <QString>
@@ -66,49 +67,44 @@ class TextModifier;
class QmlObjectNode;
struct CrumbleBarInfo;
class DesignDocumentController: public QObject
class DesignDocument: public QObject
{
Q_OBJECT
public:
DesignDocumentController(QObject *parent);
~DesignDocumentController();
DesignDocument(QObject *parent = 0);
~DesignDocument();
QString displayName() const;
QString simplfiedDisplayName() const;
QString fileName() const;
void setFileName(const QString &m_fileName);
QList<RewriterView::Error> loadMaster(QPlainTextEdit *edit);
QList<RewriterView::Error> loadMaster(const QByteArray &qml);
void loadCurrentModel();
QList<RewriterView::Error> loadDocument(QPlainTextEdit *edit);
void activateCurrentModel(TextModifier *textModifier);
void activateCurrentModel();
void activateDocumentModel();
void close();
bool isDirty() const;
bool isUndoAvailable() const;
bool isRedoAvailable() const;
Model *model() const;
Model *masterModel() const;
Model *currentModel() const;
Model *documentModel() const;
QString contextHelpId() const;
QList<RewriterView::Error> qmlSyntaxErrors() const;
bool hasQmlSyntaxErrors() const;
RewriterView *rewriterView() const;
bool isModelSyncBlocked() const;
void blockModelSync(bool block);
void setEditor(Core::IEditor *editor);
Core::IEditor *editor() const;
QString contextHelpId() const;
QList<RewriterView::Error> qmlErrors() const;
TextEditor::ITextEditor *textEditor() 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 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);
void resetToDocumentModel();
signals:
void displayNameChanged(const QString &newFileName);
@@ -122,8 +118,6 @@ signals:
void fileToOpen(const QString &path);
public slots:
bool save(QWidget *parent = 0);
void saveAs(QWidget *parent = 0);
void deleteSelected();
void copySelected();
void cutSelected();
@@ -131,68 +125,46 @@ public slots:
void selectAll();
void undo();
void redo();
void activeQtVersionChanged();
void updateActiveQtVersion();
void changeCurrentModelTo(const ModelNode &node);
void changeToSubComponent(const ModelNode &node);
void changeToExternalSubComponent(const QString &m_fileName);
void changeToExternalSubComponent(const QString &m_oldFileName);
void goIntoComponent();
#ifdef ENABLE_TEXT_VIEW
void showText();
void showForm();
#endif // ENABLE_TEXT_VIEW
private slots:
void doRealSaveAs(const QString &m_fileName);
void updateFileName(const QString &oldFileName, const QString &newFileName);
private: // functions
void detachNodeInstanceView();
void attachNodeInstanceView();
void changeToMasterModel();
QVariant createCrumbleBarInfo();
void changeToDocumentModel();
void changeToInFileComponentModel();
QWidget *centralWidget() const;
QString pathToQt() const;
const ViewManager &viewManager() const;
ViewManager &viewManager();
ModelNode rootModelNode() const;
bool loadSubComponent(const ModelNode &componentNode);
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<NodeInstanceView> m_nodeInstanceView;
QWeakPointer<ComponentView> m_componentView;
QWeakPointer<Model> m_model;
QWeakPointer<Model> m_subComponentModel;
QWeakPointer<Model> m_masterModel;
QWeakPointer<QPlainTextEdit> m_textEdit;
QWeakPointer<RewriterView> m_rewriterView;
BaseTextEditModifier *m_textModifier;
ComponentTextModifier *m_componentTextModifier;
QWeakPointer<Model> m_documentModel;
QWeakPointer<Model> m_inFileComponentModel;
QWeakPointer<Model> m_currentModel;
QWeakPointer<Core::IEditor> m_textEditor;
QWeakPointer<BaseTextEditModifier> m_documentTextModifier;
QWeakPointer<ComponentTextModifier> m_inFileComponentTextModifier;
QWeakPointer<SubComponentManager> m_subComponentManager;
QWeakPointer<Internal::ViewLogger> m_viewLogger;
ModelNode m_componentNode;
QString m_fileName;
QUrl m_searchPath;
QWeakPointer<RewriterView> m_rewriterView;
bool m_documentLoaded;
bool m_syncBlocked;
int m_qt_versionId;
static bool s_clearCrumblePath;
static bool s_pushCrumblePath;
};
struct CrumbleBarInfo {
ModelNode modelNode;
QString fileName;
int m_qtVersionId;
};
} // 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 <basetexteditmodifier.h>
#include <metainfo.h>
@@ -40,79 +40,88 @@
namespace QmlDesigner {
void DesignDocumentControllerView::nodeCreated(const ModelNode & /*createdNode*/) {}
void DesignDocumentControllerView::nodeAboutToBeRemoved(const ModelNode & /*removedNode*/) {}
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*/) {}
DesignDocumentView::DesignDocumentView(QObject *parent)
: AbstractView(parent), m_modelMerger(this)
{
}
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*/) {}
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();
}
void DesignDocumentControllerView::toClipboard() const
void DesignDocumentView::toClipboard() const
{
QClipboard *clipboard = QApplication::clipboard();
@@ -146,7 +155,7 @@ void DesignDocumentControllerView::toClipboard() const
clipboard->setMimeData(data);
}
void DesignDocumentControllerView::fromClipboard()
void DesignDocumentView::fromClipboard()
{
QClipboard *clipboard = QApplication::clipboard();
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()));
outputModel->setFileUrl(model()->fileUrl());
@@ -178,7 +187,7 @@ QString DesignDocumentControllerView::toText() const
QScopedPointer<RewriterView> rewriterView(new RewriterView(RewriterView::Amend, 0));
rewriterView->setCheckSemanticErrors(false);
rewriterView->setTextModifier(&modifier);
outputModel->attachView(rewriterView.data());
outputModel->setRewriterView(rewriterView.data());
ModelMerger merger(rewriterView.data());
@@ -190,7 +199,7 @@ QString DesignDocumentControllerView::toText() const
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()));
inputModel->setFileUrl(model()->fileUrl());
@@ -205,7 +214,7 @@ void DesignDocumentControllerView::fromText(QString text)
QScopedPointer<RewriterView> rewriterView(new RewriterView(RewriterView::Amend, 0));
rewriterView->setCheckSemanticErrors(false);
rewriterView->setTextModifier(&modifier);
inputModel->attachView(rewriterView.data());
inputModel->setRewriterView(rewriterView.data());
if (rewriterView->errors().isEmpty() && rewriterView->rootModelNode().isValid()) {
ModelMerger merger(this);
@@ -213,4 +222,9 @@ void DesignDocumentControllerView::fromText(QString text)
}
}
QWidget *DesignDocumentView::widget()
{
return 0;
}
}// namespace QmlDesigner

View File

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

View File

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

View File

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

View File

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

View File

@@ -33,7 +33,7 @@
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();
}
@@ -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()
{
m_widget->updateModel();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -58,6 +58,7 @@ class ModelState;
class NodeAnchors;
class AbstractProperty;
class RewriterView;
class NodeInstanceView;
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);
Model *masterModel() const;
void setMasterModel(Model *model);
QUrl fileUrl() const;
void setFileUrl(const QUrl &url);
@@ -103,6 +101,10 @@ public:
QString pathForImport(const Import &import);
RewriterView *rewriterView() const;
void setRewriterView(RewriterView *rewriterView);
NodeInstanceView *nodeInstanceView() const;
void setNodeInstanceView(NodeInstanceView *nodeInstanceView);
Model *metaInfoProxyModel();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1525,12 +1525,13 @@ void ModelPrivate::setRewriterView(RewriterView *rewriterView)
Q_ASSERT(!(rewriterView && m_rewriterView));
if (m_rewriterView)
m_rewriterView->modelAboutToBeDetached(model());
m_rewriterView = rewriterView;
if (rewriterView)
rewriterView->modelAttached(model());
else if (m_rewriterView)
m_rewriterView->modelAboutToBeDetached(model());
}
RewriterView *ModelPrivate::rewriterView() const
@@ -1730,6 +1731,21 @@ RewriterView *Model::rewriterView() const
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
\return Return itself if not other metaInfoProxyModel does exist
@@ -1755,16 +1771,6 @@ Model *Model::create(const QString &rootType)
}
#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.
\return The base URL.
@@ -1834,13 +1840,11 @@ void Model::attachView(AbstractView *view)
// Internal::WriteLocker locker(d);
RewriterView *rewriterView = qobject_cast<RewriterView*>(view);
if (rewriterView) {
d->setRewriterView(rewriterView);
return;
}
NodeInstanceView *nodeInstanceView = qobject_cast<NodeInstanceView*>(view);
if (nodeInstanceView) {
d->setNodeInstanceView(nodeInstanceView);
return;
}
@@ -1862,13 +1866,11 @@ void Model::detachView(AbstractView *view, ViewNotification emitDetachNotify)
RewriterView *rewriterView = qobject_cast<RewriterView*>(view);
if (rewriterView) {
d->setRewriterView(0);
return;
}
NodeInstanceView *nodeInstanceView = qobject_cast<NodeInstanceView*>(view);
if (nodeInstanceView) {
d->setNodeInstanceView(0);
return;
}

View File

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

View File

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

View File

@@ -472,6 +472,16 @@ QString RewriterView::textModifierContent() const
return QString();
}
void RewriterView::reactivateTextMofifierChangeSignals()
{
textModifier()->reactivateChangeSignals();
}
void RewriterView::deactivateTextMofifierChangeSignals()
{
textModifier()->deactivateChangeSignals();
}
void RewriterView::applyModificationGroupChanges()
{
Q_ASSERT(transactionLevel == 0);
@@ -615,6 +625,31 @@ bool RewriterView::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)
{
if (textModifier())
@@ -698,6 +733,10 @@ QString RewriterView::pathForImport(const Import &import)
return QString();
}
QWidget *RewriterView::widget()
{
return 0;
}
void RewriterView::qmlTextChanged()
{

View File

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

View File

@@ -42,7 +42,7 @@ class ViewLogger : public QmlDesigner::AbstractView
{
Q_OBJECT
public:
ViewLogger(QObject *parent);
ViewLogger(QObject *parent = 0);
void modelAttached(Model *model);
void modelAboutToBeDetached(Model *model);
@@ -87,6 +87,8 @@ public:
void actualStateChanged(const ModelNode &node);
QWidget *widget();
protected:
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 "styledoutputpaneplaceholder.h"
#include "designmodecontext.h"
#include "qmldesignerplugin.h"
#include <model.h>
#include <rewriterview.h>
#include <formeditorwidget.h>
#include <stateseditorwidget.h>
#include <itemlibrarywidget.h>
#include <componentaction.h>
#include <toolbox.h>
#include <itemlibrarywidget.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/designmode.h>
@@ -93,8 +92,6 @@ const char SB_OPENDOCUMENTS[] = "OpenDocuments";
namespace QmlDesigner {
namespace Internal {
DesignModeWidget *DesignModeWidget::s_instance = 0;
DocumentWarningWidget::DocumentWarningWidget(DesignModeWidget *parent) :
Utils::FakeToolTip(parent),
m_errorMessage(new QLabel(tr("Placeholder"), this)),
@@ -137,13 +134,13 @@ void DocumentWarningWidget::setError(const RewriterView::Error &error)
class ItemLibrarySideBarItem : public Core::SideBarItem
{
public:
explicit ItemLibrarySideBarItem(ItemLibraryWidget *widget, const QString &id);
explicit ItemLibrarySideBarItem(QWidget *widget, const QString &id);
virtual ~ItemLibrarySideBarItem();
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()
{
@@ -158,13 +155,13 @@ QList<QToolButton *> ItemLibrarySideBarItem::createToolBarWidgets()
class NavigatorSideBarItem : public Core::SideBarItem
{
public:
explicit NavigatorSideBarItem(NavigatorWidget *widget, const QString &id);
explicit NavigatorSideBarItem(QWidget *widget, const QString &id);
virtual ~NavigatorSideBarItem();
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()
{
@@ -185,7 +182,6 @@ void DocumentWarningWidget::goToError()
// ---------- DesignModeWidget
DesignModeWidget::DesignModeWidget(QWidget *parent) :
QWidget(parent),
m_syncWithTextEdit(false),
m_mainSplitter(0),
m_leftSideBar(0),
m_rightSideBar(0),
@@ -196,41 +192,10 @@ DesignModeWidget::DesignModeWidget(QWidget *parent) :
m_navigatorHistoryCounter(-1),
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_outputPanePlaceholder = new StyledOutputpanePlaceHolder(Core::DesignMode::instance(), m_outputPlaceholderSplitter);
}
DesignModeWidget::~DesignModeWidget()
{
s_instance = 0;
}
void DesignModeWidget::restoreDefaultView()
{
QSettings *settings = Core::ICore::settings();
@@ -265,19 +230,17 @@ void DesignModeWidget::toggleSidebars()
m_leftSideBar->setVisible(m_showSidebars);
if (m_rightSideBar)
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)
{
if (m_textEditor && editor)
if (m_textEditor->document()->fileName() != editor->document()->fileName()) {
if (!m_keepNavigatorHistory)
addNavigatorHistoryEntry(editor->document()->fileName());
setupNavigatorHistory();
}
if (textEditor()
&& editor
&& textEditor()->document()->fileName() != editor->document()->fileName())
setupNavigatorHistory(editor);
//
// Prevent recursive calls to function by explicitly managing initialization status
@@ -291,132 +254,16 @@ void DesignModeWidget::showEditor(Core::IEditor *editor)
setup();
}
QString fileName;
QPlainTextEdit *textEdit = 0;
TextEditor::ITextEditor *textEditor = 0;
if (editor) {
fileName = editor->document()->fileName();
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());
if (textEditor())
m_fakeToolBar->addEditor(textEditor());
newDocument->setFileName(fileName);
document = newDocument;
m_documentHash.insert(textEdit, document);
}
}
setCurrentDocument(document);
setCurrentDesignDocument(currentDesignDocument());
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()
{
QSettings *settings = Core::ICore::settings();
@@ -443,98 +290,25 @@ void DesignModeWidget::saveSettings()
settings->endGroup();
}
void DesignModeWidget::undo()
{
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()
void DesignModeWidget::enableWidgets()
{
if (debug)
qDebug() << Q_FUNC_INFO;
m_warningWidget->setVisible(false);
m_formEditorView->widget()->setEnabled(true);
m_statesEditorView->widget()->setEnabled(true);
viewManager().formEditorWidget()->setEnabled(true);
viewManager().statesEditorWidget()->setEnabled(true);
m_leftSideBar->setEnabled(true);
m_rightSideBar->setEnabled(true);
m_isDisabled = false;
}
void DesignModeWidget::disable(const QList<RewriterView::Error> &errors)
void DesignModeWidget::disableWidgets()
{
if (debug)
qDebug() << Q_FUNC_INFO;
Q_ASSERT(!errors.isEmpty());
m_warningWidget->setError(errors.first());
m_warningWidget->setVisible(true);
m_warningWidget->move(width() / 2, height() / 2);
m_formEditorView->widget()->setEnabled(false);
m_statesEditorView->widget()->setEnabled(false);
viewManager().formEditorWidget()->setEnabled(false);
viewManager().statesEditorWidget()->setEnabled(false);
m_leftSideBar->setEnabled(false);
m_rightSideBar->setEnabled(false);
m_isDisabled = true;
@@ -545,112 +319,27 @@ void DesignModeWidget::updateErrorStatus(const QList<RewriterView::Error> &error
if (debug)
qDebug() << Q_FUNC_INFO << errors.count();
if (m_isDisabled && errors.isEmpty())
enable();
else if (!errors.isEmpty())
disable(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>)));
if (m_isDisabled && errors.isEmpty()) {
enableWidgets();
} else if (!errors.isEmpty()) {
disableWidgets();
showErrorMessage(errors);
}
}
void DesignModeWidget::setCurrentDocument(DesignDocumentController *newDesignDocumentController)
TextEditor::ITextEditor *DesignModeWidget::textEditor() const
{
return currentDesignDocument()->textEditor();
}
void DesignModeWidget::setCurrentDesignDocument(DesignDocument *newDesignDocument)
{
if (debug)
qDebug() << Q_FUNC_INFO << newDesignDocumentController;
qDebug() << Q_FUNC_INFO << newDesignDocument;
if (m_currentDesignDocumentController.data() == newDesignDocumentController)
return;
if (m_currentDesignDocumentController) {
setAutoSynchronization(false);
saveSettings();
}
//viewManager().setDesignDocument(newDesignDocument);
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()
@@ -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_mainSplitter = new MiniSplitter(this);
@@ -710,9 +385,9 @@ void DesignModeWidget::setup()
m_warningWidget = new DocumentWarningWidget(this);
m_warningWidget->setVisible(false);
Core::SideBarItem *navigatorItem = new NavigatorSideBarItem(m_navigatorView->widget(), QLatin1String(SB_NAVIGATOR));
Core::SideBarItem *libraryItem = new ItemLibrarySideBarItem(m_itemLibraryView->widget(), QLatin1String(SB_LIBRARY));
Core::SideBarItem *propertiesItem = new Core::SideBarItem(m_propertyEditorView->widget(), QLatin1String(SB_PROPERTIES));
Core::SideBarItem *navigatorItem = new NavigatorSideBarItem(viewManager().navigatorWidget(), QLatin1String(SB_NAVIGATOR));
Core::SideBarItem *libraryItem = new ItemLibrarySideBarItem(viewManager().itemLibraryWidget(), QLatin1String(SB_LIBRARY));
Core::SideBarItem *propertiesItem = new Core::SideBarItem(viewManager().propertyEditorWidget(), QLatin1String(SB_PROPERTIES));
// default items
m_sideBarItems << navigatorItem << libraryItem << propertiesItem;
@@ -748,7 +423,9 @@ void DesignModeWidget::setup()
connect(m_fakeToolBar, SIGNAL(closeClicked()), this, SLOT(closeCurrentEditor()));
connect(m_fakeToolBar, SIGNAL(goForwardClicked()), this, SLOT(onGoForwardClicked()));
connect(m_fakeToolBar, SIGNAL(goBackClicked()), this, SLOT(onGoBackClicked()));
setupNavigatorHistory();
if (currentDesignDocument())
setupNavigatorHistory(currentDesignDocument()->textEditor());
// right area:
QWidget *centerWidget = new QWidget;
@@ -758,16 +435,16 @@ void DesignModeWidget::setup()
rightLayout->setSpacing(0);
rightLayout->addWidget(m_fakeToolBar);
//### 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);
NavigatorContext *navigatorContext = new NavigatorContext(m_navigatorView->widget());
NavigatorContext *navigatorContext = new NavigatorContext(viewManager().navigatorWidget());
Core::ICore::addContextObject(navigatorContext);
// editor and output panes
m_outputPlaceholderSplitter->addWidget(m_formEditorView->widget());
m_outputPlaceholderSplitter->addWidget(viewManager().formEditorWidget());
m_outputPlaceholderSplitter->addWidget(m_outputPanePlaceholder);
m_outputPlaceholderSplitter->setStretchFactor(0, 10);
m_outputPlaceholderSplitter->setStretchFactor(1, 0);
@@ -791,7 +468,7 @@ void DesignModeWidget::setup()
mainLayout->addWidget(m_mainSplitter);
m_warningWidget->setVisible(false);
m_statesEditorView->widget()->setEnabled(true);
viewManager().statesEditorWidget()->setEnabled(true);
m_leftSideBar->setEnabled(true);
m_rightSideBar->setEnabled(true);
m_leftSideBar->setCloseWhenEmpty(true);
@@ -800,7 +477,6 @@ void DesignModeWidget::setup()
readSettings();
show();
QApplication::processEvents();
}
void DesignModeWidget::updateAvailableSidebarItemsRight()
@@ -827,8 +503,10 @@ void DesignModeWidget::qmlPuppetCrashed()
{
QList<RewriterView::Error> errorList;
RewriterView::Error error(tr("Qt Quick emulation layer crashed"));
errorList << error;
disable(errorList);
errorList.append(error);
disableWidgets();
showErrorMessage(errorList);
}
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)
{
if (m_warningWidget)
@@ -869,35 +546,11 @@ void DesignModeWidget::resizeEvent(QResizeEvent *event)
QWidget::resizeEvent(event);
}
bool DesignModeWidget::isInNodeDefinition(int nodeOffset, int nodeLength, int cursorPos) const {
return (nodeOffset <= cursorPos) && (nodeOffset + nodeLength > cursorPos);
}
ModelNode DesignModeWidget::nodeForPosition(int cursorPos) const
void DesignModeWidget::setupNavigatorHistory(Core::IEditor *editor)
{
RewriterView *rewriter = m_currentDesignDocumentController->rewriterView();
QList<ModelNode> nodes = rewriter->allModelNodes();
if (!m_keepNavigatorHistory)
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 canGoForward = m_navigatorHistoryCounter < (m_navigatorHistory.size() - 1);
m_fakeToolBar->setCanGoBack(canGoBack);
@@ -914,13 +567,30 @@ void DesignModeWidget::addNavigatorHistoryEntry(const QString &fileName)
++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
{
if (m_currentDesignDocumentController)
return m_currentDesignDocumentController->contextHelpId();
if (currentDesignDocument())
return currentDesignDocument()->contextHelpId();
return QString();
}
void DesignModeWidget::initialize()
{
if (m_initStatus == NotInitialized) {
m_initStatus = Initializing;
setup();
}
m_initStatus = Initialized;
}
} // namespace Internal
} // namespace Designer

View File

@@ -35,7 +35,7 @@
#include <utils/faketooltip.h>
#include <texteditor/itexteditor.h>
#include <designdocumentcontroller.h>
#include <designdocument.h>
#include <itemlibraryview.h>
#include <navigatorwidget.h>
#include <navigatorview.h>
@@ -103,54 +103,34 @@ class DesignModeWidget : public QWidget
public:
explicit DesignModeWidget(QWidget *parent = 0);
~DesignModeWidget();
void showEditor(Core::IEditor *editor);
void closeEditors(const QList<Core::IEditor*> editors);
QString contextHelpId() const;
QAction *undoAction() const;
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 initialize();
void readSettings();
void saveSettings();
void setAutoSynchronization(bool sync);
TextEditor::ITextEditor *textEditor() const {return m_textEditor.data(); }
TextEditor::ITextEditor *textEditor() const;
static DesignModeWidget *instance();
DesignDocumentController *currentDesignDocumentController() const {return m_currentDesignDocumentController.data(); }
DesignDocument *currentDesignDocument() const;
ViewManager &viewManager();
private slots:
void undo();
void redo();
void deleteSelected();
void cutSelected();
void copySelected();
void paste();
void selectAll();
void closeCurrentEditor();
void enableWidgets();
void disableWidgets();
void showErrorMessage(const QList<RewriterView::Error> &errors);
public slots:
void updateErrorStatus(const QList<RewriterView::Error> &errors);
void restoreDefaultView();
void toggleSidebars();
void toggleLeftSidebar();
void toggleRightSidebar();
void restoreDefaultView();
void undoAvailable(bool isAvailable);
void redoAvailable(bool isAvailable);
void goIntoComponent();
void enable();
void disable(const QList<RewriterView::Error> &errors);
void updateErrorStatus(const QList<RewriterView::Error> &errors);
private slots:
void updateAvailableSidebarItemsLeft();
void updateAvailableSidebarItemsRight();
@@ -160,49 +140,20 @@ private slots:
void onGoBackClicked();
void onGoForwardClicked();
void onCrumblePathElementClicked(const QVariant &data);
protected:
void resizeEvent(QResizeEvent *event);
private:
void setCurrentDocument(DesignDocumentController *newDesignDocumentController);
//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;
private: // functions
enum InitializeStatus { NotInitialized, Initializing, Initialized };
void setCurrentDesignDocument(DesignDocument *newDesignDocument);
void setup();
bool isInNodeDefinition(int nodeOffset, int nodeLength, int cursorPos) const;
QmlDesigner::ModelNode nodeForPosition(int cursorPos) const;
void setupNavigatorHistory();
void setupNavigatorHistory(Core::IEditor *editor);
void addNavigatorHistoryEntry(const QString &fileName);
QWeakPointer<TextEditor::ITextEditor> m_textEditor;
private: // variables
QSplitter *m_mainSplitter;
Core::SideBar *m_leftSideBar;
Core::SideBar *m_rightSideBar;
@@ -213,15 +164,12 @@ private:
bool m_isDisabled;
bool m_showSidebars;
enum InitializeStatus { NotInitialized, Initializing, Initialized };
InitializeStatus m_initStatus;
DocumentWarningWidget *m_warningWidget;
QStringList m_navigatorHistory;
int m_navigatorHistoryCounter;
bool m_keepNavigatorHistory;
static DesignModeWidget *s_instance;
};
} // 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/modemanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/hostosinfo.h>
@@ -66,9 +68,18 @@
#include <QProcessEnvironment>
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()
{
@@ -76,15 +87,8 @@ bool shouldAssertInException()
return !processEnvironment.value("QMLDESIGNER_ASSERT_ON_EXCEPTION").isEmpty();
}
BauhausPlugin::BauhausPlugin() :
m_designMode(0),
m_isActive(false),
m_revertToSavedAction(new QAction(this)),
m_saveAction(new QAction(this)),
m_saveAsAction(new QAction(this)),
m_closeCurrentEditorAction(new QAction(this)),
m_closeAllEditorsAction(new QAction(this)),
m_closeOtherEditorsAction(new QAction(this))
QmlDesignerPlugin::QmlDesignerPlugin() :
m_isActive(false)
{
// Exceptions should never ever assert: they are handled in a number of
@@ -101,9 +105,11 @@ BauhausPlugin::BauhausPlugin() :
Exception::setShouldAssert(shouldAssertInException());
}
BauhausPlugin::~BauhausPlugin()
QmlDesignerPlugin::~QmlDesignerPlugin()
{
Core::ICore::removeContextObject(m_context);
m_context = 0;
m_instance = 0;
}
////////////////////////////////////////////////////
@@ -111,7 +117,7 @@ BauhausPlugin::~BauhausPlugin()
// 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,
QmlJSEditor::Constants::C_QMLJSEDITOR_ID);
@@ -121,7 +127,7 @@ bool BauhausPlugin::initialize(const QStringList & /*arguments*/, QString *error
switchAction, QmlDesigner::Constants::SWITCH_TEXT_DESIGN, switchContext);
command->setDefaultKeySequence(QKeySequence(Qt::Key_F4));
m_pluginInstance = this;
m_instance = this;
const QString pluginPath = Utils::HostOsInfo::isMacHost()
? QString(QCoreApplication::applicationDirPath() + "/../PlugIns/QmlDesigner")
@@ -132,7 +138,7 @@ bool BauhausPlugin::initialize(const QStringList & /*arguments*/, QString *error
createDesignModeWidget();
connect(switchAction, SIGNAL(triggered()), this, SLOT(switchTextDesign()));
addAutoReleasedObject(new SettingsPage);
addAutoReleasedObject(new Internal::SettingsPage);
m_settings.fromSettings(Core::ICore::settings());
@@ -142,240 +148,295 @@ bool BauhausPlugin::initialize(const QStringList & /*arguments*/, QString *error
return true;
}
void BauhausPlugin::createDesignModeWidget()
void QmlDesignerPlugin::createDesignModeWidget()
{
m_editorManager = Core::ICore::editorManager();
Core::ActionContainer *editMenu = Core::ActionManager::actionContainer(Core::Constants::M_EDIT);
m_mainWidget = new Internal::DesignModeWidget;
m_mainWidget = new DesignModeWidget;
m_context = new DesignModeContext(m_mainWidget);
m_context = new Internal::DesignModeContext(m_mainWidget);
Core::ICore::addContextObject(m_context);
Core::Context qmlDesignerMainContext(Constants::C_QMLDESIGNER);
Core::Context qmlDesignerFormEditorContext(Constants::C_QMLFORMEDITOR);
Core::Context qmlDesignerNavigatorContext(Constants::C_QMLNAVIGATOR);
// Revert to saved
Core::ActionManager::registerAction(m_revertToSavedAction,
Core::Constants::REVERTTOSAVED, qmlDesignerMainContext);
connect(m_revertToSavedAction, SIGNAL(triggered()), m_editorManager, SLOT(revertToSaved()));
m_context->context().add(qmlDesignerMainContext);
m_context->context().add(qmlDesignerFormEditorContext);
m_context->context().add(qmlDesignerNavigatorContext);
m_context->context().add(ProjectExplorer::Constants::LANG_QMLJS);
//Save
Core::ActionManager::registerAction(m_saveAction, Core::Constants::SAVE, qmlDesignerMainContext);
connect(m_saveAction, SIGNAL(triggered()), m_editorManager, SLOT(saveDocument()));
m_shortCutManager.registerActions();
//Save As
Core::ActionManager::registerAction(m_saveAsAction, Core::Constants::SAVEAS, qmlDesignerMainContext);
connect(m_saveAsAction, SIGNAL(triggered()), m_editorManager, SLOT(saveDocumentAs()));
connect(Core::ICore::editorManager(),
SIGNAL(currentEditorChanged(Core::IEditor*)),
this,
SLOT(onCurrentEditorChanged(Core::IEditor*)));
//Close Editor
Core::ActionManager::registerAction(m_closeCurrentEditorAction, Core::Constants::CLOSE, qmlDesignerMainContext);
connect(m_closeCurrentEditorAction, SIGNAL(triggered()), m_editorManager, SLOT(closeEditor()));
connect(Core::ICore::editorManager(),
SIGNAL(editorsClosed(QList<Core::IEditor*>)),
this,
SLOT(onTextEditorsClosed(QList<Core::IEditor*>)));
//Close All
Core::ActionManager::registerAction(m_closeAllEditorsAction, Core::Constants::CLOSEALL, qmlDesignerMainContext);
connect(m_closeAllEditorsAction, SIGNAL(triggered()), m_editorManager, SLOT(closeAllEditors()));
// connect(Core::ICore::editorManager(), SIGNAL(currentEditorChanged(Core::IEditor*)),
// &m_documentManager, SLOT(currentTextEditorChanged(Core::IEditor*)));
//Close All Others Action
Core::ActionManager::registerAction(m_closeOtherEditorsAction, Core::Constants::CLOSEOTHERS, qmlDesignerMainContext);
connect(m_closeOtherEditorsAction, SIGNAL(triggered()), m_editorManager, SLOT(closeOtherEditors()));
// connect(Core::ICore::instance(), SIGNAL(contextChanged(Core::IContext*,Core::Context)),
// this, SLOT(contextChanged(Core::IContext*,Core::Context)));
// Undo / Redo
Core::ActionManager::registerAction(m_mainWidget->undoAction(), Core::Constants::UNDO, qmlDesignerMainContext);
Core::ActionManager::registerAction(m_mainWidget->redoAction(), Core::Constants::REDO, qmlDesignerMainContext);
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)));
connect(Core::ModeManager::instance(),
SIGNAL(currentModeChanged(Core::IMode*,Core::IMode*)),
SLOT(onCurrentModeChanged(Core::IMode*,Core::IMode*)));
}
void BauhausPlugin::updateEditor(Core::IEditor *editor)
void QmlDesignerPlugin::showDesigner()
{
if (editor && editor->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID
&& Core::ModeManager::currentMode() == m_designMode)
{
m_mainWidget->showEditor(editor);
Q_ASSERT(!m_documentManager.hasCurrentDesignDocument());
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 BauhausPlugin::contextChanged(Core::IContext *context, const Core::Context &additionalContexts)
void QmlDesignerPlugin::selectModelNodeUnderTextCursor()
{
Q_UNUSED(context)
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);
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 BauhausPlugin::textEditorsClosed(QList<Core::IEditor*> editors)
void QmlDesignerPlugin::activateAutoSynchronization()
{
m_mainWidget->closeEditors(editors);
}
// copied from EditorManager::updateActions
void BauhausPlugin::updateActions(Core::IEditor* editor)
{
Core::IEditor *curEditor = editor;
int openedCount = m_editorManager->openedEditors().count()
+ m_editorManager->openedEditorsModel()->restoredEditors().count();
QString fName;
if (curEditor) {
if (!curEditor->document()->fileName().isEmpty()) {
QFileInfo fi(curEditor->document()->fileName());
fName = fi.fileName();
// text editor -> visual editor
if (!currentDesignDocument()->isDocumentLoaded()) {
currentDesignDocument()->loadDocument(currentDesignDocument()->plainTextEdit());
} else {
fName = curEditor->displayName();
}
currentDesignDocument()->activateCurrentModel();
}
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());
resetModelSelection();
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")));
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 BauhausPlugin::extensionsInitialized()
void QmlDesignerPlugin::deactivateAutoSynchronization()
{
m_designMode = Core::DesignMode::instance();
viewManager().detachViewsExceptRewriterAndComponetView();
viewManager().detachComponentView();
m_mimeTypes << "application/x-qml";
disconnect(currentDesignDocument()->rewriterView(),
SIGNAL(errorsChanged(QList<RewriterView::Error>)),
m_mainWidget,
SLOT(updateErrorStatus(QList<RewriterView::Error>)));
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::resetModelSelection()
{
return m_pluginInstance;
if (currentDesignDocument()->rewriterView() && currentDesignDocument()->currentModel())
currentDesignDocument()->rewriterView()->setSelectedModelNodes(QList<ModelNode>());
}
void BauhausPlugin::switchTextDesign()
void QmlDesignerPlugin::onCurrentEditorChanged(Core::IEditor *editor)
{
if (editor
&& editor->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID
&& isInDesignerMode())
{
m_shortCutManager.updateActions(editor);
changeEditor();
}
}
static bool isDesignerMode(Core::IMode *mode)
{
return mode == Core::DesignMode::instance();
}
void QmlDesignerPlugin::onCurrentModeChanged(Core::IMode *newMode, Core::IMode *oldMode)
{
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();
}
DesignDocument *QmlDesignerPlugin::currentDesignDocument() const
{
return m_documentManager.currentDesignDocument();
}
Internal::DesignModeWidget *QmlDesignerPlugin::mainWidget() const
{
return m_mainWidget;
}
void QmlDesignerPlugin::onTextEditorsClosed(QList<Core::IEditor*> editors)
{
if (m_documentManager.hasCurrentDesignDocument()
&& editors.contains(m_documentManager.currentDesignDocument()->textEditor()))
hideDesigner();
m_documentManager.removeEditors(editors);
}
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) {
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);
m_mainWidget->setFocus();
}
} else if (Core::ModeManager::currentMode()->id() == Core::Constants::MODE_DESIGN) {
Core::ModeManager::activateMode(Core::Constants::MODE_EDIT);
}
}
DesignerSettings BauhausPlugin::settings()
DesignerSettings QmlDesignerPlugin::settings()
{
m_settings.fromSettings(Core::ICore::settings());
return m_settings;
}
void BauhausPlugin::setSettings(const DesignerSettings &s)
void QmlDesignerPlugin::setSettings(const DesignerSettings &s)
{
if (s != m_settings) {
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 "documentmanager.h"
#include "viewmanager.h"
#include "shortcutmanager.h"
#include <QWeakPointer>
#include <QStringList>
@@ -51,60 +55,70 @@ namespace Core {
}
namespace QmlDesigner {
namespace Internal {
namespace Internal {
class DesignModeWidget;
class DesignModeContext;
}
class BauhausPlugin : public ExtensionSystem::IPlugin
class QmlDesignerPlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "QmlDesigner.json")
public:
BauhausPlugin();
virtual ~BauhausPlugin();
QmlDesignerPlugin();
virtual ~QmlDesignerPlugin();
//Plugin
virtual bool initialize(const QStringList &arguments, QString *errorMessage = 0);
virtual void extensionsInitialized();
static BauhausPlugin *pluginInstance();
static QmlDesignerPlugin *instance();
DocumentManager &documentManager();
const DocumentManager &documentManager() const;
ViewManager &viewManager();
const ViewManager &viewManager() const;
DesignerSettings settings();
void setSettings(const DesignerSettings &s);
DesignDocument *currentDesignDocument() const;
Internal::DesignModeWidget *mainWidget() const;
private slots:
void switchTextDesign();
void textEditorsClosed(QList<Core::IEditor *> editors);
void updateActions(Core::IEditor* editor);
void updateEditor(Core::IEditor *editor);
void contextChanged(Core::IContext *context, const Core::Context &additionalContexts);
void onTextEditorsClosed(QList<Core::IEditor *> editors);
void onCurrentEditorChanged(Core::IEditor *editor);
void onCurrentModeChanged(Core::IMode *mode, Core::IMode *oldMode);
private:
private: // functions
void createDesignModeWidget();
void showDesigner();
void hideDesigner();
void changeEditor();
void jumpTextCursorToSelectedModelNode();
void selectModelNodeUnderTextCursor();
void activateAutoSynchronization();
void deactivateAutoSynchronization();
void resetModelSelection();
QStringList m_mimeTypes;
DesignModeWidget *m_mainWidget;
private: // variables
ViewManager m_viewManager;
DocumentManager m_documentManager;
ShortCutManager m_shortCutManager;
Internal::DesignModeWidget *m_mainWidget;
QmlDesigner::PluginManager m_pluginManager;
static BauhausPlugin *m_pluginInstance;
static QmlDesignerPlugin *m_instance;
DesignerSettings m_settings;
DesignModeContext *m_context;
Core::DesignMode *m_designMode;
Core::EditorManager *m_editorManager;
Internal::DesignModeContext *m_context;
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
#endif // QMLDESIGNERPLUGIN_H

View File

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

View File

@@ -95,7 +95,7 @@ SettingsPage::SettingsPage() :
QWidget *SettingsPage::createPage(QWidget *parent)
{
m_widget = new SettingsPageWidget(parent);
m_widget->setSettings(BauhausPlugin::pluginInstance()->settings());
m_widget->setSettings(QmlDesignerPlugin::instance()->settings());
if (m_searchKeywords.isEmpty())
m_searchKeywords = m_widget->searchKeywords();
return m_widget;
@@ -105,7 +105,7 @@ void SettingsPage::apply()
{
if (!m_widget) // page was never shown
return;
BauhausPlugin::pluginInstance()->setSettings(m_widget->settings());
QmlDesignerPlugin::instance()->setSettings(m_widget->settings());
}
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