1
1
/****************************************************************************
3
3
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
4
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
** Licensees holding valid Qt Commercial licenses may use this file in
11
** accordance with the Qt Commercial License Agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and Nokia.
10
** No Commercial Usage
11
** This file contains pre-release code and may not be distributed.
12
** You may use this file in accordance with the terms and conditions
13
** contained in the Technology Preview License Agreement accompanying
15
16
** GNU Lesser General Public License Usage
16
17
** Alternatively, this file may be used under the terms of the GNU Lesser
20
21
** ensure the GNU Lesser General Public License version 2.1 requirements
21
22
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23
** In addition, as a special exception, Nokia gives you certain
24
** additional rights. These rights are described in the Nokia Qt LGPL
25
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
28
** GNU General Public License Usage
29
** Alternatively, this file may be used under the terms of the GNU
30
** General Public License version 3.0 as published by the Free Software
31
** Foundation and appearing in the file LICENSE.GPL included in the
32
** packaging of this file. Please review the following information to
33
** ensure the GNU General Public License version 3.0 requirements will be
34
** met: http://www.gnu.org/copyleft/gpl.html.
36
** If you are unsure which license is appropriate for your use, please
37
** contact the sales department at http://www.qtsoftware.com/contact.
24
** In addition, as a special exception, Nokia gives you certain additional
25
** rights. These rights are described in the Nokia Qt LGPL Exception
26
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28
** If you have questions regarding the use of this file, please contact
29
** Nokia at qt-info@nokia.com.
38
38
** $QT_END_LICENSE$
40
40
****************************************************************************/
167
174
extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
168
175
extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
170
QWidgetPrivate::QWidgetPrivate(int version) :
171
QObjectPrivate(version), extra(0), focus_child(0)
172
,layout(0), widgetItem(0)
173
,leftmargin(0), topmargin(0), rightmargin(0), bottommargin(0)
174
,leftLayoutItemMargin(0), topLayoutItemMargin(0), rightLayoutItemMargin(0)
175
,bottomLayoutItemMargin(0)
176
,fg_role(QPalette::NoRole)
177
,bg_role(QPalette::NoRole)
181
,dirtyOpaqueChildren(1)
186
,usesDoubleBufferedGLContext(0)
177
QWidgetPrivate::QWidgetPrivate(int version)
178
: QObjectPrivate(version)
187
, extraPaintEngine(0)
190
#if !defined(QT_NO_IM)
191
, imHints(Qt::ImhNone)
190
,inheritedFontResolveMask(0)
191
,inheritedPaletteResolveMask(0)
193
, inheritedFontResolveMask(0)
194
, inheritedPaletteResolveMask(0)
199
, leftLayoutItemMargin(0)
200
, topLayoutItemMargin(0)
201
, rightLayoutItemMargin(0)
202
, bottomLayoutItemMargin(0)
204
, size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred)
205
, fg_role(QPalette::NoRole)
206
, bg_role(QPalette::NoRole)
207
, dirtyOpaqueChildren(1)
212
, usesDoubleBufferedGLContext(0)
192
213
#if defined(Q_WS_X11)
201
, size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred)
215
#elif defined(Q_WS_WIN)
217
#elif defined(Q_WS_MAC)
218
, needWindowChange(0)
205
225
qFatal("QWidget: Must construct a QApplication before a QPaintDevice");
880
902
\sa QEvent, QPainter, QGridLayout, QBoxLayout
907
Softkeys are usually physical keys on a device that have a corresponding label or
908
other visual representation on the screen that is generally located next to its
909
physical counterpart. They are most often found on mobile phone platforms. In
910
modern touch based user interfaces it is also possible to have softkeys that do
911
not correspond to any physical keys. Softkeys differ from other onscreen labels
912
in that they are contextual.
914
In Qt, contextual softkeys are added to a widget by calling addAction() and
915
passing a \c QAction with a softkey role set on it. When the widget
916
containing the softkey actions has focus, its softkeys should appear in
917
the user interface. Softkeys are discovered by traversing the widget
918
heirarchy so it is possible to define a single set of softkeys that are
919
present at all times by calling addAction() for a given top level widget.
921
On some platforms, this concept overlaps with \c QMenuBar such that if no
922
other softkeys are found and the top level widget is a QMainWindow containing
923
a QMenuBar, the menubar actions may appear on one of the softkeys.
925
Note: Currently softkeys are only supported on the Symbian Platform.
927
\sa addAction(), QAction, QMenuBar
883
QWidgetMapper *QWidgetPrivate::mapper = 0; // widget with wid
884
QWidgetSet *QWidgetPrivate::uncreatedWidgets = 0; // widgets with no wid
931
QWidgetMapper *QWidgetPrivate::mapper = 0; // widget with wid
932
QWidgetSet *QWidgetPrivate::allWidgets = 0; // widgets with no wid
887
935
/*****************************************************************************
972
struct QWidgetExceptionCleaner
974
/* this cleans up when the constructor throws an exception */
975
static inline void cleanup(QWidget *that, QWidgetPrivate *d)
977
#ifdef QT_NO_EXCEPTIONS
981
QWidgetPrivate::allWidgets->remove(that);
982
if (d->focus_next != that) {
984
d->focus_next->d_func()->focus_prev = d->focus_prev;
986
d->focus_prev->d_func()->focus_next = d->focus_next;
925
993
Constructs a widget which is a child of \a parent, with widget
926
994
flags set to \a f.
961
1034
QWidget::QWidget(QWidget *parent, const char *name, Qt::WindowFlags f)
962
1035
: QObject(*new QWidgetPrivate, 0), QPaintDevice()
964
d_func()->init(parent , f);
965
setObjectName(QString::fromAscii(name));
1038
d_func()->init(parent , f);
1039
setObjectName(QString::fromAscii(name));
1041
QWidgetExceptionCleaner::cleanup(this, d_func());
1043
1127
void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
1046
if (qApp->type() == QApplication::Tty)
1130
if (QApplication::type() == QApplication::Tty)
1047
1131
qFatal("QWidget: Cannot create a QWidget when no GUI is being used");
1049
Q_ASSERT(uncreatedWidgets);
1050
uncreatedWidgets->insert(q);
1133
Q_ASSERT(allWidgets);
1134
allWidgets->insert(q);
1052
1136
QWidget *desktopWidget = 0;
1053
1137
if (parentWidget && parentWidget->windowType() == Qt::Desktop) {
1336
1416
#ifdef QT3_SUPPORT
1337
1417
if (QApplicationPrivate::main_widget == this) { // reset main widget
1338
1418
QApplicationPrivate::main_widget = 0;
1419
QApplication::quit();
1426
// swallow this problem because we are in a destructor
1345
1429
d->setDirtyOpaqueRegion();
1347
if (isWindow() && isVisible() && internalWinId())
1349
#if defined(Q_WS_WIN) || defined(Q_WS_X11)
1350
else if (!internalWinId() && isVisible())
1351
qApp->d_func()->sendSyntheticEnterLeave(this);
1431
if (isWindow() && isVisible() && internalWinId()) {
1433
d->close_helper(QWidgetPrivate::CloseNoEvent);
1435
// if we're out of memory, at least hide the window.
1439
// and if that also doesn't work, then give up
1444
#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS)
1445
else if (!internalWinId() && isVisible()) {
1446
qApp->d_func()->sendSyntheticEnterLeave(this);
1448
} else if (isVisible()) {
1449
qApp->d_func()->sendSyntheticEnterLeave(this);
1354
1454
if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
1363
1463
// set all QPointers for this object to zero
1364
1464
QObjectPrivate::clearGuards(this);
1466
if (d->declarativeData) {
1467
d->declarativeData->destroyed(this);
1468
d->declarativeData = 0; // don't activate again in ~QObject
1366
1471
if (!d->children.isEmpty())
1367
1472
d->deleteChildren();
1369
1474
QApplication::removePostedEvents(this);
1371
destroy(); // platform-dependent cleanup
1477
destroy(); // platform-dependent cleanup
1479
// if this fails we can't do anything about it but at least we are not allowed to throw.
1373
1481
--QWidgetPrivate::instanceCounter;
1375
if (QWidgetPrivate::uncreatedWidgets) // might have been deleted by ~QApplication
1376
QWidgetPrivate::uncreatedWidgets->remove(this);
1483
if (QWidgetPrivate::allWidgets) // might have been deleted by ~QApplication
1484
QWidgetPrivate::allWidgets->remove(this);
1378
1486
QEvent e(QEvent::Destroy);
1379
1487
QCoreApplication::sendEvent(this, &e);
1413
1519
if (!extra->topextra) {
1414
1520
QTLWExtra* x = extra->topextra = new QTLWExtra;
1523
x->backingStore = 0;
1415
1524
x->windowSurface = 0;
1525
x->sharedPainter = 0;
1526
x->incw = x->inch = 0;
1527
x->basew = x->baseh = 0;
1528
x->frameStrut.setCoords(0, 0, 0, 0);
1529
x->normalGeometry = QRect(0,0,-1,-1);
1416
1531
x->opacity = 255;
1417
1532
x->posFromMove = false;
1418
1533
x->sizeAdjusted = false;
1419
1534
x->inTopLevelResize = false;
1420
1535
x->inRepaint = false;
1421
x->backingStore = 0;
1424
x->frameStrut.setCoords(0, 0, 0, 0);
1425
x->incw = x->inch = 0;
1426
x->basew = x->baseh = 0;
1427
x->normalGeometry = QRect(0,0,-1,-1);
1428
#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC)
1429
1536
x->embedded = 0;
1431
#if defined(Q_WS_X11)
1433
x->spont_unmapped = 0;
1437
#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER)
1440
x->sharedPainter = 0;
1441
1537
createTLSysExtra();
1442
1538
#ifdef QWIDGET_EXTRA_DEBUG
1443
static int count = 0;
1444
qDebug() << "tlextra" << ++count;
1539
static int count = 0;
1540
qDebug() << "tlextra" << ++count;
1456
1552
if (!extra) { // if not exists
1457
1553
extra = new QWExtra;
1458
extra->minw = extra->minh = 0;
1459
extra->maxw = extra->maxh = QWIDGETSIZE_MAX;
1554
extra->glContext = 0;
1555
extra->topextra = 0;
1556
extra->proxyWidget = 0;
1557
#ifndef QT_NO_CURSOR
1562
extra->maxw = QWIDGETSIZE_MAX;
1563
extra->maxh = QWIDGETSIZE_MAX;
1564
extra->customDpiX = 0;
1565
extra->customDpiY = 0;
1460
1566
extra->explicitMinSize = 0;
1461
1567
extra->explicitMaxSize = 0;
1462
1568
extra->autoFillBackground = 0;
1463
1569
extra->nativeChildrenForced = 0;
1464
1570
extra->inRenderWithPainter = 0;
1465
1571
extra->hasMask = 0;
1466
#ifndef QT_NO_CURSOR
1470
extra->topextra = 0;
1471
extra->proxyWidget = 0;
1472
extra->glContext = 0;
1473
extra->customDpiX = 0;
1474
extra->customDpiY = 0;
1475
1572
createSysExtra();
1476
1573
#ifdef QWIDGET_EXTRA_DEBUG
1477
static int count = 0;
1478
qDebug() << "extra" << ++count;
1574
static int count = 0;
1575
qDebug() << "extra" << ++count;
1519
Returns true if the background is inherited; otherwise returns
1522
Mainly used in the paintOnScreen case.
1525
bool QWidgetPrivate::isBackgroundInherited() const
1529
// windows do not inherit their background
1530
if (q->isWindow() || q->windowType() == Qt::SubWindow)
1533
if (q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_OpaquePaintEvent))
1536
const QPalette &pal = q->palette();
1537
QPalette::ColorRole bg = q->backgroundRole();
1538
QBrush brush = pal.brush(bg);
1540
// non opaque brushes leaves us no choice, we must inherit
1541
if (!q->autoFillBackground() || !brush.isOpaque())
1544
if (brush.style() == Qt::SolidPattern) {
1545
// the background is just a solid color. If there is no
1546
// propagated contents, then we claim as performance
1547
// optimization that it was not inheritet. This is the normal
1548
// case in standard Windows or Motif style.
1549
const QWidget *w = q->parentWidget();
1550
if (!w->d_func()->isBackgroundInherited())
1558
1616
Returns true if there are widgets above this which overlap with
1559
1617
\a rect, which is in parent's coordinate system (same as crect).
1823
1881
QWidgetPrivate *pd = w->parentWidget()->d_func();
1824
1882
const int myIndex = pd->children.indexOf(const_cast<QWidget *>(w));
1883
const QRect widgetGeometry = w->d_func()->effectiveRectFor(w->data->crect);
1825
1884
for (int i = myIndex + 1; i < pd->children.size(); ++i) {
1826
1885
QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i));
1827
1886
if (!sibling || !sibling->isVisible() || sibling->isWindow())
1830
if (!qRectIntersects(sibling->data->crect, w->data->crect))
1889
const QRect siblingGeometry = sibling->d_func()->effectiveRectFor(sibling->data->crect);
1890
if (!qRectIntersects(siblingGeometry, widgetGeometry))
1833
1893
if (dirtyClipBoundingRect) {
1847
1907
const QRect siblingClipRect(sibling->d_func()->clipRect());
1848
1908
QRegion siblingDirty(parentClip);
1849
1909
siblingDirty &= (siblingClipRect.translated(siblingPos));
1850
const bool hasMask = sibling->d_func()->extra && sibling->d_func()->extra->hasMask;
1910
const bool hasMask = sibling->d_func()->extra && sibling->d_func()->extra->hasMask
1911
&& !sibling->d_func()->graphicsEffect;
1852
1913
siblingDirty &= sibling->d_func()->extra->mask.translated(siblingPos);
1853
1914
if (siblingDirty.isEmpty())
1903
bool QWidgetPrivate::hasBackground() const
1906
if (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_PaintOnScreen))
1908
if (q->testAttribute(Qt::WA_PaintOnScreen))
1910
if (!q->testAttribute(Qt::WA_OpaquePaintEvent) && !q->testAttribute(Qt::WA_NoSystemBackground)) {
1911
const QPalette &pal = q->palette();
1912
QPalette::ColorRole bg = q->backgroundRole();
1913
QBrush bgBrush = pal.brush(bg);
1914
return (bgBrush.style() != Qt::NoBrush &&
1915
((q->isWindow() || q->windowType() == Qt::SubWindow)
1916
|| (QPalette::ColorRole(bg_role) != QPalette::NoRole || (pal.resolve() & (1<<bg)))));
1921
1969
bool QWidgetPrivate::paintOnScreen() const
1923
1971
#if defined(Q_WS_QWS)
2032
2091
// Optimize pattern filling on mac by using HITheme directly
2033
2092
// when filling with the standard widget background.
2034
2093
// Defined in qmacstyle_mac.cpp
2035
extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QPoint &offset, const QBrush &brush);
2036
qt_mac_fill_background(painter, rgn, offset, brush);
2094
extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush);
2095
qt_mac_fill_background(painter, rgn, brush);
2038
const QRegion translated = rgn.translated(offset);
2039
const QRect rect(translated.boundingRect());
2040
painter->setClipRegion(translated);
2041
painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
2097
#if !defined(QT_NO_STYLE_S60)
2098
// Defined in qs60style.cpp
2099
extern bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush);
2100
if (!qt_s60_fill_background(painter, rgn, brush))
2101
#endif // !defined(QT_NO_STYLE_S60)
2103
const QRect rect(rgn.boundingRect());
2104
painter->setClipRegion(rgn);
2105
painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
2109
} else if (brush.gradient()
2110
&& brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode) {
2112
painter->setClipRegion(rgn);
2113
painter->fillRect(0, 0, painter->device()->width(), painter->device()->height(), brush);
2044
2116
const QVector<QRect> &rects = rgn.rects();
2045
2117
for (int i = 0; i < rects.size(); ++i)
2046
painter->fillRect(rects.at(i).translated(offset), brush);
2118
painter->fillRect(rects.at(i), brush);
2051
void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, const QPoint &offset, int flags) const
2122
void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const
2053
2124
Q_Q(const QWidget);
2126
#ifndef QT_NO_SCROLLAREA
2127
bool resetBrushOrigin = false;
2128
QPointF oldBrushOrigin;
2129
//If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture
2130
QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent);
2131
if (scrollArea && scrollArea->viewport() == q) {
2132
QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr.data();
2133
QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate);
2134
oldBrushOrigin = painter->brushOrigin();
2135
resetBrushOrigin = true;
2136
painter->setBrushOrigin(-priv->contentsOffset());
2139
#endif // QT_NO_SCROLLAREA
2055
2141
const QBrush autoFillBrush = q->palette().brush(q->backgroundRole());
2057
2143
if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) {
2060
2146
if (!(flags & DontSetCompositionMode) && painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff))
2061
2147
painter->setCompositionMode(QPainter::CompositionMode_Source); //copy alpha straight in
2063
fillRegion(painter, rgn, offset, bg);
2149
fillRegion(painter, rgn, bg);
2066
2152
if (q->autoFillBackground())
2067
fillRegion(painter, rgn, offset, autoFillBrush);
2153
fillRegion(painter, rgn, autoFillBrush);
2069
2155
if (q->testAttribute(Qt::WA_StyledBackground)) {
2070
painter->setClipRegion(rgn.translated(offset));
2156
painter->setClipRegion(rgn);
2071
2157
QStyleOption opt;
2072
2158
opt.initFrom(q);
2073
2159
q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q);
2162
#ifndef QT_NO_SCROLLAREA
2163
if (resetBrushOrigin)
2164
painter->setBrushOrigin(oldBrushOrigin);
2165
#endif // QT_NO_SCROLLAREA
2962
3053
if (q->testAttribute(Qt::WA_SetCursor) || q->isWindow()) {
2963
3054
// enforce the windows behavior of clearing the cursor on
2964
3055
// disabled widgets
2965
extern void qt_x11_enforce_cursor(QWidget * w); // defined in qwidget_x11.cpp
2966
3056
qt_x11_enforce_cursor(q);
2969
3059
#if defined(Q_WS_MAC)
2970
3060
setEnabled_helper_sys(enable);
2972
#if defined (Q_WS_WIN)
2974
QInputContextPrivate::updateImeStatus(q, true);
3062
if (q->testAttribute(Qt::WA_InputMethodEnabled) && q->hasFocus()) {
3063
QInputContext *qic = inputContext();
3065
qic->setFocusWidget(q);
3068
qic->setFocusWidget(0);
2976
3071
QEvent e(QEvent::EnabledChange);
2977
3072
QApplication::sendEvent(q, &e);
2978
3073
#ifdef QT3_SUPPORT
3228
3323
\property QWidget::width
3229
3324
\brief the width of the widget excluding any window frame
3231
See the \link geometry.html Window Geometry documentation\endlink
3232
for an overview of window geometry.
3326
See the \l{Window Geometry} documentation for an overview of geometry
3327
issues with windows.
3234
3329
\note Do not use this function to find the width of a screen on
3235
3330
a \l{QDesktopWidget}{multiple screen desktop}. Read
3236
\l{multiple screens note}{this note} for details.
3331
\l{QDesktopWidget#Screen Geometry}{this note} for details.
3238
3333
By default, this property contains a value that depends on the user's
3239
3334
platform and screen geometry.
3245
3340
\property QWidget::height
3246
3341
\brief the height of the widget excluding any window frame
3248
See the \link geometry.html Window Geometry documentation\endlink
3249
for an overview of window geometry.
3343
See the \l{Window Geometry} documentation for an overview of geometry
3344
issues with windows.
3251
3346
\note Do not use this function to find the height of a screen
3252
on a \l {QDesktopWidget} {multiple screen desktop}. Read
3253
\l {multiple screens note} {this note} for details.
3347
on a \l{QDesktopWidget}{multiple screen desktop}. Read
3348
\l{QDesktopWidget#Screen Geometry}{this note} for details.
3255
3350
By default, this property contains a value that depends on the user's
3256
3351
platform and screen geometry.
3604
int mw = minw, mh = minh;
3605
if (mw == QWIDGETSIZE_MAX)
3607
if (mh == QWIDGETSIZE_MAX)
3509
3609
if (minw > QWIDGETSIZE_MAX || minh > QWIDGETSIZE_MAX) {
3510
3610
qWarning("QWidget::setMinimumSize: (%s/%s) "
3511
3611
"The largest allowed size is (%d,%d)",
3512
3612
q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
3513
3613
QWIDGETSIZE_MAX);
3514
minw = qMin<int>(minw, QWIDGETSIZE_MAX);
3515
minh = qMin<int>(minh, QWIDGETSIZE_MAX);
3614
minw = mw = qMin<int>(minw, QWIDGETSIZE_MAX);
3615
minh = mh = qMin<int>(minh, QWIDGETSIZE_MAX);
3517
3617
if (minw < 0 || minh < 0) {
3518
3618
qWarning("QWidget::setMinimumSize: (%s/%s) Negative sizes (%d,%d) "
3519
3619
"are not possible",
3520
3620
q->objectName().toLocal8Bit().data(), q->metaObject()->className(), minw, minh);
3521
minw = qMax(minw, 0);
3522
minh = qMax(minh, 0);
3621
minw = mw = qMax(minw, 0);
3622
minh = mh = qMax(minh, 0);
3525
if (extra->minw == minw && extra->minh == minh)
3625
if (extra->minw == mw && extra->minh == mh)
3529
extra->explicitMinSize = (minw ? Qt::Horizontal : 0) | (minh ? Qt::Vertical : 0);
3629
extra->explicitMinSize = (mw ? Qt::Horizontal : 0) | (mh ? Qt::Vertical : 0);
4859
4977
d->extra->inRenderWithPainter = false;
4981
\brief The graphicsEffect function returns a pointer to the
4982
widget's graphics effect.
4984
If the widget has no graphics effect, 0 is returned.
4988
\sa setGraphicsEffect()
4990
QGraphicsEffect *QWidget::graphicsEffect() const
4993
return d->graphicsEffect;
4998
\brief The setGraphicsEffect function is for setting the widget's graphics effect.
5000
Sets \a effect as the widget's effect. If there already is an effect installed
5001
on this widget, QWidget will delete the existing effect before installing
5004
If \a effect is the installed on a different widget, setGraphicsEffect() will remove
5005
the effect from the widget and install it on this widget.
5007
\note This function will apply the effect on itself and all its children.
5011
\sa graphicsEffect()
5013
void QWidget::setGraphicsEffect(QGraphicsEffect *effect)
5016
if (d->graphicsEffect == effect)
5019
if (d->graphicsEffect && effect) {
5020
delete d->graphicsEffect;
5021
d->graphicsEffect = 0;
5025
// Unset current effect.
5026
QGraphicsEffectPrivate *oldEffectPrivate = d->graphicsEffect->d_func();
5027
d->graphicsEffect = 0;
5028
if (oldEffectPrivate) {
5029
oldEffectPrivate->setGraphicsEffectSource(0); // deletes the current source.
5033
QGraphicsEffectSourcePrivate *sourced = new QWidgetEffectSourcePrivate(this);
5034
QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
5035
d->graphicsEffect = effect;
5036
effect->d_func()->setGraphicsEffectSource(source);
5039
d->updateIsOpaque();
4862
5043
bool QWidgetPrivate::isAboutToShow() const
4864
5045
if (data.in_show)
5188
if (graphicsEffect && graphicsEffect->isEnabled()) {
5189
QGraphicsEffectSource *source = graphicsEffect->d_func()->source;
5190
QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
5192
if (!sourced->context) {
5193
QWidgetPaintContext context(pdev, rgn, offset, flags, sharedPainter, backingStore);
5194
sourced->context = &context;
5195
if (!sharedPainter) {
5196
QPaintEngine *paintEngine = pdev->paintEngine();
5197
paintEngine->d_func()->systemClip = rgn.translated(offset);
5199
p.translate(offset);
5200
context.painter = &p;
5201
graphicsEffect->draw(&p, source);
5202
paintEngine->d_func()->systemClip = QRegion();
5204
context.painter = sharedPainter;
5205
sharedPainter->save();
5206
sharedPainter->translate(offset);
5207
graphicsEffect->draw(sharedPainter, source);
5208
sharedPainter->restore();
5210
sourced->context = 0;
5006
5215
const bool asRoot = flags & DrawAsRoot;
5007
5216
const bool alsoOnScreen = flags & DrawPaintOnScreen;
5008
5217
const bool recursive = flags & DrawRecursive;
5035
5244
if (sharedPainter)
5036
5245
paintEngine->d_func()->systemClip = toBePainted;
5038
paintEngine->setSystemRect(q->data->crect);
5247
paintEngine->d_func()->systemRect = q->data->crect;
5040
5249
//paint the background
5041
5250
if ((asRoot || q->autoFillBackground() || onScreen || q->testAttribute(Qt::WA_StyledBackground))
5042
5251
&& !q->testAttribute(Qt::WA_OpaquePaintEvent) && !q->testAttribute(Qt::WA_NoSystemBackground)) {
5045
QPoint scrollAreaOffset;
5047
#ifndef QT_NO_SCROLLAREA
5048
QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(q->parent());
5049
if (scrollArea && scrollArea->viewport() == q) {
5050
QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr;
5051
QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate);
5052
scrollAreaOffset = priv->contentsOffset();
5053
p.translate(-scrollAreaOffset);
5055
#endif // QT_NO_SCROLLAREA
5057
paintBackground(&p, toBePainted, scrollAreaOffset, (asRoot || onScreen) ? flags | DrawAsRoot : 0);
5254
paintBackground(&p, toBePainted, (asRoot || onScreen) ? flags | DrawAsRoot : 0);
5060
5257
if (!sharedPainter)
5390
QRectF QWidgetEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
5392
if (system != Qt::DeviceCoordinates)
5393
return m_widget->rect();
5396
// Device coordinates without context not yet supported.
5397
qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
5401
return context->painter->worldTransform().mapRect(m_widget->rect());
5404
void QWidgetEffectSourcePrivate::draw(QPainter *painter)
5406
if (!context || context->painter != painter) {
5407
m_widget->render(painter);
5411
// The region saved in the context is neither clipped to the rect
5412
// nor the mask, so we have to clip it here before calling drawWidget.
5413
QRegion toBePainted = context->rgn;
5414
toBePainted &= m_widget->rect();
5415
QWidgetPrivate *wd = qt_widget_private(m_widget);
5416
if (wd->extra && wd->extra->hasMask)
5417
toBePainted &= wd->extra->mask;
5419
wd->drawWidget(context->pdev, toBePainted, context->offset, context->flags,
5420
context->sharedPainter, context->backingStore);
5423
QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset) const
5425
const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
5426
if (!context && deviceCoordinates) {
5427
// Device coordinates without context not yet supported.
5428
qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
5432
QPoint pixmapOffset;
5433
QRectF sourceRect = m_widget->rect();
5435
if (deviceCoordinates) {
5436
const QTransform &painterTransform = context->painter->worldTransform();
5437
sourceRect = painterTransform.mapRect(sourceRect);
5438
pixmapOffset = painterTransform.map(pixmapOffset);
5441
QRect effectRect = m_widget->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect();
5443
*offset = effectRect.topLeft();
5445
if (deviceCoordinates) {
5446
// Clip to device rect.
5447
int left, top, right, bottom;
5448
effectRect.getCoords(&left, &top, &right, &bottom);
5451
offset->rx() += -left;
5456
offset->ry() += -top;
5459
// NB! We use +-1 for historical reasons (see QRect documentation).
5460
QPaintDevice *device = context->painter->device();
5461
const int deviceWidth = device->width();
5462
const int deviceHeight = device->height();
5463
if (right + 1 > deviceWidth)
5464
effectRect.setRight(deviceWidth - 1);
5465
if (bottom + 1 > deviceHeight)
5466
effectRect.setBottom(deviceHeight -1);
5469
pixmapOffset -= effectRect.topLeft();
5471
QPixmap pixmap(effectRect.size());
5472
pixmap.fill(Qt::transparent);
5473
m_widget->render(&pixmap, pixmapOffset);
5334
5629
QString cap = title;
5337
QString placeHolder(QLatin1String("[*]"));
5635
QLatin1String placeHolder("[*]");
5636
int placeHolderLength = 3; // QLatin1String doesn't have length()
5339
5638
int index = cap.indexOf(placeHolder);
5640
// here the magic begins
5341
5641
while (index != -1) {
5342
index += placeHolder.length();
5642
index += placeHolderLength;
5344
5644
while (cap.indexOf(placeHolder, index) == index) {
5346
index += placeHolder.length();
5646
index += placeHolderLength;
5349
5649
if (count%2) { // odd number of [*] -> replace last one
5352
5652
&& widget->style()->styleHint(QStyle::SH_TitleBar_ModifyNotification, 0, widget))
5353
5653
cap.replace(lastIndex, 3, QWidget::tr("*"));
5355
cap.replace(lastIndex, 3, QLatin1String(""));
5655
cap.remove(lastIndex, 3);
5358
5658
index = cap.indexOf(placeHolder, index);
5361
cap.replace(QLatin1String("[*][*]"), QLatin1String("[*]"));
5661
cap.replace(QLatin1String("[*][*]"), placeHolder);
5670
5968
isActiveWindow() active window\endlink. The \a reason argument will
5671
5969
be passed into any focus event sent from this function, it is used
5672
5970
to give an explanation of what caused the widget to get focus.
5971
If the window is not active, the widget will be given the focus when
5972
the window becomes active.
5674
5974
First, a focus out event is sent to the focus widget (if any) to
5675
5975
tell it that it is about to lose the focus. Then a focus in event
5687
5987
called from focusOutEvent() or focusInEvent(), you may get an
5688
5988
infinite recursion.
5690
\sa focus(), hasFocus(), clearFocus(), focusInEvent(), focusOutEvent(),
5990
\sa hasFocus(), clearFocus(), focusInEvent(), focusOutEvent(),
5691
5991
setFocusPolicy(), focusWidget(), QApplication::focusWidget(), grabKeyboard(),
5692
5992
grabMouse(), {Keyboard Focus}
5947
6262
if(qt_mac_is_macdrawer(tlw) &&
5948
6263
tlw->parentWidget() && tlw->parentWidget()->isActiveWindow())
6266
extern bool qt_mac_insideKeyWindow(const QWidget *); //qwidget_mac.cpp
6267
if (QApplication::testAttribute(Qt::AA_MacPluginApplication) && qt_mac_insideKeyWindow(tlw))
5951
6270
if(style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, this)) {
5952
6271
if(tlw->windowType() == Qt::Tool &&
5953
6272
!tlw->isModal() &&
5954
6273
(!tlw->parentWidget() || tlw->parentWidget()->isActiveWindow()))
5956
QWidget *w = qApp->activeWindow();
6275
QWidget *w = QApplication::activeWindow();
5957
6276
while(w && tlw->windowType() == Qt::Tool &&
5958
6277
!w->isModal() && w->parentWidget()) {
5959
6278
w = w->parentWidget()->window();
6411
Sets the margins around the contents of the widget to have the
6412
sizes \a left, \a top, \a right, and \a bottom. The margins are
6413
used by the layout system, and may be used by subclasses to
6414
specify the area to draw in (e.g. excluding the frame).
6416
Changing the margins will trigger a resizeEvent().
6418
\sa contentsRect(), getContentsMargins()
6724
Sets the margins around the contents of the widget to have the sizes
6725
\a left, \a top, \a right, and \a bottom. The margins are used by
6726
the layout system, and may be used by subclasses to specify the area
6727
to draw in (e.g. excluding the frame).
6729
Changing the margins will trigger a resizeEvent().
6731
\sa contentsRect(), getContentsMargins()
6420
6733
void QWidget::setContentsMargins(int left, int top, int right, int bottom)
6446
6759
QApplication::sendEvent(this, &e);
6449
/*! Returns the widget's contents margins for \a left, \a top, \a
6766
\brief The setContentsMargins function sets the margins around the
6769
Sets the margins around the contents of the widget to have the
6770
sizes determined by \a margins. The margins are
6771
used by the layout system, and may be used by subclasses to
6772
specify the area to draw in (e.g. excluding the frame).
6774
Changing the margins will trigger a resizeEvent().
6776
\sa contentsRect(), getContentsMargins()
6778
void QWidget::setContentsMargins(const QMargins &margins)
6780
setContentsMargins(margins.left(), margins.top(),
6781
margins.right(), margins.bottom());
6785
Returns the widget's contents margins for \a left, \a top, \a
6450
6786
right, and \a bottom.
6452
6788
\sa setContentsMargins(), contentsRect()
6806
\brief The contentsMargins function returns the widget's contents margins.
6808
\sa getContentsMargins(), setContentsMargins(), contentsRect()
6810
QMargins QWidget::contentsMargins() const
6813
return QMargins(d->leftmargin, d->topmargin, d->rightmargin, d->bottommargin);
6468
6818
Returns the area inside the widget's margins.
6470
6820
\sa setContentsMargins(), getContentsMargins()
7585
7940
#ifdef QT_KEYPAD_NAVIGATION
7586
7941
if (!k->isAccepted() && QApplication::keypadNavigationEnabled()
7587
7942
&& !(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::ShiftModifier))) {
7588
if (k->key() == Qt::Key_Up)
7589
res = focusNextPrevChild(false);
7590
else if (k->key() == Qt::Key_Down)
7591
res = focusNextPrevChild(true);
7943
if (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder) {
7944
if (k->key() == Qt::Key_Up)
7945
res = focusNextPrevChild(false);
7946
else if (k->key() == Qt::Key_Down)
7947
res = focusNextPrevChild(true);
7948
} else if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
7949
if (k->key() == Qt::Key_Up)
7950
res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionNorth);
7951
else if (k->key() == Qt::Key_Right)
7952
res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionEast);
7953
else if (k->key() == Qt::Key_Down)
7954
res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionSouth);
7955
else if (k->key() == Qt::Key_Left)
7956
res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionWest);
7836
8205
QList<QObject*> childList = d->children;
7837
8206
for (int i = 0; i < childList.size(); ++i) {
7838
8207
QObject *o = childList.at(i);
7839
if (o != qApp->activeModalWidget()) {
8208
if (o != QApplication::activeModalWidget()) {
7840
8209
if (qobject_cast<QWidget *>(o) && static_cast<QWidget *>(o)->isWindow()) {
7841
8210
// do not forward the event to child windows,
7842
8211
// QApplication does this for us
7925
8297
d->needWindowChange = false;
8300
case QEvent::TouchBegin:
8301
case QEvent::TouchUpdate:
8302
case QEvent::TouchEnd:
8304
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
8305
const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().first();
8306
if (touchPoint.isPrimary())
8309
// fake a mouse event!
8310
QEvent::Type eventType = QEvent::None;
8311
switch (touchEvent->type()) {
8312
case QEvent::TouchBegin:
8313
eventType = QEvent::MouseButtonPress;
8315
case QEvent::TouchUpdate:
8316
eventType = QEvent::MouseMove;
8318
case QEvent::TouchEnd:
8319
eventType = QEvent::MouseButtonRelease;
8325
if (eventType == QEvent::None)
8328
QMouseEvent mouseEvent(eventType,
8329
touchPoint.pos().toPoint(),
8330
touchPoint.screenPos().toPoint(),
8333
touchEvent->modifiers());
8334
(void) QApplication::sendEvent(this, &mouseEvent);
8337
case QEvent::Gesture:
7928
8340
#ifndef QT_NO_PROPERTIES
7929
8341
case QEvent::DynamicPropertyChange: {
7930
8342
const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName();
8480
8896
return QRect(width()/2, 0, 1, height());
8481
8897
case Qt::ImFont:
8899
case Qt::ImAnchorPosition:
8901
return inputMethodQuery(Qt::ImCursorPosition);
8484
8903
return QVariant();
8908
\property QWidget::inputMethodHints
8909
\brief What input method specific hints the widget has.
8911
This is only relevant for input widgets. It is used by
8912
the input method to retrieve hints as to how the input method
8913
should operate. For example, if the Qt::ImhFormattedNumbersOnly flag
8914
is set, the input method may change its visual components to reflect
8915
that only numbers can be entered.
8917
\note The flags are only hints, so the particular input method
8918
implementation is free to ignore them. If you want to be
8919
sure that a certain type of characters are entered,
8920
you should also set a QValidator on the widget.
8922
The default value is Qt::ImhNone.
8926
\sa inputMethodQuery(), QInputContext
8928
Qt::InputMethodHints QWidget::inputMethodHints() const
8934
void QWidget::setInputMethodHints(Qt::InputMethodHints hints)
8938
// Optimisation to update input context only it has already been created.
8939
if (d->ic || qApp->d_func()->inputContext) {
8940
QInputContext *ic = inputContext();
8488
8947
#ifndef QT_NO_DRAGANDDROP
9256
9715
d->resolveLayoutDirection();
9257
9716
d->resolveLocale();
9259
// Note: GL widgets under Windows will always need a ParentChange
9260
// event to handle recreation/rebinding of the GL context, hence
9261
// the (f & Qt::MSWindowsOwnDC) clause
9718
// Note: GL widgets under WGL or EGL will always need a ParentChange
9719
// event to handle recreation/rebinding of the GL context, hence the
9720
// (f & Qt::MSWindowsOwnDC) clause (which is set on QGLWidgets on all
9723
#if defined(Q_WS_WIN) || defined(QT_OPENGL_ES)
9264
9724
|| (f & Qt::MSWindowsOwnDC)
9806
10271
QEvent e(QEvent::MouseTrackingChange);
9807
10272
QApplication::sendEvent(this, &e);
9809
#if !defined(QT_NO_DIRECT3D) && defined(Q_WS_WIN)
9810
case Qt::WA_MSWindowsUseDirect3D:
9811
if (!qApp->testAttribute(Qt::AA_MSWindowsUseDirect3DByDefault)) {
9815
d->extra->had_auto_fill_bg = d->extra->autoFillBackground;
9816
d->extra->had_no_system_bg = testAttribute(Qt::WA_NoSystemBackground);
9817
d->extra->had_paint_on_screen = testAttribute(Qt::WA_PaintOnScreen);
9818
// enforce the opaque widget state D3D needs
9819
d->extra->autoFillBackground = true;
9820
setAttribute(Qt::WA_PaintOnScreen);
9821
setAttribute(Qt::WA_NoSystemBackground);
9822
} else if (d->extra) {
9823
d->extra->autoFillBackground = d->extra->had_auto_fill_bg;
9824
setAttribute(Qt::WA_PaintOnScreen, d->extra->had_paint_on_screen);
9825
setAttribute(Qt::WA_NoSystemBackground, d->extra->had_no_system_bg);
9830
10274
case Qt::WA_NativeWindow: {
9831
10275
QInputContext *ic = 0;
9832
10276
if (on && !internalWinId() && testAttribute(Qt::WA_InputMethodEnabled) && hasFocus()) {
9871
10315
case Qt::WA_InputMethodEnabled: {
9872
#if defined(Q_WS_WIN) || (defined(Q_WS_QWS) && !defined(QT_NO_QWS_INPUTMETHODS))
9874
QInputContextPrivate::updateImeStatus(this, true);
9876
10316
QInputContext *ic = d->ic;
9878
// implicitly create input context only if we have a focus
9880
ic = d->inputContext();
10317
if (!ic && (!on || hasFocus()))
10318
ic = d->inputContext();
9883
if (on && hasFocus() && ic->focusWidget() != this) {
10320
if (on && hasFocus() && ic->focusWidget() != this && isEnabled()) {
9884
10321
ic->setFocusWidget(this);
9885
10322
} else if (!on && ic->focusWidget() == this) {
9988
10431
By default the value of this property is 1.0.
9990
This feature is available on Embedded Linux, Mac OS X, X11 platforms that
9991
support the Composite extension, and Windows 2000 and later.
10433
This feature is available on Embedded Linux, Mac OS X, Windows,
10434
and X11 platforms that support the Composite extension.
9993
10436
This feature is not available on Windows CE.
10959
11402
return maybeTopData() ? maybeTopData()->frameStrut : QRect();
11405
#ifdef QT_KEYPAD_NAVIGATION
11409
Changes the focus from the current focusWidget to a widget in
11412
Returns true, if there was a widget in that direction
11414
bool QWidgetPrivate::navigateToDirection(Direction direction)
11416
QWidget *targetWidget = widgetInNavigationDirection(direction);
11418
targetWidget->setFocus();
11419
return (targetWidget != 0);
11425
Searches for a widget that is positioned in the \a direction, starting
11426
from the current focusWidget.
11428
Returns the pointer to a found widget or 0, if there was no widget in
11431
QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction)
11433
const QWidget *sourceWidget = QApplication::focusWidget();
11436
const QRect sourceRect = sourceWidget->rect().translated(sourceWidget->mapToGlobal(QPoint()));
11437
const int sourceX =
11438
(direction == DirectionNorth || direction == DirectionSouth) ?
11439
(sourceRect.left() + (sourceRect.right() - sourceRect.left()) / 2)
11440
:(direction == DirectionEast ? sourceRect.right() : sourceRect.left());
11441
const int sourceY =
11442
(direction == DirectionEast || direction == DirectionWest) ?
11443
(sourceRect.top() + (sourceRect.bottom() - sourceRect.top()) / 2)
11444
:(direction == DirectionSouth ? sourceRect.bottom() : sourceRect.top());
11445
const QPoint sourcePoint(sourceX, sourceY);
11446
const QPoint sourceCenter = sourceRect.center();
11447
const QWidget *sourceWindow = sourceWidget->window();
11449
QWidget *targetWidget = 0;
11450
int shortestDistance = INT_MAX;
11451
foreach(QWidget *targetCandidate, QApplication::allWidgets()) {
11453
const QRect targetCandidateRect = targetCandidate->rect().translated(targetCandidate->mapToGlobal(QPoint()));
11455
// For focus proxies, the child widget handling the focus can have keypad navigation focus,
11456
// but the owner of the proxy cannot.
11457
// Additionally, empty widgets should be ignored.
11458
if (targetCandidate->focusProxy() || targetCandidateRect.isEmpty())
11461
// Only navigate to a target widget that...
11462
if ( targetCandidate != sourceWidget
11463
// ...takes the focus,
11464
&& targetCandidate->focusPolicy() & Qt::TabFocus
11465
// ...is above if DirectionNorth,
11466
&& !(direction == DirectionNorth && targetCandidateRect.bottom() > sourceRect.top())
11467
// ...is on the right if DirectionEast,
11468
&& !(direction == DirectionEast && targetCandidateRect.left() < sourceRect.right())
11469
// ...is below if DirectionSouth,
11470
&& !(direction == DirectionSouth && targetCandidateRect.top() < sourceRect.bottom())
11471
// ...is on the left if DirectionWest,
11472
&& !(direction == DirectionWest && targetCandidateRect.right() > sourceRect.left())
11474
&& targetCandidate->isEnabled()
11476
&& targetCandidate->isVisible()
11477
// ...is in the same window,
11478
&& targetCandidate->window() == sourceWindow) {
11479
const int targetCandidateDistance = pointToRect(sourcePoint, targetCandidateRect);
11480
if (targetCandidateDistance < shortestDistance) {
11481
shortestDistance = targetCandidateDistance;
11482
targetWidget = targetCandidate;
11486
return targetWidget;