OSDN Git Service

It's 2011 now.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qmljsinspector / qmljsobjecttree.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 #include "qmljsobjecttree.h"
34
35 #include <QContextMenuEvent>
36 #include <QEvent>
37 #include <QtGui/QMenu>
38 #include <QtGui/QAction>
39 #include <QApplication>
40 #include <QInputDialog>
41
42 #include <QDebug>
43
44 namespace QmlJSInspector {
45 namespace Internal {
46
47 // *************************************************************************
48 //  ObjectTreeItem
49 // *************************************************************************
50
51 class ObjectTreeItem : public QTreeWidgetItem
52 {
53 public:
54     explicit ObjectTreeItem(QTreeWidget *widget, int type = 0);
55     ObjectTreeItem(QTreeWidgetItem *parentItem, int type = 0);
56     QVariant data (int column, int role) const;
57     void setData (int column, int role, const QVariant & value);
58
59     void setHasValidDebugId(bool value);
60
61
62 private:
63     bool m_hasValidDebugId;
64 };
65
66 ObjectTreeItem::ObjectTreeItem(QTreeWidget *widget, int type) :
67     QTreeWidgetItem(widget, type), m_hasValidDebugId(true)
68 {
69
70 }
71
72 ObjectTreeItem::ObjectTreeItem(QTreeWidgetItem *parentItem, int type) :
73     QTreeWidgetItem(parentItem, type), m_hasValidDebugId(true)
74 {
75
76 }
77
78 QVariant ObjectTreeItem::data (int column, int role) const
79 {
80     if (role == Qt::ForegroundRole)
81         return m_hasValidDebugId ? qApp->palette().color(QPalette::Foreground) : qApp->palette().color(QPalette::Disabled, QPalette::Foreground);
82
83     return QTreeWidgetItem::data(column, role);
84 }
85
86 void ObjectTreeItem::setData (int column, int role, const QVariant & value)
87 {
88     QTreeWidgetItem::setData(column, role, value);
89 }
90
91 void ObjectTreeItem::setHasValidDebugId(bool value)
92 {
93     m_hasValidDebugId = value;
94 }
95
96 // *************************************************************************
97 //  QmlJSObjectTree
98 // *************************************************************************
99
100 QmlJSObjectTree::QmlJSObjectTree(QWidget *parent)
101     : QTreeWidget(parent)
102     , m_clickedItem(0)
103     , m_currentObjectDebugId(0)
104 {
105     setAttribute(Qt::WA_MacShowFocusRect, false);
106     setFrameStyle(QFrame::NoFrame);
107     setHeaderHidden(true);
108     setExpandsOnDoubleClick(false);
109
110     m_goToFileAction = new QAction(tr("Go to file"), this);
111     connect(m_goToFileAction, SIGNAL(triggered()), SLOT(goToFile()));
112
113     connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
114             SLOT(currentItemChanged(QTreeWidgetItem *)));
115     connect(this, SIGNAL(itemActivated(QTreeWidgetItem *, int)),
116             SLOT(activated(QTreeWidgetItem *)));
117     connect(this, SIGNAL(itemSelectionChanged()), SLOT(selectionChanged()));
118 }
119
120 void QmlJSObjectTree::selectionChanged()
121 {
122     if (selectedItems().isEmpty())
123         return;
124
125     // TODO
126 }
127
128 void QmlJSObjectTree::setCurrentObject(int debugId)
129 {
130     QTreeWidgetItem *item = findItemByObjectId(debugId);
131     if (item) {
132         setCurrentItem(item);
133         scrollToItem(item);
134         item->setExpanded(true);
135     }
136 }
137
138 void QmlJSObjectTree::currentItemChanged(QTreeWidgetItem *item)
139 {
140     if (!item)
141         return;
142
143     QDeclarativeDebugObjectReference obj = item->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>();
144     if (obj.debugId() >= 0)
145         emit currentObjectChanged(obj);
146 }
147
148 void QmlJSObjectTree::activated(QTreeWidgetItem *item)
149 {
150     if (!item)
151         return;
152
153     QDeclarativeDebugObjectReference obj = item->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>();
154     if (obj.debugId() >= 0)
155         emit activated(obj);
156 }
157
158 void QmlJSObjectTree::buildTree(const QDeclarativeDebugObjectReference &obj, QTreeWidgetItem *parent)
159 {
160     if (!parent)
161         clear();
162
163     if (obj.contextDebugId() < 0)
164         return;
165
166     ObjectTreeItem *item = parent ? new ObjectTreeItem(parent) : new ObjectTreeItem(this);
167     if (obj.idString().isEmpty())
168         item->setText(0, QString("<%1>").arg(obj.className()));
169     else
170         item->setText(0, obj.idString());
171     item->setData(0, Qt::UserRole, qVariantFromValue(obj));
172
173     if (parent && obj.contextDebugId() >= 0
174             && obj.contextDebugId() != parent->data(0, Qt::UserRole
175                     ).value<QDeclarativeDebugObjectReference>().contextDebugId())
176     {
177
178         QDeclarativeDebugFileReference source = obj.source();
179         if (!source.url().isEmpty()) {
180             QString toolTipString = tr("Url: ") + source.url().toString();
181             item->setToolTip(0, toolTipString);
182         }
183     } else {
184         item->setExpanded(true);
185     }
186
187     if (obj.contextDebugId() < 0)
188         item->setHasValidDebugId(false);
189
190     for (int ii = 0; ii < obj.children().count(); ++ii)
191         buildTree(obj.children().at(ii), item);
192 }
193
194 QTreeWidgetItem *QmlJSObjectTree::findItemByObjectId(int debugId) const
195 {
196     for (int i=0; i<topLevelItemCount(); ++i) {
197         QTreeWidgetItem *item = findItem(topLevelItem(i), debugId);
198         if (item)
199             return item;
200     }
201
202     return 0;
203 }
204
205 QTreeWidgetItem *QmlJSObjectTree::findItem(QTreeWidgetItem *item, int debugId) const
206 {
207     if (item->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>().debugId() == debugId)
208         return item;
209
210     QTreeWidgetItem *child;
211     for (int i=0; i<item->childCount(); ++i) {
212         child = findItem(item->child(i), debugId);
213         if (child)
214             return child;
215     }
216
217     return 0;
218 }
219
220 void QmlJSObjectTree::goToFile()
221 {
222     QDeclarativeDebugObjectReference obj =
223             currentItem()->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>();
224
225     if (obj.debugId() >= 0)
226         emit activated(obj);
227 }
228
229 void QmlJSObjectTree::contextMenuEvent(QContextMenuEvent *event)
230 {
231     m_clickedItem = itemAt(QPoint(event->pos().x(),
232                                   event->pos().y() ));
233     if (!m_clickedItem)
234         return;
235
236     QMenu menu;
237     menu.addAction(m_goToFileAction);
238     menu.exec(event->globalPos());
239 }
240
241 } // Internal
242 } // QmlJSInspector