forked from qt-creator/qt-creator
QmlDesigner: adding crumblePath
Change-Id: Ic0d68b145398a161194d2a469e9a2f15fe0901d5 Reviewed-on: http://codereview.qt-project.org/4996 Reviewed-by: Thomas Hartmann <Thomas.Hartmann@nokia.com>
This commit is contained in:
@@ -46,6 +46,7 @@
|
||||
#include <formeditorview.h>
|
||||
#include <propertyeditor.h>
|
||||
#include <formeditorwidget.h>
|
||||
#include <toolbox.h>
|
||||
#include <basetexteditmodifier.h>
|
||||
#include <componenttextmodifier.h>
|
||||
#include <metainfo.h>
|
||||
@@ -59,8 +60,10 @@
|
||||
#include <variantproperty.h>
|
||||
#include <rewritingexception.h>
|
||||
#include <model/modelnodecontextmenu.h>
|
||||
#include <designmodewidget.h>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/crumblepath.h>
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QDir>
|
||||
@@ -118,15 +121,22 @@ public:
|
||||
QmlDesigner::ComponentTextModifier *componentTextModifier;
|
||||
QWeakPointer<SubComponentManager> subComponentManager;
|
||||
QWeakPointer<Internal::ViewLogger> viewLogger;
|
||||
ModelNode componentNode;
|
||||
|
||||
QString fileName;
|
||||
QUrl searchPath;
|
||||
bool documentLoaded;
|
||||
bool syncBlocked;
|
||||
int qt_versionId;
|
||||
static bool clearCrumblePath;
|
||||
static bool pushCrumblePath;
|
||||
};
|
||||
|
||||
|
||||
bool DesignDocumentControllerPrivate::clearCrumblePath = true;
|
||||
bool DesignDocumentControllerPrivate::pushCrumblePath = true;
|
||||
|
||||
|
||||
/**
|
||||
\class QmlDesigner::DesignDocumentController
|
||||
|
||||
@@ -191,6 +201,15 @@ void DesignDocumentController::changeToMasterModel()
|
||||
d->rewriterView->setTextModifier(d->textModifier);
|
||||
d->model = d->masterModel;
|
||||
d->model->attachView(d->rewriterView.data());
|
||||
d->componentNode = d->rewriterView->rootModelNode();
|
||||
}
|
||||
|
||||
QVariant DesignDocumentController::createCrumbleBarInfo()
|
||||
{
|
||||
CrumbleBarInfo info;
|
||||
info.fileName = fileName();
|
||||
info.modelNode = d->componentNode;
|
||||
return QVariant::fromValue<CrumbleBarInfo>(info);
|
||||
}
|
||||
|
||||
QWidget *DesignDocumentController::centralWidget() const
|
||||
@@ -302,7 +321,27 @@ void DesignDocumentController::setComponentView(ComponentView *componentView)
|
||||
connect(d->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)
|
||||
{
|
||||
DesignDocumentControllerPrivate::clearCrumblePath = false;
|
||||
DesignDocumentControllerPrivate::pushCrumblePath = false;
|
||||
while (!compareCrumbleBarInfo(d->formEditorView->widget()->toolBox()->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>(), crumbleBarInfo))
|
||||
d->formEditorView->widget()->toolBox()->crumblePath()->popElement();
|
||||
Core::EditorManager::instance()->openEditor(crumbleBarInfo.fileName);
|
||||
DesignDocumentControllerPrivate::pushCrumblePath = true;
|
||||
Internal::DesignModeWidget::instance()->currentDesignDocumentController()->changeToSubComponent(crumbleBarInfo.modelNode);
|
||||
DesignDocumentControllerPrivate::clearCrumblePath = true;
|
||||
}
|
||||
|
||||
void DesignDocumentController::setBlockCrumbleBar(bool b)
|
||||
{
|
||||
DesignDocumentControllerPrivate::clearCrumblePath = !b;
|
||||
DesignDocumentControllerPrivate::pushCrumblePath = !b;
|
||||
}
|
||||
|
||||
QString DesignDocumentController::displayName() const
|
||||
@@ -313,6 +352,22 @@ QString DesignDocumentController::displayName() const
|
||||
return fileName();
|
||||
}
|
||||
|
||||
QString DesignDocumentController::simplfiedDisplayName() const
|
||||
{
|
||||
if (!d->componentNode.isRootNode()) {
|
||||
if (d->componentNode.id().isEmpty()) {
|
||||
if (d->formEditorView->rootModelNode().id().isEmpty()) {
|
||||
return d->formEditorView->rootModelNode().simplifiedTypeName();
|
||||
}
|
||||
return d->formEditorView->rootModelNode().id();
|
||||
}
|
||||
return d->componentNode.id();
|
||||
}
|
||||
|
||||
QStringList list = displayName().split("/");
|
||||
return list.last();
|
||||
}
|
||||
|
||||
QString DesignDocumentController::fileName() const
|
||||
{
|
||||
return d->fileName;
|
||||
@@ -374,6 +429,7 @@ QList<RewriterView::Error> DesignDocumentController::loadMaster(QPlainTextEdit *
|
||||
|
||||
d->masterModel->attachView(d->rewriterView.data());
|
||||
d->model = d->masterModel;
|
||||
d->componentNode = d->rewriterView->rootModelNode();
|
||||
|
||||
d->subComponentManager = new SubComponentManager(d->masterModel.data(), this);
|
||||
d->subComponentManager->update(d->searchPath, d->model->imports());
|
||||
@@ -385,7 +441,22 @@ QList<RewriterView::Error> DesignDocumentController::loadMaster(QPlainTextEdit *
|
||||
return d->rewriterView->errors();
|
||||
}
|
||||
|
||||
void DesignDocumentController::changeCurrentModelTo(const ModelNode &componentNode)
|
||||
void DesignDocumentController::changeCurrentModelTo(const ModelNode &node)
|
||||
{
|
||||
if (d->componentNode == node)
|
||||
return;
|
||||
if (Internal::DesignModeWidget::instance()->currentDesignDocumentController() != this)
|
||||
return;
|
||||
DesignDocumentControllerPrivate::clearCrumblePath = false;
|
||||
while (!d->formEditorView->widget()->toolBox()->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>().modelNode.isRootNode())
|
||||
d->formEditorView->widget()->toolBox()->crumblePath()->popElement();
|
||||
if (node.isRootNode())
|
||||
d->formEditorView->widget()->toolBox()->crumblePath()->popElement();
|
||||
changeToSubComponent(node);
|
||||
DesignDocumentControllerPrivate::clearCrumblePath = true;
|
||||
}
|
||||
|
||||
void DesignDocumentController::changeToSubComponent(const ModelNode &componentNode)
|
||||
{
|
||||
Q_ASSERT(d->masterModel);
|
||||
QWeakPointer<Model> oldModel = d->model;
|
||||
@@ -405,6 +476,7 @@ void DesignDocumentController::changeCurrentModelTo(const ModelNode &componentNo
|
||||
explicitComponent = true;
|
||||
}
|
||||
|
||||
d->componentNode = componentNode;
|
||||
if (!componentNode.isRootNode()) {
|
||||
Q_ASSERT(d->model == d->masterModel);
|
||||
Q_ASSERT(componentNode.isValid());
|
||||
@@ -449,6 +521,13 @@ void DesignDocumentController::changeCurrentModelTo(const ModelNode &componentNo
|
||||
d->componentView->setComponentNode(componentNode);
|
||||
}
|
||||
|
||||
void DesignDocumentController::changeToExternalSubComponent(const QString &fileName)
|
||||
{
|
||||
DesignDocumentControllerPrivate::clearCrumblePath = false;
|
||||
Core::EditorManager::instance()->openEditor(fileName);
|
||||
DesignDocumentControllerPrivate::clearCrumblePath = true;
|
||||
}
|
||||
|
||||
void DesignDocumentController::goIntoComponent()
|
||||
{
|
||||
if (!d->model)
|
||||
@@ -469,6 +548,7 @@ void DesignDocumentController::loadCurrentModel()
|
||||
Q_ASSERT(d->masterModel);
|
||||
Q_ASSERT(d->model);
|
||||
d->model->setMasterModel(d->masterModel.data());
|
||||
d->masterModel->attachView(d->componentView.data());
|
||||
|
||||
d->nodeInstanceView->setPathToQt(pathToQt());
|
||||
d->model->attachView(d->nodeInstanceView.data());
|
||||
@@ -486,6 +566,15 @@ void DesignDocumentController::loadCurrentModel()
|
||||
|
||||
d->model->attachView(d->propertyEditorView.data());
|
||||
|
||||
|
||||
if (DesignDocumentControllerPrivate::clearCrumblePath)
|
||||
d->formEditorView->widget()->toolBox()->crumblePath()->clear();
|
||||
|
||||
if (DesignDocumentControllerPrivate::pushCrumblePath &&
|
||||
!compareCrumbleBarInfo(d->formEditorView->widget()->toolBox()->crumblePath()->dataForLastIndex().value<CrumbleBarInfo>(),
|
||||
createCrumbleBarInfo().value<CrumbleBarInfo>()))
|
||||
d->formEditorView->widget()->toolBox()->crumblePath()->pushElement(simplfiedDisplayName(), createCrumbleBarInfo());
|
||||
|
||||
d->documentLoaded = true;
|
||||
Q_ASSERT(d->masterModel);
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
||||
@@ -60,6 +60,7 @@ class ComponentView;
|
||||
class PropertyEditor;
|
||||
class StatesEditorView;
|
||||
class FormEditorView;
|
||||
struct CrumbleBarInfo;
|
||||
|
||||
class DesignDocumentController: public QObject
|
||||
{
|
||||
@@ -70,6 +71,8 @@ public:
|
||||
~DesignDocumentController();
|
||||
|
||||
QString displayName() const;
|
||||
QString simplfiedDisplayName() const;
|
||||
|
||||
QString fileName() const;
|
||||
void setFileName(const QString &fileName);
|
||||
|
||||
@@ -101,7 +104,8 @@ public:
|
||||
void setNodeInstanceView(NodeInstanceView *nodeInstanceView);
|
||||
void setComponentView(ComponentView *componentView);
|
||||
|
||||
static DesignDocumentController *instance();
|
||||
void setCrumbleBarInfo(const CrumbleBarInfo &crumbleBarInfo);
|
||||
static void setBlockCrumbleBar(bool);
|
||||
|
||||
signals:
|
||||
void displayNameChanged(const QString &newFileName);
|
||||
@@ -126,6 +130,8 @@ public slots:
|
||||
void redo();
|
||||
void activeQtVersionChanged();
|
||||
void changeCurrentModelTo(const ModelNode &node);
|
||||
void changeToSubComponent(const ModelNode &node);
|
||||
void changeToExternalSubComponent(const QString &fileName);
|
||||
void goIntoComponent();
|
||||
|
||||
#ifdef ENABLE_TEXT_VIEW
|
||||
@@ -140,14 +146,23 @@ private:
|
||||
void detachNodeInstanceView();
|
||||
void attachNodeInstanceView();
|
||||
void changeToMasterModel();
|
||||
QVariant createCrumbleBarInfo();
|
||||
|
||||
QWidget *centralWidget() const;
|
||||
QString pathToQt() const;
|
||||
|
||||
class DesignDocumentControllerPrivate *d;
|
||||
|
||||
class DesignDocumentControllerPrivate *d;
|
||||
};
|
||||
|
||||
|
||||
struct CrumbleBarInfo {
|
||||
ModelNode modelNode;
|
||||
QString fileName;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(CrumbleBarInfo)
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
#endif // DesignDocumentController_h
|
||||
|
||||
@@ -47,12 +47,16 @@
|
||||
#include <rewritertransaction.h>
|
||||
#include <designmodewidget.h>
|
||||
#include <qmlanchors.h>
|
||||
#include <designdocumentcontroller.h>
|
||||
|
||||
const QString auxDataString = QLatin1String("anchors_");
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
static inline DesignDocumentController* designDocumentController()
|
||||
{
|
||||
return Internal::DesignModeWidget::instance()->currentDesignDocumentController();
|
||||
}
|
||||
|
||||
static inline QString captionForModelNode(const ModelNode &modelNode)
|
||||
{
|
||||
if (modelNode.id().isEmpty())
|
||||
@@ -188,15 +192,82 @@ static inline bool isFileComponent(const ModelNode &node)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void getWidthHeight(const ModelNode &node, int &width, int &height)
|
||||
{
|
||||
QmlItemNode itemNode(node);
|
||||
if (itemNode.isValid()) {
|
||||
width = itemNode.instanceValue("width").toInt();
|
||||
height = itemNode.instanceValue("height").toInt();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void getProperties(const ModelNode node, QHash<QString, QVariant> &propertyHash)
|
||||
{
|
||||
if (QmlObjectNode(node).isValid()) {
|
||||
foreach (const QString &propertyName, node.propertyNames()) {
|
||||
if (node.property(propertyName).isVariantProperty() ||
|
||||
node.property(propertyName).isBindingProperty() &&
|
||||
!propertyName.contains(QLatin1String("anchors."))) {
|
||||
propertyHash.insert(propertyName, QmlObjectNode(node).instanceValue(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
QmlItemNode itemNode(node);
|
||||
if (itemNode.isValid()) {
|
||||
propertyHash.insert(QLatin1String("width"), itemNode.instanceValue(QLatin1String("width")));
|
||||
propertyHash.insert(QLatin1String("height"), itemNode.instanceValue(QLatin1String("height")));
|
||||
propertyHash.remove(QLatin1String("x"));
|
||||
propertyHash.remove(QLatin1String("y"));
|
||||
propertyHash.remove(QLatin1String("rotation"));
|
||||
propertyHash.remove(QLatin1String("opacity"));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void applyProperties(ModelNode &node, const QHash<QString, QVariant> &propertyHash)
|
||||
{
|
||||
QHash<QString, QVariant> auxiliaryData = node.auxiliaryData();
|
||||
foreach (const QString propertyName, auxiliaryData.keys()) {
|
||||
node.setAuxiliaryData(propertyName, QVariant());
|
||||
}
|
||||
|
||||
QHashIterator<QString, QVariant> i(propertyHash);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
if (i.key() == QLatin1String("width") || i.key() == QLatin1String("height")) {
|
||||
node.setAuxiliaryData(i.key(), i.value());
|
||||
} else if (node.property(i.key()).isDynamic() &&
|
||||
node.property(i.key()).dynamicTypeName() == QLatin1String("alias") &&
|
||||
node.property(i.key()).isBindingProperty()) {
|
||||
AbstractProperty targetProperty = node.bindingProperty(i.key()).resolveToProperty();
|
||||
if (targetProperty.isValid()) {
|
||||
targetProperty.parentModelNode().setAuxiliaryData(targetProperty.name() + QLatin1String("@NodeInstance"), i.value());
|
||||
}
|
||||
} else {
|
||||
node.setAuxiliaryData(i.key() + QLatin1String("@NodeInstance"), i.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void openFileForComponent(const ModelNode &node)
|
||||
{
|
||||
//int width = 0;
|
||||
//int height = 0;
|
||||
QHash<QString, QVariant> propertyHash;
|
||||
if (node.metaInfo().isComponent()) {
|
||||
Core::EditorManager::instance()->openEditor(node.metaInfo().componentFileName());
|
||||
//getWidthHeight(node, width, height);
|
||||
getProperties(node, propertyHash);
|
||||
designDocumentController()->changeToExternalSubComponent(node.metaInfo().componentFileName());
|
||||
} else if (checkIfNodeIsAView(node) &&
|
||||
node.hasNodeProperty("delegate") &&
|
||||
node.nodeProperty("delegate").modelNode().metaInfo().isComponent()) {
|
||||
Core::EditorManager::instance()->openEditor(node.nodeProperty("delegate").modelNode().metaInfo().componentFileName());
|
||||
//getWidthHeight(node, width, height);
|
||||
getProperties(node, propertyHash);
|
||||
designDocumentController()->changeToExternalSubComponent(node.nodeProperty("delegate").modelNode().metaInfo().componentFileName());
|
||||
}
|
||||
ModelNode rootModelNode = designDocumentController()->model()->rewriterView()->rootModelNode();
|
||||
applyProperties(rootModelNode, propertyHash);
|
||||
//rootModelNode.setAuxiliaryData("width", width);
|
||||
//rootModelNode.setAuxiliaryData("height", height);
|
||||
}
|
||||
|
||||
static inline void openInlineComponent(const ModelNode &node)
|
||||
@@ -204,18 +275,32 @@ static inline void openInlineComponent(const ModelNode &node)
|
||||
if (!node.isValid() || !node.metaInfo().isValid())
|
||||
return;
|
||||
|
||||
if (!DesignDocumentController::instance())
|
||||
if (!designDocumentController())
|
||||
return;
|
||||
|
||||
if (node.nodeSourceType() == ModelNode::NodeWithComponentSource)
|
||||
DesignDocumentController::instance()->changeCurrentModelTo(node);
|
||||
if (checkIfNodeIsAView(node) &&
|
||||
//int width = 0;
|
||||
//int height = 0;
|
||||
QHash<QString, QVariant> propertyHash;
|
||||
|
||||
if (node.nodeSourceType() == ModelNode::NodeWithComponentSource) {
|
||||
//getWidthHeight(node, width, height);
|
||||
getProperties(node, propertyHash);
|
||||
designDocumentController()->changeToSubComponent(node);
|
||||
} else if (checkIfNodeIsAView(node) &&
|
||||
node.hasNodeProperty("delegate")) {
|
||||
if (node.nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource)
|
||||
DesignDocumentController::instance()->changeCurrentModelTo(node.nodeProperty("delegate").modelNode());
|
||||
if (node.nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource) {
|
||||
//getWidthHeight(node, width, height);
|
||||
getProperties(node, propertyHash);
|
||||
designDocumentController()->changeToSubComponent(node.nodeProperty("delegate").modelNode());
|
||||
}
|
||||
}
|
||||
|
||||
ModelNode rootModelNode = designDocumentController()->model()->rewriterView()->rootModelNode();
|
||||
applyProperties(rootModelNode, propertyHash);
|
||||
//rootModelNode.setAuxiliaryData("width", width);
|
||||
//rootModelNode.setAuxiliaryData("height", height);
|
||||
}
|
||||
|
||||
static inline bool modelNodesHaveProperty(const QList<ModelNode> &modelNodeList, const QString &propertyName)
|
||||
{
|
||||
foreach (const ModelNode &modelNode, modelNodeList)
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#include <utils/parameteraction.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/crumblepath.h>
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QEvent>
|
||||
@@ -704,6 +705,7 @@ void DesignModeWidget::setup()
|
||||
m_statesEditorView = new StatesEditorView(this);
|
||||
|
||||
m_formEditorView = new FormEditorView(this);
|
||||
connect(m_formEditorView->widget()->toolBox()->crumblePath(), SIGNAL(elementClicked(QVariant)), this, SLOT(onCrumblePathElementClicked(QVariant)));
|
||||
|
||||
m_componentView = new ComponentView(this);
|
||||
m_formEditorView->widget()->toolBox()->addLeftSideAction(m_componentView->action());
|
||||
|
||||
@@ -165,6 +165,8 @@ private slots:
|
||||
void onGoBackClicked();
|
||||
void onGoForwardClicked();
|
||||
|
||||
void onCrumblePathElementClicked(const QVariant &data);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user