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