util/src/gui/graphicsview/qgraphicswidget.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 #include "qglobal.h"
       
    43 
       
    44 #ifndef QT_NO_GRAPHICSVIEW
       
    45 
       
    46 #include "qgraphicswidget.h"
       
    47 #include "qgraphicswidget_p.h"
       
    48 #include "qgraphicslayout.h"
       
    49 #include "qgraphicslayout_p.h"
       
    50 #include "qgraphicsscene.h"
       
    51 #include "qgraphicssceneevent.h"
       
    52 
       
    53 #ifndef QT_NO_ACTION
       
    54 #include <private/qaction_p.h>
       
    55 #endif
       
    56 #include <private/qapplication_p.h>
       
    57 #include <private/qgraphicsscene_p.h>
       
    58 #ifndef QT_NO_SHORTCUT
       
    59 #include <private/qshortcutmap_p.h>
       
    60 #endif
       
    61 #include <QtCore/qmutex.h>
       
    62 #include <QtGui/qapplication.h>
       
    63 #include <QtGui/qgraphicsview.h>
       
    64 #include <QtGui/qgraphicsproxywidget.h>
       
    65 #include <QtGui/qpalette.h>
       
    66 #include <QtGui/qstyleoption.h>
       
    67 
       
    68 #include <qdebug.h>
       
    69 
       
    70 QT_BEGIN_NAMESPACE
       
    71 
       
    72 /*!
       
    73     \class QGraphicsWidget
       
    74     \brief The QGraphicsWidget class is the base class for all widget
       
    75     items in a QGraphicsScene.
       
    76     \since 4.4
       
    77     \ingroup graphicsview-api
       
    78 
       
    79     QGraphicsWidget is an extended base item that provides extra functionality
       
    80     over QGraphicsItem. It is similar to QWidget in many ways:
       
    81 
       
    82     \list
       
    83         \o Provides a \l palette, a \l font and a \l style().
       
    84         \o Has a defined geometry().
       
    85         \o Supports layouts with setLayout() and layout().
       
    86         \o Supports shortcuts and actions with grabShortcut() and insertAction()
       
    87     \endlist
       
    88 
       
    89     Unlike QGraphicsItem, QGraphicsWidget is not an abstract class; you can
       
    90     create instances of a QGraphicsWidget without having to subclass it.
       
    91     This approach is useful for widgets that only serve the purpose of
       
    92     organizing child widgets into a layout.
       
    93 
       
    94     QGraphicsWidget can be used as a base item for your own custom item if
       
    95     you require advanced input focus handling, e.g., tab focus and activation, or
       
    96     layouts.
       
    97 
       
    98     Since QGraphicsWidget resembles QWidget and has similar API, it is
       
    99     easier to port a widget from QWidget to QGraphicsWidget, instead of
       
   100     QGraphicsItem.
       
   101 
       
   102     \note QWidget-based widgets can be directly embedded into a
       
   103     QGraphicsScene using QGraphicsProxyWidget.
       
   104 
       
   105     Noticeable differences between QGraphicsWidget and QWidget are:
       
   106 
       
   107     \table
       
   108     \header \o QGraphicsWidget
       
   109                 \o QWidget
       
   110     \row      \o Coordinates and geometry are defined with qreals (doubles or
       
   111                     floats, depending on the platform).
       
   112                 \o QWidget uses integer geometry (QPoint, QRect).
       
   113     \row      \o The widget is already visible by default; you do not have to
       
   114                     call show() to display the widget.
       
   115                 \o QWidget is hidden by default until you call show().
       
   116     \row      \o A subset of widget attributes are supported.
       
   117                 \o All widget attributes are supported.
       
   118     \row      \o A top-level item's style defaults to QGraphicsScene::style
       
   119                 \o A top-level widget's style defaults to QApplication::style
       
   120     \row      \o Graphics View provides a custom drag and drop framework, different
       
   121                     from QWidget.
       
   122                 \o Standard drag and drop framework.
       
   123     \row      \o Widget items do not support modality.
       
   124                 \o Full modality support.
       
   125     \endtable
       
   126 
       
   127     QGraphicsWidget supports a subset of Qt's widget attributes,
       
   128     (Qt::WidgetAttribute), as shown in the table below. Any attributes not
       
   129     listed in this table are unsupported, or otherwise unused.
       
   130 
       
   131     \table
       
   132     \header \o Widget Attribute                         \o Usage
       
   133     \row    \o Qt::WA_SetLayoutDirection
       
   134                     \o Set by setLayoutDirection(), cleared by
       
   135                         unsetLayoutDirection(). You can test this attribute to
       
   136                         check if the widget has been explicitly assigned a
       
   137                         \l{QGraphicsWidget::layoutDirection()}
       
   138                         {layoutDirection}. If the attribute is not set, the
       
   139                         \l{QGraphicsWidget::layoutDirection()}
       
   140                         {layoutDirection()} is inherited.
       
   141     \row    \o Qt::WA_RightToLeft
       
   142                     \o Toggled by setLayoutDirection(). Inherited from the
       
   143                         parent/scene. If set, the widget's layout will order
       
   144                         horizontally arranged widgets from right to left.
       
   145     \row    \o Qt::WA_SetStyle
       
   146                     \o Set and cleared by setStyle(). If this attribute is
       
   147                         set, the widget has been explicitly assigned a style.
       
   148                         If it is unset, the widget will use the scene's or the
       
   149                         application's style.
       
   150     \row    \o Qt::WA_Resized
       
   151                     \o Set by setGeometry() and resize().
       
   152     \row    \o Qt::WA_SetPalette
       
   153                     \o Set by setPalette().
       
   154     \row    \o Qt::WA_SetFont
       
   155                     \o Set by setPalette().
       
   156     \row    \o Qt::WA_WindowPropagation
       
   157                     \o Enables propagation to window widgets.
       
   158     \endtable
       
   159 
       
   160     Although QGraphicsWidget inherits from both QObject and QGraphicsItem,
       
   161     you should use the functions provided by QGraphicsItem, \e not QObject, to
       
   162     manage the relationships between parent and child items. These functions
       
   163     control the stacking order of items as well as their ownership.
       
   164 
       
   165     \note The QObject::parent() should always return 0 for QGraphicsWidgets,
       
   166     but this policy is not strictly defined.
       
   167 
       
   168     \sa QGraphicsProxyWidget, QGraphicsItem, {Widgets and Layouts}
       
   169 */
       
   170 
       
   171 /*!
       
   172     Constructs a QGraphicsWidget instance. The optional \a parent argument is
       
   173     passed to QGraphicsItem's constructor. The optional \a wFlags argument
       
   174     specifies the widget's window flags (e.g., whether the widget should be a
       
   175     window, a tool, a popup, etc).
       
   176 */
       
   177 QGraphicsWidget::QGraphicsWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags)
       
   178     : QGraphicsObject(*new QGraphicsWidgetPrivate, 0, 0), QGraphicsLayoutItem(0, false)
       
   179 {
       
   180     Q_D(QGraphicsWidget);
       
   181     d->init(parent, wFlags);
       
   182 }
       
   183 
       
   184 /*!
       
   185     \internal
       
   186 
       
   187     Constructs a new QGraphicsWidget, using \a dd as parent.
       
   188 */
       
   189 QGraphicsWidget::QGraphicsWidget(QGraphicsWidgetPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene, Qt::WindowFlags wFlags)
       
   190     : QGraphicsObject(dd, 0, scene), QGraphicsLayoutItem(0, false)
       
   191 {
       
   192     Q_D(QGraphicsWidget);
       
   193     d->init(parent, wFlags);
       
   194 }
       
   195 
       
   196 /*
       
   197     \internal
       
   198     \class QGraphicsWidgetStyles
       
   199 
       
   200     We use this thread-safe class to maintain a hash of styles for widgets
       
   201     styles. Note that QApplication::style() itself isn't thread-safe, QStyle
       
   202     isn't thread-safe, and we don't have a thread-safe factory for creating
       
   203     the default style, nor cloning a style.
       
   204 */
       
   205 class QGraphicsWidgetStyles
       
   206 {
       
   207 public:
       
   208     QStyle *styleForWidget(const QGraphicsWidget *widget) const
       
   209     {
       
   210         QMutexLocker locker(&mutex);
       
   211         return styles.value(widget, 0);
       
   212     }
       
   213 
       
   214     void setStyleForWidget(QGraphicsWidget *widget, QStyle *style)
       
   215     {
       
   216         QMutexLocker locker(&mutex);
       
   217         if (style)
       
   218             styles[widget] = style;
       
   219         else
       
   220             styles.remove(widget);
       
   221     }
       
   222 
       
   223 private:
       
   224     QMap<const QGraphicsWidget *, QStyle *> styles;
       
   225     mutable QMutex mutex;
       
   226 };
       
   227 Q_GLOBAL_STATIC(QGraphicsWidgetStyles, widgetStyles)
       
   228 
       
   229 /*!
       
   230     Destroys the QGraphicsWidget instance.
       
   231 */
       
   232 QGraphicsWidget::~QGraphicsWidget()
       
   233 {
       
   234     Q_D(QGraphicsWidget);
       
   235 #ifndef QT_NO_ACTION
       
   236     // Remove all actions from this widget
       
   237     for (int i = 0; i < d->actions.size(); ++i) {
       
   238         QActionPrivate *apriv = d->actions.at(i)->d_func();
       
   239         apriv->graphicsWidgets.removeAll(this);
       
   240     }
       
   241     d->actions.clear();
       
   242 #endif
       
   243 
       
   244     if (QGraphicsScene *scn = scene()) {
       
   245         QGraphicsScenePrivate *sceneD = scn->d_func();
       
   246         if (sceneD->tabFocusFirst == this)
       
   247             sceneD->tabFocusFirst = (d->focusNext == this ? 0 : d->focusNext);
       
   248     }
       
   249     d->focusPrev->d_func()->focusNext = d->focusNext;
       
   250     d->focusNext->d_func()->focusPrev = d->focusPrev;
       
   251 
       
   252     // Play it really safe
       
   253     d->focusNext = this;
       
   254     d->focusPrev = this;
       
   255 
       
   256     clearFocus();
       
   257 
       
   258     //we check if we have a layout previously
       
   259     if (d->layout) {
       
   260         QGraphicsLayout *temp = d->layout;
       
   261         foreach (QGraphicsItem * item, childItems()) {
       
   262             // In case of a custom layout which doesn't remove and delete items, we ensure that
       
   263             // the parent layout item does not point to the deleted layout. This code is here to
       
   264             // avoid regression from 4.4 to 4.5, because according to 4.5 docs it is not really needed.
       
   265             if (item->isWidget()) {
       
   266                 QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
       
   267                 if (widget->parentLayoutItem() == d->layout)
       
   268                     widget->setParentLayoutItem(0);
       
   269             }
       
   270         }
       
   271         d->layout = 0;
       
   272         delete temp;
       
   273     }
       
   274 
       
   275     // Remove this graphics widget from widgetStyles
       
   276     widgetStyles()->setStyleForWidget(this, 0);
       
   277 }
       
   278 
       
   279 /*!
       
   280     \property QGraphicsWidget::size
       
   281     \brief the size of the widget
       
   282 
       
   283     Calling resize() resizes the widget to a \a size bounded by minimumSize()
       
   284     and maximumSize(). This property only affects the widget's width and
       
   285     height (e.g., its right and bottom edges); the widget's position and
       
   286     top-left corner remains unaffected.
       
   287 
       
   288     Resizing a widget triggers the widget to immediately receive a
       
   289     \l{QEvent::GraphicsSceneResize}{GraphicsSceneResize} event with the
       
   290     widget's old and new size.  If the widget has a layout assigned when this
       
   291     event arrives, the layout will be activated and it will automatically
       
   292     update any child widgets's geometry.
       
   293 
       
   294     This property does not affect any layout of the parent widget. If the
       
   295     widget itself is managed by a parent layout; e.g., it has a parent widget
       
   296     with a layout assigned, that layout will not activate.
       
   297 
       
   298     By default, this property contains a size with zero width and height.
       
   299 
       
   300     \sa setGeometry(), QGraphicsSceneResizeEvent, QGraphicsLayout
       
   301 */
       
   302 QSizeF QGraphicsWidget::size() const
       
   303 {
       
   304     return QGraphicsLayoutItem::geometry().size();
       
   305 }
       
   306 
       
   307 void QGraphicsWidget::resize(const QSizeF &size)
       
   308 {
       
   309     setGeometry(QRectF(pos(), size));
       
   310 }
       
   311 
       
   312 /*!
       
   313     \fn void QGraphicsWidget::resize(qreal w, qreal h)
       
   314 
       
   315     This convenience function is equivalent to calling resize(QSizeF(w, h)).
       
   316 
       
   317     \sa setGeometry(), setTransform()
       
   318 */
       
   319 
       
   320 /*!
       
   321     \property QGraphicsWidget::sizePolicy
       
   322     \brief the size policy for the widget
       
   323     \sa sizePolicy(), setSizePolicy(), QWidget::sizePolicy()
       
   324 */
       
   325 
       
   326 /*!
       
   327 
       
   328   \fn QGraphicsWidget::geometryChanged()
       
   329 
       
   330   This signal gets emitted whenever the geometry of the item changes
       
   331   \internal
       
   332 */
       
   333 
       
   334 /*!
       
   335     \property QGraphicsWidget::geometry
       
   336     \brief the geometry of the widget
       
   337 
       
   338     Sets the item's geometry to \a rect. The item's position and size are
       
   339     modified as a result of calling this function. The item is first moved,
       
   340     then resized.
       
   341 
       
   342     A side effect of calling this function is that the widget will receive
       
   343     a move event and a resize event. Also, if the widget has a layout
       
   344     assigned, the layout will activate.
       
   345 
       
   346     \sa geometry(), resize()
       
   347 */
       
   348 void QGraphicsWidget::setGeometry(const QRectF &rect)
       
   349 {
       
   350     QGraphicsWidgetPrivate *wd = QGraphicsWidget::d_func();
       
   351     QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr.data();
       
   352     QRectF newGeom;
       
   353     QPointF oldPos = d->geom.topLeft();
       
   354     if (!wd->inSetPos) {
       
   355         setAttribute(Qt::WA_Resized);
       
   356         newGeom = rect;
       
   357         newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize))
       
   358                                    .boundedTo(effectiveSizeHint(Qt::MaximumSize)));
       
   359         if (newGeom == d->geom)
       
   360             return;
       
   361 
       
   362         // setPos triggers ItemPositionChange, which can adjust position
       
   363         wd->inSetGeometry = 1;
       
   364         setPos(newGeom.topLeft());
       
   365         wd->inSetGeometry = 0;
       
   366         newGeom.moveTopLeft(pos());
       
   367 
       
   368         if (newGeom == d->geom)
       
   369            return;
       
   370 
       
   371          // Update and prepare to change the geometry (remove from index) if the size has changed.
       
   372         if (wd->scene) {
       
   373             if (rect.topLeft() == d->geom.topLeft()) {
       
   374                 prepareGeometryChange();
       
   375             }
       
   376         }
       
   377     }
       
   378 
       
   379     // Update the layout item geometry
       
   380     bool moved = oldPos != pos();
       
   381     if (moved) {
       
   382         // Send move event.
       
   383         QGraphicsSceneMoveEvent event;
       
   384         event.setOldPos(oldPos);
       
   385         event.setNewPos(pos());
       
   386         QApplication::sendEvent(this, &event);
       
   387         if (wd->inSetPos) {
       
   388             //set the new pos
       
   389             d->geom.moveTopLeft(pos());
       
   390             return;
       
   391         }
       
   392     }
       
   393     QSizeF oldSize = size();
       
   394     QGraphicsLayoutItem::setGeometry(newGeom);
       
   395     emit geometryChanged();
       
   396     // Send resize event
       
   397     bool resized = newGeom.size() != oldSize;
       
   398     if (resized) {
       
   399         QGraphicsSceneResizeEvent re;
       
   400         re.setOldSize(oldSize);
       
   401         re.setNewSize(newGeom.size());
       
   402         if (oldSize.width() != newGeom.size().width())
       
   403             emit widthChanged();
       
   404         if (oldSize.height() != newGeom.size().height())
       
   405             emit heightChanged();
       
   406         QApplication::sendEvent(this, &re);
       
   407     }
       
   408 }
       
   409 
       
   410 /*!
       
   411     \fn QRectF QGraphicsWidget::rect() const
       
   412 
       
   413     Returns the item's local rect as a QRectF. This function is equivalent
       
   414     to QRectF(QPointF(), size()).
       
   415 
       
   416     \sa setGeometry(), resize()
       
   417 */
       
   418 
       
   419 /*!
       
   420     \fn void QGraphicsWidget::setGeometry(qreal x, qreal y, qreal w, qreal h)
       
   421 
       
   422     This convenience function is equivalent to calling setGeometry(QRectF(
       
   423     \a x, \a y, \a w, \a h)).
       
   424 
       
   425     \sa geometry(), resize()
       
   426 */
       
   427 
       
   428 /*!
       
   429     \property QGraphicsWidget::minimumSize
       
   430     \brief the minimum size of the widget
       
   431 
       
   432     \sa setMinimumSize(), minimumSize(), preferredSize, maximumSize
       
   433 */
       
   434 
       
   435 /*!
       
   436     \property QGraphicsWidget::preferredSize
       
   437     \brief the preferred size of the widget
       
   438 
       
   439     \sa setPreferredSize(), preferredSize(), minimumSize, maximumSize
       
   440 */
       
   441 
       
   442 /*!
       
   443     \property QGraphicsWidget::maximumSize
       
   444     \brief the maximum size of the widget
       
   445 
       
   446     \sa setMaximumSize(), maximumSize(), minimumSize, preferredSize
       
   447 */
       
   448 
       
   449 /*!
       
   450     Sets the widget's contents margins to \a left, \a top, \a right and \a
       
   451     bottom.
       
   452 
       
   453     Contents margins are used by the assigned layout to define the placement
       
   454     of subwidgets and layouts. Margins are particularily useful for widgets
       
   455     that constrain subwidgets to only a section of its own geometry. For
       
   456     example, a group box with a layout will place subwidgets inside its frame,
       
   457     but below the title.
       
   458 
       
   459     Changing a widget's contents margins will always trigger an update(), and
       
   460     any assigned layout will be activated automatically. The widget will then
       
   461     receive a \l{QEvent::ContentsRectChange}{ContentsRectChange} event.
       
   462 
       
   463     \sa getContentsMargins(), setGeometry()
       
   464 */
       
   465 void QGraphicsWidget::setContentsMargins(qreal left, qreal top, qreal right, qreal bottom)
       
   466 {
       
   467     Q_D(QGraphicsWidget);
       
   468 
       
   469     if (!d->margins && left == 0 && top == 0 && right == 0 && bottom == 0)
       
   470         return;
       
   471     d->ensureMargins();
       
   472     if (left == d->margins[d->Left]
       
   473         && top == d->margins[d->Top]
       
   474         && right == d->margins[d->Right]
       
   475         && bottom == d->margins[d->Bottom])
       
   476         return;
       
   477 
       
   478     d->margins[d->Left] = left;
       
   479     d->margins[d->Top] = top;
       
   480     d->margins[d->Right] = right;
       
   481     d->margins[d->Bottom] = bottom;
       
   482 
       
   483     if (QGraphicsLayout *l = d->layout)
       
   484         l->invalidate();
       
   485     else
       
   486         updateGeometry();
       
   487 
       
   488     QEvent e(QEvent::ContentsRectChange);
       
   489     QApplication::sendEvent(this, &e);
       
   490 }
       
   491 
       
   492 /*!
       
   493     Gets the widget's contents margins. The margins are stored in \a left, \a
       
   494     top, \a right and \a bottom, as pointers to qreals. Each argument can
       
   495     be \e {omitted} by passing 0.
       
   496 
       
   497     \sa setContentsMargins()
       
   498 */
       
   499 void QGraphicsWidget::getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const
       
   500 {
       
   501     Q_D(const QGraphicsWidget);
       
   502     if (left || top || right || bottom)
       
   503         d->ensureMargins();
       
   504     if (left)
       
   505         *left = d->margins[d->Left];
       
   506     if (top)
       
   507         *top = d->margins[d->Top];
       
   508     if (right)
       
   509         *right = d->margins[d->Right];
       
   510     if (bottom)
       
   511         *bottom = d->margins[d->Bottom];
       
   512 }
       
   513 
       
   514 /*!
       
   515     Sets the widget's window frame margins to \a left, \a top, \a right and
       
   516     \a bottom. The default frame margins are provided by the style, and they
       
   517     depend on the current window flags.
       
   518 
       
   519     If you would like to draw your own window decoration, you can set your
       
   520     own frame margins to override the default margins.
       
   521 
       
   522     \sa unsetWindowFrameMargins(), getWindowFrameMargins(), windowFrameRect()
       
   523 */
       
   524 void QGraphicsWidget::setWindowFrameMargins(qreal left, qreal top, qreal right, qreal bottom)
       
   525 {
       
   526     Q_D(QGraphicsWidget);
       
   527 
       
   528     if (!d->windowFrameMargins && left == 0 && top == 0 && right == 0 && bottom == 0)
       
   529         return;
       
   530     d->ensureWindowFrameMargins();
       
   531     bool unchanged =
       
   532         d->windowFrameMargins[d->Left] == left
       
   533         && d->windowFrameMargins[d->Top] == top
       
   534         && d->windowFrameMargins[d->Right] == right
       
   535         && d->windowFrameMargins[d->Bottom] == bottom;
       
   536     if (d->setWindowFrameMargins && unchanged)
       
   537         return;
       
   538     if (!unchanged)
       
   539         prepareGeometryChange();
       
   540     d->windowFrameMargins[d->Left] = left;
       
   541     d->windowFrameMargins[d->Top] = top;
       
   542     d->windowFrameMargins[d->Right] = right;
       
   543     d->windowFrameMargins[d->Bottom] = bottom;
       
   544     d->setWindowFrameMargins = true;
       
   545 }
       
   546 
       
   547 /*!
       
   548     Gets the widget's window frame margins. The margins are stored in \a left,
       
   549     \a top, \a right and \a bottom as pointers to qreals. Each argument can
       
   550     be \e {omitted} by passing 0.
       
   551 
       
   552     \sa setWindowFrameMargins(), windowFrameRect()
       
   553 */
       
   554 void QGraphicsWidget::getWindowFrameMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const
       
   555 {
       
   556     Q_D(const QGraphicsWidget);
       
   557     if (left || top || right || bottom)
       
   558         d->ensureWindowFrameMargins();
       
   559     if (left)
       
   560         *left = d->windowFrameMargins[d->Left];
       
   561     if (top)
       
   562         *top = d->windowFrameMargins[d->Top];
       
   563     if (right)
       
   564         *right = d->windowFrameMargins[d->Right];
       
   565     if (bottom)
       
   566         *bottom = d->windowFrameMargins[d->Bottom];
       
   567 }
       
   568 
       
   569 /*!
       
   570     Resets the window frame margins to the default value, provided by the style.
       
   571 
       
   572     \sa setWindowFrameMargins(), getWindowFrameMargins(), windowFrameRect()
       
   573 */
       
   574 void QGraphicsWidget::unsetWindowFrameMargins()
       
   575 {
       
   576     Q_D(QGraphicsWidget);
       
   577     if ((d->windowFlags & Qt::Window) && (d->windowFlags & Qt::WindowType_Mask) != Qt::Popup &&
       
   578          (d->windowFlags & Qt::WindowType_Mask) != Qt::ToolTip && !(d->windowFlags & Qt::FramelessWindowHint)) {
       
   579         QStyleOptionTitleBar bar;
       
   580         d->initStyleOptionTitleBar(&bar);
       
   581         QStyle *style = this->style();
       
   582         qreal margin = style->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth);
       
   583         qreal titleBarHeight  = d->titleBarHeight(bar);
       
   584         setWindowFrameMargins(margin, titleBarHeight, margin, margin);
       
   585     } else {
       
   586         setWindowFrameMargins(0, 0, 0, 0);
       
   587     }
       
   588     d->setWindowFrameMargins = false;
       
   589 }
       
   590 
       
   591 /*!
       
   592     Returns the widget's geometry in parent coordinates including any window
       
   593     frame.
       
   594 
       
   595     \sa windowFrameRect(), getWindowFrameMargins(), setWindowFrameMargins()
       
   596 */
       
   597 QRectF QGraphicsWidget::windowFrameGeometry() const
       
   598 {
       
   599     Q_D(const QGraphicsWidget);
       
   600     return d->windowFrameMargins
       
   601         ? geometry().adjusted(-d->windowFrameMargins[d->Left], -d->windowFrameMargins[d->Top],
       
   602                               d->windowFrameMargins[d->Right], d->windowFrameMargins[d->Bottom])
       
   603         : geometry();
       
   604 }
       
   605 
       
   606 /*!
       
   607     Returns the widget's local rect including any window frame.
       
   608 
       
   609     \sa windowFrameGeometry(), getWindowFrameMargins(), setWindowFrameMargins()
       
   610 */
       
   611 QRectF QGraphicsWidget::windowFrameRect() const
       
   612 {
       
   613     Q_D(const QGraphicsWidget);
       
   614     return d->windowFrameMargins
       
   615         ? rect().adjusted(-d->windowFrameMargins[d->Left], -d->windowFrameMargins[d->Top],
       
   616                           d->windowFrameMargins[d->Right], d->windowFrameMargins[d->Bottom])
       
   617         : rect();
       
   618 }
       
   619 
       
   620 /*!
       
   621     Populates a style option object for this widget based on its current
       
   622     state, and stores the output in \a option. The default implementation
       
   623     populates \a option with the following properties.
       
   624 
       
   625     \table
       
   626       \header
       
   627         \o Style Option Property
       
   628         \o Value
       
   629       \row
       
   630         \o state & QStyle::State_Enabled
       
   631         \o Corresponds to QGraphicsItem::isEnabled().
       
   632       \row
       
   633         \o state & QStyle::State_HasFocus
       
   634         \o Corresponds to QGraphicsItem::hasFocus().
       
   635       \row
       
   636         \o state & QStyle::State_MouseOver
       
   637         \o Corresponds to QGraphicsItem::isUnderMouse().
       
   638       \row
       
   639         \o direction
       
   640         \o Corresponds to QGraphicsWidget::layoutDirection().
       
   641       \row
       
   642         \o rect
       
   643         \o Corresponds to QGraphicsWidget::rect().toRect().
       
   644       \row
       
   645         \o palette
       
   646         \o Corresponds to QGraphicsWidget::palette().
       
   647       \row
       
   648         \o fontMetrics
       
   649         \o Corresponds to QFontMetrics(QGraphicsWidget::font()).
       
   650     \endtable
       
   651 
       
   652     Subclasses of QGraphicsWidget should call the base implementation, and
       
   653     then test the type of \a option using qstyleoption_cast<>() or test
       
   654     QStyleOption::Type before storing widget-specific options.
       
   655 
       
   656     For example:
       
   657 
       
   658     \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp 0
       
   659 
       
   660     \sa QStyleOption::initFrom()
       
   661 */
       
   662 void QGraphicsWidget::initStyleOption(QStyleOption *option) const
       
   663 {
       
   664     Q_ASSERT(option);
       
   665 
       
   666     option->state = QStyle::State_None;
       
   667     if (isEnabled())
       
   668         option->state |= QStyle::State_Enabled;
       
   669     if (hasFocus())
       
   670         option->state |= QStyle::State_HasFocus;
       
   671     // if (window->testAttribute(Qt::WA_KeyboardFocusChange)) // ### Window
       
   672     //     option->state |= QStyle::State_KeyboardFocusChange;
       
   673     if (isUnderMouse())
       
   674         option->state |= QStyle::State_MouseOver;
       
   675     if (QGraphicsWidget *w = window()) {
       
   676         if (w->isActiveWindow())
       
   677             option->state |= QStyle::State_Active;
       
   678     }
       
   679     if (isWindow())
       
   680         option->state |= QStyle::State_Window;
       
   681     /*
       
   682       ###
       
   683 #ifdef Q_WS_MAC
       
   684     extern bool qt_mac_can_clickThrough(const QGraphicsWidget *w); //qwidget_mac.cpp
       
   685     if (!(option->state & QStyle::State_Active) && !qt_mac_can_clickThrough(widget))
       
   686         option->state &= ~QStyle::State_Enabled;
       
   687 
       
   688     switch (QMacStyle::widgetSizePolicy(widget)) {
       
   689     case QMacStyle::SizeSmall:
       
   690         option->state |= QStyle::State_Small;
       
   691         break;
       
   692     case QMacStyle::SizeMini:
       
   693         option->state |= QStyle::State_Mini;
       
   694         break;
       
   695     default:
       
   696         ;
       
   697     }
       
   698 #endif
       
   699 #ifdef QT_KEYPAD_NAVIGATION
       
   700     if (widget->hasEditFocus())
       
   701         state |= QStyle::State_HasEditFocus;
       
   702 #endif
       
   703     */
       
   704     option->direction = layoutDirection();
       
   705     option->rect = rect().toRect(); // ### truncation!
       
   706     option->palette = palette();
       
   707     if (!isEnabled()) {
       
   708         option->palette.setCurrentColorGroup(QPalette::Disabled);
       
   709     } else if (isActiveWindow()) {
       
   710         option->palette.setCurrentColorGroup(QPalette::Active);
       
   711     } else {
       
   712         option->palette.setCurrentColorGroup(QPalette::Inactive);
       
   713     }
       
   714     option->fontMetrics = QFontMetrics(font());
       
   715 }
       
   716 
       
   717 /*!
       
   718     \reimp
       
   719 */
       
   720 QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
       
   721 {
       
   722     Q_D(const QGraphicsWidget);
       
   723     QSizeF sh;
       
   724     if (d->layout) {
       
   725         QSizeF marginSize(0,0);
       
   726         if (d->margins) {
       
   727             marginSize = QSizeF(d->margins[d->Left] + d->margins[d->Right],
       
   728                          d->margins[d->Top] + d->margins[d->Bottom]);
       
   729         }
       
   730         sh = d->layout->effectiveSizeHint(which, constraint - marginSize);
       
   731         sh += marginSize;
       
   732     } else {
       
   733         switch (which) {
       
   734             case Qt::MinimumSize:
       
   735                 sh = QSizeF(0, 0);
       
   736                 break;
       
   737             case Qt::PreferredSize:
       
   738                 sh = QSizeF(50, 50);    //rather arbitrary
       
   739                 break;
       
   740             case Qt::MaximumSize:
       
   741                 sh = QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
       
   742                 break;
       
   743             default:
       
   744                 qWarning("QGraphicsWidget::sizeHint(): Don't know how to handle the value of 'which'");
       
   745                 break;
       
   746         }
       
   747     }
       
   748     return sh;
       
   749 }
       
   750 
       
   751 /*!
       
   752     Returns this widget's layout, or 0 if no layout is currently managing this
       
   753     widget.
       
   754 
       
   755     \sa setLayout()
       
   756 */
       
   757 QGraphicsLayout *QGraphicsWidget::layout() const
       
   758 {
       
   759     Q_D(const QGraphicsWidget);
       
   760     return d->layout;
       
   761 }
       
   762 
       
   763 /*!
       
   764     \fn void QGraphicsWidget::setLayout(QGraphicsLayout *layout)
       
   765 
       
   766     Sets the layout for this widget to \a layout. Any existing layout manager
       
   767     is deleted before the new layout is assigned. If \a layout is 0, the
       
   768     widget is left without a layout. Existing subwidgets' geometries will
       
   769     remain unaffected.
       
   770 
       
   771     All widgets that are currently managed by \a layout or all of its
       
   772     sublayouts, are automatically reparented to this item. The layout is then
       
   773     invalidated, and the child widget geometries are adjusted according to
       
   774     this item's geometry() and contentsMargins(). Children who are not
       
   775     explicitly managed by \a layout remain unaffected by the layout after
       
   776     it has been assigned to this widget.
       
   777 
       
   778     QGraphicsWidget takes ownership of \a layout.
       
   779 
       
   780     \sa layout(), QGraphicsLinearLayout::addItem(), QGraphicsLayout::invalidate()
       
   781 */
       
   782 void QGraphicsWidget::setLayout(QGraphicsLayout *l)
       
   783 {
       
   784     Q_D(QGraphicsWidget);
       
   785     if (d->layout == l)
       
   786         return;
       
   787     d->setLayout_helper(l);
       
   788     if (!l)
       
   789         return;
       
   790 
       
   791     // Prevent assigning a layout that is already assigned to another widget.
       
   792     QGraphicsLayoutItem *oldParent = l->parentLayoutItem();
       
   793     if (oldParent && oldParent != this) {
       
   794         qWarning("QGraphicsWidget::setLayout: Attempting to set a layout on %s"
       
   795                  " \"%s\", when the layout already has a parent",
       
   796                  metaObject()->className(), qPrintable(objectName()));
       
   797         return;
       
   798     }
       
   799 
       
   800     // Install and activate the layout.
       
   801     l->setParentLayoutItem(this);
       
   802     l->d_func()->reparentChildItems(this);
       
   803     l->invalidate();
       
   804 }
       
   805 
       
   806 /*!
       
   807     Adjusts the size of the widget to its effective preferred size hint.
       
   808 
       
   809     This function is called implicitly when the item is shown for the first
       
   810     time.
       
   811 
       
   812     \sa effectiveSizeHint(), Qt::MinimumSize
       
   813 */
       
   814 void QGraphicsWidget::adjustSize()
       
   815 {
       
   816     QSizeF sz = effectiveSizeHint(Qt::PreferredSize);
       
   817     // What if sz is not valid?!
       
   818     if (sz.isValid())
       
   819         resize(sz);
       
   820 }
       
   821 
       
   822 /*!
       
   823     \property QGraphicsWidget::layoutDirection
       
   824     \brief the layout direction for this widget.
       
   825 
       
   826     This property modifies this widget's and all of its descendants'
       
   827     Qt::WA_RightToLeft attribute. It also sets this widget's
       
   828     Qt::WA_SetLayoutDirection attribute.
       
   829 
       
   830     The widget's layout direction determines the order in which the layout
       
   831     manager horizontally arranges subwidgets of this widget. The default
       
   832     value depends on the language and locale of the application, and is
       
   833     typically in the same direction as words are read and written. With
       
   834     Qt::LeftToRight, the layout starts placing subwidgets from the left
       
   835     side of this widget towards the right. Qt::RightToLeft does the opposite -
       
   836     the layout will place widgets starting from the right edge moving towards
       
   837     the left.
       
   838 
       
   839     Subwidgets inherit their layout direction from the parent. Top-level
       
   840     widget items inherit their layout direction from
       
   841     QGraphicsScene::layoutDirection. If you change a widget's layout direction
       
   842     by calling setLayoutDirection(), the widget will send itself a
       
   843     \l{QEvent::LayoutDirectionChange}{LayoutDirectionChange} event, and then
       
   844     propagate the new layout direction to all its descendants.
       
   845 
       
   846     \sa QWidget::layoutDirection, QApplication::layoutDirection
       
   847 */
       
   848 Qt::LayoutDirection QGraphicsWidget::layoutDirection() const
       
   849 {
       
   850     return testAttribute(Qt::WA_RightToLeft) ? Qt::RightToLeft : Qt::LeftToRight;
       
   851 }
       
   852 void QGraphicsWidget::setLayoutDirection(Qt::LayoutDirection direction)
       
   853 {
       
   854     Q_D(QGraphicsWidget);
       
   855     setAttribute(Qt::WA_SetLayoutDirection, true);
       
   856     d->setLayoutDirection_helper(direction);
       
   857 }
       
   858 void QGraphicsWidget::unsetLayoutDirection()
       
   859 {
       
   860     Q_D(QGraphicsWidget);
       
   861     setAttribute(Qt::WA_SetLayoutDirection, false);
       
   862     d->resolveLayoutDirection();
       
   863 }
       
   864 
       
   865 /*!
       
   866     Returns a pointer to the widget's style. If this widget does not have any
       
   867     explicitly assigned style, the scene's style is returned instead. In turn,
       
   868     if the scene does not have any assigned style, this function returns
       
   869     QApplication::style().
       
   870 
       
   871     \sa setStyle()
       
   872 */
       
   873 QStyle *QGraphicsWidget::style() const
       
   874 {
       
   875     if (QStyle *style = widgetStyles()->styleForWidget(this))
       
   876         return style;
       
   877     // ### This is not thread-safe. QApplication::style() is not thread-safe.
       
   878     return scene() ? scene()->style() : QApplication::style();
       
   879 }
       
   880 
       
   881 /*!
       
   882     Sets the widget's style to \a style. QGraphicsWidget does \e not take
       
   883     ownership of \a style.
       
   884 
       
   885     If no style is assigned, or \a style is 0, the widget will use
       
   886     QGraphicsScene::style() (if this has been set). Otherwise the widget will
       
   887     use QApplication::style().
       
   888 
       
   889     This function sets the Qt::WA_SetStyle attribute if \a style is not 0;
       
   890     otherwise it clears the attribute.
       
   891 
       
   892     \sa style()
       
   893 */
       
   894 void QGraphicsWidget::setStyle(QStyle *style)
       
   895 {
       
   896     setAttribute(Qt::WA_SetStyle, style != 0);
       
   897     widgetStyles()->setStyleForWidget(this, style);
       
   898 
       
   899     // Deliver StyleChange to the widget itself (doesn't propagate).
       
   900     QEvent event(QEvent::StyleChange);
       
   901     QApplication::sendEvent(this, &event);
       
   902 }
       
   903 
       
   904 /*!
       
   905     \property QGraphicsWidget::font
       
   906     \brief the widgets' font
       
   907 
       
   908     This property provides the widget's font.
       
   909 
       
   910     QFont consists of font properties that have been explicitly defined and
       
   911     properties implicitly inherited from the widget's parent. Hence, font()
       
   912     can return a different font compared to the one set with setFont().
       
   913     This scheme allows you to define single entries in a font without
       
   914     affecting the font's inherited entries.
       
   915 
       
   916     When a widget's font changes, it resolves its entries against its
       
   917     parent widget. If the widget does not have a parent widget, it resolves
       
   918     its entries against the scene. The widget then sends itself a
       
   919     \l{QEvent::FontChange}{FontChange} event and notifies all its
       
   920     descendants so that they can resolve their fonts as well.
       
   921 
       
   922     By default, this property contains the application's default font.
       
   923 
       
   924     \sa QApplication::font(), QGraphicsScene::font, QFont::resolve()
       
   925 */
       
   926 QFont QGraphicsWidget::font() const
       
   927 {
       
   928     Q_D(const QGraphicsWidget);
       
   929     return d->font;
       
   930 }
       
   931 void QGraphicsWidget::setFont(const QFont &font)
       
   932 {
       
   933     Q_D(QGraphicsWidget);
       
   934     setAttribute(Qt::WA_SetFont, font.resolve() != 0);
       
   935 
       
   936     QFont naturalFont = d->naturalWidgetFont();
       
   937     QFont resolvedFont = font.resolve(naturalFont);
       
   938     d->setFont_helper(resolvedFont);
       
   939 }
       
   940 
       
   941 /*!
       
   942     \property QGraphicsWidget::palette
       
   943     \brief the widget's palette
       
   944 
       
   945     This property provides the widget's palette. The palette provides colors
       
   946     and brushes for color groups (e.g., QPalette::Button) and states (e.g.,
       
   947     QPalette::Inactive), loosely defining the general look of the widget and
       
   948     its children.
       
   949 
       
   950     QPalette consists of color groups that have been explicitly defined, and
       
   951     groups that are implicitly inherited from the widget's parent. Because of
       
   952     this, palette() can return a different palette than what has been set with
       
   953     setPalette(). This scheme allows you to define single entries in a palette
       
   954     without affecting the palette's inherited entries.
       
   955 
       
   956     When a widget's palette changes, it resolves its entries against its
       
   957     parent widget, or if it doesn't have a parent widget, it resolves against
       
   958     the scene. It then sends itself a \l{QEvent::PaletteChange}{PaletteChange}
       
   959     event, and notifies all its descendants so they can resolve their palettes
       
   960     as well.
       
   961 
       
   962     By default, this property contains the application's default palette.
       
   963 
       
   964     \sa QApplication::palette(), QGraphicsScene::palette, QPalette::resolve()
       
   965 */
       
   966 QPalette QGraphicsWidget::palette() const
       
   967 {
       
   968     Q_D(const QGraphicsWidget);
       
   969     return d->palette;
       
   970 }
       
   971 void QGraphicsWidget::setPalette(const QPalette &palette)
       
   972 {
       
   973     Q_D(QGraphicsWidget);
       
   974     setAttribute(Qt::WA_SetPalette, palette.resolve() != 0);
       
   975 
       
   976     QPalette naturalPalette = d->naturalWidgetPalette();
       
   977     QPalette resolvedPalette = palette.resolve(naturalPalette);
       
   978     d->setPalette_helper(resolvedPalette);
       
   979 }
       
   980 
       
   981 /*!
       
   982     If this widget is currently managed by a layout, this function notifies
       
   983     the layout that the widget's size hints have changed and the layout
       
   984     may need to resize and reposition the widget accordingly.
       
   985 
       
   986     Call this function if the widget's sizeHint() has changed.
       
   987 
       
   988     \sa QGraphicsLayout::invalidate()
       
   989 */
       
   990 void QGraphicsWidget::updateGeometry()
       
   991 {
       
   992     QGraphicsLayoutItem::updateGeometry();
       
   993     QGraphicsLayoutItem *parentItem = parentLayoutItem();
       
   994 
       
   995     if (parentItem && parentItem->isLayout()) {
       
   996         parentItem->updateGeometry();
       
   997     } else {
       
   998         if (parentItem) {
       
   999             QGraphicsWidget *parentWid = parentWidget();    //###
       
  1000             if (parentWid->isVisible())
       
  1001                 QApplication::postEvent(parentWid, new QEvent(QEvent::LayoutRequest));
       
  1002         }
       
  1003         bool wasResized = testAttribute(Qt::WA_Resized);
       
  1004         resize(size()); // this will restrict the size
       
  1005         setAttribute(Qt::WA_Resized, wasResized);
       
  1006     }
       
  1007 }
       
  1008 
       
  1009 /*!
       
  1010     \reimp
       
  1011 
       
  1012     QGraphicsWidget uses the base implementation of this function to catch and
       
  1013     deliver events related to state changes in the item. Because of this, it is
       
  1014     very important that subclasses call the base implementation.
       
  1015 
       
  1016     \a change specifies the type of change, and \a value is the new value.
       
  1017 
       
  1018     For example, QGraphicsWidget uses ItemVisibleChange to deliver
       
  1019     \l{QEvent::Show} {Show} and \l{QEvent::Hide}{Hide} events,
       
  1020     ItemPositionHasChanged to deliver \l{QEvent::Move}{Move} events,
       
  1021     and ItemParentChange both to deliver \l{QEvent::ParentChange}
       
  1022     {ParentChange} events, and for managing the focus chain.
       
  1023 
       
  1024     QGraphicsWidget enables the ItemSendsGeometryChanges flag by default in
       
  1025     order to track position changes.
       
  1026 
       
  1027     \sa QGraphicsItem::itemChange()
       
  1028 */
       
  1029 QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &value)
       
  1030 {
       
  1031     Q_D(QGraphicsWidget);
       
  1032     switch (change) {
       
  1033     case ItemEnabledHasChanged: {
       
  1034         // Send EnabledChange after the enabled state has changed.
       
  1035         QEvent event(QEvent::EnabledChange);
       
  1036         QApplication::sendEvent(this, &event);
       
  1037         break;
       
  1038     }
       
  1039     case ItemVisibleChange:
       
  1040         if (value.toBool()) {
       
  1041             // Send Show event before the item has been shown.
       
  1042             QShowEvent event;
       
  1043             QApplication::sendEvent(this, &event);
       
  1044             bool resized = testAttribute(Qt::WA_Resized);
       
  1045             if (!resized) {
       
  1046                 adjustSize();
       
  1047                 setAttribute(Qt::WA_Resized, false);
       
  1048             }
       
  1049         }
       
  1050         break;
       
  1051     case ItemVisibleHasChanged:
       
  1052         if (!value.toBool()) {
       
  1053             // Send Hide event after the item has been hidden.
       
  1054             QHideEvent event;
       
  1055             QApplication::sendEvent(this, &event);
       
  1056         }
       
  1057         break;
       
  1058     case ItemPositionHasChanged:
       
  1059         if (!d->inSetGeometry) {
       
  1060             d->inSetPos = 1;
       
  1061             // Ensure setGeometry is called (avoid recursion when setPos is
       
  1062             // called from within setGeometry).
       
  1063             setGeometry(QRectF(pos(), size()));
       
  1064             d->inSetPos = 0 ;
       
  1065         }
       
  1066         break;
       
  1067     case ItemParentChange: {
       
  1068         QGraphicsItem *parent = qVariantValue<QGraphicsItem *>(value);
       
  1069         d->fixFocusChainBeforeReparenting((parent && parent->isWidget()) ? static_cast<QGraphicsWidget *>(parent) : 0, scene());
       
  1070 
       
  1071         // Deliver ParentAboutToChange.
       
  1072         QEvent event(QEvent::ParentAboutToChange);
       
  1073         QApplication::sendEvent(this, &event);
       
  1074         break;
       
  1075     }
       
  1076     case ItemParentHasChanged: {
       
  1077         // Deliver ParentChange.
       
  1078         QEvent event(QEvent::ParentChange);
       
  1079         QApplication::sendEvent(this, &event);
       
  1080         break;
       
  1081     }
       
  1082     case ItemCursorChange: {
       
  1083         // Deliver CursorChange.
       
  1084         QEvent event(QEvent::CursorChange);
       
  1085         QApplication::sendEvent(this, &event);
       
  1086         break;
       
  1087     }
       
  1088     case ItemToolTipChange: {
       
  1089         // Deliver ToolTipChange.
       
  1090         QEvent event(QEvent::ToolTipChange);
       
  1091         QApplication::sendEvent(this, &event);
       
  1092         break;
       
  1093     }
       
  1094     default:
       
  1095         break;
       
  1096     }
       
  1097     return QGraphicsItem::itemChange(change, value);
       
  1098 }
       
  1099 
       
  1100 /*!
       
  1101     \internal
       
  1102 
       
  1103     This virtual function is used to notify changes to any property (both
       
  1104     dynamic properties, and registered with Q_PROPERTY) in the
       
  1105     widget. Depending on the property itself, the notification can be
       
  1106     delivered before or after the value has changed.
       
  1107 
       
  1108     \a propertyName is the name of the property (e.g., "size" or "font"), and
       
  1109     \a value is the (proposed) new value of the property. The function returns
       
  1110     the new value, which may be different from \a value if the notification
       
  1111     supports adjusting the property value. The base implementation simply
       
  1112     returns \a value for any \a propertyName.
       
  1113 
       
  1114     QGraphicsWidget delivers notifications for the following properties:
       
  1115 
       
  1116     \table     \o propertyName        \o Property
       
  1117     \row       \o layoutDirection     \o QGraphicsWidget::layoutDirection
       
  1118     \row       \o size                \o QGraphicsWidget::size
       
  1119     \row       \o font                \o QGraphicsWidget::font
       
  1120     \row       \o palette             \o QGraphicsWidget::palette
       
  1121     \endtable
       
  1122 
       
  1123     \sa itemChange()
       
  1124 */
       
  1125 QVariant QGraphicsWidget::propertyChange(const QString &propertyName, const QVariant &value)
       
  1126 {
       
  1127     Q_UNUSED(propertyName);
       
  1128     return value;
       
  1129 }
       
  1130 
       
  1131 /*!
       
  1132     QGraphicsWidget's implementation of sceneEvent() simply passes \a event to
       
  1133     QGraphicsWidget::event(). You can handle all events for your widget in
       
  1134     event() or in any of the convenience functions; you should not have to
       
  1135     reimplement this function in a subclass of QGraphicsWidget.
       
  1136 
       
  1137     \sa QGraphicsItem::sceneEvent()
       
  1138 */
       
  1139 bool QGraphicsWidget::sceneEvent(QEvent *event)
       
  1140 {
       
  1141     return QGraphicsItem::sceneEvent(event);
       
  1142 }
       
  1143 
       
  1144 /*!
       
  1145     This event handler, for \a event, receives events for the window frame if
       
  1146     this widget is a window. Its base implementation provides support for
       
  1147     default window frame interaction such as moving, resizing, etc.
       
  1148 
       
  1149     You can reimplement this handler in a subclass of QGraphicsWidget to
       
  1150     provide your own custom window frame interaction support.
       
  1151 
       
  1152     Returns true if \a event has been recognized and processed; otherwise,
       
  1153     returns false.
       
  1154 
       
  1155     \sa event()
       
  1156 */
       
  1157 bool QGraphicsWidget::windowFrameEvent(QEvent *event)
       
  1158 {
       
  1159     Q_D(QGraphicsWidget);
       
  1160     switch (event->type()) {
       
  1161     case QEvent::GraphicsSceneMousePress:
       
  1162         d->windowFrameMousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
       
  1163         break;
       
  1164     case QEvent::GraphicsSceneMouseMove:
       
  1165         d->ensureWindowData();
       
  1166         if (d->windowData->grabbedSection != Qt::NoSection) {
       
  1167             d->windowFrameMouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
       
  1168             event->accept();
       
  1169         }
       
  1170         break;
       
  1171     case QEvent::GraphicsSceneMouseRelease:
       
  1172         d->windowFrameMouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
       
  1173         break;
       
  1174     case QEvent::GraphicsSceneHoverMove:
       
  1175         d->windowFrameHoverMoveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
       
  1176         break;
       
  1177     case QEvent::GraphicsSceneHoverLeave:
       
  1178         d->windowFrameHoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
       
  1179         break;
       
  1180     default:
       
  1181         break;
       
  1182     }
       
  1183     return event->isAccepted();
       
  1184 }
       
  1185 
       
  1186 /*!
       
  1187     \since 4.4
       
  1188 
       
  1189     Returns the window frame section at position \a pos, or
       
  1190     Qt::NoSection if there is no window frame section at this
       
  1191     position.
       
  1192 
       
  1193     This function is used in QGraphicsWidget's base implementation for window
       
  1194     frame interaction.
       
  1195 
       
  1196     You can reimplement this function if you want to customize how a window
       
  1197     can be interactively moved or resized.  For instance, if you only want to
       
  1198     allow a window to be resized by the bottom right corner, you can
       
  1199     reimplement this function to return Qt::NoSection for all sections except
       
  1200     Qt::BottomRightSection.
       
  1201 
       
  1202     \sa windowFrameEvent(), paintWindowFrame(), windowFrameGeometry()
       
  1203 */
       
  1204 Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(const QPointF &pos) const
       
  1205 {
       
  1206     Q_D(const QGraphicsWidget);
       
  1207 
       
  1208     const QRectF r = windowFrameRect();
       
  1209     if (!r.contains(pos))
       
  1210         return Qt::NoSection;
       
  1211 
       
  1212     const qreal left = r.left();
       
  1213     const qreal top = r.top();
       
  1214     const qreal right = r.right();
       
  1215     const qreal bottom = r.bottom();
       
  1216     const qreal x = pos.x();
       
  1217     const qreal y = pos.y();
       
  1218 
       
  1219     const qreal cornerMargin = 20;
       
  1220     //### Not sure of this one, it should be the same value for all edges.
       
  1221     const qreal windowFrameWidth = d->windowFrameMargins
       
  1222         ? d->windowFrameMargins[d->Left] : 0;
       
  1223 
       
  1224     Qt::WindowFrameSection s = Qt::NoSection;
       
  1225     if (x <= left + cornerMargin) {
       
  1226         if (y <= top + windowFrameWidth || (x <= left + windowFrameWidth && y <= top + cornerMargin)) {
       
  1227             s = Qt::TopLeftSection;
       
  1228         } else if (y >= bottom - windowFrameWidth || (x <= left + windowFrameWidth && y >= bottom - windowFrameWidth)) {
       
  1229             s = Qt::BottomLeftSection;
       
  1230         } else if (x <= left + windowFrameWidth) {
       
  1231             s = Qt::LeftSection;
       
  1232         }
       
  1233     } else if (x >= right - cornerMargin) {
       
  1234         if (y <= top + windowFrameWidth || (x >= right - windowFrameWidth && y <= top + cornerMargin)) {
       
  1235             s = Qt::TopRightSection;
       
  1236         } else if (y >= bottom - windowFrameWidth || (x >= right - windowFrameWidth && y >= bottom - windowFrameWidth)) {
       
  1237             s = Qt::BottomRightSection;
       
  1238         } else if (x >= right - windowFrameWidth) {
       
  1239             s = Qt::RightSection;
       
  1240         }
       
  1241     } else if (y <= top + windowFrameWidth) {
       
  1242         s = Qt::TopSection;
       
  1243     } else if (y >= bottom - windowFrameWidth) {
       
  1244         s = Qt::BottomSection;
       
  1245     }
       
  1246     if (s == Qt::NoSection) {
       
  1247         QRectF r1 = r;
       
  1248         r1.setHeight(d->windowFrameMargins
       
  1249                      ? d->windowFrameMargins[d->Top] : 0);
       
  1250         if (r1.contains(pos))
       
  1251             s = Qt::TitleBarArea;
       
  1252     }
       
  1253     return s;
       
  1254 }
       
  1255 
       
  1256 /*!
       
  1257     \reimp
       
  1258 
       
  1259     Handles the \a event.  QGraphicsWidget handles the following
       
  1260     events:
       
  1261 
       
  1262     \table   \o Event                 \o Usage
       
  1263     \row     \o Polish
       
  1264                     \o Delivered to the widget some time after it has been
       
  1265                         shown.
       
  1266     \row     \o GraphicsSceneMove
       
  1267                     \o Delivered to the widget after its local position has
       
  1268                         changed.
       
  1269     \row     \o GraphicsSceneResize
       
  1270                     \o Delivered to the widget after its size has changed.
       
  1271     \row     \o Show
       
  1272                     \o Delivered to the widget before it has been shown.
       
  1273     \row     \o Hide
       
  1274                     \o Delivered to the widget after it has been hidden.
       
  1275     \row     \o PaletteChange
       
  1276                     \o Delivered to the widget after its palette has changed.
       
  1277     \row     \o FontChange
       
  1278                     \o Delivered to the widget after its font has changed.
       
  1279     \row     \o EnabledChange
       
  1280                     \o Delivered to the widget after its enabled state has
       
  1281                         changed.
       
  1282     \row     \o StyleChange
       
  1283                     \o Delivered to the widget after its style has changed.
       
  1284     \row     \o LayoutDirectionChange
       
  1285                     \o Delivered to the widget after its layout direction has
       
  1286                         changed.
       
  1287     \row     \o ContentsRectChange
       
  1288                     \o Delivered to the widget after its contents margins/
       
  1289                         contents rect has changed.
       
  1290     \endtable
       
  1291 */
       
  1292 bool QGraphicsWidget::event(QEvent *event)
       
  1293 {
       
  1294     Q_D(QGraphicsWidget);
       
  1295     // Forward the event to the layout first.
       
  1296     if (d->layout)
       
  1297         d->layout->widgetEvent(event);
       
  1298 
       
  1299     // Handle the event itself.
       
  1300     switch (event->type()) {
       
  1301     case QEvent::GraphicsSceneMove:
       
  1302         moveEvent(static_cast<QGraphicsSceneMoveEvent *>(event));
       
  1303         break;
       
  1304     case QEvent::GraphicsSceneResize:
       
  1305         resizeEvent(static_cast<QGraphicsSceneResizeEvent *>(event));
       
  1306         break;
       
  1307     case QEvent::Show:
       
  1308         showEvent(static_cast<QShowEvent *>(event));
       
  1309         break;
       
  1310     case QEvent::Hide:
       
  1311         hideEvent(static_cast<QHideEvent *>(event));
       
  1312         break;
       
  1313     case QEvent::Polish:
       
  1314         polishEvent();
       
  1315         d->polished = true;
       
  1316         if (!d->font.isCopyOf(QApplication::font()))
       
  1317             d->updateFont(d->font);
       
  1318         break;
       
  1319     case QEvent::WindowActivate:
       
  1320     case QEvent::WindowDeactivate:
       
  1321         update();
       
  1322         break;
       
  1323         // Taken from QWidget::event
       
  1324     case QEvent::ActivationChange:
       
  1325     case QEvent::EnabledChange:
       
  1326     case QEvent::FontChange:
       
  1327     case QEvent::StyleChange:
       
  1328     case QEvent::PaletteChange:
       
  1329     case QEvent::ParentChange:
       
  1330     case QEvent::ContentsRectChange:
       
  1331     case QEvent::LayoutDirectionChange:
       
  1332         changeEvent(event);
       
  1333         break;
       
  1334     case QEvent::Close:
       
  1335         closeEvent((QCloseEvent *)event);
       
  1336         break;
       
  1337     case QEvent::GrabMouse:
       
  1338         grabMouseEvent(event);
       
  1339         break;
       
  1340     case QEvent::UngrabMouse:
       
  1341         ungrabMouseEvent(event);
       
  1342         break;
       
  1343     case QEvent::GrabKeyboard:
       
  1344         grabKeyboardEvent(event);
       
  1345         break;
       
  1346     case QEvent::UngrabKeyboard:
       
  1347         ungrabKeyboardEvent(event);
       
  1348         break;
       
  1349     case QEvent::GraphicsSceneMousePress:
       
  1350         if (d->hasDecoration() && windowFrameEvent(event))
       
  1351             return true;
       
  1352     case QEvent::GraphicsSceneMouseMove:
       
  1353     case QEvent::GraphicsSceneMouseRelease:
       
  1354     case QEvent::GraphicsSceneMouseDoubleClick:
       
  1355         d->ensureWindowData();
       
  1356         if (d->hasDecoration() && d->windowData->grabbedSection != Qt::NoSection)
       
  1357             return windowFrameEvent(event);
       
  1358         break;
       
  1359     case QEvent::GraphicsSceneHoverEnter:
       
  1360     case QEvent::GraphicsSceneHoverMove:
       
  1361     case QEvent::GraphicsSceneHoverLeave:
       
  1362         if (d->hasDecoration()) {
       
  1363             windowFrameEvent(event);
       
  1364             // Filter out hover events if they were sent to us only because of the
       
  1365             // decoration (special case in QGraphicsScenePrivate::dispatchHoverEvent).
       
  1366             if (!acceptsHoverEvents())
       
  1367                 return true;
       
  1368         }
       
  1369         break;
       
  1370     default:
       
  1371         break;
       
  1372     }
       
  1373     return QObject::event(event);
       
  1374 }
       
  1375 
       
  1376 /*!
       
  1377    This event handler can be reimplemented to handle state changes.
       
  1378 
       
  1379    The state being changed in this event can be retrieved through \a event.
       
  1380 
       
  1381    Change events include: QEvent::ActivationChange, QEvent::EnabledChange,
       
  1382    QEvent::FontChange, QEvent::StyleChange, QEvent::PaletteChange,
       
  1383    QEvent::ParentChange, QEvent::LayoutDirectionChange, and
       
  1384    QEvent::ContentsRectChange.
       
  1385 */
       
  1386 void QGraphicsWidget::changeEvent(QEvent *event)
       
  1387 {
       
  1388     Q_D(QGraphicsWidget);
       
  1389     switch (event->type()) {
       
  1390     case QEvent::StyleChange:
       
  1391         // ### Don't unset if the margins are explicitly set.
       
  1392         unsetWindowFrameMargins();
       
  1393         if (d->layout)
       
  1394             d->layout->invalidate();
       
  1395     case QEvent::FontChange:
       
  1396         update();
       
  1397         updateGeometry();
       
  1398         break;
       
  1399     case QEvent::PaletteChange:
       
  1400         update();
       
  1401         break;
       
  1402     case QEvent::ParentChange:
       
  1403         d->resolveFont(d->inheritedFontResolveMask);
       
  1404         d->resolvePalette(d->inheritedPaletteResolveMask);
       
  1405         break;
       
  1406     default:
       
  1407         break;
       
  1408     }
       
  1409 }
       
  1410 
       
  1411 /*!
       
  1412     This event handler, for \a event, can be reimplemented in a subclass to
       
  1413     receive widget close events.  The default implementation accepts the
       
  1414     event.
       
  1415 
       
  1416     \sa close(), QCloseEvent
       
  1417 */
       
  1418 void QGraphicsWidget::closeEvent(QCloseEvent *event)
       
  1419 {
       
  1420     event->accept();
       
  1421 }
       
  1422 
       
  1423 /*!
       
  1424     \reimp
       
  1425 */
       
  1426 void QGraphicsWidget::focusInEvent(QFocusEvent *event)
       
  1427 {
       
  1428     Q_UNUSED(event);
       
  1429     if (focusPolicy() != Qt::NoFocus)
       
  1430         update();
       
  1431 }
       
  1432 
       
  1433 /*!
       
  1434     Finds a new widget to give the keyboard focus to, as appropriate for Tab
       
  1435     and Shift+Tab, and returns true if it can find a new widget; returns false
       
  1436     otherwise. If \a next is true, this function searches forward; if \a next
       
  1437     is false, it searches backward.
       
  1438 
       
  1439     Sometimes, you will want to reimplement this function to provide special
       
  1440     focus handling for your widget and its subwidgets. For example, a web
       
  1441     browser might reimplement it to move its current active link forward or
       
  1442     backward, and call the base implementation only when it reaches the last
       
  1443     or first link on the page.
       
  1444 
       
  1445     Child widgets call focusNextPrevChild() on their parent widgets, but only
       
  1446     the window that contains the child widgets decides where to redirect
       
  1447     focus. By reimplementing this function for an object, you gain control of
       
  1448     focus traversal for all child widgets.
       
  1449 
       
  1450     \sa focusPolicy()
       
  1451 */
       
  1452 bool QGraphicsWidget::focusNextPrevChild(bool next)
       
  1453 {
       
  1454     Q_D(QGraphicsWidget);
       
  1455     // Let the parent's focusNextPrevChild implementation decide what to do.
       
  1456     QGraphicsWidget *parent = 0;
       
  1457     if (!isWindow() && (parent = parentWidget()))
       
  1458         return parent->focusNextPrevChild(next);
       
  1459     if (!d->scene)
       
  1460         return false;
       
  1461     if (d->scene->focusNextPrevChild(next))
       
  1462         return true;
       
  1463     if (isWindow()) {
       
  1464         setFocus(next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
       
  1465         if (hasFocus())
       
  1466             return true;
       
  1467     }
       
  1468     return false;
       
  1469 }
       
  1470 
       
  1471 /*!
       
  1472     \reimp
       
  1473 */
       
  1474 void QGraphicsWidget::focusOutEvent(QFocusEvent *event)
       
  1475 {
       
  1476     Q_UNUSED(event);
       
  1477     if (focusPolicy() != Qt::NoFocus)
       
  1478         update();
       
  1479 }
       
  1480 
       
  1481 /*!
       
  1482     This event handler, for \l{QEvent::Hide}{Hide} events, is delivered after
       
  1483     the widget has been hidden, for example, setVisible(false) has been called
       
  1484     for the widget or one of its ancestors when the widget was previously
       
  1485     shown.
       
  1486 
       
  1487     You can reimplement this event handler to detect when your widget is
       
  1488     hidden. Calling QEvent::accept() or QEvent::ignore() on \a event has no
       
  1489     effect.
       
  1490 
       
  1491     \sa showEvent(), QWidget::hideEvent(), ItemVisibleChange
       
  1492 */
       
  1493 void QGraphicsWidget::hideEvent(QHideEvent *event)
       
  1494 {
       
  1495     ///### focusNextPrevChild(true), don't lose focus when the focus widget
       
  1496     // is hidden.
       
  1497     Q_UNUSED(event);
       
  1498 }
       
  1499 
       
  1500 /*!
       
  1501     This event handler, for \l{QEvent::GraphicsSceneMove}{GraphicsSceneMove}
       
  1502     events, is delivered after the widget has moved (e.g., its local position
       
  1503     has changed).
       
  1504 
       
  1505     This event is only delivered when the item is moved locally. Calling
       
  1506     setTransform() or moving any of the item's ancestors does not affect the
       
  1507     item's local position.
       
  1508 
       
  1509     You can reimplement this event handler to detect when your widget has
       
  1510     moved. Calling QEvent::accept() or QEvent::ignore() on \a event has no
       
  1511     effect.
       
  1512 
       
  1513     \sa ItemPositionChange, ItemPositionHasChanged
       
  1514 */
       
  1515 void QGraphicsWidget::moveEvent(QGraphicsSceneMoveEvent *event)
       
  1516 {
       
  1517     // ### Last position is always == current position
       
  1518     Q_UNUSED(event);
       
  1519 }
       
  1520 
       
  1521 /*!
       
  1522     This event is delivered to the item by the scene at some point after it
       
  1523     has been constructed, but before it is shown or otherwise accessed through
       
  1524     the scene. You can use this event handler to do last-minute initializations
       
  1525     of the widget which require the item to be fully constructed.
       
  1526 
       
  1527     The base implementation does nothing.
       
  1528 */
       
  1529 void QGraphicsWidget::polishEvent()
       
  1530 {
       
  1531 }
       
  1532 
       
  1533 /*!
       
  1534     This event handler, for
       
  1535     \l{QEvent::GraphicsSceneResize}{GraphicsSceneResize} events, is
       
  1536     delivered after the widget has been resized (i.e., its local size has
       
  1537     changed). \a event contains both the old and the new size.
       
  1538 
       
  1539     This event is only delivered when the widget is resized locally; calling
       
  1540     setTransform() on the widget or any of its ancestors or view, does not
       
  1541     affect the widget's local size.
       
  1542 
       
  1543     You can reimplement this event handler to detect when your widget has been
       
  1544     resized. Calling QEvent::accept() or QEvent::ignore() on \a event has no
       
  1545     effect.
       
  1546 
       
  1547     \sa geometry(), setGeometry()
       
  1548 */
       
  1549 void QGraphicsWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
       
  1550 {
       
  1551     Q_UNUSED(event);
       
  1552 }
       
  1553 
       
  1554 /*!
       
  1555     This event handler, for \l{QEvent::Show}{Show} events, is delivered before
       
  1556     the widget has been shown, for example, setVisible(true) has been called
       
  1557     for the widget or one of its ancestors when the widget was previously
       
  1558     hidden.
       
  1559 
       
  1560     You can reimplement this event handler to detect when your widget is
       
  1561     shown. Calling QEvent::accept() or QEvent::ignore() on \a event has no
       
  1562     effect.
       
  1563 
       
  1564     \sa hideEvent(), QWidget::showEvent(), ItemVisibleChange
       
  1565 */
       
  1566 void QGraphicsWidget::showEvent(QShowEvent *event)
       
  1567 {
       
  1568     Q_UNUSED(event);
       
  1569 }
       
  1570 
       
  1571 /*!
       
  1572     \reimp
       
  1573 */
       
  1574 void QGraphicsWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
       
  1575 {
       
  1576     Q_UNUSED(event);
       
  1577 }
       
  1578 
       
  1579 /*!
       
  1580     \reimp
       
  1581 */
       
  1582 void QGraphicsWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
       
  1583 {
       
  1584     Q_UNUSED(event);
       
  1585 }
       
  1586 
       
  1587 /*!
       
  1588     This event handler, for \a event, can be reimplemented in a subclass to
       
  1589     receive notifications for Qt::GrabMouse events.
       
  1590 
       
  1591     \sa grabMouse(), grabKeyboard()
       
  1592 */
       
  1593 void QGraphicsWidget::grabMouseEvent(QEvent *event)
       
  1594 {
       
  1595     Q_UNUSED(event);
       
  1596 }
       
  1597 
       
  1598 /*!
       
  1599     This event handler, for \a event, can be reimplemented in a subclass to
       
  1600     receive notifications for Qt::UngrabMouse events.
       
  1601 
       
  1602     \sa ungrabMouse(), ungrabKeyboard()
       
  1603 */
       
  1604 void QGraphicsWidget::ungrabMouseEvent(QEvent *event)
       
  1605 {
       
  1606     Q_UNUSED(event);
       
  1607 }
       
  1608 
       
  1609 /*!
       
  1610     This event handler, for \a event, can be reimplemented in a subclass to
       
  1611     receive notifications for Qt::GrabKeyboard events.
       
  1612 
       
  1613     \sa grabKeyboard(), grabMouse()
       
  1614 */
       
  1615 void QGraphicsWidget::grabKeyboardEvent(QEvent *event)
       
  1616 {
       
  1617     Q_UNUSED(event);
       
  1618 }
       
  1619 
       
  1620 /*!
       
  1621     This event handler, for \a event, can be reimplemented in a subclass to
       
  1622     receive notifications for Qt::UngrabKeyboard events.
       
  1623 
       
  1624     \sa ungrabKeyboard(), ungrabMouse()
       
  1625 */
       
  1626 void QGraphicsWidget::ungrabKeyboardEvent(QEvent *event)
       
  1627 {
       
  1628     Q_UNUSED(event);
       
  1629 }
       
  1630 
       
  1631 /*!
       
  1632     Returns the widgets window type.
       
  1633 
       
  1634     \sa windowFlags(), isWindow(), isPanel()
       
  1635 */
       
  1636 Qt::WindowType QGraphicsWidget::windowType() const
       
  1637 {
       
  1638     return Qt::WindowType(int(windowFlags()) & Qt::WindowType_Mask);
       
  1639 }
       
  1640 
       
  1641 /*!
       
  1642     \property QGraphicsWidget::windowFlags
       
  1643     \brief the widget's window flags
       
  1644 
       
  1645     Window flags are a combination of a window type (e.g., Qt::Dialog) and
       
  1646     several flags giving hints on the behavior of the window. The behavior
       
  1647     is platform-dependent.
       
  1648 
       
  1649     By default, this property contains no window flags.
       
  1650 
       
  1651     Windows are panels. If you set the Qt::Window flag, the ItemIsPanel flag
       
  1652     will be set automatically. If you clear the Qt::Window flag, the
       
  1653     ItemIsPanel flag is also cleared. Note that the ItemIsPanel flag can be
       
  1654     set independently of Qt::Window.
       
  1655 
       
  1656     \sa isWindow(), isPanel()
       
  1657 */
       
  1658 Qt::WindowFlags QGraphicsWidget::windowFlags() const
       
  1659 {
       
  1660     Q_D(const QGraphicsWidget);
       
  1661     return d->windowFlags;
       
  1662 }
       
  1663 void QGraphicsWidget::setWindowFlags(Qt::WindowFlags wFlags)
       
  1664 {
       
  1665     Q_D(QGraphicsWidget);
       
  1666     if (d->windowFlags == wFlags)
       
  1667         return;
       
  1668     bool wasPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
       
  1669 
       
  1670     d->adjustWindowFlags(&wFlags);
       
  1671     d->windowFlags = wFlags;
       
  1672     if (!d->setWindowFrameMargins)
       
  1673         unsetWindowFrameMargins();
       
  1674 
       
  1675     setFlag(ItemIsPanel, d->windowFlags & Qt::Window);
       
  1676 
       
  1677     bool isPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
       
  1678     if (d->scene && isVisible() && wasPopup != isPopup) {
       
  1679         // Popup state changed; update implicit mouse grab.
       
  1680         if (!isPopup)
       
  1681             d->scene->d_func()->removePopup(this);
       
  1682         else
       
  1683             d->scene->d_func()->addPopup(this);
       
  1684     }
       
  1685 
       
  1686     if (d->scene && d->scene->d_func()->allItemsIgnoreHoverEvents && d->hasDecoration()) {
       
  1687         d->scene->d_func()->allItemsIgnoreHoverEvents = false;
       
  1688         d->scene->d_func()->enableMouseTrackingOnViews();
       
  1689     }
       
  1690 }
       
  1691 
       
  1692 /*!
       
  1693     Returns true if this widget's window is in the active window, or if the
       
  1694     widget does not have a window but is in an active scene (i.e., a scene
       
  1695     that currently has focus).
       
  1696 
       
  1697     The active window is the window that either contains a child widget that
       
  1698     currently has input focus, or that itself has input focus.
       
  1699 
       
  1700     \sa QGraphicsScene::activeWindow(), QGraphicsScene::setActiveWindow(), isActive()
       
  1701 */
       
  1702 bool QGraphicsWidget::isActiveWindow() const
       
  1703 {
       
  1704     return isActive();
       
  1705 }
       
  1706 
       
  1707 /*!
       
  1708     \property QGraphicsWidget::windowTitle
       
  1709     \brief This property holds the window title (caption).
       
  1710 
       
  1711     This property is only used for windows.
       
  1712 
       
  1713     By default, if no title has been set, this property contains an
       
  1714     empty string.
       
  1715 */
       
  1716 void QGraphicsWidget::setWindowTitle(const QString &title)
       
  1717 {
       
  1718     Q_D(QGraphicsWidget);
       
  1719     d->ensureWindowData();
       
  1720     d->windowData->windowTitle = title;
       
  1721 }
       
  1722 QString QGraphicsWidget::windowTitle() const
       
  1723 {
       
  1724     Q_D(const QGraphicsWidget);
       
  1725     return d->windowData ? d->windowData->windowTitle : QString();
       
  1726 }
       
  1727 
       
  1728 /*!
       
  1729     \property QGraphicsWidget::focusPolicy
       
  1730     \brief the way the widget accepts keyboard focus
       
  1731 
       
  1732     The focus policy is Qt::TabFocus if the widget accepts keyboard focus by
       
  1733     tabbing, Qt::ClickFocus if the widget accepts focus by clicking,
       
  1734     Qt::StrongFocus if it accepts both, and Qt::NoFocus (the default) if it
       
  1735     does not accept focus at all.
       
  1736 
       
  1737     You must enable keyboard focus for a widget if it processes keyboard
       
  1738     events. This is normally done from the widget's constructor. For instance,
       
  1739     the QLineEdit constructor calls setFocusPolicy(Qt::StrongFocus).
       
  1740 
       
  1741     If you enable a focus policy (i.e., not Qt::NoFocus), QGraphicsWidget will
       
  1742     automatically enable the ItemIsFocusable flag.  Setting Qt::NoFocus on a
       
  1743     widget will clear the ItemIsFocusable flag. If the widget currently has
       
  1744     keyboard focus, the widget will automatically lose focus.
       
  1745 
       
  1746     \sa focusInEvent(), focusOutEvent(), keyPressEvent(), keyReleaseEvent(), enabled
       
  1747 */
       
  1748 Qt::FocusPolicy QGraphicsWidget::focusPolicy() const
       
  1749 {
       
  1750     Q_D(const QGraphicsWidget);
       
  1751     return d->focusPolicy;
       
  1752 }
       
  1753 void QGraphicsWidget::setFocusPolicy(Qt::FocusPolicy policy)
       
  1754 {
       
  1755     Q_D(QGraphicsWidget);
       
  1756     if (d->focusPolicy == policy)
       
  1757         return;
       
  1758     d->focusPolicy = policy;
       
  1759     if (hasFocus() && policy == Qt::NoFocus)
       
  1760         clearFocus();
       
  1761     setFlag(ItemIsFocusable, policy != Qt::NoFocus);
       
  1762 }
       
  1763 
       
  1764 /*!
       
  1765     If this widget, a child or descendant of this widget currently has input
       
  1766     focus, this function will return a pointer to that widget. If
       
  1767     no descendant widget has input focus, 0 is returned.
       
  1768 
       
  1769     \sa QGraphicsItem::focusItem(), QWidget::focusWidget()
       
  1770 */
       
  1771 QGraphicsWidget *QGraphicsWidget::focusWidget() const
       
  1772 {
       
  1773     Q_D(const QGraphicsWidget);
       
  1774     if (d->subFocusItem && d->subFocusItem->d_ptr->isWidget)
       
  1775         return static_cast<QGraphicsWidget *>(d->subFocusItem);
       
  1776     return 0;
       
  1777 }
       
  1778 
       
  1779 #ifndef QT_NO_SHORTCUT
       
  1780 /*!
       
  1781     \since 4.5
       
  1782 
       
  1783     Adds a shortcut to Qt's shortcut system that watches for the given key \a
       
  1784     sequence in the given \a context. If the \a context is
       
  1785     Qt::ApplicationShortcut, the shortcut applies to the application as a
       
  1786     whole. Otherwise, it is either local to this widget, Qt::WidgetShortcut,
       
  1787     or to the window itself, Qt::WindowShortcut. For widgets that are not part
       
  1788     of a window (i.e., top-level widgets and their children),
       
  1789     Qt::WindowShortcut shortcuts apply to the scene.
       
  1790 
       
  1791     If the same key \a sequence has been grabbed by several widgets,
       
  1792     when the key \a sequence occurs a QEvent::Shortcut event is sent
       
  1793     to all the widgets to which it applies in a non-deterministic
       
  1794     order, but with the ``ambiguous'' flag set to true.
       
  1795 
       
  1796     \warning You should not normally need to use this function;
       
  1797     instead create \l{QAction}s with the shortcut key sequences you
       
  1798     require (if you also want equivalent menu options and toolbar
       
  1799     buttons), or create \l{QShortcut}s if you just need key sequences.
       
  1800     Both QAction and QShortcut handle all the event filtering for you,
       
  1801     and provide signals which are triggered when the user triggers the
       
  1802     key sequence, so are much easier to use than this low-level
       
  1803     function.
       
  1804 
       
  1805     \sa releaseShortcut() setShortcutEnabled() QWidget::grabShortcut()
       
  1806 */
       
  1807 int QGraphicsWidget::grabShortcut(const QKeySequence &sequence, Qt::ShortcutContext context)
       
  1808 {
       
  1809     Q_ASSERT(qApp);
       
  1810     if (sequence.isEmpty())
       
  1811         return 0;
       
  1812     // ### setAttribute(Qt::WA_GrabbedShortcut);
       
  1813     return qApp->d_func()->shortcutMap.addShortcut(this, sequence, context);
       
  1814 }
       
  1815 
       
  1816 /*!
       
  1817     \since 4.5
       
  1818 
       
  1819     Removes the shortcut with the given \a id from Qt's shortcut
       
  1820     system. The widget will no longer receive QEvent::Shortcut events
       
  1821     for the shortcut's key sequence (unless it has other shortcuts
       
  1822     with the same key sequence).
       
  1823 
       
  1824     \warning You should not normally need to use this function since
       
  1825     Qt's shortcut system removes shortcuts automatically when their
       
  1826     parent widget is destroyed. It is best to use QAction or
       
  1827     QShortcut to handle shortcuts, since they are easier to use than
       
  1828     this low-level function. Note also that this is an expensive
       
  1829     operation.
       
  1830 
       
  1831     \sa grabShortcut() setShortcutEnabled() , QWidget::releaseShortcut()
       
  1832 */
       
  1833 void QGraphicsWidget::releaseShortcut(int id)
       
  1834 {
       
  1835     Q_ASSERT(qApp);
       
  1836     if (id)
       
  1837         qApp->d_func()->shortcutMap.removeShortcut(id, this, 0);
       
  1838 }
       
  1839 
       
  1840 /*!
       
  1841     \since 4.5
       
  1842 
       
  1843     If \a enabled is true, the shortcut with the given \a id is
       
  1844     enabled; otherwise the shortcut is disabled.
       
  1845 
       
  1846     \warning You should not normally need to use this function since
       
  1847     Qt's shortcut system enables/disables shortcuts automatically as
       
  1848     widgets become hidden/visible and gain or lose focus. It is best
       
  1849     to use QAction or QShortcut to handle shortcuts, since they are
       
  1850     easier to use than this low-level function.
       
  1851 
       
  1852     \sa grabShortcut() releaseShortcut(), QWidget::setShortcutEnabled()
       
  1853 */
       
  1854 void QGraphicsWidget::setShortcutEnabled(int id, bool enabled)
       
  1855 {
       
  1856     Q_ASSERT(qApp);
       
  1857     if (id)
       
  1858         qApp->d_func()->shortcutMap.setShortcutEnabled(enabled, id, this, 0);
       
  1859 }
       
  1860 
       
  1861 /*!
       
  1862     \since 4.5
       
  1863 
       
  1864     If \a enabled is true, auto repeat of the shortcut with the
       
  1865     given \a id is enabled; otherwise it is disabled.
       
  1866 
       
  1867     \sa grabShortcut() releaseShortcut() QWidget::setShortcutAutoRepeat()
       
  1868 */
       
  1869 void QGraphicsWidget::setShortcutAutoRepeat(int id, bool enabled)
       
  1870 {
       
  1871     Q_ASSERT(qApp);
       
  1872     if (id)
       
  1873         qApp->d_func()->shortcutMap.setShortcutAutoRepeat(enabled, id, this, 0);
       
  1874 }
       
  1875 #endif
       
  1876 
       
  1877 #ifndef QT_NO_ACTION
       
  1878 /*!
       
  1879     \since 4.5
       
  1880 
       
  1881     Appends the action \a action to this widget's list of actions.
       
  1882 
       
  1883     All QGraphicsWidgets have a list of \l{QAction}s, however they can be
       
  1884     represented graphically in many different ways. The default use of the
       
  1885     QAction list (as returned by actions()) is to create a context QMenu.
       
  1886 
       
  1887     A QGraphicsWidget should only have one of each action and adding an action
       
  1888     it already has will not cause the same action to be in the widget twice.
       
  1889 
       
  1890     \sa removeAction(), insertAction(), actions(), QWidget::addAction()
       
  1891 */
       
  1892 void QGraphicsWidget::addAction(QAction *action)
       
  1893 {
       
  1894     insertAction(0, action);
       
  1895 }
       
  1896 
       
  1897 /*!
       
  1898     \since 4.5
       
  1899 
       
  1900     Appends the actions \a actions to this widget's list of actions.
       
  1901 
       
  1902     \sa removeAction(), QMenu, addAction(), QWidget::addActions()
       
  1903 */
       
  1904 void QGraphicsWidget::addActions(QList<QAction *> actions)
       
  1905 {
       
  1906     for (int i = 0; i < actions.count(); ++i)
       
  1907         insertAction(0, actions.at(i));
       
  1908 }
       
  1909 
       
  1910 /*!
       
  1911     \since 4.5
       
  1912 
       
  1913     Inserts the action \a action to this widget's list of actions,
       
  1914     before the action \a before. It appends the action if \a before is 0 or
       
  1915     \a before is not a valid action for this widget.
       
  1916 
       
  1917     A QGraphicsWidget should only have one of each action.
       
  1918 
       
  1919     \sa removeAction(), addAction(), QMenu, actions(),
       
  1920     QWidget::insertActions()
       
  1921 */
       
  1922 void QGraphicsWidget::insertAction(QAction *before, QAction *action)
       
  1923 {
       
  1924     if (!action) {
       
  1925         qWarning("QWidget::insertAction: Attempt to insert null action");
       
  1926         return;
       
  1927     }
       
  1928 
       
  1929     Q_D(QGraphicsWidget);
       
  1930     int index = d->actions.indexOf(action);
       
  1931     if (index != -1)
       
  1932         d->actions.removeAt(index);
       
  1933 
       
  1934     int pos = d->actions.indexOf(before);
       
  1935     if (pos < 0) {
       
  1936         before = 0;
       
  1937         pos = d->actions.size();
       
  1938     }
       
  1939     d->actions.insert(pos, action);
       
  1940 
       
  1941     if (index == -1) {
       
  1942         QActionPrivate *apriv = action->d_func();
       
  1943         apriv->graphicsWidgets.append(this);
       
  1944     }
       
  1945 
       
  1946     QActionEvent e(QEvent::ActionAdded, action, before);
       
  1947     QApplication::sendEvent(this, &e);
       
  1948 }
       
  1949 
       
  1950 /*!
       
  1951     \since 4.5
       
  1952 
       
  1953     Inserts the actions \a actions to this widget's list of actions,
       
  1954     before the action \a before. It appends the action if \a before is 0 or
       
  1955     \a before is not a valid action for this widget.
       
  1956 
       
  1957     A QGraphicsWidget can have at most one of each action.
       
  1958 
       
  1959     \sa removeAction(), QMenu, insertAction(), QWidget::insertActions()
       
  1960 */
       
  1961 void QGraphicsWidget::insertActions(QAction *before, QList<QAction *> actions)
       
  1962 {
       
  1963     for (int i = 0; i < actions.count(); ++i)
       
  1964         insertAction(before, actions.at(i));
       
  1965 }
       
  1966 
       
  1967 /*!
       
  1968     \since 4.5
       
  1969 
       
  1970     Removes the action \a action from this widget's list of actions.
       
  1971 
       
  1972     \sa insertAction(), actions(), insertAction(), QWidget::removeAction()
       
  1973 */
       
  1974 void QGraphicsWidget::removeAction(QAction *action)
       
  1975 {
       
  1976     if (!action)
       
  1977         return;
       
  1978 
       
  1979     Q_D(QGraphicsWidget);
       
  1980 
       
  1981     QActionPrivate *apriv = action->d_func();
       
  1982     apriv->graphicsWidgets.removeAll(this);
       
  1983 
       
  1984     if (d->actions.removeAll(action)) {
       
  1985         QActionEvent e(QEvent::ActionRemoved, action);
       
  1986         QApplication::sendEvent(this, &e);
       
  1987     }
       
  1988 }
       
  1989 
       
  1990 /*!
       
  1991     \since 4.5
       
  1992 
       
  1993     Returns the (possibly empty) list of this widget's actions.
       
  1994 
       
  1995     \sa insertAction(), removeAction(), QWidget::actions(),
       
  1996     QAction::associatedWidgets(), QAction::associatedGraphicsWidgets()
       
  1997 */
       
  1998 QList<QAction *> QGraphicsWidget::actions() const
       
  1999 {
       
  2000     Q_D(const QGraphicsWidget);
       
  2001     return d->actions;
       
  2002 }
       
  2003 #endif
       
  2004 
       
  2005 /*!
       
  2006     Moves the \a second widget around the ring of focus widgets so that
       
  2007     keyboard focus moves from the \a first widget to the \a second widget when
       
  2008     the Tab key is pressed.
       
  2009 
       
  2010     Note that since the tab order of the \a second widget is changed, you
       
  2011     should order a chain like this:
       
  2012 
       
  2013     \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp 1
       
  2014 
       
  2015     \e not like this:
       
  2016 
       
  2017     \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp 2
       
  2018 
       
  2019     If \a first is 0, this indicates that \a second should be the first widget
       
  2020     to receive input focus should the scene gain Tab focus (i.e., the user
       
  2021     hits Tab so that focus passes into the scene). If \a second is 0, this
       
  2022     indicates that \a first should be the first widget to gain focus if the
       
  2023     scene gained BackTab focus.
       
  2024 
       
  2025     By default, tab order is defined implicitly using widget creation order.
       
  2026 
       
  2027     \sa focusPolicy, {Keyboard Focus}
       
  2028 */
       
  2029 void QGraphicsWidget::setTabOrder(QGraphicsWidget *first, QGraphicsWidget *second)
       
  2030 {
       
  2031     if (!first && !second) {
       
  2032         qWarning("QGraphicsWidget::setTabOrder(0, 0) is undefined");
       
  2033         return;
       
  2034     }
       
  2035     if ((first && second) && first->scene() != second->scene()) {
       
  2036         qWarning("QGraphicsWidget::setTabOrder: scenes %p and %p are different",
       
  2037                  first->scene(), second->scene());
       
  2038         return;
       
  2039     }
       
  2040     QGraphicsScene *scene = first ? first->scene() : second->scene();
       
  2041     if (!scene && (!first || !second)) {
       
  2042         qWarning("QGraphicsWidget::setTabOrder: assigning tab order from/to the"
       
  2043                  " scene requires the item to be in a scene.");
       
  2044         return;
       
  2045     }
       
  2046 
       
  2047     // If either first or second are 0, the scene's tabFocusFirst is updated
       
  2048     // to point to the first item in the scene's focus chain. Then first or
       
  2049     // second are set to point to tabFocusFirst.
       
  2050     QGraphicsScenePrivate *sceneD = scene->d_func();
       
  2051     if (!first) {
       
  2052         sceneD->tabFocusFirst = second;
       
  2053         return;
       
  2054     }
       
  2055     if (!second) {
       
  2056         sceneD->tabFocusFirst = first->d_func()->focusNext;
       
  2057         return;
       
  2058     }
       
  2059 
       
  2060     // Both first and second are != 0.
       
  2061     QGraphicsWidget *firstFocusNext = first->d_func()->focusNext;
       
  2062     if (firstFocusNext == second) {
       
  2063         // Nothing to do.
       
  2064         return;
       
  2065     }
       
  2066 
       
  2067     // Update the focus chain.
       
  2068     QGraphicsWidget *secondFocusPrev = second->d_func()->focusPrev;
       
  2069     QGraphicsWidget *secondFocusNext = second->d_func()->focusNext;
       
  2070     firstFocusNext->d_func()->focusPrev = second;
       
  2071     first->d_func()->focusNext = second;
       
  2072     second->d_func()->focusNext = firstFocusNext;
       
  2073     second->d_func()->focusPrev = first;
       
  2074     secondFocusPrev->d_func()->focusNext = secondFocusNext;
       
  2075     secondFocusNext->d_func()->focusPrev = secondFocusPrev;
       
  2076 
       
  2077     Q_ASSERT(first->d_func()->focusNext->d_func()->focusPrev == first);
       
  2078     Q_ASSERT(first->d_func()->focusPrev->d_func()->focusNext == first);
       
  2079 
       
  2080     Q_ASSERT(second->d_func()->focusNext->d_func()->focusPrev == second);
       
  2081     Q_ASSERT(second->d_func()->focusPrev->d_func()->focusNext == second);
       
  2082 
       
  2083 }
       
  2084 
       
  2085 /*!
       
  2086     If \a on is true, this function enables \a attribute; otherwise
       
  2087     \a attribute is disabled.
       
  2088 
       
  2089     See the class documentation for QGraphicsWidget for a complete list of
       
  2090     which attributes are supported, and what they are for.
       
  2091 
       
  2092     \sa testAttribute(), QWidget::setAttribute()
       
  2093 */
       
  2094 void QGraphicsWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
       
  2095 {
       
  2096     Q_D(QGraphicsWidget);
       
  2097     // ### most flags require some immediate action
       
  2098     // ### we might want to qWarn use of unsupported attributes
       
  2099     // ### we might want to not use Qt::WidgetAttribute, but roll our own instead
       
  2100     d->setAttribute(attribute, on);
       
  2101 }
       
  2102 
       
  2103 /*!
       
  2104     Returns true if \a attribute is enabled for this widget; otherwise,
       
  2105     returns false.
       
  2106 
       
  2107     \sa setAttribute()
       
  2108 */
       
  2109 bool QGraphicsWidget::testAttribute(Qt::WidgetAttribute attribute) const
       
  2110 {
       
  2111     Q_D(const QGraphicsWidget);
       
  2112     return d->testAttribute(attribute);
       
  2113 }
       
  2114 
       
  2115 /*!
       
  2116     \reimp
       
  2117 */
       
  2118 int QGraphicsWidget::type() const
       
  2119 {
       
  2120     return Type;
       
  2121 }
       
  2122 
       
  2123 /*!
       
  2124     \reimp
       
  2125 */
       
  2126 void QGraphicsWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
       
  2127 {
       
  2128     Q_UNUSED(painter);
       
  2129     Q_UNUSED(option);
       
  2130     Q_UNUSED(widget);
       
  2131 }
       
  2132 
       
  2133 /*!
       
  2134     This virtual function is called by QGraphicsScene to draw the window frame
       
  2135     for windows using \a painter, \a option, and \a widget, in local
       
  2136     coordinates. The base implementation uses the current style to render the
       
  2137     frame and title bar.
       
  2138 
       
  2139     You can reimplement this function in a subclass of QGraphicsWidget to
       
  2140     provide custom rendering of the widget's window frame.
       
  2141 
       
  2142     \sa QGraphicsItem::paint()
       
  2143 */
       
  2144 void QGraphicsWidget::paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option,
       
  2145                                        QWidget *widget)
       
  2146 {
       
  2147     const bool fillBackground = !testAttribute(Qt::WA_OpaquePaintEvent)
       
  2148                                 && !testAttribute(Qt::WA_NoSystemBackground);
       
  2149     QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(this);
       
  2150     const bool embeddedWidgetFillsOwnBackground = proxy && proxy->widget();
       
  2151 
       
  2152     if (rect().contains(option->exposedRect)) {
       
  2153         if (fillBackground && !embeddedWidgetFillsOwnBackground)
       
  2154             painter->fillRect(option->exposedRect, palette().window());
       
  2155         return;
       
  2156     }
       
  2157 
       
  2158     Q_D(QGraphicsWidget);
       
  2159 
       
  2160     QRect windowFrameRect = QRect(QPoint(), windowFrameGeometry().size().toSize());
       
  2161     QStyleOptionTitleBar bar;
       
  2162     bar.QStyleOption::operator=(*option);
       
  2163     d->initStyleOptionTitleBar(&bar);   // this clear flags in bar.state
       
  2164     d->ensureWindowData();
       
  2165     if (d->windowData->buttonMouseOver)
       
  2166         bar.state |= QStyle::State_MouseOver;
       
  2167     else
       
  2168         bar.state &= ~QStyle::State_MouseOver;
       
  2169     if (d->windowData->buttonSunken)
       
  2170         bar.state |= QStyle::State_Sunken;
       
  2171     else
       
  2172         bar.state &= ~QStyle::State_Sunken;
       
  2173 
       
  2174     bar.rect = windowFrameRect;
       
  2175 
       
  2176     // translate painter to make the style happy
       
  2177     const QPointF styleOrigin = this->windowFrameRect().topLeft();
       
  2178     painter->translate(styleOrigin);
       
  2179 
       
  2180 #ifdef Q_WS_MAC
       
  2181     const QSize pixmapSize = windowFrameRect.size();
       
  2182     if (pixmapSize.width() <= 0 || pixmapSize.height() <= 0)
       
  2183         return;
       
  2184     QPainter *realPainter = painter;
       
  2185     QPixmap pm(pixmapSize);
       
  2186     painter = new QPainter(&pm);
       
  2187 #endif
       
  2188 
       
  2189     // Fill background
       
  2190     QStyleHintReturnMask mask;
       
  2191     bool setMask = style()->styleHint(QStyle::SH_WindowFrame_Mask, &bar, widget, &mask) && !mask.region.isEmpty();
       
  2192     bool hasBorder = !style()->styleHint(QStyle::SH_TitleBar_NoBorder, &bar, widget);
       
  2193     int frameWidth = style()->pixelMetric(QStyle::PM_MDIFrameWidth, &bar, widget);
       
  2194     if (setMask) {
       
  2195         painter->save();
       
  2196         painter->setClipRegion(mask.region, Qt::IntersectClip);
       
  2197     }
       
  2198     if (fillBackground) {
       
  2199         if (embeddedWidgetFillsOwnBackground) {
       
  2200             // Don't fill the background twice.
       
  2201             QPainterPath windowFrameBackground;
       
  2202             windowFrameBackground.addRect(windowFrameRect);
       
  2203             // Adjust with 0.5 to avoid border artifacts between
       
  2204             // widget background and frame background.
       
  2205             windowFrameBackground.addRect(rect().translated(-styleOrigin).adjusted(0.5, 0.5, -0.5, -0.5));
       
  2206             painter->fillPath(windowFrameBackground, palette().window());
       
  2207         } else {
       
  2208             painter->fillRect(windowFrameRect, palette().window());
       
  2209         }
       
  2210     }
       
  2211     painter->setRenderHint(QPainter::NonCosmeticDefaultPen);
       
  2212 
       
  2213     // Draw title
       
  2214     int height = (int)d->titleBarHeight(bar);
       
  2215     bar.rect.setHeight(height);
       
  2216     if (hasBorder) // Frame is painted by PE_FrameWindow
       
  2217         bar.rect.adjust(frameWidth, frameWidth, -frameWidth, 0);
       
  2218 
       
  2219     painter->save();
       
  2220     painter->setFont(QApplication::font("QWorkspaceTitleBar"));
       
  2221     style()->drawComplexControl(QStyle::CC_TitleBar, &bar, painter, widget);
       
  2222     painter->restore();
       
  2223     if (setMask)
       
  2224         painter->restore();
       
  2225     // Draw window frame
       
  2226     QStyleOptionFrame frameOptions;
       
  2227     frameOptions.QStyleOption::operator=(*option);
       
  2228     initStyleOption(&frameOptions);
       
  2229     if (!hasBorder)
       
  2230         painter->setClipRect(windowFrameRect.adjusted(0, +height, 0, 0), Qt::IntersectClip);
       
  2231     if (hasFocus()) {
       
  2232         frameOptions.state |= QStyle::State_HasFocus;
       
  2233     } else {
       
  2234         frameOptions.state &= ~QStyle::State_HasFocus;
       
  2235     }
       
  2236     bool isActive = isActiveWindow();
       
  2237     if (isActive) {
       
  2238         frameOptions.state |= QStyle::State_Active;
       
  2239     } else {
       
  2240         frameOptions.state &= ~QStyle::State_Active;
       
  2241     }
       
  2242 
       
  2243     frameOptions.palette.setCurrentColorGroup(isActive ? QPalette::Active : QPalette::Normal);
       
  2244     frameOptions.rect = windowFrameRect;
       
  2245     frameOptions.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, widget);
       
  2246     frameOptions.midLineWidth = 1;
       
  2247     style()->drawPrimitive(QStyle::PE_FrameWindow, &frameOptions, painter, widget);
       
  2248 
       
  2249 #ifdef Q_WS_MAC
       
  2250     realPainter->drawPixmap(QPoint(), pm);
       
  2251     delete painter;
       
  2252 #endif
       
  2253 }
       
  2254 
       
  2255 /*!
       
  2256     \reimp
       
  2257 */
       
  2258 QRectF QGraphicsWidget::boundingRect() const
       
  2259 {
       
  2260     return windowFrameRect();
       
  2261 }
       
  2262 
       
  2263 /*!
       
  2264     \reimp
       
  2265 */
       
  2266 QPainterPath QGraphicsWidget::shape() const
       
  2267 {
       
  2268     QPainterPath path;
       
  2269     path.addRect(rect());
       
  2270     return path;
       
  2271 }
       
  2272 
       
  2273 /*!
       
  2274     Call this function to close the widget.
       
  2275 
       
  2276     Returns true if the widget was closed; otherwise returns false.
       
  2277     This slot will first send a QCloseEvent to the widget, which may or may
       
  2278     not accept the event. If the event was ignored, nothing happens. If the
       
  2279     event was accepted, it will hide() the widget.
       
  2280 
       
  2281     If the widget has the Qt::WA_DeleteOnClose attribute set it will be
       
  2282     deleted.
       
  2283 */
       
  2284 bool QGraphicsWidget::close()
       
  2285 {
       
  2286     QCloseEvent closeEvent;
       
  2287     QApplication::sendEvent(this, &closeEvent);
       
  2288     if (!closeEvent.isAccepted()) {
       
  2289         return false;
       
  2290     }
       
  2291     // hide
       
  2292     if (isVisible()) {
       
  2293         hide();
       
  2294     }
       
  2295     if (testAttribute(Qt::WA_DeleteOnClose)) {
       
  2296         deleteLater();
       
  2297     }
       
  2298     return true;
       
  2299 }
       
  2300 
       
  2301 #ifdef Q_NO_USING_KEYWORD
       
  2302 /*!
       
  2303     \fn const QObjectList &QGraphicsWidget::children() const
       
  2304     \internal
       
  2305 
       
  2306     This function returns the same value as QObject::children(). It's
       
  2307     provided to differentiate between the obsolete member
       
  2308     QGraphicsItem::children() and QObject::children(). QGraphicsItem now
       
  2309     provides childItems() instead.
       
  2310 */
       
  2311 #endif
       
  2312 
       
  2313 #if 0
       
  2314 void QGraphicsWidget::dumpFocusChain()
       
  2315 {
       
  2316     qDebug() << "=========== Dumping focus chain ==============";
       
  2317     int i = 0;
       
  2318     QGraphicsWidget *next = this;
       
  2319     QSet<QGraphicsWidget*> visited;
       
  2320     do {
       
  2321         if (!next) {
       
  2322             qWarning("Found a focus chain that is not circular, (next == 0)");
       
  2323             break;
       
  2324         }
       
  2325         qDebug() << i++ << QString::number(uint(next), 16) << next->className() << next->data(0) << QString::fromAscii("focusItem:%1").arg(next->hasFocus() ? '1' : '0') << QLatin1String("next:") << next->d_func()->focusNext->data(0) << QLatin1String("prev:") << next->d_func()->focusPrev->data(0);
       
  2326         if (visited.contains(next)) {
       
  2327             qWarning("Already visited this node. However, I expected to dump until I found myself.");
       
  2328             break;
       
  2329         }
       
  2330         visited << next;
       
  2331         next = next->d_func()->focusNext;
       
  2332     } while (next != this);
       
  2333 }
       
  2334 #endif
       
  2335 
       
  2336 QT_END_NAMESPACE
       
  2337 
       
  2338 #endif //QT_NO_GRAPHICSVIEW