util/src/gui/graphicsview/qgraphicsanchorlayout.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     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 QtGui 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 /*!
       
    43     \class QGraphicsAnchorLayout
       
    44     \brief The QGraphicsAnchorLayout class provides a layout where one can anchor widgets
       
    45     together in Graphics View.
       
    46     \since 4.6
       
    47     \ingroup appearance
       
    48     \ingroup geomanagement
       
    49     \ingroup graphicsview-api
       
    50 
       
    51     The anchor layout allows developers to specify how widgets should be placed relative to
       
    52     each other, and to the layout itself. The specification is made by adding anchors to the
       
    53     layout by calling addAnchor(), addAnchors() or addCornerAnchors().
       
    54 
       
    55     Existing anchors in the layout can be accessed with the anchor() function.
       
    56     Items that are anchored are automatically added to the layout, and if items
       
    57     are removed, all their anchors will be automatically removed.
       
    58 
       
    59     \beginfloatleft
       
    60     \inlineimage simpleanchorlayout-example.png Using an anchor layout to align simple colored widgets.
       
    61     \endfloat
       
    62 
       
    63     Anchors are always set up between edges of an item, where the "center" is also considered to
       
    64     be an edge. Consider the following example:
       
    65 
       
    66     \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding anchors
       
    67 
       
    68     Here, the right edge of item \c a is anchored to the left edge of item \c b and the bottom
       
    69     edge of item \c a is anchored to the top edge of item \c b, with the result that
       
    70     item \c b will be placed diagonally to the right and below item \c b.
       
    71 
       
    72     The addCornerAnchors() function provides a simpler way of anchoring the corners
       
    73     of two widgets than the two individual calls to addAnchor() shown in the code
       
    74     above. Here, we see how a widget can be anchored to the top-left corner of the enclosing
       
    75     layout:
       
    76 
       
    77     \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding a corner anchor
       
    78 
       
    79     In cases where anchors are used to match the widths or heights of widgets, it is
       
    80     convenient to use the addAnchors() function. As with the other functions for specifying
       
    81     anchors, it can also be used to anchor a widget to a layout.
       
    82 
       
    83     \clearfloat
       
    84     \section1 Size Hints and Size Policies in an Anchor Layout
       
    85 
       
    86     QGraphicsAnchorLayout respects each item's size hints and size policies.
       
    87     Note that there are some properties of QSizePolicy that are \l{Known issues}{not respected}.
       
    88 
       
    89     \section1 Spacing within an Anchor Layout
       
    90 
       
    91     The layout may distribute some space between the items. If the spacing has not been
       
    92     explicitly specified, the actual amount of space will usually be 0.
       
    93 
       
    94     However, if the first edge is the \e opposite of the second edge (e.g., the right edge
       
    95     of the first widget is anchored to the left edge of the second widget), the size of the
       
    96     anchor will be queried from the style through a pixel metric:
       
    97     \l{QStyle::}{PM_LayoutHorizontalSpacing} for horizontal anchors and
       
    98     \l{QStyle::}{PM_LayoutVerticalSpacing} for vertical anchors.
       
    99 
       
   100     If the spacing is negative, the items will overlap to some extent.
       
   101 
       
   102 
       
   103     \section1 Known issues
       
   104     There are some features that QGraphicsAnchorLayout currently does not support.
       
   105     This might change in the future, so avoid using these features if you want to
       
   106     avoid any future regressions in behaviour:
       
   107     \list
       
   108 
       
   109     \o Stretch factors are not respected.
       
   110 
       
   111     \o QSizePolicy::ExpandFlag is not respected.
       
   112 
       
   113     \o Height for width is not respected.
       
   114 
       
   115     \endlist
       
   116 
       
   117     \sa QGraphicsLinearLayout, QGraphicsGridLayout, QGraphicsLayout
       
   118 */
       
   119 
       
   120 /*!
       
   121     \class QGraphicsAnchor
       
   122     \brief The QGraphicsAnchor class represents an anchor between two items in a
       
   123            QGraphicsAnchorLayout.
       
   124     \since 4.6
       
   125     \ingroup appearance
       
   126     \ingroup geomanagement
       
   127     \ingroup graphicsview-api
       
   128 
       
   129     The graphics anchor provides an API that enables you to query and manipulate the
       
   130     properties an anchor has. When an anchor is added to the layout with
       
   131     QGraphicsAnchorLayout::addAnchor(), a QGraphicsAnchor instance is returned where the properties
       
   132     are initialized to their default values. The properties can then be further changed, and they
       
   133     will be picked up the next time the layout is activated.
       
   134 
       
   135     \sa QGraphicsAnchorLayout::anchor()
       
   136 
       
   137 */
       
   138 #include "qgraphicsanchorlayout_p.h"
       
   139 #ifndef QT_NO_GRAPHICSVIEW
       
   140 QT_BEGIN_NAMESPACE
       
   141 
       
   142 QGraphicsAnchor::QGraphicsAnchor(QGraphicsAnchorLayout *parentLayout)
       
   143     : QObject(*(new QGraphicsAnchorPrivate))
       
   144 {
       
   145     Q_D(QGraphicsAnchor);
       
   146     Q_ASSERT(parentLayout);
       
   147     d->layoutPrivate = parentLayout->d_func();
       
   148 }
       
   149 
       
   150 /*!
       
   151     Removes the QGraphicsAnchor object from the layout and destroys it.
       
   152 */
       
   153 QGraphicsAnchor::~QGraphicsAnchor()
       
   154 {
       
   155 }
       
   156 
       
   157 /*!
       
   158     \property QGraphicsAnchor::sizePolicy
       
   159     \brief the size policy for the QGraphicsAnchor.
       
   160 
       
   161     By setting the size policy on an anchor you can configure how the anchor can resize itself
       
   162     from its preferred spacing. For instance, if the anchor has the size policy
       
   163     QSizePolicy::Minimum, the spacing is the minimum size of the anchor. However, its size
       
   164     can grow up to the anchors maximum size. If the default size policy is QSizePolicy::Fixed,
       
   165     the anchor can neither grow or shrink, which means that the only size the anchor can have
       
   166     is the spacing. QSizePolicy::Fixed is the default size policy.
       
   167     QGraphicsAnchor always has a minimum spacing of 0 and a very large maximum spacing.
       
   168 
       
   169     \sa QGraphicsAnchor::spacing
       
   170 */
       
   171 
       
   172 void QGraphicsAnchor::setSizePolicy(QSizePolicy::Policy policy)
       
   173 {
       
   174     Q_D(QGraphicsAnchor);
       
   175     d->setSizePolicy(policy);
       
   176 }
       
   177 
       
   178 QSizePolicy::Policy QGraphicsAnchor::sizePolicy() const
       
   179 {
       
   180     Q_D(const QGraphicsAnchor);
       
   181     return d->sizePolicy;
       
   182 }
       
   183 
       
   184 /*!
       
   185     \property QGraphicsAnchor::spacing
       
   186     \brief the preferred space between items in the QGraphicsAnchorLayout.
       
   187 
       
   188     Depending on the anchor type, the default spacing is either
       
   189     0 or a value returned from the style.
       
   190 
       
   191     \sa QGraphicsAnchorLayout::addAnchor()
       
   192 */
       
   193 void QGraphicsAnchor::setSpacing(qreal spacing)
       
   194 {
       
   195     Q_D(QGraphicsAnchor);
       
   196     d->setSpacing(spacing);
       
   197 }
       
   198 
       
   199 qreal QGraphicsAnchor::spacing() const
       
   200 {
       
   201     Q_D(const QGraphicsAnchor);
       
   202     return d->spacing();
       
   203 }
       
   204 
       
   205 void QGraphicsAnchor::unsetSpacing()
       
   206 {
       
   207     Q_D(QGraphicsAnchor);
       
   208     d->unsetSpacing();
       
   209 }
       
   210 
       
   211 /*!
       
   212     Constructs a QGraphicsAnchorLayout instance.  \a parent is passed to
       
   213     QGraphicsLayout's constructor.
       
   214   */
       
   215 QGraphicsAnchorLayout::QGraphicsAnchorLayout(QGraphicsLayoutItem *parent)
       
   216     : QGraphicsLayout(*new QGraphicsAnchorLayoutPrivate(), parent)
       
   217 {
       
   218     Q_D(QGraphicsAnchorLayout);
       
   219     d->createLayoutEdges();
       
   220 }
       
   221 
       
   222 /*!
       
   223     Destroys the QGraphicsAnchorLayout object.
       
   224 */
       
   225 QGraphicsAnchorLayout::~QGraphicsAnchorLayout()
       
   226 {
       
   227     Q_D(QGraphicsAnchorLayout);
       
   228 
       
   229     for (int i = count() - 1; i >= 0; --i) {
       
   230         QGraphicsLayoutItem *item = d->items.at(i);
       
   231         removeAt(i);
       
   232         if (item) {
       
   233             if (item->ownedByLayout())
       
   234                 delete item;
       
   235         }
       
   236     }
       
   237 
       
   238     d->removeCenterConstraints(this, QGraphicsAnchorLayoutPrivate::Horizontal);
       
   239     d->removeCenterConstraints(this, QGraphicsAnchorLayoutPrivate::Vertical);
       
   240     d->deleteLayoutEdges();
       
   241 
       
   242     Q_ASSERT(d->itemCenterConstraints[0].isEmpty());
       
   243     Q_ASSERT(d->itemCenterConstraints[1].isEmpty());
       
   244     Q_ASSERT(d->items.isEmpty());
       
   245     Q_ASSERT(d->m_vertexList.isEmpty());
       
   246 }
       
   247 
       
   248 /*!
       
   249     Creates an anchor between the edge \a firstEdge of item \a firstItem and the edge \a secondEdge
       
   250     of item \a secondItem. The spacing of the anchor is picked up from the style. Anchors
       
   251     between a layout edge and an item edge will have a size of 0.
       
   252     If there is already an anchor between the edges, the the new anchor will replace the old one.
       
   253 
       
   254     \a firstItem and \a secondItem are automatically added to the layout if they are not part
       
   255     of the layout. This means that count() can increase by up to 2.
       
   256 
       
   257     The spacing an anchor will get depends on the type of anchor. For instance, anchors from the
       
   258     Right edge of one item to the Left edge of another (or vice versa) will use the default
       
   259     horizontal spacing. The same behaviour applies to Bottom to Top anchors, (but they will use
       
   260     the default vertical spacing). For all other anchor combinations, the spacing will be 0.
       
   261     All anchoring functions will follow this rule.
       
   262 
       
   263     The spacing can also be set manually by using QGraphicsAnchor::setSpacing() method.
       
   264 
       
   265     Calling this function where \a firstItem or \a secondItem are ancestors of the layout have
       
   266     undefined behaviour.
       
   267 
       
   268     \sa addAnchors(), addCornerAnchors()
       
   269  */
       
   270 QGraphicsAnchor *
       
   271 QGraphicsAnchorLayout::addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge,
       
   272                                  QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge)
       
   273 {
       
   274     Q_D(QGraphicsAnchorLayout);
       
   275     QGraphicsAnchor *a = d->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
       
   276     invalidate();
       
   277     return a;
       
   278 }
       
   279 
       
   280 /*!
       
   281     Returns the anchor between the anchor points defined by \a firstItem and \a firstEdge and
       
   282     \a secondItem and \a secondEdge. If there is no such anchor, the function will return 0.
       
   283 */
       
   284 QGraphicsAnchor *
       
   285 QGraphicsAnchorLayout::anchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge,
       
   286                               QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge)
       
   287 {
       
   288     Q_D(QGraphicsAnchorLayout);
       
   289     return d->getAnchor(firstItem, firstEdge, secondItem, secondEdge);
       
   290 }
       
   291 
       
   292 /*!
       
   293     Creates two anchors between \a firstItem and \a secondItem specified by the corners,
       
   294     \a firstCorner and \a secondCorner, where one is for the horizontal edge and another
       
   295     one for the vertical edge.
       
   296 
       
   297     This is a convenience function, since anchoring corners can be expressed as anchoring
       
   298     two edges. For instance:
       
   299 
       
   300     \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding a corner anchor in two steps
       
   301 
       
   302     This can also be achieved with the following line of code:
       
   303 
       
   304     \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding a corner anchor
       
   305 
       
   306     If there is already an anchor between the edge pairs, it will be replaced by the anchors that
       
   307     this function specifies.
       
   308 
       
   309     \a firstItem and \a secondItem are automatically added to the layout if they are not part of the
       
   310     layout. This means that count() can increase by up to 2.
       
   311 
       
   312     \sa addAnchor(), addAnchors()
       
   313 */
       
   314 void QGraphicsAnchorLayout::addCornerAnchors(QGraphicsLayoutItem *firstItem,
       
   315                                              Qt::Corner firstCorner,
       
   316                                              QGraphicsLayoutItem *secondItem,
       
   317                                              Qt::Corner secondCorner)
       
   318 {
       
   319     Q_D(QGraphicsAnchorLayout);
       
   320 
       
   321     // Horizontal anchor
       
   322     Qt::AnchorPoint firstEdge = (firstCorner & 1 ? Qt::AnchorRight: Qt::AnchorLeft);
       
   323     Qt::AnchorPoint secondEdge = (secondCorner & 1 ? Qt::AnchorRight: Qt::AnchorLeft);
       
   324     if (d->addAnchor(firstItem, firstEdge, secondItem, secondEdge)) {
       
   325         // Vertical anchor
       
   326         firstEdge = (firstCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop);
       
   327         secondEdge = (secondCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop);
       
   328         d->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
       
   329 
       
   330         invalidate();
       
   331     }
       
   332 }
       
   333 
       
   334 /*!
       
   335     Anchors two or four edges of \a firstItem with the corresponding
       
   336     edges of \a secondItem, so that \a firstItem has the same size as
       
   337     \a secondItem in the dimensions specified by \a orientations.
       
   338 
       
   339     For example, the following example anchors the left and right edges of two items
       
   340     to match their widths:
       
   341 
       
   342     \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding anchors to match sizes in two steps
       
   343 
       
   344     This can also be achieved using the following line of code:
       
   345 
       
   346     \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding anchors to match sizes
       
   347 
       
   348     \sa addAnchor(), addCornerAnchors()
       
   349 */
       
   350 void QGraphicsAnchorLayout::addAnchors(QGraphicsLayoutItem *firstItem,
       
   351                                        QGraphicsLayoutItem *secondItem,
       
   352                                        Qt::Orientations orientations)
       
   353 {
       
   354     bool ok = true;
       
   355     if (orientations & Qt::Horizontal) {
       
   356         // Currently, if the first is ok, then the rest of the calls should be ok
       
   357         ok = addAnchor(secondItem, Qt::AnchorLeft, firstItem, Qt::AnchorLeft) != 0;
       
   358         if (ok)
       
   359             addAnchor(firstItem, Qt::AnchorRight, secondItem, Qt::AnchorRight);
       
   360     }
       
   361     if (orientations & Qt::Vertical && ok) {
       
   362         addAnchor(secondItem, Qt::AnchorTop, firstItem, Qt::AnchorTop);
       
   363         addAnchor(firstItem, Qt::AnchorBottom, secondItem, Qt::AnchorBottom);
       
   364     }
       
   365 }
       
   366 
       
   367 /*!
       
   368     Sets the default horizontal spacing for the anchor layout to \a spacing.
       
   369 
       
   370     \sa horizontalSpacing(), setVerticalSpacing(), setSpacing()
       
   371 */
       
   372 void QGraphicsAnchorLayout::setHorizontalSpacing(qreal spacing)
       
   373 {
       
   374     Q_D(QGraphicsAnchorLayout);
       
   375 
       
   376     d->spacings[0] = spacing;
       
   377     invalidate();
       
   378 }
       
   379 
       
   380 /*!
       
   381     Sets the default vertical spacing for the anchor layout to \a spacing.
       
   382 
       
   383     \sa verticalSpacing(), setHorizontalSpacing(), setSpacing()
       
   384 */
       
   385 void QGraphicsAnchorLayout::setVerticalSpacing(qreal spacing)
       
   386 {
       
   387     Q_D(QGraphicsAnchorLayout);
       
   388 
       
   389     d->spacings[1] = spacing;
       
   390     invalidate();
       
   391 }
       
   392 
       
   393 /*!
       
   394     Sets the default horizontal and the default vertical spacing for the anchor layout to \a spacing.
       
   395 
       
   396     If an item is anchored with no spacing associated with the anchor, it will use the default
       
   397     spacing.
       
   398 
       
   399     QGraphicsAnchorLayout does not support negative spacings. Setting a negative value will unset the
       
   400     previous spacing and make the layout use the spacing provided by the current widget style.
       
   401 
       
   402     \sa setHorizontalSpacing(), setVerticalSpacing()
       
   403 */
       
   404 void QGraphicsAnchorLayout::setSpacing(qreal spacing)
       
   405 {
       
   406     Q_D(QGraphicsAnchorLayout);
       
   407 
       
   408     d->spacings[0] = d->spacings[1] = spacing;
       
   409     invalidate();
       
   410 }
       
   411 
       
   412 /*!
       
   413     Returns the default horizontal spacing for the anchor layout.
       
   414 
       
   415     \sa verticalSpacing(), setHorizontalSpacing()
       
   416 */
       
   417 qreal QGraphicsAnchorLayout::horizontalSpacing() const
       
   418 {
       
   419     Q_D(const QGraphicsAnchorLayout);
       
   420     return d->styleInfo().defaultSpacing(Qt::Horizontal);
       
   421 }
       
   422 
       
   423 /*!
       
   424     Returns the default vertical spacing for the anchor layout.
       
   425 
       
   426     \sa horizontalSpacing(), setVerticalSpacing()
       
   427 */
       
   428 qreal QGraphicsAnchorLayout::verticalSpacing() const
       
   429 {
       
   430     Q_D(const QGraphicsAnchorLayout);
       
   431     return d->styleInfo().defaultSpacing(Qt::Vertical);
       
   432 }
       
   433 
       
   434 /*!
       
   435     \reimp
       
   436 */
       
   437 void QGraphicsAnchorLayout::setGeometry(const QRectF &geom)
       
   438 {
       
   439     Q_D(QGraphicsAnchorLayout);
       
   440 
       
   441     QGraphicsLayout::setGeometry(geom);
       
   442     d->calculateVertexPositions(QGraphicsAnchorLayoutPrivate::Horizontal);
       
   443     d->calculateVertexPositions(QGraphicsAnchorLayoutPrivate::Vertical);
       
   444     d->setItemsGeometries(geom);
       
   445 }
       
   446 
       
   447 /*!
       
   448     Removes the layout item at \a index without destroying it. Ownership of
       
   449     the item is transferred to the caller.
       
   450 
       
   451     Removing an item will also remove any of the anchors associated with it.
       
   452 
       
   453     \sa itemAt(), count()
       
   454 */
       
   455 void QGraphicsAnchorLayout::removeAt(int index)
       
   456 {
       
   457     Q_D(QGraphicsAnchorLayout);
       
   458     QGraphicsLayoutItem *item = d->items.value(index);
       
   459 
       
   460     if (!item)
       
   461         return;
       
   462 
       
   463     // Removing an item affects both horizontal and vertical graphs
       
   464     d->removeCenterConstraints(item, QGraphicsAnchorLayoutPrivate::Horizontal);
       
   465     d->removeCenterConstraints(item, QGraphicsAnchorLayoutPrivate::Vertical);
       
   466     d->removeAnchors(item);
       
   467     d->items.remove(index);
       
   468 
       
   469     item->setParentLayoutItem(0);
       
   470     invalidate();
       
   471 }
       
   472 
       
   473 /*!
       
   474     \reimp
       
   475 */
       
   476 int QGraphicsAnchorLayout::count() const
       
   477 {
       
   478     Q_D(const QGraphicsAnchorLayout);
       
   479     return d->items.size();
       
   480 }
       
   481 
       
   482 /*!
       
   483     \reimp
       
   484 */
       
   485 QGraphicsLayoutItem *QGraphicsAnchorLayout::itemAt(int index) const
       
   486 {
       
   487     Q_D(const QGraphicsAnchorLayout);
       
   488     return d->items.value(index);
       
   489 }
       
   490 
       
   491 /*!
       
   492     \reimp
       
   493 */
       
   494 void QGraphicsAnchorLayout::invalidate()
       
   495 {
       
   496     Q_D(QGraphicsAnchorLayout);
       
   497     QGraphicsLayout::invalidate();
       
   498     d->calculateGraphCacheDirty = true;
       
   499     d->styleInfoDirty = true;
       
   500 }
       
   501 
       
   502 /*!
       
   503     \reimp
       
   504 */
       
   505 QSizeF QGraphicsAnchorLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
       
   506 {
       
   507     Q_UNUSED(constraint);
       
   508     Q_D(const QGraphicsAnchorLayout);
       
   509 
       
   510     // Some setup calculations are delayed until the information is
       
   511     // actually needed, avoiding unnecessary recalculations when
       
   512     // adding multiple anchors.
       
   513 
       
   514     // sizeHint() / effectiveSizeHint() already have a cache
       
   515     // mechanism, using invalidate() to force recalculation. However
       
   516     // sizeHint() is called three times after invalidation (for max,
       
   517     // min and pref), but we just need do our setup once.
       
   518 
       
   519     const_cast<QGraphicsAnchorLayoutPrivate *>(d)->calculateGraphs();
       
   520 
       
   521     // ### apply constraint!
       
   522     QSizeF engineSizeHint(
       
   523         d->sizeHints[QGraphicsAnchorLayoutPrivate::Horizontal][which],
       
   524         d->sizeHints[QGraphicsAnchorLayoutPrivate::Vertical][which]);
       
   525 
       
   526     qreal left, top, right, bottom;
       
   527     getContentsMargins(&left, &top, &right, &bottom);
       
   528 
       
   529     return engineSizeHint + QSizeF(left + right, top + bottom);
       
   530 }
       
   531 
       
   532 QT_END_NAMESPACE
       
   533 #endif //QT_NO_GRAPHICSVIEW