OSDN Git Service

4f3227430f5d982362a5d5ed8b0f1dfaf595fd9d
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qmldesigner / components / navigator / navigatorview.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
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
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
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.
24 **
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.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "navigatorview.h"
35 #include "navigatortreemodel.h"
36 #include "navigatorwidget.h"
37
38 #include <coreplugin/editormanager/editormanager.h>
39
40 #include <nodeproperty.h>
41 #include <nodelistproperty.h>
42 #include <QHeaderView>
43
44
45 namespace QmlDesigner {
46
47 NavigatorView::NavigatorView(QObject* parent) :
48         AbstractView(parent),
49         m_blockSelectionChangedSignal(false),
50         m_widget(new NavigatorWidget),
51         m_treeModel(new NavigatorTreeModel(this))
52 {
53     m_widget->setTreeModel(m_treeModel.data());
54
55     connect(treeWidget()->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(changeSelection(QItemSelection,QItemSelection)));
56     treeWidget()->setIndentation(treeWidget()->indentation() * 0.5);
57
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());
61
62 #ifdef _LOCK_ITEMS_
63     IconCheckboxItemDelegate *lockDelegate = new IconCheckboxItemDelegate(this,":/qmldesigner/images/lock.png",
64                                                           ":/qmldesigner/images/hole.png",m_treeModel.data());
65 #endif
66
67
68     treeWidget()->setItemDelegateForColumn(0,idDelegate);
69 #ifdef _LOCK_ITEMS_
70     treeWidget()->setItemDelegateForColumn(1,lockDelegate);
71     treeWidget()->setItemDelegateForColumn(2,showDelegate);
72 #else
73     treeWidget()->setItemDelegateForColumn(1,showDelegate);
74 #endif
75
76 }
77
78 NavigatorView::~NavigatorView()
79 {
80     if (m_widget && !m_widget->parent())
81         delete m_widget.data();
82 }
83
84 QWidget *NavigatorView::widget()
85 {
86     return m_widget.data();
87 }
88
89 void NavigatorView::modelAttached(Model *model)
90 {
91     AbstractView::modelAttached(model);
92
93     m_treeModel->setView(this);
94
95     QTreeView *treeView = treeWidget();
96     treeView->expandAll();
97
98     treeView->header()->setResizeMode(0, QHeaderView::Stretch);
99     treeView->header()->resizeSection(1,26);
100     treeView->setRootIsDecorated(false);
101     treeView->setIndentation(20);
102 #ifdef _LOCK_ITEMS_
103     treeView->header()->resizeSection(2,20);
104 #endif
105 }
106
107 void NavigatorView::modelAboutToBeDetached(Model *model)
108 {
109     m_treeModel->clearView();
110     AbstractView::modelAboutToBeDetached(model);
111 }
112
113 void NavigatorView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/)
114 {
115     treeWidget()->update();
116 }
117
118 void NavigatorView::nodeCreated(const ModelNode & /*createdNode*/)
119 {
120 }
121
122 void NavigatorView::nodeRemoved(const ModelNode & /*removedNode*/, const NodeAbstractProperty & /*parentProperty*/, PropertyChangeFlags /*propertyChange*/)
123 {
124 }
125
126 void NavigatorView::propertiesRemoved(const QList<AbstractProperty> & /*propertyList*/)
127 {
128 }
129
130 void NavigatorView::variantPropertiesChanged(const QList<VariantProperty> & /*propertyList*/, PropertyChangeFlags /*propertyChange*/)
131 {
132 }
133
134 void NavigatorView::bindingPropertiesChanged(const QList<BindingProperty> & /*propertyList*/, PropertyChangeFlags /*propertyChange*/)
135 {
136 }
137
138 void NavigatorView::nodeAboutToBeRemoved(const ModelNode &removedNode)
139 {
140     if (m_treeModel->isInTree(removedNode))
141         m_treeModel->removeSubTree(removedNode);
142 }
143
144 void NavigatorView::nodeAboutToBeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
145 {
146 }
147
148 void NavigatorView::nodeReparented(const ModelNode &node, const NodeAbstractProperty & /*newPropertyParent*/, const NodeAbstractProperty & /*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
149 {
150     bool blocked = blockSelectionChangedSignal(true);
151
152     if (m_treeModel->isInTree(node))
153         m_treeModel->removeSubTree(node);
154     if (node.isInHierarchy())
155         m_treeModel->addSubTree(node);
156
157     // make sure selection is in sync again
158     updateItemSelection();
159
160     blockSelectionChangedSignal(blocked);
161 }
162
163 void NavigatorView::nodeIdChanged(const ModelNode& node, const QString & /*newId*/, const QString & /*oldId*/)
164 {
165     if (m_treeModel->isInTree(node))
166         m_treeModel->updateItemRow(node);
167 }
168
169 void NavigatorView::propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList)
170 {
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);
179             }
180         }
181     }
182 }
183
184 void NavigatorView::rootNodeTypeChanged(const QString & /*type*/, int /*majorVersion*/, int /*minorVersion*/)
185 {
186     if (m_treeModel->isInTree(rootModelNode()))
187         m_treeModel->updateItemRow(rootModelNode());
188 }
189
190 void NavigatorView::auxiliaryDataChanged(const ModelNode &node, const QString & /*name*/, const QVariant & /*data*/)
191 {
192     if (m_treeModel->isInTree(node))
193     {
194         // update model
195         m_treeModel->updateItemRow(node);
196
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) );
201     }
202 }
203
204 void NavigatorView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStringList &/*scriptFunctionList*/)
205 {
206 }
207
208 void NavigatorView::instancePropertyChange(const QList<QPair<ModelNode, QString> > &/*propertyList*/)
209 {
210 }
211
212 void NavigatorView::instancesCompleted(const QVector<ModelNode> &/*completedNodeList*/)
213 {
214 }
215
216 void NavigatorView::instanceInformationsChange(const QVector<ModelNode> &/*nodeList*/)
217 {
218 }
219
220 void NavigatorView::instancesRenderImageChanged(const QVector<ModelNode> &/*nodeList*/)
221 {
222 }
223
224 void NavigatorView::instancesPreviewImageChanged(const QVector<ModelNode> &/*nodeList*/)
225 {
226 }
227
228 void NavigatorView::instancesChildrenChanged(const QVector<ModelNode> &/*nodeList*/)
229 {
230
231 }
232
233 void NavigatorView::rewriterBeginTransaction()
234 {
235 }
236
237 void NavigatorView::rewriterEndTransaction()
238 {
239 }
240
241 void NavigatorView::actualStateChanged(const ModelNode &/*node*/)
242 {
243 }
244
245 void NavigatorView::nodeOrderChanged(const NodeListProperty &listProperty, const ModelNode &node, int oldIndex)
246 {
247     if (m_treeModel->isInTree(node))
248         m_treeModel->updateItemRowOrder(listProperty, node, oldIndex);
249 }
250
251 void NavigatorView::changeToComponent(const QModelIndex &index)
252 {
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());
257     }
258 }
259
260 void NavigatorView::changeSelection(const QItemSelection & /*newSelection*/, const QItemSelection &/*deselected*/)
261 {
262     if (m_blockSelectionChangedSignal)
263         return;
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));
268     }
269
270     bool blocked = blockSelectionChangedSignal(true);
271     setSelectedModelNodes(nodeSet.toList());
272     blockSelectionChangedSignal(blocked);
273 }
274
275 void NavigatorView::selectedNodesChanged(const QList<ModelNode> &/*selectedNodeList*/, const QList<ModelNode> &/*lastSelectedNodeList*/)
276 {
277     updateItemSelection();
278 }
279
280 void NavigatorView::updateItemSelection()
281 {
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);
290         }
291     }
292
293     bool blocked = blockSelectionChangedSignal(true);
294     treeWidget()->selectionModel()->select(itemSelection, QItemSelectionModel::ClearAndSelect);
295     blockSelectionChangedSignal(blocked);
296
297     if (!selectedModelNodes().isEmpty())
298         treeWidget()->scrollTo(m_treeModel->indexForNode(selectedModelNodes().first()));
299
300     // make sure selected nodes a visible
301     foreach(const QModelIndex &selectedIndex, itemSelection.indexes()) {
302         if (selectedIndex.column() == 0)
303             expandRecursively(selectedIndex);
304     }
305 }
306
307 QTreeView *NavigatorView::treeWidget()
308 {
309     if (m_widget)
310         return m_widget->treeView();
311     return 0;
312 }
313
314 NavigatorTreeModel *NavigatorView::treeModel()
315 {
316     return m_treeModel.data();
317 }
318
319 // along the lines of QObject::blockSignals
320 bool NavigatorView::blockSelectionChangedSignal(bool block)
321 {
322     bool oldValue = m_blockSelectionChangedSignal;
323     m_blockSelectionChangedSignal = block;
324     return oldValue;
325 }
326
327 void NavigatorView::expandRecursively(const QModelIndex &index)
328 {
329     QModelIndex currentIndex = index;
330     while (currentIndex.isValid()) {
331         if (!treeWidget()->isExpanded(currentIndex))
332             treeWidget()->expand(currentIndex);
333         currentIndex = currentIndex.parent();
334     }
335 }
336
337 } // namespace QmlDesigner