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