Make QPen default to 1-width non-cosmetic.
[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 }
738
739 /*!
740     \reimp
741 */
742 QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
743 {
744     Q_D(const QGraphicsWidget);
745     QSizeF sh;
746     if (d->layout) {
747         QSizeF marginSize(0,0);
748         if (d->margins) {
749             marginSize = QSizeF(d->margins[d->Left] + d->margins[d->Right],
750                          d->margins[d->Top] + d->margins[d->Bottom]);
751         }
752         sh = d->layout->effectiveSizeHint(which, constraint - marginSize);
753         sh += marginSize;
754     } else {
755         switch (which) {
756             case Qt::MinimumSize:
757                 sh = QSizeF(0, 0);
758                 break;
759             case Qt::PreferredSize:
760                 sh = QSizeF(50, 50);    //rather arbitrary
761                 break;
762             case Qt::MaximumSize:
763                 sh = QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
764                 break;
765             default:
766                 qWarning("QGraphicsWidget::sizeHint(): Don't know how to handle the value of 'which'");
767                 break;
768         }
769     }
770     return sh;
771 }
772
773 /*!
774     \property QGraphicsWidget::layout
775     \brief The layout of the widget
776
777     Any existing layout manager is deleted before the new layout is assigned. If
778      \a layout is 0, the widget is left without a layout. Existing subwidgets'
779     geometries will remain unaffected.
780
781     QGraphicsWidget takes ownership of \a layout.
782
783     All widgets that are currently managed by \a layout or all of its
784     sublayouts, are automatically reparented to this item. The layout is then
785     invalidated, and the child widget geometries are adjusted according to
786     this item's geometry() and contentsMargins(). Children who are not
787     explicitly managed by \a layout remain unaffected by the layout after
788     it has been assigned to this widget.
789
790     If no layout is currently managing this widget, layout() will return 0.
791
792 */
793
794 /*!
795     \fn void QGraphicsWidget::layoutChanged()
796     This signal gets emitted whenever the layout of the item changes
797     \internal
798 */
799
800 /*!
801     Returns this widget's layout, or 0 if no layout is currently managing this
802     widget.
803
804     \sa setLayout()
805 */
806 QGraphicsLayout *QGraphicsWidget::layout() const
807 {
808     Q_D(const QGraphicsWidget);
809     return d->layout;
810 }
811
812 /*!
813     \fn void QGraphicsWidget::setLayout(QGraphicsLayout *layout)
814
815     Sets the layout for this widget to \a layout. Any existing layout manager
816     is deleted before the new layout is assigned. If \a layout is 0, the
817     widget is left without a layout. Existing subwidgets' geometries will
818     remain unaffected.
819
820     All widgets that are currently managed by \a layout or all of its
821     sublayouts, are automatically reparented to this item. The layout is then
822     invalidated, and the child widget geometries are adjusted according to
823     this item's geometry() and contentsMargins(). Children who are not
824     explicitly managed by \a layout remain unaffected by the layout after
825     it has been assigned to this widget.
826
827     QGraphicsWidget takes ownership of \a layout.
828
829     \sa layout(), QGraphicsLinearLayout::addItem(), QGraphicsLayout::invalidate()
830 */
831 void QGraphicsWidget::setLayout(QGraphicsLayout *l)
832 {
833     Q_D(QGraphicsWidget);
834     if (d->layout == l)
835         return;
836     d->setLayout_helper(l);
837     if (!l)
838         return;
839
840     // Prevent assigning a layout that is already assigned to another widget.
841     QGraphicsLayoutItem *oldParent = l->parentLayoutItem();
842     if (oldParent && oldParent != this) {
843         qWarning("QGraphicsWidget::setLayout: Attempting to set a layout on %s"
844                  " \"%s\", when the layout already has a parent",
845                  metaObject()->className(), qPrintable(objectName()));
846         return;
847     }
848
849     // Install and activate the layout.
850     l->setParentLayoutItem(this);
851     l->d_func()->reparentChildItems(this);
852     l->invalidate();
853     emit layoutChanged();
854 }
855
856 /*!
857     Adjusts the size of the widget to its effective preferred size hint.
858
859     This function is called implicitly when the item is shown for the first
860     time.
861
862     \sa effectiveSizeHint(), Qt::MinimumSize
863 */
864 void QGraphicsWidget::adjustSize()
865 {
866     QSizeF sz = effectiveSizeHint(Qt::PreferredSize);
867     // What if sz is not valid?!
868     if (sz.isValid())
869         resize(sz);
870 }
871
872 /*!
873     \property QGraphicsWidget::layoutDirection
874     \brief the layout direction for this widget.
875
876     This property modifies this widget's and all of its descendants'
877     Qt::WA_RightToLeft attribute. It also sets this widget's
878     Qt::WA_SetLayoutDirection attribute.
879
880     The widget's layout direction determines the order in which the layout
881     manager horizontally arranges subwidgets of this widget. The default
882     value depends on the language and locale of the application, and is
883     typically in the same direction as words are read and written. With
884     Qt::LeftToRight, the layout starts placing subwidgets from the left
885     side of this widget towards the right. Qt::RightToLeft does the opposite -
886     the layout will place widgets starting from the right edge moving towards
887     the left.
888
889     Subwidgets inherit their layout direction from the parent. Top-level
890     widget items inherit their layout direction from
891     QGraphicsScene::layoutDirection. If you change a widget's layout direction
892     by calling setLayoutDirection(), the widget will send itself a
893     \l{QEvent::LayoutDirectionChange}{LayoutDirectionChange} event, and then
894     propagate the new layout direction to all its descendants.
895
896     \sa QWidget::layoutDirection, QApplication::layoutDirection
897 */
898 Qt::LayoutDirection QGraphicsWidget::layoutDirection() const
899 {
900     return testAttribute(Qt::WA_RightToLeft) ? Qt::RightToLeft : Qt::LeftToRight;
901 }
902 void QGraphicsWidget::setLayoutDirection(Qt::LayoutDirection direction)
903 {
904     Q_D(QGraphicsWidget);
905     setAttribute(Qt::WA_SetLayoutDirection, true);
906     d->setLayoutDirection_helper(direction);
907 }
908 void QGraphicsWidget::unsetLayoutDirection()
909 {
910     Q_D(QGraphicsWidget);
911     setAttribute(Qt::WA_SetLayoutDirection, false);
912     d->resolveLayoutDirection();
913 }
914
915 /*!
916     Returns a pointer to the widget's style. If this widget does not have any
917     explicitly assigned style, the scene's style is returned instead. In turn,
918     if the scene does not have any assigned style, this function returns
919     QApplication::style().
920
921     \sa setStyle()
922 */
923 QStyle *QGraphicsWidget::style() const
924 {
925     if (QStyle *style = widgetStyles()->styleForWidget(this))
926         return style;
927     // ### This is not thread-safe. QApplication::style() is not thread-safe.
928     return scene() ? scene()->style() : QApplication::style();
929 }
930
931 /*!
932     Sets the widget's style to \a style. QGraphicsWidget does \e not take
933     ownership of \a style.
934
935     If no style is assigned, or \a style is 0, the widget will use
936     QGraphicsScene::style() (if this has been set). Otherwise the widget will
937     use QApplication::style().
938
939     This function sets the Qt::WA_SetStyle attribute if \a style is not 0;
940     otherwise it clears the attribute.
941
942     \sa style()
943 */
944 void QGraphicsWidget::setStyle(QStyle *style)
945 {
946     setAttribute(Qt::WA_SetStyle, style != 0);
947     widgetStyles()->setStyleForWidget(this, style);
948
949     // Deliver StyleChange to the widget itself (doesn't propagate).
950     QEvent event(QEvent::StyleChange);
951     QApplication::sendEvent(this, &event);
952 }
953
954 /*!
955     \property QGraphicsWidget::font
956     \brief the widgets' font
957
958     This property provides the widget's font.
959
960     QFont consists of font properties that have been explicitly defined and
961     properties implicitly inherited from the widget's parent. Hence, font()
962     can return a different font compared to the one set with setFont().
963     This scheme allows you to define single entries in a font without
964     affecting the font's inherited entries.
965
966     When a widget's font changes, it resolves its entries against its
967     parent widget. If the widget does not have a parent widget, it resolves
968     its entries against the scene. The widget then sends itself a
969     \l{QEvent::FontChange}{FontChange} event and notifies all its
970     descendants so that they can resolve their fonts as well.
971
972     By default, this property contains the application's default font.
973
974     \sa QApplication::font(), QGraphicsScene::font, QFont::resolve()
975 */
976 QFont QGraphicsWidget::font() const
977 {
978     Q_D(const QGraphicsWidget);
979     QFont fnt = d->font;
980     fnt.resolve(fnt.resolve() | d->inheritedFontResolveMask);
981     return fnt;
982 }
983 void QGraphicsWidget::setFont(const QFont &font)
984 {
985     Q_D(QGraphicsWidget);
986     setAttribute(Qt::WA_SetFont, font.resolve() != 0);
987
988     QFont naturalFont = d->naturalWidgetFont();
989     QFont resolvedFont = font.resolve(naturalFont);
990     d->setFont_helper(resolvedFont);
991 }
992
993 /*!
994     \property QGraphicsWidget::palette
995     \brief the widget's palette
996
997     This property provides the widget's palette. The palette provides colors
998     and brushes for color groups (e.g., QPalette::Button) and states (e.g.,
999     QPalette::Inactive), loosely defining the general look of the widget and
1000     its children.
1001
1002     QPalette consists of color groups that have been explicitly defined, and
1003     groups that are implicitly inherited from the widget's parent. Because of
1004     this, palette() can return a different palette than what has been set with
1005     setPalette(). This scheme allows you to define single entries in a palette
1006     without affecting the palette's inherited entries.
1007
1008     When a widget's palette changes, it resolves its entries against its
1009     parent widget, or if it doesn't have a parent widget, it resolves against
1010     the scene. It then sends itself a \l{QEvent::PaletteChange}{PaletteChange}
1011     event, and notifies all its descendants so they can resolve their palettes
1012     as well.
1013
1014     By default, this property contains the application's default palette.
1015
1016     \sa QApplication::palette(), QGraphicsScene::palette, QPalette::resolve()
1017 */
1018 QPalette QGraphicsWidget::palette() const
1019 {
1020     Q_D(const QGraphicsWidget);
1021     return d->palette;
1022 }
1023 void QGraphicsWidget::setPalette(const QPalette &palette)
1024 {
1025     Q_D(QGraphicsWidget);
1026     setAttribute(Qt::WA_SetPalette, palette.resolve() != 0);
1027
1028     QPalette naturalPalette = d->naturalWidgetPalette();
1029     QPalette resolvedPalette = palette.resolve(naturalPalette);
1030     d->setPalette_helper(resolvedPalette);
1031 }
1032
1033 /*!
1034     \property QGraphicsWidget::autoFillBackground
1035     \brief whether the widget background is filled automatically
1036     \since 4.7
1037
1038     If enabled, this property will cause Qt to fill the background of the
1039     widget before invoking the paint() method. The color used is defined by the
1040     QPalette::Window color role from the widget's \l{QPalette}{palette}.
1041
1042     In addition, Windows are always filled with QPalette::Window, unless the
1043     WA_OpaquePaintEvent or WA_NoSystemBackground attributes are set.
1044
1045     By default, this property is false.
1046
1047     \sa Qt::WA_OpaquePaintEvent, Qt::WA_NoSystemBackground,
1048 */
1049 bool QGraphicsWidget::autoFillBackground() const
1050 {
1051     Q_D(const QGraphicsWidget);
1052     return d->autoFillBackground;
1053 }
1054 void QGraphicsWidget::setAutoFillBackground(bool enabled)
1055 {
1056     Q_D(QGraphicsWidget);
1057     if (d->autoFillBackground != enabled) {
1058         d->autoFillBackground = enabled;
1059         update();
1060     }
1061 }
1062
1063 /*!
1064     If this widget is currently managed by a layout, this function notifies
1065     the layout that the widget's size hints have changed and the layout
1066     may need to resize and reposition the widget accordingly.
1067
1068     Call this function if the widget's sizeHint() has changed.
1069
1070     \sa QGraphicsLayout::invalidate()
1071 */
1072 void QGraphicsWidget::updateGeometry()
1073 {
1074     QGraphicsLayoutItem::updateGeometry();
1075     QGraphicsLayoutItem *parentItem = parentLayoutItem();
1076
1077     if (parentItem && parentItem->isLayout()) {
1078         if (QGraphicsLayout::instantInvalidatePropagation()) {
1079             static_cast<QGraphicsLayout *>(parentItem)->invalidate();
1080         } else {
1081             parentItem->updateGeometry();
1082         }
1083     } else {
1084         if (parentItem) {
1085             // This is for custom layouting
1086             QGraphicsWidget *parentWid = parentWidget();    //###
1087             if (parentWid->isVisible())
1088                 QApplication::postEvent(parentWid, new QEvent(QEvent::LayoutRequest));
1089         } else {
1090             /**
1091              * If this is the topmost widget, post a LayoutRequest event to the widget.
1092              * When the event is received, it will start flowing all the way down to the leaf
1093              * widgets in one go. This will make a relayout flicker-free.
1094              */
1095             if (QGraphicsLayout::instantInvalidatePropagation())
1096                 QApplication::postEvent(static_cast<QGraphicsWidget *>(this), new QEvent(QEvent::LayoutRequest));
1097         }
1098         if (!QGraphicsLayout::instantInvalidatePropagation()) {
1099             bool wasResized = testAttribute(Qt::WA_Resized);
1100             resize(size()); // this will restrict the size
1101             setAttribute(Qt::WA_Resized, wasResized);
1102         }
1103     }
1104 }
1105
1106 /*!
1107     \reimp
1108
1109     QGraphicsWidget uses the base implementation of this function to catch and
1110     deliver events related to state changes in the item. Because of this, it is
1111     very important that subclasses call the base implementation.
1112
1113     \a change specifies the type of change, and \a value is the new value.
1114
1115     For example, QGraphicsWidget uses ItemVisibleChange to deliver
1116     \l{QEvent::Show} {Show} and \l{QEvent::Hide}{Hide} events,
1117     ItemPositionHasChanged to deliver \l{QEvent::Move}{Move} events,
1118     and ItemParentChange both to deliver \l{QEvent::ParentChange}
1119     {ParentChange} events, and for managing the focus chain.
1120
1121     QGraphicsWidget enables the ItemSendsGeometryChanges flag by default in
1122     order to track position changes.
1123
1124     \sa QGraphicsItem::itemChange()
1125 */
1126 QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &value)
1127 {
1128     Q_D(QGraphicsWidget);
1129     switch (change) {
1130     case ItemEnabledHasChanged: {
1131         // Send EnabledChange after the enabled state has changed.
1132         QEvent event(QEvent::EnabledChange);
1133         QApplication::sendEvent(this, &event);
1134         break;
1135     }
1136     case ItemVisibleChange:
1137         if (value.toBool()) {
1138             // Send Show event before the item has been shown.
1139             QShowEvent event;
1140             QApplication::sendEvent(this, &event);
1141             bool resized = testAttribute(Qt::WA_Resized);
1142             if (!resized) {
1143                 adjustSize();
1144                 setAttribute(Qt::WA_Resized, false);
1145             }
1146         }
1147         break;
1148     case ItemVisibleHasChanged:
1149         if (!value.toBool()) {
1150             // Send Hide event after the item has been hidden.
1151             QHideEvent event;
1152             QApplication::sendEvent(this, &event);
1153         }
1154         break;
1155     case ItemPositionHasChanged:
1156         d->setGeometryFromSetPos();
1157         break;
1158     case ItemParentChange: {
1159         // Deliver ParentAboutToChange.
1160         QEvent event(QEvent::ParentAboutToChange);
1161         QApplication::sendEvent(this, &event);
1162         break;
1163     }
1164     case ItemParentHasChanged: {
1165         // Deliver ParentChange.
1166         QEvent event(QEvent::ParentChange);
1167         QApplication::sendEvent(this, &event);
1168         break;
1169     }
1170     case ItemCursorHasChanged: {
1171         // Deliver CursorChange.
1172         QEvent event(QEvent::CursorChange);
1173         QApplication::sendEvent(this, &event);
1174         break;
1175     }
1176     case ItemToolTipHasChanged: {
1177         // Deliver ToolTipChange.
1178         QEvent event(QEvent::ToolTipChange);
1179         QApplication::sendEvent(this, &event);
1180         break;
1181     }
1182     default:
1183         break;
1184     }
1185     return QGraphicsItem::itemChange(change, value);
1186 }
1187
1188 /*!
1189     \internal
1190
1191     This virtual function is used to notify changes to any property (both
1192     dynamic properties, and registered with Q_PROPERTY) in the
1193     widget. Depending on the property itself, the notification can be
1194     delivered before or after the value has changed.
1195
1196     \a propertyName is the name of the property (e.g., "size" or "font"), and
1197     \a value is the (proposed) new value of the property. The function returns
1198     the new value, which may be different from \a value if the notification
1199     supports adjusting the property value. The base implementation simply
1200     returns \a value for any \a propertyName.
1201
1202     QGraphicsWidget delivers notifications for the following properties:
1203
1204     \table
1205     \header    \li propertyName        \li Property
1206     \row       \li layoutDirection     \li QGraphicsWidget::layoutDirection
1207     \row       \li size                \li QGraphicsWidget::size
1208     \row       \li font                \li QGraphicsWidget::font
1209     \row       \li palette             \li QGraphicsWidget::palette
1210     \endtable
1211
1212     \sa itemChange()
1213 */
1214 QVariant QGraphicsWidget::propertyChange(const QString &propertyName, const QVariant &value)
1215 {
1216     Q_UNUSED(propertyName);
1217     return value;
1218 }
1219
1220 /*!
1221     QGraphicsWidget's implementation of sceneEvent() simply passes \a event to
1222     QGraphicsWidget::event(). You can handle all events for your widget in
1223     event() or in any of the convenience functions; you should not have to
1224     reimplement this function in a subclass of QGraphicsWidget.
1225
1226     \sa QGraphicsItem::sceneEvent()
1227 */
1228 bool QGraphicsWidget::sceneEvent(QEvent *event)
1229 {
1230     return QGraphicsItem::sceneEvent(event);
1231 }
1232
1233 /*!
1234     This event handler, for \a event, receives events for the window frame if
1235     this widget is a window. Its base implementation provides support for
1236     default window frame interaction such as moving, resizing, etc.
1237
1238     You can reimplement this handler in a subclass of QGraphicsWidget to
1239     provide your own custom window frame interaction support.
1240
1241     Returns true if \a event has been recognized and processed; otherwise,
1242     returns false.
1243
1244     \sa event()
1245 */
1246 bool QGraphicsWidget::windowFrameEvent(QEvent *event)
1247 {
1248     Q_D(QGraphicsWidget);
1249     switch (event->type()) {
1250     case QEvent::GraphicsSceneMousePress:
1251         d->windowFrameMousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
1252         break;
1253     case QEvent::GraphicsSceneMouseMove:
1254         d->ensureWindowData();
1255         if (d->windowData->grabbedSection != Qt::NoSection) {
1256             d->windowFrameMouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
1257             event->accept();
1258         }
1259         break;
1260     case QEvent::GraphicsSceneMouseRelease:
1261         d->windowFrameMouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
1262         break;
1263     case QEvent::GraphicsSceneHoverMove:
1264         d->windowFrameHoverMoveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
1265         break;
1266     case QEvent::GraphicsSceneHoverLeave:
1267         d->windowFrameHoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
1268         break;
1269     default:
1270         break;
1271     }
1272     return event->isAccepted();
1273 }
1274
1275 /*!
1276     \since 4.4
1277
1278     Returns the window frame section at position \a pos, or
1279     Qt::NoSection if there is no window frame section at this
1280     position.
1281
1282     This function is used in QGraphicsWidget's base implementation for window
1283     frame interaction.
1284
1285     You can reimplement this function if you want to customize how a window
1286     can be interactively moved or resized.  For instance, if you only want to
1287     allow a window to be resized by the bottom right corner, you can
1288     reimplement this function to return Qt::NoSection for all sections except
1289     Qt::BottomRightSection.
1290
1291     \sa windowFrameEvent(), paintWindowFrame(), windowFrameGeometry()
1292 */
1293 Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(const QPointF &pos) const
1294 {
1295     Q_D(const QGraphicsWidget);
1296
1297     const QRectF r = windowFrameRect();
1298     if (!r.contains(pos))
1299         return Qt::NoSection;
1300
1301     const qreal left = r.left();
1302     const qreal top = r.top();
1303     const qreal right = r.right();
1304     const qreal bottom = r.bottom();
1305     const qreal x = pos.x();
1306     const qreal y = pos.y();
1307
1308     const qreal cornerMargin = 20;
1309     //### Not sure of this one, it should be the same value for all edges.
1310     const qreal windowFrameWidth = d->windowFrameMargins
1311         ? d->windowFrameMargins[d->Left] : 0;
1312
1313     Qt::WindowFrameSection s = Qt::NoSection;
1314     if (x <= left + cornerMargin) {
1315         if (y <= top + windowFrameWidth || (x <= left + windowFrameWidth && y <= top + cornerMargin)) {
1316             s = Qt::TopLeftSection;
1317         } else if (y >= bottom - windowFrameWidth || (x <= left + windowFrameWidth && y >= bottom - windowFrameWidth)) {
1318             s = Qt::BottomLeftSection;
1319         } else if (x <= left + windowFrameWidth) {
1320             s = Qt::LeftSection;
1321         }
1322     } else if (x >= right - cornerMargin) {
1323         if (y <= top + windowFrameWidth || (x >= right - windowFrameWidth && y <= top + cornerMargin)) {
1324             s = Qt::TopRightSection;
1325         } else if (y >= bottom - windowFrameWidth || (x >= right - windowFrameWidth && y >= bottom - windowFrameWidth)) {
1326             s = Qt::BottomRightSection;
1327         } else if (x >= right - windowFrameWidth) {
1328             s = Qt::RightSection;
1329         }
1330     } else if (y <= top + windowFrameWidth) {
1331         s = Qt::TopSection;
1332     } else if (y >= bottom - windowFrameWidth) {
1333         s = Qt::BottomSection;
1334     }
1335     if (s == Qt::NoSection) {
1336         QRectF r1 = r;
1337         r1.setHeight(d->windowFrameMargins
1338                      ? d->windowFrameMargins[d->Top] : 0);
1339         if (r1.contains(pos))
1340             s = Qt::TitleBarArea;
1341     }
1342     return s;
1343 }
1344
1345 /*!
1346     \reimp
1347
1348     Handles the \a event.  QGraphicsWidget handles the following
1349     events:
1350
1351     \table
1352     \header  \li Event                 \li Usage
1353     \row     \li Polish
1354                     \li Delivered to the widget some time after it has been
1355                         shown.
1356     \row     \li GraphicsSceneMove
1357                     \li Delivered to the widget after its local position has
1358                         changed.
1359     \row     \li GraphicsSceneResize
1360                     \li Delivered to the widget after its size has changed.
1361     \row     \li Show
1362                     \li Delivered to the widget before it has been shown.
1363     \row     \li Hide
1364                     \li Delivered to the widget after it has been hidden.
1365     \row     \li PaletteChange
1366                     \li Delivered to the widget after its palette has changed.
1367     \row     \li FontChange
1368                     \li Delivered to the widget after its font has changed.
1369     \row     \li EnabledChange
1370                     \li Delivered to the widget after its enabled state has
1371                         changed.
1372     \row     \li StyleChange
1373                     \li Delivered to the widget after its style has changed.
1374     \row     \li LayoutDirectionChange
1375                     \li Delivered to the widget after its layout direction has
1376                         changed.
1377     \row     \li ContentsRectChange
1378                     \li Delivered to the widget after its contents margins/
1379                         contents rect has changed.
1380     \endtable
1381 */
1382 bool QGraphicsWidget::event(QEvent *event)
1383 {
1384     Q_D(QGraphicsWidget);
1385     // Forward the event to the layout first.
1386     if (d->layout)
1387         d->layout->widgetEvent(event);
1388
1389     // Handle the event itself.
1390     switch (event->type()) {
1391     case QEvent::GraphicsSceneMove:
1392         moveEvent(static_cast<QGraphicsSceneMoveEvent *>(event));
1393         break;
1394     case QEvent::GraphicsSceneResize:
1395         resizeEvent(static_cast<QGraphicsSceneResizeEvent *>(event));
1396         break;
1397     case QEvent::Show:
1398         showEvent(static_cast<QShowEvent *>(event));
1399         break;
1400     case QEvent::Hide:
1401         hideEvent(static_cast<QHideEvent *>(event));
1402         break;
1403     case QEvent::Polish:
1404         polishEvent();
1405         d->polished = true;
1406         if (!d->font.isCopyOf(QApplication::font()))
1407             d->updateFont(d->font);
1408         break;
1409     case QEvent::WindowActivate:
1410     case QEvent::WindowDeactivate:
1411     case QEvent::StyleAnimationUpdate:
1412         update();
1413         break;
1414         // Taken from QWidget::event
1415     case QEvent::ActivationChange:
1416     case QEvent::EnabledChange:
1417     case QEvent::FontChange:
1418     case QEvent::StyleChange:
1419     case QEvent::PaletteChange:
1420     case QEvent::ParentChange:
1421     case QEvent::ContentsRectChange:
1422     case QEvent::LayoutDirectionChange:
1423         changeEvent(event);
1424         break;
1425     case QEvent::Close:
1426         closeEvent((QCloseEvent *)event);
1427         break;
1428     case QEvent::GrabMouse:
1429         grabMouseEvent(event);
1430         break;
1431     case QEvent::UngrabMouse:
1432         ungrabMouseEvent(event);
1433         break;
1434     case QEvent::GrabKeyboard:
1435         grabKeyboardEvent(event);
1436         break;
1437     case QEvent::UngrabKeyboard:
1438         ungrabKeyboardEvent(event);
1439         break;
1440     case QEvent::GraphicsSceneMousePress:
1441         if (d->hasDecoration() && windowFrameEvent(event))
1442             return true;
1443     case QEvent::GraphicsSceneMouseMove:
1444     case QEvent::GraphicsSceneMouseRelease:
1445     case QEvent::GraphicsSceneMouseDoubleClick:
1446         d->ensureWindowData();
1447         if (d->hasDecoration() && d->windowData->grabbedSection != Qt::NoSection)
1448             return windowFrameEvent(event);
1449         break;
1450     case QEvent::GraphicsSceneHoverEnter:
1451     case QEvent::GraphicsSceneHoverMove:
1452     case QEvent::GraphicsSceneHoverLeave:
1453         if (d->hasDecoration()) {
1454             windowFrameEvent(event);
1455             // Filter out hover events if they were sent to us only because of the
1456             // decoration (special case in QGraphicsScenePrivate::dispatchHoverEvent).
1457             if (!acceptHoverEvents())
1458                 return true;
1459         }
1460         break;
1461     default:
1462         break;
1463     }
1464     return QObject::event(event);
1465 }
1466
1467 /*!
1468    This event handler can be reimplemented to handle state changes.
1469
1470    The state being changed in this event can be retrieved through \a event.
1471
1472    Change events include: QEvent::ActivationChange, QEvent::EnabledChange,
1473    QEvent::FontChange, QEvent::StyleChange, QEvent::PaletteChange,
1474    QEvent::ParentChange, QEvent::LayoutDirectionChange, and
1475    QEvent::ContentsRectChange.
1476 */
1477 void QGraphicsWidget::changeEvent(QEvent *event)
1478 {
1479     Q_D(QGraphicsWidget);
1480     switch (event->type()) {
1481     case QEvent::StyleChange:
1482         // ### Don't unset if the margins are explicitly set.
1483         unsetWindowFrameMargins();
1484         if (d->layout)
1485             d->layout->invalidate();
1486     case QEvent::FontChange:
1487         update();
1488         updateGeometry();
1489         break;
1490     case QEvent::PaletteChange:
1491         update();
1492         break;
1493     case QEvent::ParentChange:
1494         d->resolveFont(d->inheritedFontResolveMask);
1495         d->resolvePalette(d->inheritedPaletteResolveMask);
1496         break;
1497     default:
1498         break;
1499     }
1500 }
1501
1502 /*!
1503     This event handler, for \a event, can be reimplemented in a subclass to
1504     receive widget close events.  The default implementation accepts the
1505     event.
1506
1507     \sa close(), QCloseEvent
1508 */
1509 void QGraphicsWidget::closeEvent(QCloseEvent *event)
1510 {
1511     event->accept();
1512 }
1513
1514 /*!
1515     \reimp
1516 */
1517 void QGraphicsWidget::focusInEvent(QFocusEvent *event)
1518 {
1519     Q_UNUSED(event);
1520     if (focusPolicy() != Qt::NoFocus)
1521         update();
1522 }
1523
1524 /*!
1525     Finds a new widget to give the keyboard focus to, as appropriate for Tab
1526     and Shift+Tab, and returns true if it can find a new widget; returns false
1527     otherwise. If \a next is true, this function searches forward; if \a next
1528     is false, it searches backward.
1529
1530     Sometimes, you will want to reimplement this function to provide special
1531     focus handling for your widget and its subwidgets. For example, a web
1532     browser might reimplement it to move its current active link forward or
1533     backward, and call the base implementation only when it reaches the last
1534     or first link on the page.
1535
1536     Child widgets call focusNextPrevChild() on their parent widgets, but only
1537     the window that contains the child widgets decides where to redirect
1538     focus. By reimplementing this function for an object, you gain control of
1539     focus traversal for all child widgets.
1540
1541     \sa focusPolicy()
1542 */
1543 bool QGraphicsWidget::focusNextPrevChild(bool next)
1544 {
1545     Q_D(QGraphicsWidget);
1546     // Let the parent's focusNextPrevChild implementation decide what to do.
1547     QGraphicsWidget *parent = 0;
1548     if (!isWindow() && (parent = parentWidget()))
1549         return parent->focusNextPrevChild(next);
1550     if (!d->scene)
1551         return false;
1552     if (d->scene->focusNextPrevChild(next))
1553         return true;
1554     if (isWindow()) {
1555         setFocus(next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
1556         if (hasFocus())
1557             return true;
1558     }
1559     return false;
1560 }
1561
1562 /*!
1563     \reimp
1564 */
1565 void QGraphicsWidget::focusOutEvent(QFocusEvent *event)
1566 {
1567     Q_UNUSED(event);
1568     if (focusPolicy() != Qt::NoFocus)
1569         update();
1570 }
1571
1572 /*!
1573     This event handler, for \l{QEvent::Hide}{Hide} events, is delivered after
1574     the widget has been hidden, for example, setVisible(false) has been called
1575     for the widget or one of its ancestors when the widget was previously
1576     shown.
1577
1578     You can reimplement this event handler to detect when your widget is
1579     hidden. Calling QEvent::accept() or QEvent::ignore() on \a event has no
1580     effect.
1581
1582     \sa showEvent(), QWidget::hideEvent(), ItemVisibleChange
1583 */
1584 void QGraphicsWidget::hideEvent(QHideEvent *event)
1585 {
1586     ///### focusNextPrevChild(true), don't lose focus when the focus widget
1587     // is hidden.
1588     Q_UNUSED(event);
1589 }
1590
1591 /*!
1592     This event handler, for \l{QEvent::GraphicsSceneMove}{GraphicsSceneMove}
1593     events, is delivered after the widget has moved (e.g., its local position
1594     has changed).
1595
1596     This event is only delivered when the item is moved locally. Calling
1597     setTransform() or moving any of the item's ancestors does not affect the
1598     item's local position.
1599
1600     You can reimplement this event handler to detect when your widget has
1601     moved. Calling QEvent::accept() or QEvent::ignore() on \a event has no
1602     effect.
1603
1604     \sa ItemPositionChange, ItemPositionHasChanged
1605 */
1606 void QGraphicsWidget::moveEvent(QGraphicsSceneMoveEvent *event)
1607 {
1608     // ### Last position is always == current position
1609     Q_UNUSED(event);
1610 }
1611
1612 /*!
1613     This event is delivered to the item by the scene at some point after it
1614     has been constructed, but before it is shown or otherwise accessed through
1615     the scene. You can use this event handler to do last-minute initializations
1616     of the widget which require the item to be fully constructed.
1617
1618     The base implementation does nothing.
1619 */
1620 void QGraphicsWidget::polishEvent()
1621 {
1622 }
1623
1624 /*!
1625     This event handler, for
1626     \l{QEvent::GraphicsSceneResize}{GraphicsSceneResize} events, is
1627     delivered after the widget has been resized (i.e., its local size has
1628     changed). \a event contains both the old and the new size.
1629
1630     This event is only delivered when the widget is resized locally; calling
1631     setTransform() on the widget or any of its ancestors or view, does not
1632     affect the widget's local size.
1633
1634     You can reimplement this event handler to detect when your widget has been
1635     resized. Calling QEvent::accept() or QEvent::ignore() on \a event has no
1636     effect.
1637
1638     \sa geometry(), setGeometry()
1639 */
1640 void QGraphicsWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
1641 {
1642     Q_UNUSED(event);
1643 }
1644
1645 /*!
1646     This event handler, for \l{QEvent::Show}{Show} events, is delivered before
1647     the widget has been shown, for example, setVisible(true) has been called
1648     for the widget or one of its ancestors when the widget was previously
1649     hidden.
1650
1651     You can reimplement this event handler to detect when your widget is
1652     shown. Calling QEvent::accept() or QEvent::ignore() on \a event has no
1653     effect.
1654
1655     \sa hideEvent(), QWidget::showEvent(), ItemVisibleChange
1656 */
1657 void QGraphicsWidget::showEvent(QShowEvent *event)
1658 {
1659     Q_UNUSED(event);
1660 }
1661
1662 /*!
1663     \reimp
1664 */
1665 void QGraphicsWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
1666 {
1667     Q_UNUSED(event);
1668 }
1669
1670 /*!
1671     \reimp
1672 */
1673 void QGraphicsWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
1674 {
1675     Q_UNUSED(event);
1676 }
1677
1678 /*!
1679     This event handler, for \a event, can be reimplemented in a subclass to
1680     receive notifications for QEvent::GrabMouse events.
1681
1682     \sa grabMouse(), grabKeyboard()
1683 */
1684 void QGraphicsWidget::grabMouseEvent(QEvent *event)
1685 {
1686     Q_UNUSED(event);
1687 }
1688
1689 /*!
1690     This event handler, for \a event, can be reimplemented in a subclass to
1691     receive notifications for QEvent::UngrabMouse events.
1692
1693     \sa ungrabMouse(), ungrabKeyboard()
1694 */
1695 void QGraphicsWidget::ungrabMouseEvent(QEvent *event)
1696 {
1697     Q_UNUSED(event);
1698 }
1699
1700 /*!
1701     This event handler, for \a event, can be reimplemented in a subclass to
1702     receive notifications for QEvent::GrabKeyboard events.
1703
1704     \sa grabKeyboard(), grabMouse()
1705 */
1706 void QGraphicsWidget::grabKeyboardEvent(QEvent *event)
1707 {
1708     Q_UNUSED(event);
1709 }
1710
1711 /*!
1712     This event handler, for \a event, can be reimplemented in a subclass to
1713     receive notifications for QEvent::UngrabKeyboard events.
1714
1715     \sa ungrabKeyboard(), ungrabMouse()
1716 */
1717 void QGraphicsWidget::ungrabKeyboardEvent(QEvent *event)
1718 {
1719     Q_UNUSED(event);
1720 }
1721
1722 /*!
1723     Returns the widgets window type.
1724
1725     \sa windowFlags(), isWindow(), isPanel()
1726 */
1727 Qt::WindowType QGraphicsWidget::windowType() const
1728 {
1729     return Qt::WindowType(int(windowFlags()) & Qt::WindowType_Mask);
1730 }
1731
1732 /*!
1733     \property QGraphicsWidget::windowFlags
1734     \brief the widget's window flags
1735
1736     Window flags are a combination of a window type (e.g., Qt::Dialog) and
1737     several flags giving hints on the behavior of the window. The behavior
1738     is platform-dependent.
1739
1740     By default, this property contains no window flags.
1741
1742     Windows are panels. If you set the Qt::Window flag, the ItemIsPanel flag
1743     will be set automatically. If you clear the Qt::Window flag, the
1744     ItemIsPanel flag is also cleared. Note that the ItemIsPanel flag can be
1745     set independently of Qt::Window.
1746
1747     \sa isWindow(), isPanel()
1748 */
1749 Qt::WindowFlags QGraphicsWidget::windowFlags() const
1750 {
1751     Q_D(const QGraphicsWidget);
1752     return d->windowFlags;
1753 }
1754 void QGraphicsWidget::setWindowFlags(Qt::WindowFlags wFlags)
1755 {
1756     Q_D(QGraphicsWidget);
1757     if (d->windowFlags == wFlags)
1758         return;
1759     bool wasPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
1760
1761     d->adjustWindowFlags(&wFlags);
1762     d->windowFlags = wFlags;
1763     if (!d->setWindowFrameMargins)
1764         unsetWindowFrameMargins();
1765
1766     setFlag(ItemIsPanel, d->windowFlags & Qt::Window);
1767
1768     bool isPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
1769     if (d->scene && isVisible() && wasPopup != isPopup) {
1770         // Popup state changed; update implicit mouse grab.
1771         if (!isPopup)
1772             d->scene->d_func()->removePopup(this);
1773         else
1774             d->scene->d_func()->addPopup(this);
1775     }
1776
1777     if (d->scene && d->scene->d_func()->allItemsIgnoreHoverEvents && d->hasDecoration()) {
1778         d->scene->d_func()->allItemsIgnoreHoverEvents = false;
1779         d->scene->d_func()->enableMouseTrackingOnViews();
1780     }
1781 }
1782
1783 /*!
1784     Returns true if this widget's window is in the active window, or if the
1785     widget does not have a window but is in an active scene (i.e., a scene
1786     that currently has focus).
1787
1788     The active window is the window that either contains a child widget that
1789     currently has input focus, or that itself has input focus.
1790
1791     \sa QGraphicsScene::activeWindow(), QGraphicsScene::setActiveWindow(), isActive()
1792 */
1793 bool QGraphicsWidget::isActiveWindow() const
1794 {
1795     return isActive();
1796 }
1797
1798 /*!
1799     \property QGraphicsWidget::windowTitle
1800     \brief This property holds the window title (caption).
1801
1802     This property is only used for windows.
1803
1804     By default, if no title has been set, this property contains an
1805     empty string.
1806 */
1807 void QGraphicsWidget::setWindowTitle(const QString &title)
1808 {
1809     Q_D(QGraphicsWidget);
1810     d->ensureWindowData();
1811     d->windowData->windowTitle = title;
1812 }
1813 QString QGraphicsWidget::windowTitle() const
1814 {
1815     Q_D(const QGraphicsWidget);
1816     return d->windowData ? d->windowData->windowTitle : QString();
1817 }
1818
1819 /*!
1820     \property QGraphicsWidget::focusPolicy
1821     \brief the way the widget accepts keyboard focus
1822
1823     The focus policy is Qt::TabFocus if the widget accepts keyboard focus by
1824     tabbing, Qt::ClickFocus if the widget accepts focus by clicking,
1825     Qt::StrongFocus if it accepts both, and Qt::NoFocus (the default) if it
1826     does not accept focus at all.
1827
1828     You must enable keyboard focus for a widget if it processes keyboard
1829     events. This is normally done from the widget's constructor. For instance,
1830     the QLineEdit constructor calls setFocusPolicy(Qt::StrongFocus).
1831
1832     If you enable a focus policy (i.e., not Qt::NoFocus), QGraphicsWidget will
1833     automatically enable the ItemIsFocusable flag.  Setting Qt::NoFocus on a
1834     widget will clear the ItemIsFocusable flag. If the widget currently has
1835     keyboard focus, the widget will automatically lose focus.
1836
1837     \sa focusInEvent(), focusOutEvent(), keyPressEvent(), keyReleaseEvent(), enabled
1838 */
1839 Qt::FocusPolicy QGraphicsWidget::focusPolicy() const
1840 {
1841     Q_D(const QGraphicsWidget);
1842     return d->focusPolicy;
1843 }
1844 void QGraphicsWidget::setFocusPolicy(Qt::FocusPolicy policy)
1845 {
1846     Q_D(QGraphicsWidget);
1847     if (d->focusPolicy == policy)
1848         return;
1849     d->focusPolicy = policy;
1850     if (hasFocus() && policy == Qt::NoFocus)
1851         clearFocus();
1852     setFlag(ItemIsFocusable, policy != Qt::NoFocus);
1853 }
1854
1855 /*!
1856     If this widget, a child or descendant of this widget currently has input
1857     focus, this function will return a pointer to that widget. If
1858     no descendant widget has input focus, 0 is returned.
1859
1860     \sa QGraphicsItem::focusItem(), QWidget::focusWidget()
1861 */
1862 QGraphicsWidget *QGraphicsWidget::focusWidget() const
1863 {
1864     Q_D(const QGraphicsWidget);
1865     if (d->subFocusItem && d->subFocusItem->d_ptr->isWidget)
1866         return static_cast<QGraphicsWidget *>(d->subFocusItem);
1867     return 0;
1868 }
1869
1870 #ifndef QT_NO_SHORTCUT
1871 /*!
1872     \since 4.5
1873
1874     Adds a shortcut to Qt's shortcut system that watches for the given key \a
1875     sequence in the given \a context. If the \a context is
1876     Qt::ApplicationShortcut, the shortcut applies to the application as a
1877     whole. Otherwise, it is either local to this widget, Qt::WidgetShortcut,
1878     or to the window itself, Qt::WindowShortcut. For widgets that are not part
1879     of a window (i.e., top-level widgets and their children),
1880     Qt::WindowShortcut shortcuts apply to the scene.
1881
1882     If the same key \a sequence has been grabbed by several widgets,
1883     when the key \a sequence occurs a QEvent::Shortcut event is sent
1884     to all the widgets to which it applies in a non-deterministic
1885     order, but with the ``ambiguous'' flag set to true.
1886
1887     \warning You should not normally need to use this function;
1888     instead create \l{QAction}s with the shortcut key sequences you
1889     require (if you also want equivalent menu options and toolbar
1890     buttons), or create \l{QShortcut}s if you just need key sequences.
1891     Both QAction and QShortcut handle all the event filtering for you,
1892     and provide signals which are triggered when the user triggers the
1893     key sequence, so are much easier to use than this low-level
1894     function.
1895
1896     \sa releaseShortcut(), setShortcutEnabled(), QWidget::grabShortcut()
1897 */
1898 int QGraphicsWidget::grabShortcut(const QKeySequence &sequence, Qt::ShortcutContext context)
1899 {
1900     Q_ASSERT(qApp);
1901     if (sequence.isEmpty())
1902         return 0;
1903     // ### setAttribute(Qt::WA_GrabbedShortcut);
1904     return qApp->d_func()->shortcutMap.addShortcut(this, sequence, context, qWidgetShortcutContextMatcher);
1905 }
1906
1907 /*!
1908     \since 4.5
1909
1910     Removes the shortcut with the given \a id from Qt's shortcut
1911     system. The widget will no longer receive QEvent::Shortcut events
1912     for the shortcut's key sequence (unless it has other shortcuts
1913     with the same key sequence).
1914
1915     \warning You should not normally need to use this function since
1916     Qt's shortcut system removes shortcuts automatically when their
1917     parent widget is destroyed. It is best to use QAction or
1918     QShortcut to handle shortcuts, since they are easier to use than
1919     this low-level function. Note also that this is an expensive
1920     operation.
1921
1922     \sa grabShortcut(), setShortcutEnabled(), QWidget::releaseShortcut()
1923 */
1924 void QGraphicsWidget::releaseShortcut(int id)
1925 {
1926     Q_ASSERT(qApp);
1927     if (id)
1928         qApp->d_func()->shortcutMap.removeShortcut(id, this, 0);
1929 }
1930
1931 /*!
1932     \since 4.5
1933
1934     If \a enabled is true, the shortcut with the given \a id is
1935     enabled; otherwise the shortcut is disabled.
1936
1937     \warning You should not normally need to use this function since
1938     Qt's shortcut system enables/disables shortcuts automatically as
1939     widgets become hidden/visible and gain or lose focus. It is best
1940     to use QAction or QShortcut to handle shortcuts, since they are
1941     easier to use than this low-level function.
1942
1943     \sa grabShortcut(), releaseShortcut(), QWidget::setShortcutEnabled()
1944 */
1945 void QGraphicsWidget::setShortcutEnabled(int id, bool enabled)
1946 {
1947     Q_ASSERT(qApp);
1948     if (id)
1949         qApp->d_func()->shortcutMap.setShortcutEnabled(enabled, id, this, 0);
1950 }
1951
1952 /*!
1953     \since 4.5
1954
1955     If \a enabled is true, auto repeat of the shortcut with the
1956     given \a id is enabled; otherwise it is disabled.
1957
1958     \sa grabShortcut(), releaseShortcut(), QWidget::setShortcutAutoRepeat()
1959 */
1960 void QGraphicsWidget::setShortcutAutoRepeat(int id, bool enabled)
1961 {
1962     Q_ASSERT(qApp);
1963     if (id)
1964         qApp->d_func()->shortcutMap.setShortcutAutoRepeat(enabled, id, this, 0);
1965 }
1966 #endif
1967
1968 #ifndef QT_NO_ACTION
1969 /*!
1970     \since 4.5
1971
1972     Appends the action \a action to this widget's list of actions.
1973
1974     All QGraphicsWidgets have a list of \l{QAction}s, however they can be
1975     represented graphically in many different ways. The default use of the
1976     QAction list (as returned by actions()) is to create a context QMenu.
1977
1978     A QGraphicsWidget should only have one of each action and adding an action
1979     it already has will not cause the same action to be in the widget twice.
1980
1981     \sa removeAction(), insertAction(), actions(), QWidget::addAction()
1982 */
1983 void QGraphicsWidget::addAction(QAction *action)
1984 {
1985     insertAction(0, action);
1986 }
1987
1988 /*!
1989     \since 4.5
1990
1991     Appends the actions \a actions to this widget's list of actions.
1992
1993     \sa removeAction(), QMenu, addAction(), QWidget::addActions()
1994 */
1995 void QGraphicsWidget::addActions(QList<QAction *> actions)
1996 {
1997     for (int i = 0; i < actions.count(); ++i)
1998         insertAction(0, actions.at(i));
1999 }
2000
2001 /*!
2002     \since 4.5
2003
2004     Inserts the action \a action to this widget's list of actions,
2005     before the action \a before. It appends the action if \a before is 0 or
2006     \a before is not a valid action for this widget.
2007
2008     A QGraphicsWidget should only have one of each action.
2009
2010     \sa removeAction(), addAction(), QMenu, actions(),
2011     QWidget::insertActions()
2012 */
2013 void QGraphicsWidget::insertAction(QAction *before, QAction *action)
2014 {
2015     if (!action) {
2016         qWarning("QWidget::insertAction: Attempt to insert null action");
2017         return;
2018     }
2019
2020     Q_D(QGraphicsWidget);
2021     int index = d->actions.indexOf(action);
2022     if (index != -1)
2023         d->actions.removeAt(index);
2024
2025     int pos = d->actions.indexOf(before);
2026     if (pos < 0) {
2027         before = 0;
2028         pos = d->actions.size();
2029     }
2030     d->actions.insert(pos, action);
2031
2032     if (index == -1) {
2033         QActionPrivate *apriv = action->d_func();
2034         apriv->graphicsWidgets.append(this);
2035     }
2036
2037     QActionEvent e(QEvent::ActionAdded, action, before);
2038     QApplication::sendEvent(this, &e);
2039 }
2040
2041 /*!
2042     \since 4.5
2043
2044     Inserts the actions \a actions to this widget's list of actions,
2045     before the action \a before. It appends the action if \a before is 0 or
2046     \a before is not a valid action for this widget.
2047
2048     A QGraphicsWidget can have at most one of each action.
2049
2050     \sa removeAction(), QMenu, insertAction(), QWidget::insertActions()
2051 */
2052 void QGraphicsWidget::insertActions(QAction *before, QList<QAction *> actions)
2053 {
2054     for (int i = 0; i < actions.count(); ++i)
2055         insertAction(before, actions.at(i));
2056 }
2057
2058 /*!
2059     \since 4.5
2060
2061     Removes the action \a action from this widget's list of actions.
2062
2063     \sa insertAction(), actions(), insertAction(), QWidget::removeAction()
2064 */
2065 void QGraphicsWidget::removeAction(QAction *action)
2066 {
2067     if (!action)
2068         return;
2069
2070     Q_D(QGraphicsWidget);
2071
2072     QActionPrivate *apriv = action->d_func();
2073     apriv->graphicsWidgets.removeAll(this);
2074
2075     if (d->actions.removeAll(action)) {
2076         QActionEvent e(QEvent::ActionRemoved, action);
2077         QApplication::sendEvent(this, &e);
2078     }
2079 }
2080
2081 /*!
2082     \since 4.5
2083
2084     Returns the (possibly empty) list of this widget's actions.
2085
2086     \sa insertAction(), removeAction(), QWidget::actions(),
2087     QAction::associatedWidgets(), QAction::associatedGraphicsWidgets()
2088 */
2089 QList<QAction *> QGraphicsWidget::actions() const
2090 {
2091     Q_D(const QGraphicsWidget);
2092     return d->actions;
2093 }
2094 #endif
2095
2096 /*!
2097     Moves the \a second widget around the ring of focus widgets so that
2098     keyboard focus moves from the \a first widget to the \a second widget when
2099     the Tab key is pressed.
2100
2101     Note that since the tab order of the \a second widget is changed, you
2102     should order a chain like this:
2103
2104     \snippet code/src_gui_graphicsview_qgraphicswidget.cpp 1
2105
2106     \e not like this:
2107
2108     \snippet code/src_gui_graphicsview_qgraphicswidget.cpp 2
2109
2110     If \a first is 0, this indicates that \a second should be the first widget
2111     to receive input focus should the scene gain Tab focus (i.e., the user
2112     hits Tab so that focus passes into the scene). If \a second is 0, this
2113     indicates that \a first should be the first widget to gain focus if the
2114     scene gained BackTab focus.
2115
2116     By default, tab order is defined implicitly using widget creation order.
2117
2118     \sa focusPolicy, {Keyboard Focus}
2119 */
2120 void QGraphicsWidget::setTabOrder(QGraphicsWidget *first, QGraphicsWidget *second)
2121 {
2122     if (!first && !second) {
2123         qWarning("QGraphicsWidget::setTabOrder(0, 0) is undefined");
2124         return;
2125     }
2126     if ((first && second) && first->scene() != second->scene()) {
2127         qWarning("QGraphicsWidget::setTabOrder: scenes %p and %p are different",
2128                  first->scene(), second->scene());
2129         return;
2130     }
2131     QGraphicsScene *scene = first ? first->scene() : second->scene();
2132     if (!scene && (!first || !second)) {
2133         qWarning("QGraphicsWidget::setTabOrder: assigning tab order from/to the"
2134                  " scene requires the item to be in a scene.");
2135         return;
2136     }
2137
2138     // If either first or second are 0, the scene's tabFocusFirst is updated
2139     // to point to the first item in the scene's focus chain. Then first or
2140     // second are set to point to tabFocusFirst.
2141     QGraphicsScenePrivate *sceneD = scene->d_func();
2142     if (!first) {
2143         sceneD->tabFocusFirst = second;
2144         return;
2145     }
2146     if (!second) {
2147         sceneD->tabFocusFirst = first->d_func()->focusNext;
2148         return;
2149     }
2150
2151     // Both first and second are != 0.
2152     QGraphicsWidget *firstFocusNext = first->d_func()->focusNext;
2153     if (firstFocusNext == second) {
2154         // Nothing to do.
2155         return;
2156     }
2157
2158     // Update the focus chain.
2159     QGraphicsWidget *secondFocusPrev = second->d_func()->focusPrev;
2160     QGraphicsWidget *secondFocusNext = second->d_func()->focusNext;
2161     firstFocusNext->d_func()->focusPrev = second;
2162     first->d_func()->focusNext = second;
2163     second->d_func()->focusNext = firstFocusNext;
2164     second->d_func()->focusPrev = first;
2165     secondFocusPrev->d_func()->focusNext = secondFocusNext;
2166     secondFocusNext->d_func()->focusPrev = secondFocusPrev;
2167
2168     Q_ASSERT(first->d_func()->focusNext->d_func()->focusPrev == first);
2169     Q_ASSERT(first->d_func()->focusPrev->d_func()->focusNext == first);
2170
2171     Q_ASSERT(second->d_func()->focusNext->d_func()->focusPrev == second);
2172     Q_ASSERT(second->d_func()->focusPrev->d_func()->focusNext == second);
2173
2174 }
2175
2176 /*!
2177     If \a on is true, this function enables \a attribute; otherwise
2178     \a attribute is disabled.
2179
2180     See the class documentation for QGraphicsWidget for a complete list of
2181     which attributes are supported, and what they are for.
2182
2183     \sa testAttribute(), QWidget::setAttribute()
2184 */
2185 void QGraphicsWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
2186 {
2187     Q_D(QGraphicsWidget);
2188     // ### most flags require some immediate action
2189     // ### we might want to qWarn use of unsupported attributes
2190     // ### we might want to not use Qt::WidgetAttribute, but roll our own instead
2191     d->setAttribute(attribute, on);
2192 }
2193
2194 /*!
2195     Returns true if \a attribute is enabled for this widget; otherwise,
2196     returns false.
2197
2198     \sa setAttribute()
2199 */
2200 bool QGraphicsWidget::testAttribute(Qt::WidgetAttribute attribute) const
2201 {
2202     Q_D(const QGraphicsWidget);
2203     return d->testAttribute(attribute);
2204 }
2205
2206 /*!
2207     \reimp
2208 */
2209 int QGraphicsWidget::type() const
2210 {
2211     return Type;
2212 }
2213
2214 /*!
2215     \reimp
2216 */
2217 void QGraphicsWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
2218 {
2219     Q_UNUSED(painter);
2220     Q_UNUSED(option);
2221     Q_UNUSED(widget);
2222 }
2223
2224 /*!
2225     This virtual function is called by QGraphicsScene to draw the window frame
2226     for windows using \a painter, \a option, and \a widget, in local
2227     coordinates. The base implementation uses the current style to render the
2228     frame and title bar.
2229
2230     You can reimplement this function in a subclass of QGraphicsWidget to
2231     provide custom rendering of the widget's window frame.
2232
2233     \sa QGraphicsItem::paint()
2234 */
2235 void QGraphicsWidget::paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option,
2236                                        QWidget *widget)
2237 {
2238     const bool fillBackground = !testAttribute(Qt::WA_OpaquePaintEvent)
2239                                 && !testAttribute(Qt::WA_NoSystemBackground);
2240     QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(this);
2241     const bool embeddedWidgetFillsOwnBackground = proxy && proxy->widget();
2242
2243     if (rect().contains(option->exposedRect)) {
2244         if (fillBackground && !embeddedWidgetFillsOwnBackground)
2245             painter->fillRect(option->exposedRect, palette().window());
2246         return;
2247     }
2248
2249     Q_D(QGraphicsWidget);
2250
2251     QRect windowFrameRect = QRect(QPoint(), windowFrameGeometry().size().toSize());
2252     QStyleOptionTitleBar bar;
2253     bar.QStyleOption::operator=(*option);
2254     d->initStyleOptionTitleBar(&bar);   // this clear flags in bar.state
2255     d->ensureWindowData();
2256     if (d->windowData->buttonMouseOver)
2257         bar.state |= QStyle::State_MouseOver;
2258     else
2259         bar.state &= ~QStyle::State_MouseOver;
2260     if (d->windowData->buttonSunken)
2261         bar.state |= QStyle::State_Sunken;
2262     else
2263         bar.state &= ~QStyle::State_Sunken;
2264
2265     bar.rect = windowFrameRect;
2266
2267     // translate painter to make the style happy
2268     const QPointF styleOrigin = this->windowFrameRect().topLeft();
2269     painter->translate(styleOrigin);
2270
2271 #ifdef Q_WS_MAC
2272     const QSize pixmapSize = windowFrameRect.size();
2273     if (pixmapSize.width() <= 0 || pixmapSize.height() <= 0)
2274         return;
2275     QPainter *realPainter = painter;
2276     QPixmap pm(pixmapSize);
2277     painter = new QPainter(&pm);
2278 #endif
2279
2280     // Fill background
2281     QStyleHintReturnMask mask;
2282     bool setMask = style()->styleHint(QStyle::SH_WindowFrame_Mask, &bar, widget, &mask) && !mask.region.isEmpty();
2283     bool hasBorder = !style()->styleHint(QStyle::SH_TitleBar_NoBorder, &bar, widget);
2284     int frameWidth = style()->pixelMetric(QStyle::PM_MDIFrameWidth, &bar, widget);
2285     if (setMask) {
2286         painter->save();
2287         painter->setClipRegion(mask.region, Qt::IntersectClip);
2288     }
2289     if (fillBackground) {
2290         if (embeddedWidgetFillsOwnBackground) {
2291             // Don't fill the background twice.
2292             QPainterPath windowFrameBackground;
2293             windowFrameBackground.addRect(windowFrameRect);
2294             // Adjust with 0.5 to avoid border artifacts between
2295             // widget background and frame background.
2296             windowFrameBackground.addRect(rect().translated(-styleOrigin).adjusted(0.5, 0.5, -0.5, -0.5));
2297             painter->fillPath(windowFrameBackground, palette().window());
2298         } else {
2299             painter->fillRect(windowFrameRect, palette().window());
2300         }
2301     }
2302
2303     // Draw title
2304     int height = (int)d->titleBarHeight(bar);
2305     bar.rect.setHeight(height);
2306     if (hasBorder) // Frame is painted by PE_FrameWindow
2307         bar.rect.adjust(frameWidth, frameWidth, -frameWidth, 0);
2308
2309     painter->save();
2310     painter->setFont(QApplication::font("QMdiSubWindowTitleBar"));
2311     style()->drawComplexControl(QStyle::CC_TitleBar, &bar, painter, widget);
2312     painter->restore();
2313     if (setMask)
2314         painter->restore();
2315     // Draw window frame
2316     QStyleOptionFrame frameOptions;
2317     frameOptions.QStyleOption::operator=(*option);
2318     initStyleOption(&frameOptions);
2319     if (!hasBorder)
2320         painter->setClipRect(windowFrameRect.adjusted(0, +height, 0, 0), Qt::IntersectClip);
2321     if (hasFocus()) {
2322         frameOptions.state |= QStyle::State_HasFocus;
2323     } else {
2324         frameOptions.state &= ~QStyle::State_HasFocus;
2325     }
2326     bool isActive = isActiveWindow();
2327     if (isActive) {
2328         frameOptions.state |= QStyle::State_Active;
2329     } else {
2330         frameOptions.state &= ~QStyle::State_Active;
2331     }
2332
2333     frameOptions.palette.setCurrentColorGroup(isActive ? QPalette::Active : QPalette::Normal);
2334     frameOptions.rect = windowFrameRect;
2335     frameOptions.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, widget);
2336     frameOptions.midLineWidth = 1;
2337     style()->drawPrimitive(QStyle::PE_FrameWindow, &frameOptions, painter, widget);
2338
2339 #ifdef Q_WS_MAC
2340     realPainter->drawPixmap(QPoint(), pm);
2341     delete painter;
2342 #endif
2343 }
2344
2345 /*!
2346     \reimp
2347 */
2348 QRectF QGraphicsWidget::boundingRect() const
2349 {
2350     return windowFrameRect();
2351 }
2352
2353 /*!
2354     \reimp
2355 */
2356 QPainterPath QGraphicsWidget::shape() const
2357 {
2358     QPainterPath path;
2359     path.addRect(rect());
2360     return path;
2361 }
2362
2363 /*!
2364     Call this function to close the widget.
2365
2366     Returns true if the widget was closed; otherwise returns false.
2367     This slot will first send a QCloseEvent to the widget, which may or may
2368     not accept the event. If the event was ignored, nothing happens. If the
2369     event was accepted, it will hide() the widget.
2370
2371     If the widget has the Qt::WA_DeleteOnClose attribute set it will be
2372     deleted.
2373 */
2374 bool QGraphicsWidget::close()
2375 {
2376     QCloseEvent closeEvent;
2377     QApplication::sendEvent(this, &closeEvent);
2378     if (!closeEvent.isAccepted()) {
2379         return false;
2380     }
2381     // hide
2382     if (isVisible()) {
2383         hide();
2384     }
2385     if (testAttribute(Qt::WA_DeleteOnClose)) {
2386         deleteLater();
2387     }
2388     return true;
2389 }
2390
2391 #ifdef Q_NO_USING_KEYWORD
2392 /*!
2393     \fn const QObjectList &QGraphicsWidget::children() const
2394     \internal
2395
2396     This function returns the same value as QObject::children(). It's
2397     provided to differentiate between the obsolete member
2398     QGraphicsItem::children() and QObject::children(). QGraphicsItem now
2399     provides childItems() instead.
2400 */
2401 #endif
2402
2403 #if 0
2404 void QGraphicsWidget::dumpFocusChain()
2405 {
2406     qDebug() << "=========== Dumping focus chain ==============";
2407     int i = 0;
2408     QGraphicsWidget *next = this;
2409     QSet<QGraphicsWidget*> visited;
2410     do {
2411         if (!next) {
2412             qWarning("Found a focus chain that is not circular, (next == 0)");
2413             break;
2414         }
2415         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);
2416         if (visited.contains(next)) {
2417             qWarning("Already visited this node. However, I expected to dump until I found myself.");
2418             break;
2419         }
2420         visited << next;
2421         next = next->d_func()->focusNext;
2422     } while (next != this);
2423 }
2424 #endif
2425
2426 QT_END_NAMESPACE
2427
2428 #endif //QT_NO_GRAPHICSVIEW