OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / share / qtcreator / qml / qmljsdebugger / editor / subcomponenteditortool.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 (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 **
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 **
23 ** Other Usage
24 **
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32
33 #include "subcomponenteditortool.h"
34 #include "../qdeclarativeviewobserver_p.h"
35 #include "subcomponentmasklayeritem.h"
36 #include "livelayeritem.h"
37
38 #include <QtGui/QGraphicsItem>
39 #include <QtGui/QGraphicsObject>
40 #include <QtGui/QMouseEvent>
41 #include <QtGui/QKeyEvent>
42
43 #include <QtCore/QTimer>
44 #include <QtCore/QDebug>
45
46 namespace QmlJSDebugger {
47
48 const qreal MaxOpacity = 0.5f;
49
50 SubcomponentEditorTool::SubcomponentEditorTool(QDeclarativeViewObserver *view)
51     : AbstractLiveEditTool(view),
52       m_animIncrement(0.05f),
53       m_animTimer(new QTimer(this))
54 {
55     QDeclarativeViewObserverPrivate *observerPrivate =
56             QDeclarativeViewObserverPrivate::get(view);
57     m_mask = new SubcomponentMaskLayerItem(view, observerPrivate->manipulatorLayer);
58     connect(m_animTimer, SIGNAL(timeout()), SLOT(animate()));
59     m_animTimer->setInterval(20);
60 }
61
62 SubcomponentEditorTool::~SubcomponentEditorTool()
63 {
64
65 }
66
67 void SubcomponentEditorTool::mousePressEvent(QMouseEvent * /*event*/)
68 {
69
70 }
71
72 void SubcomponentEditorTool::mouseMoveEvent(QMouseEvent * /*event*/)
73 {
74
75 }
76
77 bool SubcomponentEditorTool::containsCursor(const QPoint &mousePos) const
78 {
79     if (!m_currentContext.size())
80         return false;
81
82     QPointF scenePos = view()->mapToScene(mousePos);
83     QRectF itemRect = m_currentContext.top()->boundingRect()
84             | m_currentContext.top()->childrenBoundingRect();
85     QRectF polyRect = m_currentContext.top()->mapToScene(itemRect).boundingRect();
86
87     return polyRect.contains(scenePos);
88 }
89
90 void SubcomponentEditorTool::mouseReleaseEvent(QMouseEvent * /*event*/)
91 {
92
93 }
94
95 void SubcomponentEditorTool::mouseDoubleClickEvent(QMouseEvent *event)
96 {
97     if (event->buttons() & Qt::LeftButton
98             && !containsCursor(event->pos())
99             && m_currentContext.size() > 1)
100     {
101         aboutToPopContext();
102     }
103 }
104
105 void SubcomponentEditorTool::hoverMoveEvent(QMouseEvent *event)
106 {
107     if (!containsCursor(event->pos()) && m_currentContext.size() > 1) {
108         QDeclarativeViewObserverPrivate::get(observer())->clearHighlight();
109     }
110 }
111
112 void SubcomponentEditorTool::wheelEvent(QWheelEvent * /*event*/)
113 {
114
115 }
116
117 void SubcomponentEditorTool::keyPressEvent(QKeyEvent * /*event*/)
118 {
119
120 }
121
122 void SubcomponentEditorTool::keyReleaseEvent(QKeyEvent * /*keyEvent*/)
123 {
124
125 }
126
127 void SubcomponentEditorTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/)
128 {
129
130 }
131
132 void SubcomponentEditorTool::animate()
133 {
134     if (m_animIncrement > 0) {
135         if (m_mask->opacity() + m_animIncrement < MaxOpacity) {
136             m_mask->setOpacity(m_mask->opacity() + m_animIncrement);
137         } else {
138             m_animTimer->stop();
139             m_mask->setOpacity(MaxOpacity);
140         }
141     } else {
142         if (m_mask->opacity() + m_animIncrement > 0) {
143             m_mask->setOpacity(m_mask->opacity() + m_animIncrement);
144         } else {
145             m_animTimer->stop();
146             m_mask->setOpacity(0);
147             popContext();
148             emit contextPathChanged(m_path);
149         }
150     }
151
152 }
153
154 void SubcomponentEditorTool::clear()
155 {
156     m_currentContext.clear();
157     m_mask->setCurrentItem(0);
158     m_animTimer->stop();
159     m_mask->hide();
160     m_path.clear();
161
162     emit contextPathChanged(m_path);
163     emit cleared();
164 }
165
166 void SubcomponentEditorTool::selectedItemsChanged(const QList<QGraphicsItem*> &/*itemList*/)
167 {
168
169 }
170
171 void SubcomponentEditorTool::setCurrentItem(QGraphicsItem* contextItem)
172 {
173     if (!contextItem)
174         return;
175
176     QGraphicsObject *gfxObject = contextItem->toGraphicsObject();
177     if (!gfxObject)
178         return;
179
180     //QString parentClassName = gfxObject->metaObject()->className();
181     //if (parentClassName.contains(QRegExp("_QMLTYPE_\\d+")))
182
183     bool containsSelectableItems = false;
184     foreach (QGraphicsItem *item, gfxObject->childItems()) {
185         if (item->type() == Constants::EditorItemType
186                 || item->type() == Constants::ResizeHandleItemType)
187         {
188             continue;
189         }
190         containsSelectableItems = true;
191         break;
192     }
193
194     if (containsSelectableItems) {
195         m_mask->setCurrentItem(gfxObject);
196         m_mask->setOpacity(0);
197         m_mask->show();
198         m_animIncrement = 0.05f;
199         m_animTimer->start();
200
201         QDeclarativeViewObserverPrivate::get(observer())->clearHighlight();
202         observer()->setSelectedItems(QList<QGraphicsItem*>());
203
204         pushContext(gfxObject);
205     }
206 }
207
208 QGraphicsItem *SubcomponentEditorTool::firstChildOfContext(QGraphicsItem *item) const
209 {
210     if (!item)
211         return 0;
212
213     if (isDirectChildOfContext(item))
214         return item;
215
216     QGraphicsItem *parent = item->parentItem();
217     while (parent) {
218         if (isDirectChildOfContext(parent))
219             return parent;
220         parent = parent->parentItem();
221     }
222
223     return 0;
224 }
225
226 bool SubcomponentEditorTool::isChildOfContext(QGraphicsItem *item) const
227 {
228     return (firstChildOfContext(item) != 0);
229 }
230
231 bool SubcomponentEditorTool::isDirectChildOfContext(QGraphicsItem *item) const
232 {
233     return (item->parentItem() == m_currentContext.top());
234 }
235
236 bool SubcomponentEditorTool::itemIsChildOfQmlSubComponent(QGraphicsItem *item) const
237 {
238     if (item->parentItem() && item->parentItem() != m_currentContext.top()) {
239         QGraphicsObject *parent = item->parentItem()->toGraphicsObject();
240         QString parentClassName = parent->metaObject()->className();
241
242         if (parentClassName.contains(QRegExp("_QMLTYPE_\\d+"))) {
243             return true;
244         } else {
245             return itemIsChildOfQmlSubComponent(parent);
246         }
247     }
248
249     return false;
250 }
251
252 void SubcomponentEditorTool::pushContext(QGraphicsObject *contextItem)
253 {
254     connect(contextItem, SIGNAL(destroyed(QObject*)), this, SLOT(contextDestroyed(QObject*)));
255     connect(contextItem, SIGNAL(xChanged()), this, SLOT(resizeMask()));
256     connect(contextItem, SIGNAL(yChanged()), this, SLOT(resizeMask()));
257     connect(contextItem, SIGNAL(widthChanged()), this, SLOT(resizeMask()));
258     connect(contextItem, SIGNAL(heightChanged()), this, SLOT(resizeMask()));
259     connect(contextItem, SIGNAL(rotationChanged()), this, SLOT(resizeMask()));
260
261     m_currentContext.push(contextItem);
262     QString title = titleForItem(contextItem);
263     emit contextPushed(title);
264
265     m_path << title;
266     emit contextPathChanged(m_path);
267 }
268
269 void SubcomponentEditorTool::aboutToPopContext()
270 {
271     if (m_currentContext.size() > 2) {
272         popContext();
273         emit contextPathChanged(m_path);
274     } else {
275         m_animIncrement = -0.05f;
276         m_animTimer->start();
277     }
278 }
279
280 QGraphicsObject *SubcomponentEditorTool::popContext()
281 {
282     QGraphicsObject *popped = m_currentContext.pop();
283     m_path.removeLast();
284
285     emit contextPopped();
286
287     disconnect(popped, SIGNAL(xChanged()), this, SLOT(resizeMask()));
288     disconnect(popped, SIGNAL(yChanged()), this, SLOT(resizeMask()));
289     disconnect(popped, SIGNAL(scaleChanged()), this, SLOT(resizeMask()));
290     disconnect(popped, SIGNAL(widthChanged()), this, SLOT(resizeMask()));
291     disconnect(popped, SIGNAL(heightChanged()), this, SLOT(resizeMask()));
292
293     if (m_currentContext.size() > 1) {
294         QGraphicsObject *item = m_currentContext.top();
295         m_mask->setCurrentItem(item);
296         m_mask->setOpacity(MaxOpacity);
297         m_mask->setVisible(true);
298     } else {
299         m_mask->setVisible(false);
300     }
301
302     return popped;
303 }
304
305 void SubcomponentEditorTool::resizeMask()
306 {
307     QGraphicsObject *item = m_currentContext.top();
308     m_mask->setCurrentItem(item);
309 }
310
311 QGraphicsObject *SubcomponentEditorTool::currentRootItem() const
312 {
313     return m_currentContext.top();
314 }
315
316 void SubcomponentEditorTool::contextDestroyed(QObject *contextToDestroy)
317 {
318     disconnect(contextToDestroy, SIGNAL(destroyed(QObject*)),
319                this, SLOT(contextDestroyed(QObject*)));
320
321     // pop out the whole context - it might not be safe anymore.
322     while (m_currentContext.size() > 1) {
323         m_currentContext.pop();
324         m_path.removeLast();
325         emit contextPopped();
326     }
327     m_mask->setVisible(false);
328
329     emit contextPathChanged(m_path);
330 }
331
332 QGraphicsObject *SubcomponentEditorTool::setContext(int contextIndex)
333 {
334     Q_ASSERT(contextIndex >= 0);
335
336     // sometimes we have to delete the context while user was still clicking around,
337     // so just bail out.
338     if (contextIndex >= m_currentContext.size() -1)
339         return 0;
340
341     while (m_currentContext.size() - 1 > contextIndex) {
342         popContext();
343     }
344     emit contextPathChanged(m_path);
345
346     return m_currentContext.top();
347 }
348
349 int SubcomponentEditorTool::contextIndex() const
350 {
351     return m_currentContext.size() - 1;
352 }
353
354 } // namespace QmlJSDebugger