1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "navigatorview.h"
35 #include "navigatortreemodel.h"
36 #include "navigatorwidget.h"
38 #include <coreplugin/editormanager/editormanager.h>
40 #include <nodeproperty.h>
41 #include <nodelistproperty.h>
42 #include <QHeaderView>
45 namespace QmlDesigner {
47 NavigatorView::NavigatorView(QObject* parent) :
49 m_blockSelectionChangedSignal(false),
50 m_widget(new NavigatorWidget),
51 m_treeModel(new NavigatorTreeModel(this))
53 m_widget->setTreeModel(m_treeModel.data());
55 connect(treeWidget()->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(changeSelection(QItemSelection,QItemSelection)));
56 treeWidget()->setIndentation(treeWidget()->indentation() * 0.5);
58 NameItemDelegate *idDelegate = new NameItemDelegate(this,m_treeModel.data());
59 IconCheckboxItemDelegate *showDelegate = new IconCheckboxItemDelegate(this,":/qmldesigner/images/eye_open.png",
60 ":/qmldesigner/images/placeholder.png",m_treeModel.data());
63 IconCheckboxItemDelegate *lockDelegate = new IconCheckboxItemDelegate(this,":/qmldesigner/images/lock.png",
64 ":/qmldesigner/images/hole.png",m_treeModel.data());
68 treeWidget()->setItemDelegateForColumn(0,idDelegate);
70 treeWidget()->setItemDelegateForColumn(1,lockDelegate);
71 treeWidget()->setItemDelegateForColumn(2,showDelegate);
73 treeWidget()->setItemDelegateForColumn(1,showDelegate);
78 NavigatorView::~NavigatorView()
80 if (m_widget && !m_widget->parent())
81 delete m_widget.data();
84 QWidget *NavigatorView::widget()
86 return m_widget.data();
89 void NavigatorView::modelAttached(Model *model)
91 AbstractView::modelAttached(model);
93 m_treeModel->setView(this);
95 QTreeView *treeView = treeWidget();
96 treeView->expandAll();
98 treeView->header()->setResizeMode(0, QHeaderView::Stretch);
99 treeView->header()->resizeSection(1,26);
100 treeView->setRootIsDecorated(false);
101 treeView->setIndentation(20);
103 treeView->header()->resizeSection(2,20);
107 void NavigatorView::modelAboutToBeDetached(Model *model)
109 m_treeModel->clearView();
110 AbstractView::modelAboutToBeDetached(model);
113 void NavigatorView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/)
115 treeWidget()->update();
118 void NavigatorView::nodeCreated(const ModelNode & /*createdNode*/)
122 void NavigatorView::nodeRemoved(const ModelNode & /*removedNode*/, const NodeAbstractProperty & /*parentProperty*/, PropertyChangeFlags /*propertyChange*/)
126 void NavigatorView::propertiesRemoved(const QList<AbstractProperty> & /*propertyList*/)
130 void NavigatorView::variantPropertiesChanged(const QList<VariantProperty> & /*propertyList*/, PropertyChangeFlags /*propertyChange*/)
134 void NavigatorView::bindingPropertiesChanged(const QList<BindingProperty> & /*propertyList*/, PropertyChangeFlags /*propertyChange*/)
138 void NavigatorView::nodeAboutToBeRemoved(const ModelNode &removedNode)
140 if (m_treeModel->isInTree(removedNode))
141 m_treeModel->removeSubTree(removedNode);
144 void NavigatorView::nodeAboutToBeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
148 void NavigatorView::nodeReparented(const ModelNode &node, const NodeAbstractProperty & /*newPropertyParent*/, const NodeAbstractProperty & /*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
150 bool blocked = blockSelectionChangedSignal(true);
152 if (m_treeModel->isInTree(node))
153 m_treeModel->removeSubTree(node);
154 if (node.isInHierarchy())
155 m_treeModel->addSubTree(node);
157 // make sure selection is in sync again
158 updateItemSelection();
160 blockSelectionChangedSignal(blocked);
163 void NavigatorView::nodeIdChanged(const ModelNode& node, const QString & /*newId*/, const QString & /*oldId*/)
165 if (m_treeModel->isInTree(node))
166 m_treeModel->updateItemRow(node);
169 void NavigatorView::propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList)
171 foreach (const AbstractProperty &property, propertyList) {
172 if (property.isNodeProperty()) {
173 NodeProperty nodeProperty(property.toNodeProperty());
174 m_treeModel->removeSubTree(nodeProperty.modelNode());
175 } else if (property.isNodeListProperty()) {
176 NodeListProperty nodeListProperty(property.toNodeListProperty());
177 foreach (const ModelNode &node, nodeListProperty.toModelNodeList()) {
178 m_treeModel->removeSubTree(node);
184 void NavigatorView::rootNodeTypeChanged(const QString & /*type*/, int /*majorVersion*/, int /*minorVersion*/)
186 if (m_treeModel->isInTree(rootModelNode()))
187 m_treeModel->updateItemRow(rootModelNode());
190 void NavigatorView::auxiliaryDataChanged(const ModelNode &node, const QString & /*name*/, const QVariant & /*data*/)
192 if (m_treeModel->isInTree(node))
195 m_treeModel->updateItemRow(node);
197 // repaint row (id and icon)
198 QModelIndex index = m_treeModel->indexForNode(node);
199 treeWidget()->update( index );
200 treeWidget()->update( index.sibling(index.row(),index.column()+1) );
204 void NavigatorView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStringList &/*scriptFunctionList*/)
208 void NavigatorView::instancePropertyChange(const QList<QPair<ModelNode, QString> > &/*propertyList*/)
212 void NavigatorView::instancesCompleted(const QVector<ModelNode> &/*completedNodeList*/)
216 void NavigatorView::instanceInformationsChange(const QVector<ModelNode> &/*nodeList*/)
220 void NavigatorView::instancesRenderImageChanged(const QVector<ModelNode> &/*nodeList*/)
224 void NavigatorView::instancesPreviewImageChanged(const QVector<ModelNode> &/*nodeList*/)
228 void NavigatorView::instancesChildrenChanged(const QVector<ModelNode> &/*nodeList*/)
233 void NavigatorView::rewriterBeginTransaction()
237 void NavigatorView::rewriterEndTransaction()
241 void NavigatorView::actualStateChanged(const ModelNode &/*node*/)
245 void NavigatorView::nodeOrderChanged(const NodeListProperty &listProperty, const ModelNode &node, int oldIndex)
247 if (m_treeModel->isInTree(node))
248 m_treeModel->updateItemRowOrder(listProperty, node, oldIndex);
251 void NavigatorView::changeToComponent(const QModelIndex &index)
253 if (index.isValid() && m_treeModel->data(index, Qt::UserRole).isValid()) {
254 ModelNode doubleClickNode = m_treeModel->nodeForIndex(index);
255 if (doubleClickNode.metaInfo().isComponent())
256 Core::EditorManager::instance()->openEditor(doubleClickNode.metaInfo().componentFileName());
260 void NavigatorView::changeSelection(const QItemSelection & /*newSelection*/, const QItemSelection &/*deselected*/)
262 if (m_blockSelectionChangedSignal)
264 QSet<ModelNode> nodeSet;
265 foreach (const QModelIndex &index, treeWidget()->selectionModel()->selectedIndexes()) {
266 if (m_treeModel->data(index, Qt::UserRole).isValid())
267 nodeSet.insert(m_treeModel->nodeForIndex(index));
270 bool blocked = blockSelectionChangedSignal(true);
271 setSelectedModelNodes(nodeSet.toList());
272 blockSelectionChangedSignal(blocked);
275 void NavigatorView::selectedNodesChanged(const QList<ModelNode> &/*selectedNodeList*/, const QList<ModelNode> &/*lastSelectedNodeList*/)
277 updateItemSelection();
280 void NavigatorView::updateItemSelection()
282 QItemSelection itemSelection;
283 foreach (const ModelNode &node, selectedModelNodes()) {
284 const QModelIndex index = m_treeModel->indexForNode(node);
285 if (index.isValid()) {
286 const QModelIndex beginIndex(m_treeModel->index(index.row(), 0, index.parent()));
287 const QModelIndex endIndex(m_treeModel->index(index.row(), m_treeModel->columnCount(index.parent()) - 1, index.parent()));
288 if (beginIndex.isValid() && endIndex.isValid())
289 itemSelection.select(beginIndex, endIndex);
293 bool blocked = blockSelectionChangedSignal(true);
294 treeWidget()->selectionModel()->select(itemSelection, QItemSelectionModel::ClearAndSelect);
295 blockSelectionChangedSignal(blocked);
297 if (!selectedModelNodes().isEmpty())
298 treeWidget()->scrollTo(m_treeModel->indexForNode(selectedModelNodes().first()));
300 // make sure selected nodes a visible
301 foreach(const QModelIndex &selectedIndex, itemSelection.indexes()) {
302 if (selectedIndex.column() == 0)
303 expandRecursively(selectedIndex);
307 QTreeView *NavigatorView::treeWidget()
310 return m_widget->treeView();
314 NavigatorTreeModel *NavigatorView::treeModel()
316 return m_treeModel.data();
319 // along the lines of QObject::blockSignals
320 bool NavigatorView::blockSelectionChangedSignal(bool block)
322 bool oldValue = m_blockSelectionChangedSignal;
323 m_blockSelectionChangedSignal = block;
327 void NavigatorView::expandRecursively(const QModelIndex &index)
329 QModelIndex currentIndex = index;
330 while (currentIndex.isValid()) {
331 if (!treeWidget()->isExpanded(currentIndex))
332 treeWidget()->expand(currentIndex);
333 currentIndex = currentIndex.parent();
337 } // namespace QmlDesigner