eb9d335d01bfaa456554e7e0f02e59234506183f
[profile/ivi/qtdeclarative.git] / src / qtquick1 / util / qdeclarativeview.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "QtQuick1/qdeclarativeview.h"
43
44 #include <QtDeclarative/qdeclarative.h>
45 #include <QtQuick1/qdeclarativeitem.h>
46 #include <QtDeclarative/qdeclarativeengine.h>
47 #include <QtDeclarative/qdeclarativecontext.h>
48 #include <QtDeclarative/private/qdeclarativeglobal_p.h>
49 #include <QtDeclarative/private/qdeclarativeguard_p.h>
50
51 #include <QtDeclarative/private/qdeclarativedebugtrace_p.h>
52 #include <QtDeclarative/private/qdeclarativeinspectorservice_p.h>
53
54 #include <qdebug.h>
55 #include <qtimer.h>
56 #include <qevent.h>
57 #include <qdir.h>
58 #include <qcoreapplication.h>
59 #include <qfontdatabase.h>
60 #include <qicon.h>
61 #include <qurl.h>
62 #include <qlayout.h>
63 #include <qwidget.h>
64 #include <qgraphicswidget.h>
65 #include <qbasictimer.h>
66 #include <QtCore/qabstractanimation.h>
67 #include <QtQuick1/private/qdeclarativeitem_p.h>
68 #include <QtWidgets/private/qgraphicsview_p.h>
69 #include <private/qabstractanimation_p.h>
70 #include <QtQuick1/private/qdeclarativeitemchangelistener_p.h>
71
72 QT_BEGIN_NAMESPACE
73
74 DEFINE_BOOL_CONFIG_OPTION(frameRateDebug, QML_SHOW_FRAMERATE)
75
76 class QDeclarative1Scene : public QGraphicsScene
77 {
78 public:
79     QDeclarative1Scene(QObject *parent = 0);
80
81 protected:
82     virtual void keyPressEvent(QKeyEvent *);
83     virtual void keyReleaseEvent(QKeyEvent *);
84
85     virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
86     virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
87     virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
88 };
89
90 QDeclarative1Scene::QDeclarative1Scene(QObject *parent) : QGraphicsScene(parent)
91 {
92 }
93
94 void QDeclarative1Scene::keyPressEvent(QKeyEvent *e)
95 {
96     QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Key);
97
98     QGraphicsScene::keyPressEvent(e);
99 }
100
101 void QDeclarative1Scene::keyReleaseEvent(QKeyEvent *e)
102 {
103     QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Key);
104
105     QGraphicsScene::keyReleaseEvent(e);
106 }
107
108 void QDeclarative1Scene::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
109 {
110     QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
111
112     QGraphicsScene::mouseMoveEvent(e);
113 }
114
115 void QDeclarative1Scene::mousePressEvent(QGraphicsSceneMouseEvent *e)
116 {
117     QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
118
119     QGraphicsScene::mousePressEvent(e);
120 }
121
122 void QDeclarative1Scene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e)
123 {
124     QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
125
126     QGraphicsScene::mouseReleaseEvent(e);
127 }
128
129 class QDeclarativeViewPrivate : public QGraphicsViewPrivate, public QDeclarativeItemChangeListener
130 {
131     Q_DECLARE_PUBLIC(QDeclarativeView)
132 public:
133     QDeclarativeViewPrivate()
134         : root(0), declarativeItemRoot(0), graphicsWidgetRoot(0), component(0),
135           resizeMode(QDeclarativeView::SizeViewToRootObject), initialSize(0,0) {}
136     ~QDeclarativeViewPrivate() { delete root; delete engine; }
137     void execute();
138     void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
139     void initResize();
140     void updateSize();
141     inline QSize rootObjectSize() const;
142
143     QDeclarativeGuard<QGraphicsObject> root;
144     QDeclarativeGuard<QDeclarativeItem> declarativeItemRoot;
145     QDeclarativeGuard<QGraphicsWidget> graphicsWidgetRoot;
146
147     QUrl source;
148
149     QDeclarativeEngine* engine;
150     QDeclarativeComponent *component;
151     QBasicTimer resizetimer;
152
153     QDeclarativeView::ResizeMode resizeMode;
154     QSize initialSize;
155     QElapsedTimer frameTimer;
156
157     void init();
158 };
159
160 void QDeclarativeViewPrivate::execute()
161 {
162     Q_Q(QDeclarativeView);
163     if (root) {
164         delete root;
165         root = 0;
166     }
167     if (component) {
168         delete component;
169         component = 0;
170     }
171     if (!source.isEmpty()) {
172         component = new QDeclarativeComponent(engine, source, q);
173         if (!component->isLoading()) {
174             q->continueExecute();
175         } else {
176             QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), q, SLOT(continueExecute()));
177         }
178     }
179 }
180
181 void QDeclarativeViewPrivate::itemGeometryChanged(QDeclarativeItem *resizeItem, const QRectF &newGeometry, const QRectF &oldGeometry)
182 {
183     Q_Q(QDeclarativeView);
184     if (resizeItem == root && resizeMode == QDeclarativeView::SizeViewToRootObject) {
185         // wait for both width and height to be changed
186         resizetimer.start(0,q);
187     }
188     QDeclarativeItemChangeListener::itemGeometryChanged(resizeItem, newGeometry, oldGeometry);
189 }
190
191 /*!
192     \class QDeclarativeView
193     \since QtQuick 1.0
194     \brief The QDeclarativeView class provides a widget for displaying a Qt Declarative user interface.
195
196     QDeclarativeItem objects can be placed on a standard QGraphicsScene and
197     displayed with QGraphicsView. QDeclarativeView is a QGraphicsView subclass
198     provided as a convenience for displaying QML files, and connecting between
199     QML and C++ Qt objects.
200
201     QDeclarativeView provides:
202
203     \list
204     \o Management of QDeclarativeComponent loading and object creation
205     \o Initialization of QGraphicsView for optimal performance with QML using these settings:
206         \list
207         \o QGraphicsView::setOptimizationFlags(QGraphicsView::DontSavePainterState)
208         \o QGraphicsView::setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate)
209         \o QGraphicsScene::setItemIndexMethod(QGraphicsScene::NoIndex)
210         \endlist
211     \o Initialization of QGraphicsView for QML key handling using these settings:
212         \list
213         \o QGraphicsView::viewport()->setFocusPolicy(Qt::NoFocus)
214         \o QGraphicsView::setFocusPolicy(Qt::StrongFocus)
215         \o QGraphicsScene::setStickyFocus(true)
216         \endlist
217     \endlist
218
219     Typical usage:
220
221     \code
222     QDeclarativeView *view = new QDeclarativeView;
223     view->setSource(QUrl::fromLocalFile("myqmlfile.qml"));
224     view->show();
225     \endcode
226
227     Since QDeclarativeView is a QWidget-based class, it can be used to
228     display QML interfaces within QWidget-based GUI applications that do not
229     use the Graphics View framework.
230
231     To receive errors related to loading and executing QML with QDeclarativeView,
232     you can connect to the statusChanged() signal and monitor for QDeclarativeView::Error.
233     The errors are available via QDeclarativeView::errors().
234
235     If you're using your own QGraphicsScene-based scene with QDeclarativeView, remember to
236     enable scene's sticky focus mode and to set itemIndexMethod to QGraphicsScene::NoIndex.
237
238     \sa {Integrating QML Code with Existing Qt UI Code}, {Using QML Bindings in C++ Applications}
239 */
240
241
242 /*! \fn void QDeclarativeView::sceneResized(QSize size)
243   This signal is emitted when the view is resized to \a size.
244 */
245
246 /*! \fn void QDeclarativeView::statusChanged(QDeclarativeView::Status status)
247     This signal is emitted when the component's current \a status changes.
248 */
249
250 /*! \fn void QDeclarativeView::initialSizeChanged(QSize size)
251   \internal
252 */
253
254 /*!
255   \fn QDeclarativeView::QDeclarativeView(QWidget *parent)
256
257   Constructs a QDeclarativeView with the given \a parent.
258 */
259 QDeclarativeView::QDeclarativeView(QWidget *parent)
260     : QGraphicsView(*(new QDeclarativeViewPrivate), parent)
261 {
262     Q_D(QDeclarativeView);
263     setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
264     d->init();
265 }
266
267 /*!
268   \fn QDeclarativeView::QDeclarativeView(const QUrl &source, QWidget *parent)
269
270   Constructs a QDeclarativeView with the given QML \a source and \a parent.
271 */
272 QDeclarativeView::QDeclarativeView(const QUrl &source, QWidget *parent)
273     : QGraphicsView(*(new QDeclarativeViewPrivate), parent)
274 {
275     Q_D(QDeclarativeView);
276     setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
277     d->init();
278     setSource(source);
279 }
280
281 void QDeclarativeViewPrivate::init()
282 {
283     Q_Q(QDeclarativeView);
284     engine = new QDeclarativeEngine();
285     q->setScene(new QDeclarative1Scene(q));
286
287     q->setOptimizationFlags(QGraphicsView::DontSavePainterState);
288     q->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
289     q->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
290     q->setFrameStyle(0);
291
292     // These seem to give the best performance
293     q->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
294     q->scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
295     q->viewport()->setFocusPolicy(Qt::NoFocus);
296     q->setFocusPolicy(Qt::StrongFocus);
297
298     q->scene()->setStickyFocus(true);  //### needed for correct focus handling
299
300 #ifdef QDECLARATIVEVIEW_NOBACKGROUND
301     q->setAttribute(Qt::WA_OpaquePaintEvent);
302     q->setAttribute(Qt::WA_NoSystemBackground);
303     q->viewport()->setAttribute(Qt::WA_OpaquePaintEvent);
304     q->viewport()->setAttribute(Qt::WA_NoSystemBackground);
305 #endif
306
307     if (QDeclarativeDebugService::isDebuggingEnabled())
308         QDeclarativeInspectorService::instance()->addView(q);
309 }
310
311 /*!
312     Destroys the view.
313  */
314 QDeclarativeView::~QDeclarativeView()
315 {
316     if (QDeclarativeDebugService::isDebuggingEnabled())
317         QDeclarativeInspectorService::instance()->removeView(this);
318 }
319
320 /*! \property QDeclarativeView::source
321   \brief The URL of the source of the QML component.
322
323   Changing this property causes the QML component to be reloaded.
324
325     Ensure that the URL provided is full and correct, in particular, use
326     \l QUrl::fromLocalFile() when loading a file from the local filesystem.
327  */
328
329 /*!
330     Sets the source to the \a url, loads the QML component and instantiates it.
331
332     Ensure that the URL provided is full and correct, in particular, use
333     \l QUrl::fromLocalFile() when loading a file from the local filesystem.
334
335     Calling this methods multiple times with the same url will result
336     in the QML being reloaded.
337  */
338 void QDeclarativeView::setSource(const QUrl& url)
339 {
340     Q_D(QDeclarativeView);
341     d->source = url;
342     d->execute();
343 }
344
345 /*!
346   Returns the source URL, if set.
347
348   \sa setSource()
349  */
350 QUrl QDeclarativeView::source() const
351 {
352     Q_D(const QDeclarativeView);
353     return d->source;
354 }
355
356 /*!
357   Returns a pointer to the QDeclarativeEngine used for instantiating
358   QML Components.
359  */
360 QDeclarativeEngine* QDeclarativeView::engine() const
361 {
362     Q_D(const QDeclarativeView);
363     return d->engine;
364 }
365
366 /*!
367   This function returns the root of the context hierarchy.  Each QML
368   component is instantiated in a QDeclarativeContext.  QDeclarativeContext's are
369   essential for passing data to QML components.  In QML, contexts are
370   arranged hierarchically and this hierarchy is managed by the
371   QDeclarativeEngine.
372  */
373 QDeclarativeContext* QDeclarativeView::rootContext() const
374 {
375     Q_D(const QDeclarativeView);
376     return d->engine->rootContext();
377 }
378
379 /*!
380     \enum QDeclarativeView::Status
381     Specifies the loading status of the QDeclarativeView.
382
383     \value Null This QDeclarativeView has no source set.
384     \value Ready This QDeclarativeView has loaded and created the QML component.
385     \value Loading This QDeclarativeView is loading network data.
386     \value Error One or more errors has occurred. Call errors() to retrieve a list
387            of errors.
388 */
389
390 /*! \enum QDeclarativeView::ResizeMode
391
392   This enum specifies how to resize the view.
393
394   \value SizeViewToRootObject The view resizes with the root item in the QML.
395   \value SizeRootObjectToView The view will automatically resize the root item to the size of the view.
396 */
397
398 /*!
399     \property QDeclarativeView::status
400     The component's current \l{QDeclarativeView::Status} {status}.
401 */
402
403 QDeclarativeView::Status QDeclarativeView::status() const
404 {
405     Q_D(const QDeclarativeView);
406     if (!d->component)
407         return QDeclarativeView::Null;
408
409     return QDeclarativeView::Status(d->component->status());
410 }
411
412 /*!
413     Return the list of errors that occurred during the last compile or create
414     operation.  When the status is not Error, an empty list is returned.
415 */
416 QList<QDeclarativeError> QDeclarativeView::errors() const
417 {
418     Q_D(const QDeclarativeView);
419     if (d->component)
420         return d->component->errors();
421     return QList<QDeclarativeError>();
422 }
423
424 /*!
425     \property QDeclarativeView::resizeMode
426     \brief whether the view should resize the canvas contents
427
428     If this property is set to SizeViewToRootObject (the default), the view
429     resizes with the root item in the QML.
430
431     If this property is set to SizeRootObjectToView, the view will
432     automatically resize the root item.
433
434     Regardless of this property, the sizeHint of the view
435     is the initial size of the root item. Note though that
436     since QML may load dynamically, that size may change.
437 */
438
439 void QDeclarativeView::setResizeMode(ResizeMode mode)
440 {
441     Q_D(QDeclarativeView);
442     if (d->resizeMode == mode)
443         return;
444
445     if (d->declarativeItemRoot) {
446         if (d->resizeMode == SizeViewToRootObject) {
447             QDeclarativeItemPrivate *p =
448                 static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(d->declarativeItemRoot));
449             p->removeItemChangeListener(d, QDeclarativeItemPrivate::Geometry);
450         }
451     } else if (d->graphicsWidgetRoot) {
452          if (d->resizeMode == QDeclarativeView::SizeViewToRootObject) {
453              d->graphicsWidgetRoot->removeEventFilter(this);
454          }
455     }
456
457     d->resizeMode = mode;
458     if (d->root) {
459         d->initResize();
460     }
461 }
462
463 void QDeclarativeViewPrivate::initResize()
464 {
465     Q_Q(QDeclarativeView);
466     if (declarativeItemRoot) {
467         if (resizeMode == QDeclarativeView::SizeViewToRootObject) {
468             QDeclarativeItemPrivate *p =
469                 static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(declarativeItemRoot));
470             p->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry);
471         }
472     } else if (graphicsWidgetRoot) {
473         if (resizeMode == QDeclarativeView::SizeViewToRootObject) {
474             graphicsWidgetRoot->installEventFilter(q);
475         }
476     }
477     updateSize();
478 }
479
480 void QDeclarativeViewPrivate::updateSize()
481 {
482     Q_Q(QDeclarativeView);
483     if (!root)
484         return;
485     if (declarativeItemRoot) {
486         if (resizeMode == QDeclarativeView::SizeViewToRootObject) {
487             QSize newSize = QSize(declarativeItemRoot->width(), declarativeItemRoot->height());
488             if (newSize.isValid() && newSize != q->size()) {
489                 q->resize(newSize);
490             }
491         } else if (resizeMode == QDeclarativeView::SizeRootObjectToView) {
492             if (!qFuzzyCompare(q->width(), declarativeItemRoot->width()))
493                 declarativeItemRoot->setWidth(q->width());
494             if (!qFuzzyCompare(q->height(), declarativeItemRoot->height()))
495                 declarativeItemRoot->setHeight(q->height());
496         }
497     } else if (graphicsWidgetRoot) {
498         if (resizeMode == QDeclarativeView::SizeViewToRootObject) {
499             QSize newSize = QSize(graphicsWidgetRoot->size().width(), graphicsWidgetRoot->size().height());
500             if (newSize.isValid() && newSize != q->size()) {
501                 q->resize(newSize);
502             }
503         } else if (resizeMode == QDeclarativeView::SizeRootObjectToView) {
504             QSizeF newSize = QSize(q->size().width(), q->size().height());
505             if (newSize.isValid() && newSize != graphicsWidgetRoot->size()) {
506                 graphicsWidgetRoot->resize(newSize);
507             }
508         }
509     }
510     q->updateGeometry();
511 }
512
513 QSize QDeclarativeViewPrivate::rootObjectSize() const
514 {
515     QSize rootObjectSize(0,0);
516     int widthCandidate = -1;
517     int heightCandidate = -1;
518     if (root) {
519         QSizeF size = root->boundingRect().size();
520         widthCandidate = size.width();
521         heightCandidate = size.height();
522     }
523     if (widthCandidate > 0) {
524         rootObjectSize.setWidth(widthCandidate);
525     }
526     if (heightCandidate > 0) {
527         rootObjectSize.setHeight(heightCandidate);
528     }
529     return rootObjectSize;
530 }
531
532 QDeclarativeView::ResizeMode QDeclarativeView::resizeMode() const
533 {
534     Q_D(const QDeclarativeView);
535     return d->resizeMode;
536 }
537
538 /*!
539   \internal
540  */
541 void QDeclarativeView::continueExecute()
542 {
543     Q_D(QDeclarativeView);
544     disconnect(d->component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), this, SLOT(continueExecute()));
545
546     if (d->component->isError()) {
547         QList<QDeclarativeError> errorList = d->component->errors();
548         foreach (const QDeclarativeError &error, errorList) {
549             qWarning() << error;
550         }
551         emit statusChanged(status());
552         return;
553     }
554
555     QObject *obj = d->component->create();
556
557     if(d->component->isError()) {
558         QList<QDeclarativeError> errorList = d->component->errors();
559         foreach (const QDeclarativeError &error, errorList) {
560             qWarning() << error;
561         }
562         emit statusChanged(status());
563         return;
564     }
565
566     setRootObject(obj);
567     emit statusChanged(status());
568 }
569
570 /*!
571   \internal
572 */
573 void QDeclarativeView::setRootObject(QObject *obj)
574 {
575     Q_D(QDeclarativeView);
576     if (d->root == obj || !scene())
577         return;
578     if (QDeclarativeItem *declarativeItem = qobject_cast<QDeclarativeItem *>(obj)) {
579         scene()->addItem(declarativeItem);
580         d->root = declarativeItem;
581         d->declarativeItemRoot = declarativeItem;
582     } else if (QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(obj)) {
583         scene()->addItem(graphicsObject);
584         d->root = graphicsObject;
585         if (graphicsObject->isWidget()) {
586             d->graphicsWidgetRoot = static_cast<QGraphicsWidget*>(graphicsObject);
587         } else {
588             qWarning() << "QDeclarativeView::resizeMode is not honored for components of type QGraphicsObject";
589         }
590     } else if (obj) {
591         qWarning() << "QDeclarativeView only supports loading of root objects that derive from QGraphicsObject";
592         if (QWidget* widget  = qobject_cast<QWidget *>(obj)) {
593             window()->setAttribute(Qt::WA_OpaquePaintEvent, false);
594             window()->setAttribute(Qt::WA_NoSystemBackground, false);
595             if (layout() && layout()->count()) {
596                 // Hide the QGraphicsView in GV mode.
597                 QLayoutItem *item = layout()->itemAt(0);
598                 if (item->widget())
599                     item->widget()->hide();
600             }
601             widget->setParent(this);
602             if (isVisible()) {
603                 widget->setVisible(true);
604             }
605             resize(widget->size());
606         }else{
607             delete obj;
608         }
609     }
610
611     if (d->root) {
612         d->initialSize = d->rootObjectSize();
613         if ((d->resizeMode == QDeclarativeView::SizeViewToRootObject || !testAttribute(Qt::WA_Resized))
614              && d->initialSize != size()) {
615             if (!(parentWidget() && parentWidget()->layout())) {
616                 resize(d->initialSize);
617             }
618         }
619         emit initialSizeChanged(d->initialSize);
620         d->initResize();
621     }
622 }
623
624 /*!
625   \internal
626   If the \l {QTimerEvent} {timer event} \a e is this
627   view's resize timer, sceneResized() is emitted.
628  */
629 void QDeclarativeView::timerEvent(QTimerEvent* e)
630 {
631     Q_D(QDeclarativeView);
632     if (!e || e->timerId() == d->resizetimer.timerId()) {
633         d->updateSize();
634         d->resizetimer.stop();
635     }
636 }
637
638 /*! \internal */
639 bool QDeclarativeView::eventFilter(QObject *watched, QEvent *e)
640 {
641     Q_D(QDeclarativeView);
642     if (watched == d->root && d->resizeMode == SizeViewToRootObject) {
643         if (d->graphicsWidgetRoot) {
644             if (e->type() == QEvent::GraphicsSceneResize) {
645                 d->updateSize();
646             }
647         }
648     }
649     return QGraphicsView::eventFilter(watched, e);
650 }
651
652 /*!
653     \internal
654     Preferred size follows the root object geometry.
655 */
656 QSize QDeclarativeView::sizeHint() const
657 {
658     Q_D(const QDeclarativeView);
659     QSize rootObjectSize = d->rootObjectSize();
660     if (rootObjectSize.isEmpty()) {
661         return size();
662     } else {
663         return rootObjectSize;
664     }
665 }
666
667 /*!
668   Returns the initial size of the root object
669 */
670 QSize QDeclarativeView::initialSize() const
671 {
672     Q_D(const QDeclarativeView);
673     return d->initialSize;
674 }
675
676 /*!
677   Returns the view's root \l {QGraphicsObject} {item}.
678  */
679 QGraphicsObject *QDeclarativeView::rootObject() const
680 {
681     Q_D(const QDeclarativeView);
682     return d->root;
683 }
684
685 /*!
686   \internal
687   This function handles the \l {QResizeEvent} {resize event}
688   \a e.
689  */
690 void QDeclarativeView::resizeEvent(QResizeEvent *e)
691 {
692     Q_D(QDeclarativeView);
693     if (d->resizeMode == SizeRootObjectToView) {
694         d->updateSize();
695     }
696     if (d->declarativeItemRoot) {
697         setSceneRect(QRectF(0, 0, d->declarativeItemRoot->width(), d->declarativeItemRoot->height()));
698     } else if (d->root) {
699         setSceneRect(d->root->boundingRect());
700     } else {
701         setSceneRect(rect());
702     }
703     emit sceneResized(e->size());
704     QGraphicsView::resizeEvent(e);
705 }
706
707 /*!
708     \internal
709 */
710 void QDeclarativeView::paintEvent(QPaintEvent *event)
711 {
712     Q_D(QDeclarativeView);
713
714     QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::FramePaint);
715     QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Painting);
716
717     int time = 0;
718     if (frameRateDebug())
719         time = d->frameTimer.restart();
720
721     QGraphicsView::paintEvent(event);
722
723     QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Painting);
724
725     if (frameRateDebug())
726         qDebug() << "paintEvent:" << d->frameTimer.elapsed() << "time since last frame:" << time;
727
728 #if QT_SHOW_DECLARATIVEVIEW_FPS
729     static QTime timer;
730     static int frames;
731
732     if (frames == 0) {
733         timer.start();
734     } else if (timer.elapsed() > 5000) {
735         qreal avgtime = timer.elapsed() / (qreal) frames;
736         qDebug("Average time per frame: %f ms (%i fps)", avgtime, int(1000 / avgtime));
737         timer.start();
738         frames = 0;
739     }
740     ++frames;
741     scene()->update();
742 #endif
743
744 }
745
746 QDeclarativeItem * QDeclarativeView::accessibleRootItem() const
747 {
748     Q_D(const QDeclarativeView);
749     return d->declarativeItemRoot;
750 }
751
752 QT_END_NAMESPACE