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