/**************************************************************************** | |
** | |
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). | |
** All rights reserved. | |
** Contact: Nokia Corporation (qt-info@nokia.com) | |
** | |
** This file is part of the QtGui module of the Qt Toolkit. | |
** | |
** $QT_BEGIN_LICENSE:LGPL$ | |
** GNU Lesser General Public License Usage | |
** This file may be used under the terms of the GNU Lesser General Public | |
** License version 2.1 as published by the Free Software Foundation and | |
** appearing in the file LICENSE.LGPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU Lesser | |
** General Public License version 2.1 requirements will be met: | |
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | |
** | |
** In addition, as a special exception, Nokia gives you certain additional | |
** rights. These rights are described in the Nokia Qt LGPL Exception | |
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | |
** | |
** GNU General Public License Usage | |
** Alternatively, this file may be used under the terms of the GNU General | |
** Public License version 3.0 as published by the Free Software Foundation | |
** and appearing in the file LICENSE.GPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU General | |
** Public License version 3.0 requirements will be met: | |
** http://www.gnu.org/copyleft/gpl.html. | |
** | |
** Other Usage | |
** Alternatively, this file may be used in accordance with the terms and | |
** conditions contained in a signed written agreement between you and Nokia. | |
** | |
** | |
** | |
** | |
** | |
** $QT_END_LICENSE$ | |
** | |
****************************************************************************/ | |
#include "qapplication.h" | |
#include "qapplication_p.h" | |
#include "qbrush.h" | |
#include "qcursor.h" | |
#include "qdesktopwidget.h" | |
#include "qevent.h" | |
#include "qhash.h" | |
#include "qlayout.h" | |
#include "qmenu.h" | |
#include "qmetaobject.h" | |
#include "qpixmap.h" | |
#include "qpointer.h" | |
#include "qstack.h" | |
#include "qstyle.h" | |
#include "qstylefactory.h" | |
#include "qvariant.h" | |
#include "qwidget.h" | |
#include "qstyleoption.h" | |
#ifndef QT_NO_ACCESSIBILITY | |
# include "qaccessible.h" | |
#endif | |
#if defined(Q_WS_WIN) | |
# include "qt_windows.h" | |
#endif | |
#ifdef Q_WS_MAC | |
# include "qt_mac_p.h" | |
# include "qt_cocoa_helpers_mac_p.h" | |
# include "qmainwindow.h" | |
# include "qtoolbar.h" | |
# include <private/qmainwindowlayout_p.h> | |
#endif | |
#if defined(Q_WS_QWS) | |
# include "qwsdisplay_qws.h" | |
# include "qwsmanager_qws.h" | |
# include "qpaintengine.h" // for PorterDuff | |
# include "private/qwindowsurface_qws_p.h" | |
#endif | |
#include "qpainter.h" | |
#include "qtooltip.h" | |
#include "qwhatsthis.h" | |
#include "qdebug.h" | |
#include "private/qstylesheetstyle_p.h" | |
#include "private/qstyle_p.h" | |
#include "private/qinputcontext_p.h" | |
#include "qfileinfo.h" | |
#include "private/qsoftkeymanager_p.h" | |
#if defined (Q_WS_WIN) | |
# include <private/qwininputcontext_p.h> | |
#endif | |
#if defined(Q_WS_X11) | |
# include <private/qpaintengine_x11_p.h> | |
# include "qx11info_x11.h" | |
#endif | |
#include <private/qgraphicseffect_p.h> | |
#include <private/qwindowsurface_p.h> | |
#include <private/qbackingstore_p.h> | |
#ifdef Q_WS_MAC | |
# include <private/qpaintengine_mac_p.h> | |
#endif | |
#include <private/qpaintengine_raster_p.h> | |
#if defined(Q_OS_SYMBIAN) | |
#include "private/qt_s60_p.h" | |
#endif | |
#include "qwidget_p.h" | |
#include "qaction_p.h" | |
#include "qlayout_p.h" | |
#include "QtGui/qgraphicsproxywidget.h" | |
#include "QtGui/qgraphicsscene.h" | |
#include "private/qgraphicsproxywidget_p.h" | |
#include "QtGui/qabstractscrollarea.h" | |
#include "private/qabstractscrollarea_p.h" | |
#include "private/qevent_p.h" | |
#include "private/qgraphicssystem_p.h" | |
#include "private/qgesturemanager_p.h" | |
#ifdef QT_KEYPAD_NAVIGATION | |
#include "qtabwidget.h" // Needed in inTabWidget() | |
#endif // QT_KEYPAD_NAVIGATION | |
#ifdef Q_WS_S60 | |
#include <aknappui.h> | |
#endif | |
// widget/widget data creation count | |
//#define QWIDGET_EXTRA_DEBUG | |
//#define ALIEN_DEBUG | |
QT_BEGIN_NAMESPACE | |
#if !defined(Q_WS_QWS) | |
static bool qt_enable_backingstore = true; | |
#endif | |
#ifdef Q_WS_X11 | |
// for compatibility with Qt 4.0 | |
Q_GUI_EXPORT void qt_x11_set_global_double_buffer(bool enable) | |
{ | |
qt_enable_backingstore = enable; | |
} | |
#endif | |
static inline bool qRectIntersects(const QRect &r1, const QRect &r2) | |
{ | |
return (qMax(r1.left(), r2.left()) <= qMin(r1.right(), r2.right()) && | |
qMax(r1.top(), r2.top()) <= qMin(r1.bottom(), r2.bottom())); | |
} | |
static inline bool hasBackingStoreSupport() | |
{ | |
#ifdef Q_WS_MAC | |
return QApplicationPrivate::graphicsSystem() != 0; | |
#else | |
return true; | |
#endif | |
} | |
#ifdef Q_WS_MAC | |
# define QT_NO_PAINT_DEBUG | |
#endif | |
extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp | |
extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp | |
/*! | |
\internal | |
\class QWidgetBackingStoreTracker | |
\brief Class which allows tracking of which widgets are using a given backing store | |
QWidgetBackingStoreTracker is a thin wrapper around a QWidgetBackingStore pointer, | |
which maintains a list of the QWidgets which are currently using the backing | |
store. This list is modified via the registerWidget and unregisterWidget functions. | |
*/ | |
QWidgetBackingStoreTracker::QWidgetBackingStoreTracker() | |
: m_ptr(0) | |
{ | |
} | |
QWidgetBackingStoreTracker::~QWidgetBackingStoreTracker() | |
{ | |
delete m_ptr; | |
} | |
/*! | |
\internal | |
Destroy the contained QWidgetBackingStore, if not null, and clear the list of | |
widgets using the backing store, then create a new QWidgetBackingStore, providing | |
the QWidget. | |
*/ | |
void QWidgetBackingStoreTracker::create(QWidget *widget) | |
{ | |
destroy(); | |
m_ptr = new QWidgetBackingStore(widget); | |
} | |
/*! | |
\internal | |
Destroy the contained QWidgetBackingStore, if not null, and clear the list of | |
widgets using the backing store. | |
*/ | |
void QWidgetBackingStoreTracker::destroy() | |
{ | |
delete m_ptr; | |
m_ptr = 0; | |
m_widgets.clear(); | |
} | |
/*! | |
\internal | |
Add the widget to the list of widgets currently using the backing store. | |
If the widget was already in the list, this function is a no-op. | |
*/ | |
void QWidgetBackingStoreTracker::registerWidget(QWidget *w) | |
{ | |
Q_ASSERT(m_ptr); | |
Q_ASSERT(w->internalWinId()); | |
Q_ASSERT(qt_widget_private(w)->maybeBackingStore() == m_ptr); | |
m_widgets.insert(w); | |
} | |
/*! | |
\internal | |
Remove the widget from the list of widgets currently using the backing store. | |
If the widget was in the list, and removing it causes the list to be empty, | |
the backing store is deleted. | |
If the widget was not in the list, this function is a no-op. | |
*/ | |
void QWidgetBackingStoreTracker::unregisterWidget(QWidget *w) | |
{ | |
if (m_widgets.remove(w) && m_widgets.isEmpty()) { | |
delete m_ptr; | |
m_ptr = 0; | |
} | |
} | |
/*! | |
\internal | |
Recursively remove widget and all of its descendents. | |
*/ | |
void QWidgetBackingStoreTracker::unregisterWidgetSubtree(QWidget *widget) | |
{ | |
unregisterWidget(widget); | |
foreach (QObject *child, widget->children()) | |
if (QWidget *childWidget = qobject_cast<QWidget *>(child)) | |
unregisterWidgetSubtree(childWidget); | |
} | |
QWidgetPrivate::QWidgetPrivate(int version) | |
: QObjectPrivate(version) | |
, extra(0) | |
, focus_next(0) | |
, focus_prev(0) | |
, focus_child(0) | |
, layout(0) | |
, needsFlush(0) | |
, redirectDev(0) | |
, widgetItem(0) | |
, extraPaintEngine(0) | |
, polished(0) | |
, graphicsEffect(0) | |
#if !defined(QT_NO_IM) | |
, imHints(Qt::ImhNone) | |
#endif | |
, inheritedFontResolveMask(0) | |
, inheritedPaletteResolveMask(0) | |
, leftmargin(0) | |
, topmargin(0) | |
, rightmargin(0) | |
, bottommargin(0) | |
, leftLayoutItemMargin(0) | |
, topLayoutItemMargin(0) | |
, rightLayoutItemMargin(0) | |
, bottomLayoutItemMargin(0) | |
, hd(0) | |
, size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred) | |
, fg_role(QPalette::NoRole) | |
, bg_role(QPalette::NoRole) | |
, dirtyOpaqueChildren(1) | |
, isOpaque(0) | |
, inDirtyList(0) | |
, isScrolled(0) | |
, isMoved(0) | |
, isGLWidget(0) | |
, usesDoubleBufferedGLContext(0) | |
#ifndef QT_NO_IM | |
, inheritsInputMethodHints(0) | |
#endif | |
, inSetParent(0) | |
#if defined(Q_WS_X11) | |
, picture(0) | |
#elif defined(Q_WS_WIN) | |
, noPaintOnScreen(0) | |
#ifndef QT_NO_GESTURES | |
, nativeGesturePanEnabled(0) | |
#endif | |
#elif defined(Q_WS_MAC) | |
, needWindowChange(0) | |
, hasAlienChildren(0) | |
, window_event(0) | |
, qd_hd(0) | |
#elif defined(Q_OS_SYMBIAN) | |
, symbianScreenNumber(0) | |
, fixNativeOrientationCalled(false) | |
#endif | |
{ | |
if (!qApp) { | |
qFatal("QWidget: Must construct a QApplication before a QPaintDevice"); | |
return; | |
} | |
if (version != QObjectPrivateVersion) | |
qFatal("Cannot mix incompatible Qt libraries"); | |
isWidget = true; | |
memset(high_attributes, 0, sizeof(high_attributes)); | |
#if QT_MAC_USE_COCOA | |
drawRectOriginalAdded = false; | |
originalDrawMethod = true; | |
changeMethods = false; | |
#endif // QT_MAC_USE_COCOA | |
#ifdef QWIDGET_EXTRA_DEBUG | |
static int count = 0; | |
qDebug() << "widgets" << ++count; | |
#endif | |
} | |
QWidgetPrivate::~QWidgetPrivate() | |
{ | |
if (widgetItem) | |
widgetItem->wid = 0; | |
if (extra) | |
deleteExtra(); | |
#ifndef QT_NO_GRAPHICSEFFECT | |
delete graphicsEffect; | |
#endif //QT_NO_GRAPHICSEFFECT | |
} | |
class QDummyWindowSurface : public QWindowSurface | |
{ | |
public: | |
QDummyWindowSurface(QWidget *window) : QWindowSurface(window) {} | |
QPaintDevice *paintDevice() { return window(); } | |
void flush(QWidget *, const QRegion &, const QPoint &) {} | |
}; | |
QWindowSurface *QWidgetPrivate::createDefaultWindowSurface() | |
{ | |
Q_Q(QWidget); | |
QWindowSurface *surface; | |
if (q->property("_q_DummyWindowSurface").toBool()) { | |
surface = new QDummyWindowSurface(q); | |
} else { | |
if (QApplicationPrivate::graphicsSystem()) | |
surface = QApplicationPrivate::graphicsSystem()->createWindowSurface(q); | |
else | |
surface = createDefaultWindowSurface_sys(); | |
} | |
return surface; | |
} | |
/*! | |
\internal | |
*/ | |
void QWidgetPrivate::scrollChildren(int dx, int dy) | |
{ | |
Q_Q(QWidget); | |
if (q->children().size() > 0) { // scroll children | |
QPoint pd(dx, dy); | |
QObjectList childObjects = q->children(); | |
for (int i = 0; i < childObjects.size(); ++i) { // move all children | |
QWidget *w = qobject_cast<QWidget*>(childObjects.at(i)); | |
if (w && !w->isWindow()) { | |
QPoint oldp = w->pos(); | |
QRect r(w->pos() + pd, w->size()); | |
w->data->crect = r; | |
#ifndef Q_WS_QWS | |
if (w->testAttribute(Qt::WA_WState_Created)) | |
w->d_func()->setWSGeometry(); | |
#endif | |
w->d_func()->setDirtyOpaqueRegion(); | |
QMoveEvent e(r.topLeft(), oldp); | |
QApplication::sendEvent(w, &e); | |
} | |
} | |
} | |
} | |
QInputContext *QWidgetPrivate::assignedInputContext() const | |
{ | |
#ifndef QT_NO_IM | |
const QWidget *widget = q_func(); | |
while (widget) { | |
if (QInputContext *qic = widget->d_func()->ic) | |
return qic; | |
widget = widget->parentWidget(); | |
} | |
#endif | |
return 0; | |
} | |
QInputContext *QWidgetPrivate::inputContext() const | |
{ | |
#ifndef QT_NO_IM | |
if (QInputContext *qic = assignedInputContext()) | |
return qic; | |
return qApp->inputContext(); | |
#else | |
return 0; | |
#endif | |
} | |
/*! | |
This function returns the QInputContext for this widget. By | |
default the input context is inherited from the widgets | |
parent. For toplevels it is inherited from QApplication. | |
You can override this and set a special input context for this | |
widget by using the setInputContext() method. | |
\sa setInputContext() | |
*/ | |
QInputContext *QWidget::inputContext() | |
{ | |
Q_D(QWidget); | |
if (!testAttribute(Qt::WA_InputMethodEnabled)) | |
return 0; | |
return d->inputContext(); | |
} | |
/*! | |
This function sets the input context \a context | |
on this widget. | |
Qt takes ownership of the given input \a context. | |
\sa inputContext() | |
*/ | |
void QWidget::setInputContext(QInputContext *context) | |
{ | |
Q_D(QWidget); | |
if (!testAttribute(Qt::WA_InputMethodEnabled)) | |
return; | |
#ifndef QT_NO_IM | |
if (context == d->ic) | |
return; | |
if (d->ic) | |
delete d->ic; | |
d->ic = context; | |
if (d->ic) | |
d->ic->setParent(this); | |
#endif | |
} | |
/*! | |
\obsolete | |
This function can be called on the widget that currently has focus | |
to reset the input method operating on it. | |
This function is providing for convenience, instead you should use | |
\l{QInputContext::}{reset()} on the input context that was | |
returned by inputContext(). | |
\sa QInputContext, inputContext(), QInputContext::reset() | |
*/ | |
void QWidget::resetInputContext() | |
{ | |
if (!hasFocus()) | |
return; | |
#ifndef QT_NO_IM | |
QInputContext *qic = this->inputContext(); | |
if(qic) | |
qic->reset(); | |
#endif // QT_NO_IM | |
} | |
#ifdef QT_KEYPAD_NAVIGATION | |
QPointer<QWidget> QWidgetPrivate::editingWidget; | |
/*! | |
Returns true if this widget currently has edit focus; otherwise false. | |
This feature is only available in Qt for Embedded Linux. | |
\sa setEditFocus(), QApplication::keypadNavigationEnabled() | |
*/ | |
bool QWidget::hasEditFocus() const | |
{ | |
const QWidget* w = this; | |
while (w->d_func()->extra && w->d_func()->extra->focus_proxy) | |
w = w->d_func()->extra->focus_proxy; | |
return QWidgetPrivate::editingWidget == w; | |
} | |
/*! | |
\fn void QWidget::setEditFocus(bool enable) | |
If \a enable is true, make this widget have edit focus, in which | |
case Qt::Key_Up and Qt::Key_Down will be delivered to the widget | |
normally; otherwise, Qt::Key_Up and Qt::Key_Down are used to | |
change focus. | |
This feature is only available in Qt for Embedded Linux and Qt | |
for Symbian. | |
\sa hasEditFocus(), QApplication::keypadNavigationEnabled() | |
*/ | |
void QWidget::setEditFocus(bool on) | |
{ | |
QWidget *f = this; | |
while (f->d_func()->extra && f->d_func()->extra->focus_proxy) | |
f = f->d_func()->extra->focus_proxy; | |
if (QWidgetPrivate::editingWidget && QWidgetPrivate::editingWidget != f) | |
QWidgetPrivate::editingWidget->setEditFocus(false); | |
if (on && !f->hasFocus()) | |
f->setFocus(); | |
if ((!on && !QWidgetPrivate::editingWidget) | |
|| (on && QWidgetPrivate::editingWidget == f)) { | |
return; | |
} | |
if (!on && QWidgetPrivate::editingWidget == f) { | |
QWidgetPrivate::editingWidget = 0; | |
QEvent event(QEvent::LeaveEditFocus); | |
QApplication::sendEvent(f, &event); | |
QApplication::sendEvent(f->style(), &event); | |
} else if (on) { | |
QWidgetPrivate::editingWidget = f; | |
QEvent event(QEvent::EnterEditFocus); | |
QApplication::sendEvent(f, &event); | |
QApplication::sendEvent(f->style(), &event); | |
} | |
} | |
#endif | |
/*! | |
\property QWidget::autoFillBackground | |
\brief whether the widget background is filled automatically | |
\since 4.1 | |
If enabled, this property will cause Qt to fill the background of the | |
widget before invoking the paint event. The color used is defined by the | |
QPalette::Window color role from the widget's \l{QPalette}{palette}. | |
In addition, Windows are always filled with QPalette::Window, unless the | |
WA_OpaquePaintEvent or WA_NoSystemBackground attributes are set. | |
This property cannot be turned off (i.e., set to false) if a widget's | |
parent has a static gradient for its background. | |
\warning Use this property with caution in conjunction with | |
\l{Qt Style Sheets}. When a widget has a style sheet with a valid | |
background or a border-image, this property is automatically disabled. | |
By default, this property is false. | |
\sa Qt::WA_OpaquePaintEvent, Qt::WA_NoSystemBackground, | |
{QWidget#Transparency and Double Buffering}{Transparency and Double Buffering} | |
*/ | |
bool QWidget::autoFillBackground() const | |
{ | |
Q_D(const QWidget); | |
return d->extra && d->extra->autoFillBackground; | |
} | |
void QWidget::setAutoFillBackground(bool enabled) | |
{ | |
Q_D(QWidget); | |
if (!d->extra) | |
d->createExtra(); | |
if (d->extra->autoFillBackground == enabled) | |
return; | |
d->extra->autoFillBackground = enabled; | |
d->updateIsOpaque(); | |
update(); | |
d->updateIsOpaque(); | |
} | |
/*! | |
\class QWidget | |
\brief The QWidget class is the base class of all user interface objects. | |
\ingroup basicwidgets | |
The widget is the atom of the user interface: it receives mouse, keyboard | |
and other events from the window system, and paints a representation of | |
itself on the screen. Every widget is rectangular, and they are sorted in a | |
Z-order. A widget is clipped by its parent and by the widgets in front of | |
it. | |
A widget that is not embedded in a parent widget is called a window. | |
Usually, windows have a frame and a title bar, although it is also possible | |
to create windows without such decoration using suitable | |
\l{Qt::WindowFlags}{window flags}). In Qt, QMainWindow and the various | |
subclasses of QDialog are the most common window types. | |
Every widget's constructor accepts one or two standard arguments: | |
\list 1 | |
\i \c{QWidget *parent = 0} is the parent of the new widget. If it is 0 | |
(the default), the new widget will be a window. If not, it will be | |
a child of \e parent, and be constrained by \e parent's geometry | |
(unless you specify Qt::Window as window flag). | |
\i \c{Qt::WindowFlags f = 0} (where available) sets the window flags; | |
the default is suitable for almost all widgets, but to get, for | |
example, a window without a window system frame, you must use | |
special flags. | |
\endlist | |
QWidget has many member functions, but some of them have little direct | |
functionality; for example, QWidget has a font property, but never uses | |
this itself. There are many subclasses which provide real functionality, | |
such as QLabel, QPushButton, QListWidget, and QTabWidget. | |
\section1 Top-Level and Child Widgets | |
A widget without a parent widget is always an independent window (top-level | |
widget). For these widgets, setWindowTitle() and setWindowIcon() set the | |
title bar and icon respectively. | |
Non-window widgets are child widgets, displayed within their parent | |
widgets. Most widgets in Qt are mainly useful as child widgets. For | |
example, it is possible to display a button as a top-level window, but most | |
people prefer to put their buttons inside other widgets, such as QDialog. | |
\image parent-child-widgets.png A parent widget containing various child widgets. | |
The diagram above shows a QGroupBox widget being used to hold various child | |
widgets in a layout provided by QGridLayout. The QLabel child widgets have | |
been outlined to indicate their full sizes. | |
If you want to use a QWidget to hold child widgets you will usually want to | |
add a layout to the parent QWidget. See \l{Layout Management} for more | |
information. | |
\section1 Composite Widgets | |
When a widget is used as a container to group a number of child widgets, it | |
is known as a composite widget. These can be created by constructing a | |
widget with the required visual properties - a QFrame, for example - and | |
adding child widgets to it, usually managed by a layout. The above diagram | |
shows such a composite widget that was created using \l{Qt Designer}. | |
Composite widgets can also be created by subclassing a standard widget, | |
such as QWidget or QFrame, and adding the necessary layout and child | |
widgets in the constructor of the subclass. Many of the \l{Qt Examples} | |
{examples provided with Qt} use this approach, and it is also covered in | |
the Qt \l{Tutorials}. | |
\section1 Custom Widgets and Painting | |
Since QWidget is a subclass of QPaintDevice, subclasses can be used to | |
display custom content that is composed using a series of painting | |
operations with an instance of the QPainter class. This approach contrasts | |
with the canvas-style approach used by the \l{Graphics View} | |
{Graphics View Framework} where items are added to a scene by the | |
application and are rendered by the framework itself. | |
Each widget performs all painting operations from within its paintEvent() | |
function. This is called whenever the widget needs to be redrawn, either | |
as a result of some external change or when requested by the application. | |
The \l{widgets/analogclock}{Analog Clock example} shows how a simple widget | |
can handle paint events. | |
\section1 Size Hints and Size Policies | |
When implementing a new widget, it is almost always useful to reimplement | |
sizeHint() to provide a reasonable default size for the widget and to set | |
the correct size policy with setSizePolicy(). | |
By default, composite widgets which do not provide a size hint will be | |
sized according to the space requirements of their child widgets. | |
The size policy lets you supply good default behavior for the layout | |
management system, so that other widgets can contain and manage yours | |
easily. The default size policy indicates that the size hint represents | |
the preferred size of the widget, and this is often good enough for many | |
widgets. | |
\note The size of top-level widgets are constrained to 2/3 of the desktop's | |
height and width. You can resize() the widget manually if these bounds are | |
inadequate. | |
\section1 Events | |
Widgets respond to events that are typically caused by user actions. Qt | |
delivers events to widgets by calling specific event handler functions with | |
instances of QEvent subclasses containing information about each event. | |
If your widget only contains child widgets, you probably do not need to | |
implement any event handlers. If you want to detect a mouse click in a | |
child widget call the child's underMouse() function inside the widget's | |
mousePressEvent(). | |
The \l{widgets/scribble}{Scribble example} implements a wider set of | |
events to handle mouse movement, button presses, and window resizing. | |
You will need to supply the behavior and content for your own widgets, but | |
here is a brief overview of the events that are relevant to QWidget, | |
starting with the most common ones: | |
\list | |
\i paintEvent() is called whenever the widget needs to be repainted. | |
Every widget displaying custom content must implement it. Painting | |
using a QPainter can only take place in a paintEvent() or a | |
function called by a paintEvent(). | |
\i resizeEvent() is called when the widget has been resized. | |
\i mousePressEvent() is called when a mouse button is pressed while | |
the mouse cursor is inside the widget, or when the widget has | |
grabbed the mouse using grabMouse(). Pressing the mouse without | |
releasing it is effectively the same as calling grabMouse(). | |
\i mouseReleaseEvent() is called when a mouse button is released. A | |
widget receives mouse release events when it has received the | |
corresponding mouse press event. This means that if the user | |
presses the mouse inside \e your widget, then drags the mouse | |
somewhere else before releasing the mouse button, \e your widget | |
receives the release event. There is one exception: if a popup menu | |
appears while the mouse button is held down, this popup immediately | |
steals the mouse events. | |
\i mouseDoubleClickEvent() is called when the user double-clicks in | |
the widget. If the user double-clicks, the widget receives a mouse | |
press event, a mouse release event and finally this event instead | |
of a second mouse press event. (Some mouse move events may also be | |
received if the mouse is not held steady during this operation.) It | |
is \e{not possible} to distinguish a click from a double-click | |
until the second click arrives. (This is one reason why most GUI | |
books recommend that double-clicks be an extension of | |
single-clicks, rather than trigger a different action.) | |
\endlist | |
Widgets that accept keyboard input need to reimplement a few more event | |
handlers: | |
\list | |
\i keyPressEvent() is called whenever a key is pressed, and again when | |
a key has been held down long enough for it to auto-repeat. The | |
\key Tab and \key Shift+Tab keys are only passed to the widget if | |
they are not used by the focus-change mechanisms. To force those | |
keys to be processed by your widget, you must reimplement | |
QWidget::event(). | |
\i focusInEvent() is called when the widget gains keyboard focus | |
(assuming you have called setFocusPolicy()). Well-behaved widgets | |
indicate that they own the keyboard focus in a clear but discreet | |
way. | |
\i focusOutEvent() is called when the widget loses keyboard focus. | |
\endlist | |
You may be required to also reimplement some of the less common event | |
handlers: | |
\list | |
\i mouseMoveEvent() is called whenever the mouse moves while a mouse | |
button is held down. This can be useful during drag and drop | |
operations. If you call \l{setMouseTracking()}{setMouseTracking}(true), | |
you get mouse move events even when no buttons are held down. | |
(See also the \l{Drag and Drop} guide.) | |
\i keyReleaseEvent() is called whenever a key is released and while it | |
is held down (if the key is auto-repeating). In that case, the | |
widget will receive a pair of key release and key press event for | |
every repeat. The \key Tab and \key Shift+Tab keys are only passed | |
to the widget if they are not used by the focus-change mechanisms. | |
To force those keys to be processed by your widget, you must | |
reimplement QWidget::event(). | |
\i wheelEvent() is called whenever the user turns the mouse wheel | |
while the widget has the focus. | |
\i enterEvent() is called when the mouse enters the widget's screen | |
space. (This excludes screen space owned by any of the widget's | |
children.) | |
\i leaveEvent() is called when the mouse leaves the widget's screen | |
space. If the mouse enters a child widget it will not cause a | |
leaveEvent(). | |
\i moveEvent() is called when the widget has been moved relative to | |
its parent. | |
\i closeEvent() is called when the user closes the widget (or when | |
close() is called). | |
\endlist | |
There are also some rather obscure events described in the documentation | |
for QEvent::Type. To handle these events, you need to reimplement event() | |
directly. | |
The default implementation of event() handles \key Tab and \key Shift+Tab | |
(to move the keyboard focus), and passes on most of the other events to | |
one of the more specialized handlers above. | |
Events and the mechanism used to deliver them are covered in | |
\l{The Event System}. | |
\section1 Groups of Functions and Properties | |
\table | |
\header \i Context \i Functions and Properties | |
\row \i Window functions \i | |
show(), | |
hide(), | |
raise(), | |
lower(), | |
close(). | |
\row \i Top-level windows \i | |
\l windowModified, \l windowTitle, \l windowIcon, \l windowIconText, | |
\l isActiveWindow, activateWindow(), \l minimized, showMinimized(), | |
\l maximized, showMaximized(), \l fullScreen, showFullScreen(), | |
showNormal(). | |
\row \i Window contents \i | |
update(), | |
repaint(), | |
scroll(). | |
\row \i Geometry \i | |
\l pos, x(), y(), \l rect, \l size, width(), height(), move(), resize(), | |
\l sizePolicy, sizeHint(), minimumSizeHint(), | |
updateGeometry(), layout(), | |
\l frameGeometry, \l geometry, \l childrenRect, \l childrenRegion, | |
adjustSize(), | |
mapFromGlobal(), mapToGlobal(), | |
mapFromParent(), mapToParent(), | |
\l maximumSize, \l minimumSize, \l sizeIncrement, | |
\l baseSize, setFixedSize() | |
\row \i Mode \i | |
\l visible, isVisibleTo(), | |
\l enabled, isEnabledTo(), | |
\l modal, | |
isWindow(), | |
\l mouseTracking, | |
\l updatesEnabled, | |
visibleRegion(). | |
\row \i Look and feel \i | |
style(), | |
setStyle(), | |
\l styleSheet, | |
\l cursor, | |
\l font, | |
\l palette, | |
backgroundRole(), setBackgroundRole(), | |
fontInfo(), fontMetrics(). | |
\row \i Keyboard focus functions \i | |
\l focus, \l focusPolicy, | |
setFocus(), clearFocus(), setTabOrder(), setFocusProxy(), | |
focusNextChild(), focusPreviousChild(). | |
\row \i Mouse and keyboard grabbing \i | |
grabMouse(), releaseMouse(), | |
grabKeyboard(), releaseKeyboard(), | |
mouseGrabber(), keyboardGrabber(). | |
\row \i Event handlers \i | |
event(), | |
mousePressEvent(), | |
mouseReleaseEvent(), | |
mouseDoubleClickEvent(), | |
mouseMoveEvent(), | |
keyPressEvent(), | |
keyReleaseEvent(), | |
focusInEvent(), | |
focusOutEvent(), | |
wheelEvent(), | |
enterEvent(), | |
leaveEvent(), | |
paintEvent(), | |
moveEvent(), | |
resizeEvent(), | |
closeEvent(), | |
dragEnterEvent(), | |
dragMoveEvent(), | |
dragLeaveEvent(), | |
dropEvent(), | |
childEvent(), | |
showEvent(), | |
hideEvent(), | |
customEvent(). | |
changeEvent(), | |
\row \i System functions \i | |
parentWidget(), window(), setParent(), winId(), | |
find(), metric(). | |
\row \i Interactive help \i | |
setToolTip(), setWhatsThis() | |
\endtable | |
\section1 Widget Style Sheets | |
In addition to the standard widget styles for each platform, widgets can | |
also be styled according to rules specified in a \l{styleSheet} | |
{style sheet}. This feature enables you to customize the appearance of | |
specific widgets to provide visual cues to users about their purpose. For | |
example, a button could be styled in a particular way to indicate that it | |
performs a destructive action. | |
The use of widget style sheets is described in more detail in the | |
\l{Qt Style Sheets} document. | |
\section1 Transparency and Double Buffering | |
Since Qt 4.0, QWidget automatically double-buffers its painting, so there | |
is no need to write double-buffering code in paintEvent() to avoid | |
flicker. | |
Since Qt 4.1, the Qt::WA_ContentsPropagated widget attribute has been | |
deprecated. Instead, the contents of parent widgets are propagated by | |
default to each of their children as long as Qt::WA_PaintOnScreen is not | |
set. Custom widgets can be written to take advantage of this feature by | |
updating irregular regions (to create non-rectangular child widgets), or | |
painting with colors that have less than full alpha component. The | |
following diagram shows how attributes and properties of a custom widget | |
can be fine-tuned to achieve different effects. | |
\image propagation-custom.png | |
In the above diagram, a semi-transparent rectangular child widget with an | |
area removed is constructed and added to a parent widget (a QLabel showing | |
a pixmap). Then, different properties and widget attributes are set to | |
achieve different effects: | |
\list | |
\i The left widget has no additional properties or widget attributes | |
set. This default state suits most custom widgets using | |
transparency, are irregularly-shaped, or do not paint over their | |
entire area with an opaque brush. | |
\i The center widget has the \l autoFillBackground property set. This | |
property is used with custom widgets that rely on the widget to | |
supply a default background, and do not paint over their entire | |
area with an opaque brush. | |
\i The right widget has the Qt::WA_OpaquePaintEvent widget attribute | |
set. This indicates that the widget will paint over its entire area | |
with opaque colors. The widget's area will initially be | |
\e{uninitialized}, represented in the diagram with a red diagonal | |
grid pattern that shines through the overpainted area. The | |
Qt::WA_OpaquePaintArea attribute is useful for widgets that need to | |
paint their own specialized contents quickly and do not need a | |
default filled background. | |
\endlist | |
To rapidly update custom widgets with simple background colors, such as | |
real-time plotting or graphing widgets, it is better to define a suitable | |
background color (using setBackgroundRole() with the | |
QPalette::Window role), set the \l autoFillBackground property, and only | |
implement the necessary drawing functionality in the widget's paintEvent(). | |
To rapidly update custom widgets that constantly paint over their entire | |
areas with opaque content, e.g., video streaming widgets, it is better to | |
set the widget's Qt::WA_OpaquePaintEvent, avoiding any unnecessary overhead | |
associated with repainting the widget's background. | |
If a widget has both the Qt::WA_OpaquePaintEvent widget attribute \e{and} | |
the \l autoFillBackground property set, the Qt::WA_OpaquePaintEvent | |
attribute takes precedence. Depending on your requirements, you should | |
choose either one of them. | |
Since Qt 4.1, the contents of parent widgets are also propagated to | |
standard Qt widgets. This can lead to some unexpected results if the | |
parent widget is decorated in a non-standard way, as shown in the diagram | |
below. | |
\image propagation-standard.png | |
The scope for customizing the painting behavior of standard Qt widgets, | |
without resorting to subclassing, is slightly less than that possible for | |
custom widgets. Usually, the desired appearance of a standard widget can be | |
achieved by setting its \l autoFillBackground property. | |
\section1 Creating Translucent Windows | |
Since Qt 4.5, it has been possible to create windows with translucent regions | |
on window systems that support compositing. | |
To enable this feature in a top-level widget, set its Qt::WA_TranslucentBackground | |
attribute with setAttribute() and ensure that its background is painted with | |
non-opaque colors in the regions you want to be partially transparent. | |
Platform notes: | |
\list | |
\o X11: This feature relies on the use of an X server that supports ARGB visuals | |
and a compositing window manager. | |
\o Windows: The widget needs to have the Qt::FramelessWindowHint window flag set | |
for the translucency to work. | |
\endlist | |
\section1 Native Widgets vs Alien Widgets | |
Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing | |
system. They do not have a native window handle associated with them. This | |
feature significantly speeds up widget painting, resizing, and removes flicker. | |
Should you require the old behavior with native windows, you can choose | |
one of the following options: | |
\list 1 | |
\i Use the \c{QT_USE_NATIVE_WINDOWS=1} in your environment. | |
\i Set the Qt::AA_NativeWindows attribute on your application. All | |
widgets will be native widgets. | |
\i Set the Qt::WA_NativeWindow attribute on widgets: The widget itself | |
and all of its ancestors will become native (unless | |
Qt::WA_DontCreateNativeAncestors is set). | |
\i Call QWidget::winId to enforce a native window (this implies 3). | |
\i Set the Qt::WA_PaintOnScreen attribute to enforce a native window | |
(this implies 3). | |
\endlist | |
\sa QEvent, QPainter, QGridLayout, QBoxLayout | |
\section1 Softkeys | |
Since Qt 4.6, Softkeys are usually physical keys on a device that have a corresponding label or | |
other visual representation on the screen that is generally located next to its | |
physical counterpart. They are most often found on mobile phone platforms. In | |
modern touch based user interfaces it is also possible to have softkeys that do | |
not correspond to any physical keys. Softkeys differ from other onscreen labels | |
in that they are contextual. | |
In Qt, contextual softkeys are added to a widget by calling addAction() and | |
passing a \c QAction with a softkey role set on it. When the widget | |
containing the softkey actions has focus, its softkeys should appear in | |
the user interface. Softkeys are discovered by traversing the widget | |
hierarchy so it is possible to define a single set of softkeys that are | |
present at all times by calling addAction() for a given top level widget. | |
On some platforms, this concept overlaps with \c QMenuBar such that if no | |
other softkeys are found and the top level widget is a QMainWindow containing | |
a QMenuBar, the menubar actions may appear on one of the softkeys. | |
Note: Currently softkeys are only supported on the Symbian Platform. | |
\sa addAction(), QAction, QMenuBar | |
*/ | |
QWidgetMapper *QWidgetPrivate::mapper = 0; // widget with wid | |
QWidgetSet *QWidgetPrivate::allWidgets = 0; // widgets with no wid | |
/***************************************************************************** | |
QWidget utility functions | |
*****************************************************************************/ | |
QRegion qt_dirtyRegion(QWidget *widget) | |
{ | |
if (!widget) | |
return QRegion(); | |
QWidgetBackingStore *bs = qt_widget_private(widget)->maybeBackingStore(); | |
if (!bs) | |
return QRegion(); | |
return bs->dirtyRegion(widget); | |
} | |
/***************************************************************************** | |
QWidget member functions | |
*****************************************************************************/ | |
/* | |
Widget state flags: | |
\list | |
\i Qt::WA_WState_Created The widget has a valid winId(). | |
\i Qt::WA_WState_Visible The widget is currently visible. | |
\i Qt::WA_WState_Hidden The widget is hidden, i.e. it won't | |
become visible unless you call show() on it. Qt::WA_WState_Hidden | |
implies !Qt::WA_WState_Visible. | |
\i Qt::WA_WState_CompressKeys Compress keyboard events. | |
\i Qt::WA_WState_BlockUpdates Repaints and updates are disabled. | |
\i Qt::WA_WState_InPaintEvent Currently processing a paint event. | |
\i Qt::WA_WState_Reparented The widget has been reparented. | |
\i Qt::WA_WState_ConfigPending A configuration (resize/move) event is pending. | |
\i Qt::WA_WState_DND (Deprecated) The widget supports drag and drop, see setAcceptDrops(). | |
\endlist | |
*/ | |
struct QWidgetExceptionCleaner | |
{ | |
/* this cleans up when the constructor throws an exception */ | |
static inline void cleanup(QWidget *that, QWidgetPrivate *d) | |
{ | |
#ifdef QT_NO_EXCEPTIONS | |
Q_UNUSED(that); | |
Q_UNUSED(d); | |
#else | |
QWidgetPrivate::allWidgets->remove(that); | |
if (d->focus_next != that) { | |
if (d->focus_next) | |
d->focus_next->d_func()->focus_prev = d->focus_prev; | |
if (d->focus_prev) | |
d->focus_prev->d_func()->focus_next = d->focus_next; | |
} | |
#endif | |
} | |
}; | |
/*! | |
Constructs a widget which is a child of \a parent, with widget | |
flags set to \a f. | |
If \a parent is 0, the new widget becomes a window. If | |
\a parent is another widget, this widget becomes a child window | |
inside \a parent. The new widget is deleted when its \a parent is | |
deleted. | |
The widget flags argument, \a f, is normally 0, but it can be set | |
to customize the frame of a window (i.e. \a | |
parent must be 0). To customize the frame, use a value composed | |
from the bitwise OR of any of the \l{Qt::WindowFlags}{window flags}. | |
If you add a child widget to an already visible widget you must | |
explicitly show the child to make it visible. | |
Note that the X11 version of Qt may not be able to deliver all | |
combinations of style flags on all systems. This is because on | |
X11, Qt can only ask the window manager, and the window manager | |
can override the application's settings. On Windows, Qt can set | |
whatever flags you want. | |
\sa windowFlags | |
*/ | |
QWidget::QWidget(QWidget *parent, Qt::WindowFlags f) | |
: QObject(*new QWidgetPrivate, 0), QPaintDevice() | |
{ | |
QT_TRY { | |
d_func()->init(parent, f); | |
} QT_CATCH(...) { | |
QWidgetExceptionCleaner::cleanup(this, d_func()); | |
QT_RETHROW; | |
} | |
} | |
#ifdef QT3_SUPPORT | |
/*! | |
\overload | |
\obsolete | |
*/ | |
QWidget::QWidget(QWidget *parent, const char *name, Qt::WindowFlags f) | |
: QObject(*new QWidgetPrivate, 0), QPaintDevice() | |
{ | |
QT_TRY { | |
d_func()->init(parent , f); | |
setObjectName(QString::fromAscii(name)); | |
} QT_CATCH(...) { | |
QWidgetExceptionCleaner::cleanup(this, d_func()); | |
QT_RETHROW; | |
} | |
} | |
#endif | |
/*! \internal | |
*/ | |
QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f) | |
: QObject(dd, 0), QPaintDevice() | |
{ | |
Q_D(QWidget); | |
QT_TRY { | |
d->init(parent, f); | |
} QT_CATCH(...) { | |
QWidgetExceptionCleaner::cleanup(this, d_func()); | |
QT_RETHROW; | |
} | |
} | |
/*! | |
\internal | |
*/ | |
int QWidget::devType() const | |
{ | |
return QInternal::Widget; | |
} | |
//### w is a "this" ptr, passed as a param because QWorkspace needs special logic | |
void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w) | |
{ | |
bool customize = (flags & (Qt::CustomizeWindowHint | |
| Qt::FramelessWindowHint | |
| Qt::WindowTitleHint | |
| Qt::WindowSystemMenuHint | |
| Qt::WindowMinimizeButtonHint | |
| Qt::WindowMaximizeButtonHint | |
| Qt::WindowCloseButtonHint | |
| Qt::WindowContextHelpButtonHint)); | |
uint type = (flags & Qt::WindowType_Mask); | |
if ((type == Qt::Widget || type == Qt::SubWindow) && w && !w->parent()) { | |
type = Qt::Window; | |
flags |= Qt::Window; | |
} | |
if (flags & Qt::CustomizeWindowHint) { | |
// modify window flags to make them consistent. | |
// Only enable this on non-Mac platforms. Since the old way of doing this would | |
// interpret WindowSystemMenuHint as a close button and we can't change that behavior | |
// we can't just add this in. | |
#ifndef Q_WS_MAC | |
if (flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint)) { | |
flags |= Qt::WindowSystemMenuHint; | |
#else | |
if (flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | |
| Qt::WindowSystemMenuHint)) { | |
#endif | |
flags |= Qt::WindowTitleHint; | |
flags &= ~Qt::FramelessWindowHint; | |
} | |
} else if (customize && !(flags & Qt::FramelessWindowHint)) { | |
// if any of the window hints that affect the titlebar are set | |
// and the window is supposed to have frame, we add a titlebar | |
// and system menu by default. | |
flags |= Qt::WindowSystemMenuHint; | |
flags |= Qt::WindowTitleHint; | |
} | |
if (customize) | |
; // don't modify window flags if the user explicitly set them. | |
else if (type == Qt::Dialog || type == Qt::Sheet) | |
#ifndef Q_WS_WINCE | |
flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowContextHelpButtonHint | Qt::WindowCloseButtonHint; | |
#else | |
flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint; | |
#endif | |
else if (type == Qt::Tool) | |
flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint; | |
else | |
flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint; | |
} | |
void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) | |
{ | |
Q_Q(QWidget); | |
if (QApplication::type() == QApplication::Tty) | |
qFatal("QWidget: Cannot create a QWidget when no GUI is being used"); | |
Q_ASSERT(allWidgets); | |
if (allWidgets) | |
allWidgets->insert(q); | |
QWidget *desktopWidget = 0; | |
if (parentWidget && parentWidget->windowType() == Qt::Desktop) { | |
desktopWidget = parentWidget; | |
parentWidget = 0; | |
} | |
q->data = &data; | |
#ifndef QT_NO_THREAD | |
if (!parent) { | |
Q_ASSERT_X(q->thread() == qApp->thread(), "QWidget", | |
"Widgets must be created in the GUI thread."); | |
} | |
#endif | |
#if defined(Q_WS_X11) | |
if (desktopWidget) { | |
// make sure the widget is created on the same screen as the | |
// programmer specified desktop widget | |
xinfo = desktopWidget->d_func()->xinfo; | |
} | |
#elif defined(Q_OS_SYMBIAN) | |
if (desktopWidget) { | |
symbianScreenNumber = qt_widget_private(desktopWidget)->symbianScreenNumber; | |
} | |
#else | |
Q_UNUSED(desktopWidget); | |
#endif | |
data.fstrut_dirty = true; | |
data.winid = 0; | |
data.widget_attributes = 0; | |
data.window_flags = f; | |
data.window_state = 0; | |
data.focus_policy = 0; | |
data.context_menu_policy = Qt::DefaultContextMenu; | |
data.window_modality = Qt::NonModal; | |
data.sizehint_forced = 0; | |
data.is_closing = 0; | |
data.in_show = 0; | |
data.in_set_window_state = 0; | |
data.in_destructor = false; | |
// Widgets with Qt::MSWindowsOwnDC (typically QGLWidget) must have a window handle. | |
if (f & Qt::MSWindowsOwnDC) | |
q->setAttribute(Qt::WA_NativeWindow); | |
#ifdef Q_WS_MAC | |
q->setAttribute(Qt::WA_NativeWindow); | |
#endif | |
q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute() | |
adjustQuitOnCloseAttribute(); | |
q->setAttribute(Qt::WA_WState_Hidden); | |
//give potential windows a bigger "pre-initial" size; create_sys() will give them a new size later | |
#ifdef Q_OS_SYMBIAN | |
if (isGLWidget) { | |
// Don't waste GPU mem for unnecessary large egl surface until resized by application | |
data.crect = QRect(0,0,1,1); | |
} else { | |
data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,360,640); | |
} | |
#else | |
data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,640,480); | |
#endif | |
focus_next = focus_prev = q; | |
if ((f & Qt::WindowType_Mask) == Qt::Desktop) | |
q->create(); | |
else if (parentWidget) | |
q->setParent(parentWidget, data.window_flags); | |
else { | |
adjustFlags(data.window_flags, q); | |
resolveLayoutDirection(); | |
// opaque system background? | |
const QBrush &background = q->palette().brush(QPalette::Window); | |
setOpaque(q->isWindow() && background.style() != Qt::NoBrush && background.isOpaque()); | |
} | |
data.fnt = QFont(data.fnt, q); | |
#if defined(Q_WS_X11) | |
data.fnt.x11SetScreen(xinfo.screen()); | |
#endif // Q_WS_X11 | |
q->setAttribute(Qt::WA_PendingMoveEvent); | |
q->setAttribute(Qt::WA_PendingResizeEvent); | |
if (++QWidgetPrivate::instanceCounter > QWidgetPrivate::maxInstances) | |
QWidgetPrivate::maxInstances = QWidgetPrivate::instanceCounter; | |
if (QApplicationPrivate::app_compile_version < 0x040200 | |
|| QApplicationPrivate::testAttribute(Qt::AA_ImmediateWidgetCreation)) | |
q->create(); | |
QEvent e(QEvent::Create); | |
QApplication::sendEvent(q, &e); | |
QApplication::postEvent(q, new QEvent(QEvent::PolishRequest)); | |
extraPaintEngine = 0; | |
} | |
void QWidgetPrivate::createRecursively() | |
{ | |
Q_Q(QWidget); | |
q->create(0, true, true); | |
for (int i = 0; i < children.size(); ++i) { | |
QWidget *child = qobject_cast<QWidget *>(children.at(i)); | |
if (child && !child->isHidden() && !child->isWindow() && !child->testAttribute(Qt::WA_WState_Created)) | |
child->d_func()->createRecursively(); | |
} | |
} | |
/*! | |
Creates a new widget window if \a window is 0, otherwise sets the | |
widget's window to \a window. | |
Initializes the window (sets the geometry etc.) if \a | |
initializeWindow is true. If \a initializeWindow is false, no | |
initialization is performed. This parameter only makes sense if \a | |
window is a valid window. | |
Destroys the old window if \a destroyOldWindow is true. If \a | |
destroyOldWindow is false, you are responsible for destroying the | |
window yourself (using platform native code). | |
The QWidget constructor calls create(0,true,true) to create a | |
window for this widget. | |
*/ | |
void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) | |
{ | |
Q_D(QWidget); | |
if (testAttribute(Qt::WA_WState_Created) && window == 0 && internalWinId()) | |
return; | |
if (d->data.in_destructor) | |
return; | |
Qt::WindowType type = windowType(); | |
Qt::WindowFlags &flags = data->window_flags; | |
if ((type == Qt::Widget || type == Qt::SubWindow) && !parentWidget()) { | |
type = Qt::Window; | |
flags |= Qt::Window; | |
} | |
if (QWidget *parent = parentWidget()) { | |
#ifdef Q_WS_MAC | |
if (testAttribute(Qt::WA_NativeWindow) == false) | |
parent->d_func()->hasAlienChildren = true; | |
#endif | |
if (type & Qt::Window) { | |
if (!parent->testAttribute(Qt::WA_WState_Created)) | |
parent->createWinId(); | |
} else if (testAttribute(Qt::WA_NativeWindow) && !parent->internalWinId() | |
&& !testAttribute(Qt::WA_DontCreateNativeAncestors)) { | |
// We're about to create a native child widget that doesn't have a native parent; | |
// enforce a native handle for the parent unless the Qt::WA_DontCreateNativeAncestors | |
// attribute is set. | |
d->createWinId(window); | |
// Nothing more to do. | |
Q_ASSERT(testAttribute(Qt::WA_WState_Created)); | |
Q_ASSERT(internalWinId()); | |
return; | |
} | |
} | |
#ifdef QT3_SUPPORT | |
if (flags & Qt::WStaticContents) | |
setAttribute(Qt::WA_StaticContents); | |
if (flags & Qt::WDestructiveClose) | |
setAttribute(Qt::WA_DeleteOnClose); | |
if (flags & Qt::WShowModal) | |
setWindowModality(Qt::ApplicationModal); | |
if (flags & Qt::WMouseNoMask) | |
setAttribute(Qt::WA_MouseNoMask); | |
if (flags & Qt::WGroupLeader) | |
setAttribute(Qt::WA_GroupLeader); | |
if (flags & Qt::WNoMousePropagation) | |
setAttribute(Qt::WA_NoMousePropagation); | |
#endif | |
static int paintOnScreenEnv = -1; | |
if (paintOnScreenEnv == -1) | |
paintOnScreenEnv = qgetenv("QT_ONSCREEN_PAINT").toInt() > 0 ? 1 : 0; | |
if (paintOnScreenEnv == 1) | |
setAttribute(Qt::WA_PaintOnScreen); | |
if (QApplicationPrivate::testAttribute(Qt::AA_NativeWindows)) | |
setAttribute(Qt::WA_NativeWindow); | |
#ifdef ALIEN_DEBUG | |
qDebug() << "QWidget::create:" << this << "parent:" << parentWidget() | |
<< "Alien?" << !testAttribute(Qt::WA_NativeWindow); | |
#endif | |
#if defined (Q_WS_WIN) && !defined(QT_NO_DRAGANDDROP) | |
// Unregister the dropsite (if already registered) before we | |
// re-create the widget with a native window. | |
if (testAttribute(Qt::WA_WState_Created) && !internalWinId() && testAttribute(Qt::WA_NativeWindow) | |
&& d->extra && d->extra->dropTarget) { | |
d->registerDropSite(false); | |
} | |
#endif // defined (Q_WS_WIN) && !defined(QT_NO_DRAGANDDROP) | |
d->updateIsOpaque(); | |
setAttribute(Qt::WA_WState_Created); // set created flag | |
d->create_sys(window, initializeWindow, destroyOldWindow); | |
// a real toplevel window needs a backing store | |
if (isWindow() && windowType() != Qt::Desktop) { | |
d->topData()->backingStore.destroy(); | |
if (hasBackingStoreSupport()) | |
d->topData()->backingStore.create(this); | |
} | |
d->setModal_sys(); | |
if (!isWindow() && parentWidget() && parentWidget()->testAttribute(Qt::WA_DropSiteRegistered)) | |
setAttribute(Qt::WA_DropSiteRegistered, true); | |
#ifdef QT_EVAL | |
extern void qt_eval_init_widget(QWidget *w); | |
qt_eval_init_widget(this); | |
#endif | |
// need to force the resting of the icon after changing parents | |
if (testAttribute(Qt::WA_SetWindowIcon)) | |
d->setWindowIcon_sys(true); | |
if (isWindow() && !d->topData()->iconText.isEmpty()) | |
d->setWindowIconText_helper(d->topData()->iconText); | |
if (isWindow() && !d->topData()->caption.isEmpty()) | |
d->setWindowTitle_helper(d->topData()->caption); | |
if (windowType() != Qt::Desktop) { | |
d->updateSystemBackground(); | |
if (isWindow() && !testAttribute(Qt::WA_SetWindowIcon)) | |
d->setWindowIcon_sys(); | |
} | |
} | |
/*! | |
Destroys the widget. | |
All this widget's children are deleted first. The application | |
exits if this widget is the main widget. | |
*/ | |
QWidget::~QWidget() | |
{ | |
Q_D(QWidget); | |
d->data.in_destructor = true; | |
#if defined (QT_CHECK_STATE) | |
if (paintingActive()) | |
qWarning("QWidget: %s (%s) deleted while being painted", className(), name()); | |
#endif | |
#ifndef QT_NO_GESTURES | |
foreach (Qt::GestureType type, d->gestureContext.keys()) | |
ungrabGesture(type); | |
#endif | |
// force acceptDrops false before winId is destroyed. | |
d->registerDropSite(false); | |
#ifndef QT_NO_ACTION | |
// remove all actions from this widget | |
for (int i = 0; i < d->actions.size(); ++i) { | |
QActionPrivate *apriv = d->actions.at(i)->d_func(); | |
apriv->widgets.removeAll(this); | |
} | |
d->actions.clear(); | |
#endif | |
#ifndef QT_NO_SHORTCUT | |
// Remove all shortcuts grabbed by this | |
// widget, unless application is closing | |
if (!QApplicationPrivate::is_app_closing && testAttribute(Qt::WA_GrabbedShortcut)) | |
qApp->d_func()->shortcutMap.removeShortcut(0, this, QKeySequence()); | |
#endif | |
// delete layout while we still are a valid widget | |
delete d->layout; | |
// Remove myself from focus list | |
Q_ASSERT(d->focus_next->d_func()->focus_prev == this); | |
Q_ASSERT(d->focus_prev->d_func()->focus_next == this); | |
if (d->focus_next != this) { | |
d->focus_next->d_func()->focus_prev = d->focus_prev; | |
d->focus_prev->d_func()->focus_next = d->focus_next; | |
d->focus_next = d->focus_prev = 0; | |
} | |
#ifdef QT3_SUPPORT | |
if (QApplicationPrivate::main_widget == this) { // reset main widget | |
QApplicationPrivate::main_widget = 0; | |
QApplication::quit(); | |
} | |
#endif | |
QT_TRY { | |
clearFocus(); | |
} QT_CATCH(...) { | |
// swallow this problem because we are in a destructor | |
} | |
d->setDirtyOpaqueRegion(); | |
if (isWindow() && isVisible() && internalWinId()) { | |
QT_TRY { | |
d->close_helper(QWidgetPrivate::CloseNoEvent); | |
} QT_CATCH(...) { | |
// if we're out of memory, at least hide the window. | |
QT_TRY { | |
hide(); | |
} QT_CATCH(...) { | |
// and if that also doesn't work, then give up | |
} | |
} | |
} | |
#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) | |
else if (!internalWinId() && isVisible()) { | |
qApp->d_func()->sendSyntheticEnterLeave(this); | |
#ifdef Q_WS_QWS | |
} else if (isVisible()) { | |
qApp->d_func()->sendSyntheticEnterLeave(this); | |
#endif | |
} | |
#endif | |
#ifdef Q_OS_SYMBIAN | |
if (d->extra && d->extra->topextra && d->extra->topextra->backingStore) { | |
// Okay, we are about to destroy the top-level window that owns | |
// the backing store. Make sure we delete the backing store right away | |
// before the window handle is invalid. This is important because | |
// the backing store will delete its window surface, which may or may | |
// not have a reference to this widget that will be used later to | |
// notify the window it no longer has a surface. | |
d->extra->topextra->backingStore.destroy(); | |
} | |
#endif | |
if (QWidgetBackingStore *bs = d->maybeBackingStore()) { | |
bs->removeDirtyWidget(this); | |
if (testAttribute(Qt::WA_StaticContents)) | |
bs->removeStaticWidget(this); | |
} | |
delete d->needsFlush; | |
d->needsFlush = 0; | |
// set all QPointers for this object to zero | |
QObjectPrivate::clearGuards(this); | |
if (d->declarativeData) { | |
QAbstractDeclarativeData::destroyed(d->declarativeData, this); | |
d->declarativeData = 0; // don't activate again in ~QObject | |
} | |
#ifdef QT_MAC_USE_COCOA | |
// QCocoaView holds a pointer back to this widget. Clear it now | |
// to make sure it's not followed later on. The lifetime of the | |
// QCocoaView might exceed the lifetime of this widget in cases | |
// where Cocoa itself holds references to it. | |
extern void qt_mac_clearCocoaViewQWidgetPointers(QWidget *); | |
qt_mac_clearCocoaViewQWidgetPointers(this); | |
#endif | |
if (!d->children.isEmpty()) | |
d->deleteChildren(); | |
QApplication::removePostedEvents(this); | |
QT_TRY { | |
destroy(); // platform-dependent cleanup | |
} QT_CATCH(...) { | |
// if this fails we can't do anything about it but at least we are not allowed to throw. | |
} | |
--QWidgetPrivate::instanceCounter; | |
if (QWidgetPrivate::allWidgets) // might have been deleted by ~QApplication | |
QWidgetPrivate::allWidgets->remove(this); | |
QT_TRY { | |
QEvent e(QEvent::Destroy); | |
QCoreApplication::sendEvent(this, &e); | |
} QT_CATCH(const std::exception&) { | |
// if this fails we can't do anything about it but at least we are not allowed to throw. | |
} | |
} | |
int QWidgetPrivate::instanceCounter = 0; // Current number of widget instances | |
int QWidgetPrivate::maxInstances = 0; // Maximum number of widget instances | |
void QWidgetPrivate::setWinId(WId id) // set widget identifier | |
{ | |
Q_Q(QWidget); | |
// the user might create a widget with Qt::Desktop window | |
// attribute (or create another QDesktopWidget instance), which | |
// will have the same windowid (the root window id) as the | |
// qt_desktopWidget. We should not add the second desktop widget | |
// to the mapper. | |
bool userDesktopWidget = qt_desktopWidget != 0 && qt_desktopWidget != q && q->windowType() == Qt::Desktop; | |
if (mapper && data.winid && !userDesktopWidget) { | |
mapper->remove(data.winid); | |
} | |
const WId oldWinId = data.winid; | |
data.winid = id; | |
#if defined(Q_WS_X11) | |
hd = id; // X11: hd == ident | |
#endif | |
if (mapper && id && !userDesktopWidget) { | |
mapper->insert(data.winid, q); | |
} | |
if(oldWinId != id) { | |
QEvent e(QEvent::WinIdChange); | |
QCoreApplication::sendEvent(q, &e); | |
} | |
} | |
void QWidgetPrivate::createTLExtra() | |
{ | |
if (!extra) | |
createExtra(); | |
if (!extra->topextra) { | |
QTLWExtra* x = extra->topextra = new QTLWExtra; | |
x->icon = 0; | |
x->iconPixmap = 0; | |
x->windowSurface = 0; | |
x->sharedPainter = 0; | |
x->incw = x->inch = 0; | |
x->basew = x->baseh = 0; | |
x->frameStrut.setCoords(0, 0, 0, 0); | |
x->normalGeometry = QRect(0,0,-1,-1); | |
x->savedFlags = 0; | |
x->opacity = 255; | |
x->posFromMove = false; | |
x->sizeAdjusted = false; | |
x->inTopLevelResize = false; | |
x->inRepaint = false; | |
x->embedded = 0; | |
#ifdef Q_WS_MAC | |
#ifdef QT_MAC_USE_COCOA | |
x->wasMaximized = false; | |
#endif // QT_MAC_USE_COCOA | |
#endif // Q_WS_MAC | |
createTLSysExtra(); | |
#ifdef QWIDGET_EXTRA_DEBUG | |
static int count = 0; | |
qDebug() << "tlextra" << ++count; | |
#endif | |
} | |
} | |
/*! | |
\internal | |
Creates the widget extra data. | |
*/ | |
void QWidgetPrivate::createExtra() | |
{ | |
if (!extra) { // if not exists | |
extra = new QWExtra; | |
extra->glContext = 0; | |
extra->topextra = 0; | |
#ifndef QT_NO_GRAPHICSVIEW | |
extra->proxyWidget = 0; | |
#endif | |
#ifndef QT_NO_CURSOR | |
extra->curs = 0; | |
#endif | |
extra->minw = 0; | |
extra->minh = 0; | |
extra->maxw = QWIDGETSIZE_MAX; | |
extra->maxh = QWIDGETSIZE_MAX; | |
extra->customDpiX = 0; | |
extra->customDpiY = 0; | |
extra->explicitMinSize = 0; | |
extra->explicitMaxSize = 0; | |
extra->autoFillBackground = 0; | |
extra->nativeChildrenForced = 0; | |
extra->inRenderWithPainter = 0; | |
extra->hasMask = 0; | |
createSysExtra(); | |
#ifdef QWIDGET_EXTRA_DEBUG | |
static int count = 0; | |
qDebug() << "extra" << ++count; | |
#endif | |
} | |
} | |
/*! | |
\internal | |
Deletes the widget extra data. | |
*/ | |
void QWidgetPrivate::deleteExtra() | |
{ | |
if (extra) { // if exists | |
#ifndef QT_NO_CURSOR | |
delete extra->curs; | |
#endif | |
deleteSysExtra(); | |
#ifndef QT_NO_STYLE_STYLESHEET | |
// dereference the stylesheet style | |
if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(extra->style)) | |
proxy->deref(); | |
#endif | |
if (extra->topextra) { | |
deleteTLSysExtra(); | |
extra->topextra->backingStore.destroy(); | |
delete extra->topextra->icon; | |
delete extra->topextra->iconPixmap; | |
#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) | |
delete extra->topextra->qwsManager; | |
#endif | |
delete extra->topextra->windowSurface; | |
delete extra->topextra; | |
} | |
delete extra; | |
// extra->xic destroyed in QWidget::destroy() | |
extra = 0; | |
} | |
} | |
/* | |
Returns true if there are widgets above this which overlap with | |
\a rect, which is in parent's coordinate system (same as crect). | |
*/ | |
bool QWidgetPrivate::isOverlapped(const QRect &rect) const | |
{ | |
Q_Q(const QWidget); | |
const QWidget *w = q; | |
QRect r = rect; | |
while (w) { | |
if (w->isWindow()) | |
return false; | |
QWidgetPrivate *pd = w->parentWidget()->d_func(); | |
bool above = false; | |
for (int i = 0; i < pd->children.size(); ++i) { | |
QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i)); | |
if (!sibling || !sibling->isVisible() || sibling->isWindow()) | |
continue; | |
if (!above) { | |
above = (sibling == w); | |
continue; | |
} | |
if (qRectIntersects(sibling->d_func()->effectiveRectFor(sibling->data->crect), r)) { | |
const QWExtra *siblingExtra = sibling->d_func()->extra; | |
if (siblingExtra && siblingExtra->hasMask && !sibling->d_func()->graphicsEffect | |
&& !siblingExtra->mask.translated(sibling->data->crect.topLeft()).intersects(r)) { | |
continue; | |
} | |
return true; | |
} | |
} | |
w = w->parentWidget(); | |
r.translate(pd->data.crect.topLeft()); | |
} | |
return false; | |
} | |
void QWidgetPrivate::syncBackingStore() | |
{ | |
if (paintOnScreen()) { | |
repaint_sys(dirty); | |
dirty = QRegion(); | |
} else if (QWidgetBackingStore *bs = maybeBackingStore()) { | |
#ifdef QT_MAC_USE_COCOA | |
Q_UNUSED(bs); | |
void qt_mac_set_needs_display(QWidget *, QRegion); | |
qt_mac_set_needs_display(q_func(), QRegion()); | |
#else | |
bs->sync(); | |
#endif | |
} | |
} | |
void QWidgetPrivate::syncBackingStore(const QRegion ®ion) | |
{ | |
if (paintOnScreen()) | |
repaint_sys(region); | |
else if (QWidgetBackingStore *bs = maybeBackingStore()) { | |
#ifdef QT_MAC_USE_COCOA | |
Q_UNUSED(bs); | |
void qt_mac_set_needs_display(QWidget *, QRegion); | |
qt_mac_set_needs_display(q_func(), region); | |
#else | |
bs->sync(q_func(), region); | |
#endif | |
} | |
} | |
void QWidgetPrivate::setUpdatesEnabled_helper(bool enable) | |
{ | |
Q_Q(QWidget); | |
if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->updatesEnabled()) | |
return; // nothing we can do | |
if (enable != q->testAttribute(Qt::WA_UpdatesDisabled)) | |
return; // nothing to do | |
q->setAttribute(Qt::WA_UpdatesDisabled, !enable); | |
if (enable) | |
q->update(); | |
Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceUpdatesDisabled : Qt::WA_UpdatesDisabled; | |
for (int i = 0; i < children.size(); ++i) { | |
QWidget *w = qobject_cast<QWidget *>(children.at(i)); | |
if (w && !w->isWindow() && !w->testAttribute(attribute)) | |
w->d_func()->setUpdatesEnabled_helper(enable); | |
} | |
} | |
/*! | |
\internal | |
Propagate this widget's palette to all children, except style sheet | |
widgets, and windows that don't enable window propagation (palettes don't | |
normally propagate to windows). | |
*/ | |
void QWidgetPrivate::propagatePaletteChange() | |
{ | |
Q_Q(QWidget); | |
// Propagate a new inherited mask to all children. | |
#ifndef QT_NO_GRAPHICSVIEW | |
if (!q->parentWidget() && extra && extra->proxyWidget) { | |
QGraphicsProxyWidget *p = extra->proxyWidget; | |
inheritedPaletteResolveMask = p->d_func()->inheritedPaletteResolveMask | p->palette().resolve(); | |
} else | |
#endif //QT_NO_GRAPHICSVIEW | |
if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) { | |
inheritedPaletteResolveMask = 0; | |
} | |
int mask = data.pal.resolve() | inheritedPaletteResolveMask; | |
QEvent pc(QEvent::PaletteChange); | |
QApplication::sendEvent(q, &pc); | |
for (int i = 0; i < children.size(); ++i) { | |
QWidget *w = qobject_cast<QWidget*>(children.at(i)); | |
if (w && !w->testAttribute(Qt::WA_StyleSheet) | |
&& (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) { | |
QWidgetPrivate *wd = w->d_func(); | |
wd->inheritedPaletteResolveMask = mask; | |
wd->resolvePalette(); | |
} | |
} | |
#if defined(QT3_SUPPORT) | |
q->paletteChange(q->palette()); // compatibility | |
#endif | |
} | |
/* | |
Returns the widget's clipping rectangle. | |
*/ | |
QRect QWidgetPrivate::clipRect() const | |
{ | |
Q_Q(const QWidget); | |
const QWidget * w = q; | |
if (!w->isVisible()) | |
return QRect(); | |
QRect r = effectiveRectFor(q->rect()); | |
int ox = 0; | |
int oy = 0; | |
while (w | |
&& w->isVisible() | |
&& !w->isWindow() | |
&& w->parentWidget()) { | |
ox -= w->x(); | |
oy -= w->y(); | |
w = w->parentWidget(); | |
r &= QRect(ox, oy, w->width(), w->height()); | |
} | |
return r; | |
} | |
/* | |
Returns the widget's clipping region (without siblings). | |
*/ | |
QRegion QWidgetPrivate::clipRegion() const | |
{ | |
Q_Q(const QWidget); | |
if (!q->isVisible()) | |
return QRegion(); | |
QRegion r(q->rect()); | |
const QWidget * w = q; | |
const QWidget *ignoreUpTo; | |
int ox = 0; | |
int oy = 0; | |
while (w | |
&& w->isVisible() | |
&& !w->isWindow() | |
&& w->parentWidget()) { | |
ox -= w->x(); | |
oy -= w->y(); | |
ignoreUpTo = w; | |
w = w->parentWidget(); | |
r &= QRegion(ox, oy, w->width(), w->height()); | |
int i = 0; | |
while(w->d_func()->children.at(i++) != static_cast<const QObject *>(ignoreUpTo)) | |
; | |
for ( ; i < w->d_func()->children.size(); ++i) { | |
if(QWidget *sibling = qobject_cast<QWidget *>(w->d_func()->children.at(i))) { | |
if(sibling->isVisible() && !sibling->isWindow()) { | |
QRect siblingRect(ox+sibling->x(), oy+sibling->y(), | |
sibling->width(), sibling->height()); | |
if (qRectIntersects(siblingRect, q->rect())) | |
r -= QRegion(siblingRect); | |
} | |
} | |
} | |
} | |
return r; | |
} | |
#ifndef QT_NO_GRAPHICSEFFECT | |
void QWidgetPrivate::invalidateGraphicsEffectsRecursively() | |
{ | |
Q_Q(QWidget); | |
QWidget *w = q; | |
do { | |
if (w->graphicsEffect()) { | |
QWidgetEffectSourcePrivate *sourced = | |
static_cast<QWidgetEffectSourcePrivate *>(w->graphicsEffect()->source()->d_func()); | |
if (!sourced->updateDueToGraphicsEffect) | |
w->graphicsEffect()->source()->d_func()->invalidateCache(); | |
} | |
w = w->parentWidget(); | |
} while (w); | |
} | |
#endif //QT_NO_GRAPHICSEFFECT | |
void QWidgetPrivate::setDirtyOpaqueRegion() | |
{ | |
Q_Q(QWidget); | |
dirtyOpaqueChildren = true; | |
#ifndef QT_NO_GRAPHICSEFFECT | |
invalidateGraphicsEffectsRecursively(); | |
#endif //QT_NO_GRAPHICSEFFECT | |
if (q->isWindow()) | |
return; | |
QWidget *parent = q->parentWidget(); | |
if (!parent) | |
return; | |
// TODO: instead of setting dirtyflag, manipulate the dirtyregion directly? | |
QWidgetPrivate *pd = parent->d_func(); | |
if (!pd->dirtyOpaqueChildren) | |
pd->setDirtyOpaqueRegion(); | |
} | |
const QRegion &QWidgetPrivate::getOpaqueChildren() const | |
{ | |
if (!dirtyOpaqueChildren) | |
return opaqueChildren; | |
QWidgetPrivate *that = const_cast<QWidgetPrivate*>(this); | |
that->opaqueChildren = QRegion(); | |
for (int i = 0; i < children.size(); ++i) { | |
QWidget *child = qobject_cast<QWidget *>(children.at(i)); | |
if (!child || !child->isVisible() || child->isWindow()) | |
continue; | |
const QPoint offset = child->geometry().topLeft(); | |
QWidgetPrivate *childd = child->d_func(); | |
QRegion r = childd->isOpaque ? child->rect() : childd->getOpaqueChildren(); | |
if (childd->extra && childd->extra->hasMask) | |
r &= childd->extra->mask; | |
if (r.isEmpty()) | |
continue; | |
r.translate(offset); | |
that->opaqueChildren += r; | |
} | |
that->opaqueChildren &= q_func()->rect(); | |
that->dirtyOpaqueChildren = false; | |
return that->opaqueChildren; | |
} | |
void QWidgetPrivate::subtractOpaqueChildren(QRegion &source, const QRect &clipRect) const | |
{ | |
if (children.isEmpty() || clipRect.isEmpty()) | |
return; | |
const QRegion &r = getOpaqueChildren(); | |
if (!r.isEmpty()) | |
source -= (r & clipRect); | |
} | |
//subtract any relatives that are higher up than me --- this is too expensive !!! | |
void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirtySiblingsAbove, | |
bool alsoNonOpaque) const | |
{ | |
Q_Q(const QWidget); | |
static int disableSubtractOpaqueSiblings = qgetenv("QT_NO_SUBTRACTOPAQUESIBLINGS").toInt(); | |
if (disableSubtractOpaqueSiblings || q->isWindow()) | |
return; | |
QRect clipBoundingRect; | |
bool dirtyClipBoundingRect = true; | |
QRegion parentClip; | |
bool dirtyParentClip = true; | |
QPoint parentOffset = data.crect.topLeft(); | |
const QWidget *w = q; | |
while (w) { | |
if (w->isWindow()) | |
break; | |
QWidgetPrivate *pd = w->parentWidget()->d_func(); | |
const int myIndex = pd->children.indexOf(const_cast<QWidget *>(w)); | |
const QRect widgetGeometry = w->d_func()->effectiveRectFor(w->data->crect); | |
for (int i = myIndex + 1; i < pd->children.size(); ++i) { | |
QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i)); | |
if (!sibling || !sibling->isVisible() || sibling->isWindow()) | |
continue; | |
const QRect siblingGeometry = sibling->d_func()->effectiveRectFor(sibling->data->crect); | |
if (!qRectIntersects(siblingGeometry, widgetGeometry)) | |
continue; | |
if (dirtyClipBoundingRect) { | |
clipBoundingRect = sourceRegion.boundingRect(); | |
dirtyClipBoundingRect = false; | |
} | |
if (!qRectIntersects(siblingGeometry, clipBoundingRect.translated(parentOffset))) | |
continue; | |
if (dirtyParentClip) { | |
parentClip = sourceRegion.translated(parentOffset); | |
dirtyParentClip = false; | |
} | |
const QPoint siblingPos(sibling->data->crect.topLeft()); | |
const QRect siblingClipRect(sibling->d_func()->clipRect()); | |
QRegion siblingDirty(parentClip); | |
siblingDirty &= (siblingClipRect.translated(siblingPos)); | |
const bool hasMask = sibling->d_func()->extra && sibling->d_func()->extra->hasMask | |
&& !sibling->d_func()->graphicsEffect; | |
if (hasMask) | |
siblingDirty &= sibling->d_func()->extra->mask.translated(siblingPos); | |
if (siblingDirty.isEmpty()) | |
continue; | |
if (sibling->d_func()->isOpaque || alsoNonOpaque) { | |
if (hasMask) { | |
siblingDirty.translate(-parentOffset); | |
sourceRegion -= siblingDirty; | |
} else { | |
sourceRegion -= siblingGeometry.translated(-parentOffset); | |
} | |
} else { | |
if (hasDirtySiblingsAbove) | |
*hasDirtySiblingsAbove = true; | |
if (sibling->d_func()->children.isEmpty()) | |
continue; | |
QRegion opaqueSiblingChildren(sibling->d_func()->getOpaqueChildren()); | |
opaqueSiblingChildren.translate(-parentOffset + siblingPos); | |
sourceRegion -= opaqueSiblingChildren; | |
} | |
if (sourceRegion.isEmpty()) | |
return; | |
dirtyClipBoundingRect = true; | |
dirtyParentClip = true; | |
} | |
w = w->parentWidget(); | |
parentOffset += pd->data.crect.topLeft(); | |
dirtyParentClip = true; | |
} | |
} | |
void QWidgetPrivate::clipToEffectiveMask(QRegion ®ion) const | |
{ | |
Q_Q(const QWidget); | |
const QWidget *w = q; | |
QPoint offset; | |
#ifndef QT_NO_GRAPHICSEFFECT | |
if (graphicsEffect) { | |
w = q->parentWidget(); | |
offset -= data.crect.topLeft(); | |
} | |
#endif //QT_NO_GRAPHICSEFFECT | |
while (w) { | |
const QWidgetPrivate *wd = w->d_func(); | |
if (wd->extra && wd->extra->hasMask) | |
region &= (w != q) ? wd->extra->mask.translated(offset) : wd->extra->mask; | |
if (w->isWindow()) | |
return; | |
offset -= wd->data.crect.topLeft(); | |
w = w->parentWidget(); | |
} | |
} | |
bool QWidgetPrivate::paintOnScreen() const | |
{ | |
#if defined(Q_WS_QWS) | |
return false; | |
#elif defined(QT_NO_BACKINGSTORE) | |
return true; | |
#else | |
Q_Q(const QWidget); | |
if (q->testAttribute(Qt::WA_PaintOnScreen) | |
|| (!q->isWindow() && q->window()->testAttribute(Qt::WA_PaintOnScreen))) { | |
return true; | |
} | |
return !qt_enable_backingstore; | |
#endif | |
} | |
void QWidgetPrivate::updateIsOpaque() | |
{ | |
// hw: todo: only needed if opacity actually changed | |
setDirtyOpaqueRegion(); | |
#ifndef QT_NO_GRAPHICSEFFECT | |
if (graphicsEffect) { | |
// ### We should probably add QGraphicsEffect::isOpaque at some point. | |
setOpaque(false); | |
return; | |
} | |
#endif //QT_NO_GRAPHICSEFFECT | |
Q_Q(QWidget); | |
#ifdef Q_WS_X11 | |
if (q->testAttribute(Qt::WA_X11OpenGLOverlay)) { | |
setOpaque(false); | |
return; | |
} | |
#endif | |
#ifdef Q_WS_S60 | |
if (q->windowType() == Qt::Dialog && q->testAttribute(Qt::WA_TranslucentBackground) | |
&& S60->avkonComponentsSupportTransparency) { | |
setOpaque(false); | |
return; | |
} | |
#endif | |
if (q->testAttribute(Qt::WA_OpaquePaintEvent) || q->testAttribute(Qt::WA_PaintOnScreen)) { | |
setOpaque(true); | |
return; | |
} | |
const QPalette &pal = q->palette(); | |
if (q->autoFillBackground()) { | |
const QBrush &autoFillBrush = pal.brush(q->backgroundRole()); | |
if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) { | |
setOpaque(true); | |
return; | |
} | |
} | |
if (q->isWindow() && !q->testAttribute(Qt::WA_NoSystemBackground)) { | |
const QBrush &windowBrush = q->palette().brush(QPalette::Window); | |
if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) { | |
setOpaque(true); | |
return; | |
} | |
} | |
setOpaque(false); | |
} | |
void QWidgetPrivate::setOpaque(bool opaque) | |
{ | |
if (isOpaque == opaque) | |
return; | |
isOpaque = opaque; | |
#ifdef Q_WS_MAC | |
macUpdateIsOpaque(); | |
#endif | |
#ifdef Q_WS_X11 | |
x11UpdateIsOpaque(); | |
#endif | |
#ifdef Q_WS_WIN | |
winUpdateIsOpaque(); | |
#endif | |
#ifdef Q_OS_SYMBIAN | |
s60UpdateIsOpaque(); | |
#endif | |
} | |
void QWidgetPrivate::updateIsTranslucent() | |
{ | |
#ifdef Q_WS_MAC | |
macUpdateIsOpaque(); | |
#endif | |
#ifdef Q_WS_X11 | |
x11UpdateIsOpaque(); | |
#endif | |
#ifdef Q_WS_WIN | |
winUpdateIsOpaque(); | |
#endif | |
#ifdef Q_OS_SYMBIAN | |
s60UpdateIsOpaque(); | |
#endif | |
} | |
/*! | |
\fn void QPixmap::fill(const QWidget *widget, const QPoint &offset) | |
Fills the pixmap with the \a widget's background color or pixmap | |
according to the given offset. | |
The QPoint \a offset defines a point in widget coordinates to | |
which the pixmap's top-left pixel will be mapped to. This is only | |
significant if the widget has a background pixmap; otherwise the | |
pixmap will simply be filled with the background color of the | |
widget. | |
*/ | |
void QPixmap::fill( const QWidget *widget, const QPoint &off ) | |
{ | |
QPainter p(this); | |
p.translate(-off); | |
widget->d_func()->paintBackground(&p, QRect(off, size())); | |
} | |
static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrush &brush) | |
{ | |
Q_ASSERT(painter); | |
if (brush.style() == Qt::TexturePattern) { | |
#ifdef Q_WS_MAC | |
// Optimize pattern filling on mac by using HITheme directly | |
// when filling with the standard widget background. | |
// Defined in qmacstyle_mac.cpp | |
extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush); | |
qt_mac_fill_background(painter, rgn, brush); | |
#else | |
#if !defined(QT_NO_STYLE_S60) | |
// Defined in qs60style.cpp | |
extern bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush); | |
if (!qt_s60_fill_background(painter, rgn, brush)) | |
#endif // !defined(QT_NO_STYLE_S60) | |
{ | |
const QRect rect(rgn.boundingRect()); | |
painter->setClipRegion(rgn); | |
painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft()); | |
} | |
#endif // Q_WS_MAC | |
} else if (brush.gradient() | |
&& brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode) { | |
painter->save(); | |
painter->setClipRegion(rgn); | |
painter->fillRect(0, 0, painter->device()->width(), painter->device()->height(), brush); | |
painter->restore(); | |
} else { | |
const QVector<QRect> &rects = rgn.rects(); | |
for (int i = 0; i < rects.size(); ++i) | |
painter->fillRect(rects.at(i), brush); | |
} | |
} | |
void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const | |
{ | |
Q_Q(const QWidget); | |
#ifndef QT_NO_SCROLLAREA | |
bool resetBrushOrigin = false; | |
QPointF oldBrushOrigin; | |
//If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture | |
QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent); | |
if (scrollArea && scrollArea->viewport() == q) { | |
QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr.data(); | |
QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate); | |
oldBrushOrigin = painter->brushOrigin(); | |
resetBrushOrigin = true; | |
painter->setBrushOrigin(-priv->contentsOffset()); | |
} | |
#endif // QT_NO_SCROLLAREA | |
const QBrush autoFillBrush = q->palette().brush(q->backgroundRole()); | |
if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) { | |
const QBrush bg = q->palette().brush(QPalette::Window); | |
#ifdef Q_WS_QWS | |
if (!(flags & DontSetCompositionMode) && painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff)) | |
painter->setCompositionMode(QPainter::CompositionMode_Source); //copy alpha straight in | |
#endif | |
fillRegion(painter, rgn, bg); | |
} | |
if (q->autoFillBackground()) | |
fillRegion(painter, rgn, autoFillBrush); | |
if (q->testAttribute(Qt::WA_StyledBackground)) { | |
painter->setClipRegion(rgn); | |
QStyleOption opt; | |
opt.initFrom(q); | |
q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q); | |
} | |
#ifndef QT_NO_SCROLLAREA | |
if (resetBrushOrigin) | |
painter->setBrushOrigin(oldBrushOrigin); | |
#endif // QT_NO_SCROLLAREA | |
} | |
/* | |
\internal | |
This function is called when a widget is hidden or destroyed. | |
It resets some application global pointers that should only refer active, | |
visible widgets. | |
*/ | |
#ifdef Q_WS_MAC | |
extern QPointer<QWidget> qt_button_down; | |
#else | |
extern QWidget *qt_button_down; | |
#endif | |
void QWidgetPrivate::deactivateWidgetCleanup() | |
{ | |
Q_Q(QWidget); | |
// If this was the active application window, reset it | |
if (QApplication::activeWindow() == q) | |
QApplication::setActiveWindow(0); | |
// If the is the active mouse press widget, reset it | |
if (q == qt_button_down) | |
qt_button_down = 0; | |
} | |
/*! | |
Returns a pointer to the widget with window identifer/handle \a | |
id. | |
The window identifier type depends on the underlying window | |
system, see \c qwindowdefs.h for the actual definition. If there | |
is no widget with this identifier, 0 is returned. | |
*/ | |
QWidget *QWidget::find(WId id) | |
{ | |
return QWidgetPrivate::mapper ? QWidgetPrivate::mapper->value(id, 0) : 0; | |
} | |
/*! | |
\fn WId QWidget::internalWinId() const | |
\internal | |
Returns the window system identifier of the widget, or 0 if the widget is not created yet. | |
*/ | |
/*! | |
\fn WId QWidget::winId() const | |
Returns the window system identifier of the widget. | |
Portable in principle, but if you use it you are probably about to | |
do something non-portable. Be careful. | |
If a widget is non-native (alien) and winId() is invoked on it, that widget | |
will be provided a native handle. | |
On Mac OS X, the type returned depends on which framework Qt was linked | |
against. If Qt is using Carbon, the {WId} is actually an HIViewRef. If Qt | |
is using Cocoa, {WId} is a pointer to an NSView. | |
This value may change at run-time. An event with type QEvent::WinIdChange | |
will be sent to the widget following a change in window system identifier. | |
\sa find() | |
*/ | |
WId QWidget::winId() const | |
{ | |
if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) { | |
#ifdef ALIEN_DEBUG | |
qDebug() << "QWidget::winId: creating native window for" << this; | |
#endif | |
QWidget *that = const_cast<QWidget*>(this); | |
that->setAttribute(Qt::WA_NativeWindow); | |
that->d_func()->createWinId(); | |
return that->data->winid; | |
} | |
return data->winid; | |
} | |
void QWidgetPrivate::createWinId(WId winid) | |
{ | |
Q_Q(QWidget); | |
#ifdef ALIEN_DEBUG | |
qDebug() << "QWidgetPrivate::createWinId for" << q << winid; | |
#endif | |
const bool forceNativeWindow = q->testAttribute(Qt::WA_NativeWindow); | |
if (!q->testAttribute(Qt::WA_WState_Created) || (forceNativeWindow && !q->internalWinId())) { | |
if (!q->isWindow()) { | |
QWidget *parent = q->parentWidget(); | |
QWidgetPrivate *pd = parent->d_func(); | |
if (forceNativeWindow && !q->testAttribute(Qt::WA_DontCreateNativeAncestors)) | |
parent->setAttribute(Qt::WA_NativeWindow); | |
if (!parent->internalWinId()) { | |
pd->createWinId(); | |
} | |
for (int i = 0; i < pd->children.size(); ++i) { | |
QWidget *w = qobject_cast<QWidget *>(pd->children.at(i)); | |
if (w && !w->isWindow() && (!w->testAttribute(Qt::WA_WState_Created) | |
|| (!w->internalWinId() && w->testAttribute(Qt::WA_NativeWindow)))) { | |
if (w!=q) { | |
w->create(); | |
} else { | |
w->create(winid); | |
// if the window has already been created, we | |
// need to raise it to its proper stacking position | |
if (winid) | |
w->raise(); | |
} | |
} | |
} | |
} else { | |
q->create(); | |
} | |
} | |
} | |
/*! | |
\internal | |
Ensures that the widget has a window system identifier, i.e. that it is known to the windowing system. | |
*/ | |
void QWidget::createWinId() | |
{ | |
Q_D(QWidget); | |
#ifdef ALIEN_DEBUG | |
qDebug() << "QWidget::createWinId" << this; | |
#endif | |
// qWarning("QWidget::createWinId is obsolete, please fix your code."); | |
d->createWinId(); | |
} | |
/*! | |
\since 4.4 | |
Returns the effective window system identifier of the widget, i.e. the | |
native parent's window system identifier. | |
If the widget is native, this function returns the native widget ID. | |
Otherwise, the window ID of the first native parent widget, i.e., the | |
top-level widget that contains this widget, is returned. | |
\note We recommend that you do not store this value as it is likely to | |
change at run-time. | |
\sa nativeParentWidget() | |
*/ | |
WId QWidget::effectiveWinId() const | |
{ | |
WId id = internalWinId(); | |
if (id || !testAttribute(Qt::WA_WState_Created)) | |
return id; | |
QWidget *realParent = nativeParentWidget(); | |
if (!realParent && d_func()->inSetParent) { | |
// In transitional state. This is really just a workaround. The real problem | |
// is that QWidgetPrivate::setParent_sys (platform specific code) first sets | |
// the window id to 0 (setWinId(0)) before it sets the Qt::WA_WState_Created | |
// attribute to false. The correct way is to do it the other way around, and | |
// in that case the Qt::WA_WState_Created logic above will kick in and | |
// return 0 whenever the widget is in a transitional state. However, changing | |
// the original logic for all platforms is far more intrusive and might | |
// break existing applications. | |
// Note: The widget can only be in a transitional state when changing its | |
// parent -- everything else is an internal error -- hence explicitly checking | |
// against 'inSetParent' rather than doing an unconditional return whenever | |
// 'realParent' is 0 (which may cause strange artifacts and headache later). | |
return 0; | |
} | |
// This widget *must* have a native parent widget. | |
Q_ASSERT(realParent); | |
Q_ASSERT(realParent->internalWinId()); | |
return realParent->internalWinId(); | |
} | |
#ifndef QT_NO_STYLE_STYLESHEET | |
/*! | |
\property QWidget::styleSheet | |
\brief the widget's style sheet | |
\since 4.2 | |
The style sheet contains a textual description of customizations to the | |
widget's style, as described in the \l{Qt Style Sheets} document. | |
Since Qt 4.5, Qt style sheets fully supports Mac OS X. | |
\warning Qt style sheets are currently not supported for custom QStyle | |
subclasses. We plan to address this in some future release. | |
\sa setStyle(), QApplication::styleSheet, {Qt Style Sheets} | |
*/ | |
QString QWidget::styleSheet() const | |
{ | |
Q_D(const QWidget); | |
if (!d->extra) | |
return QString(); | |
return d->extra->styleSheet; | |
} | |
void QWidget::setStyleSheet(const QString& styleSheet) | |
{ | |
Q_D(QWidget); | |
d->createExtra(); | |
QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(d->extra->style); | |
d->extra->styleSheet = styleSheet; | |
if (styleSheet.isEmpty()) { // stylesheet removed | |
if (!proxy) | |
return; | |
d->inheritStyle(); | |
return; | |
} | |
if (proxy) { // style sheet update | |
proxy->repolish(this); | |
return; | |
} | |
if (testAttribute(Qt::WA_SetStyle)) { | |
d->setStyle_helper(new QStyleSheetStyle(d->extra->style), true); | |
} else { | |
d->setStyle_helper(new QStyleSheetStyle(0), true); | |
} | |
} | |
#endif // QT_NO_STYLE_STYLESHEET | |
/*! | |
\sa QWidget::setStyle(), QApplication::setStyle(), QApplication::style() | |
*/ | |
QStyle *QWidget::style() const | |
{ | |
Q_D(const QWidget); | |
if (d->extra && d->extra->style) | |
return d->extra->style; | |
return QApplication::style(); | |
} | |
/*! | |
Sets the widget's GUI style to \a style. The ownership of the style | |
object is not transferred. | |
If no style is set, the widget uses the application's style, | |
QApplication::style() instead. | |
Setting a widget's style has no effect on existing or future child | |
widgets. | |
\warning This function is particularly useful for demonstration | |
purposes, where you want to show Qt's styling capabilities. Real | |
applications should avoid it and use one consistent GUI style | |
instead. | |
\warning Qt style sheets are currently not supported for custom QStyle | |
subclasses. We plan to address this in some future release. | |
\sa style(), QStyle, QApplication::style(), QApplication::setStyle() | |
*/ | |
void QWidget::setStyle(QStyle *style) | |
{ | |
Q_D(QWidget); | |
setAttribute(Qt::WA_SetStyle, style != 0); | |
d->createExtra(); | |
#ifndef QT_NO_STYLE_STYLESHEET | |
if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(style)) { | |
//if for some reason someone try to set a QStyleSheetStyle, ref it | |
//(this may happen for exemple in QButtonDialogBox which propagates its style) | |
proxy->ref(); | |
d->setStyle_helper(style, false); | |
} else if (qobject_cast<QStyleSheetStyle *>(d->extra->style) || !qApp->styleSheet().isEmpty()) { | |
// if we have an application stylesheet or have a proxy already, propagate | |
d->setStyle_helper(new QStyleSheetStyle(style), true); | |
} else | |
#endif | |
d->setStyle_helper(style, false); | |
} | |
void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool | |
#ifdef Q_WS_MAC | |
metalHack | |
#endif | |
) | |
{ | |
Q_Q(QWidget); | |
QStyle *oldStyle = q->style(); | |
#ifndef QT_NO_STYLE_STYLESHEET | |
QWeakPointer<QStyle> origStyle; | |
#endif | |
#ifdef Q_WS_MAC | |
// the metalhack boolean allows Qt/Mac to do a proper re-polish depending | |
// on how the Qt::WA_MacBrushedMetal attribute is set. It is only ever | |
// set when changing that attribute and passes the widget's CURRENT style. | |
// therefore no need to do a reassignment. | |
if (!metalHack) | |
#endif | |
{ | |
createExtra(); | |
#ifndef QT_NO_STYLE_STYLESHEET | |
origStyle = extra->style.data(); | |
#endif | |
extra->style = newStyle; | |
} | |
// repolish | |
if (q->windowType() != Qt::Desktop) { | |
if (polished) { | |
oldStyle->unpolish(q); | |
#ifdef Q_WS_MAC | |
if (metalHack) | |
macUpdateMetalAttribute(); | |
#endif | |
q->style()->polish(q); | |
#ifdef Q_WS_MAC | |
} else if (metalHack) { | |
macUpdateMetalAttribute(); | |
#endif | |
} | |
} | |
if (propagate) { | |
for (int i = 0; i < children.size(); ++i) { | |
QWidget *c = qobject_cast<QWidget*>(children.at(i)); | |
if (c) | |
c->d_func()->inheritStyle(); | |
} | |
} | |
#ifndef QT_NO_STYLE_STYLESHEET | |
if (!qobject_cast<QStyleSheetStyle*>(newStyle)) { | |
if (const QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(origStyle.data())) { | |
cssStyle->clearWidgetFont(q); | |
} | |
} | |
#endif | |
QEvent e(QEvent::StyleChange); | |
QApplication::sendEvent(q, &e); | |
#ifdef QT3_SUPPORT | |
q->styleChange(*oldStyle); | |
#endif | |
#ifndef QT_NO_STYLE_STYLESHEET | |
// dereference the old stylesheet style | |
if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(origStyle.data())) | |
proxy->deref(); | |
#endif | |
} | |
// Inherits style from the current parent and propagates it as necessary | |
void QWidgetPrivate::inheritStyle() | |
{ | |
#ifndef QT_NO_STYLE_STYLESHEET | |
Q_Q(QWidget); | |
QStyleSheetStyle *proxy = extra ? qobject_cast<QStyleSheetStyle *>(extra->style) : 0; | |
if (!q->styleSheet().isEmpty()) { | |
Q_ASSERT(proxy); | |
proxy->repolish(q); | |
return; | |
} | |
QStyle *origStyle = proxy ? proxy->base : (extra ? (QStyle*)extra->style : 0); | |
QWidget *parent = q->parentWidget(); | |
QStyle *parentStyle = (parent && parent->d_func()->extra) ? (QStyle*)parent->d_func()->extra->style : 0; | |
// If we have stylesheet on app or parent has stylesheet style, we need | |
// to be running a proxy | |
if (!qApp->styleSheet().isEmpty() || qobject_cast<QStyleSheetStyle *>(parentStyle)) { | |
QStyle *newStyle = parentStyle; | |
if (q->testAttribute(Qt::WA_SetStyle)) | |
newStyle = new QStyleSheetStyle(origStyle); | |
else if (QStyleSheetStyle *newProxy = qobject_cast<QStyleSheetStyle *>(parentStyle)) | |
newProxy->ref(); | |
setStyle_helper(newStyle, true); | |
return; | |
} | |
// So, we have no stylesheet on parent/app and we have an empty stylesheet | |
// we just need our original style back | |
if (origStyle == (extra ? (QStyle*)extra->style : 0)) // is it any different? | |
return; | |
// We could have inherited the proxy from our parent (which has a custom style) | |
// In such a case we need to start following the application style (i.e revert | |
// the propagation behavior of QStyleSheetStyle) | |
if (!q->testAttribute(Qt::WA_SetStyle)) | |
origStyle = 0; | |
setStyle_helper(origStyle, true); | |
#endif // QT_NO_STYLE_STYLESHEET | |
} | |
#ifdef QT3_SUPPORT | |
/*! | |
\overload | |
Sets the widget's GUI style to \a style using the QStyleFactory. | |
*/ | |
QStyle* QWidget::setStyle(const QString &style) | |
{ | |
QStyle *s = QStyleFactory::create(style); | |
setStyle(s); | |
return s; | |
} | |
#endif | |
/*! | |
\fn bool QWidget::isWindow() const | |
Returns true if the widget is an independent window, otherwise | |
returns false. | |
A window is a widget that isn't visually the child of any other | |
widget and that usually has a frame and a | |
\l{QWidget::setWindowTitle()}{window title}. | |
A window can have a \l{QWidget::parentWidget()}{parent widget}. | |
It will then be grouped with its parent and deleted when the | |
parent is deleted, minimized when the parent is minimized etc. If | |
supported by the window manager, it will also have a common | |
taskbar entry with its parent. | |
QDialog and QMainWindow widgets are by default windows, even if a | |
parent widget is specified in the constructor. This behavior is | |
specified by the Qt::Window flag. | |
\sa window(), isModal(), parentWidget() | |
*/ | |
/*! | |
\property QWidget::modal | |
\brief whether the widget is a modal widget | |
This property only makes sense for windows. A modal widget | |
prevents widgets in all other windows from getting any input. | |
By default, this property is false. | |
\sa isWindow(), windowModality, QDialog | |
*/ | |
/*! | |
\property QWidget::windowModality | |
\brief which windows are blocked by the modal widget | |
\since 4.1 | |
This property only makes sense for windows. A modal widget | |
prevents widgets in other windows from getting input. The value of | |
this property controls which windows are blocked when the widget | |
is visible. Changing this property while the window is visible has | |
no effect; you must hide() the widget first, then show() it again. | |
By default, this property is Qt::NonModal. | |
\sa isWindow(), QWidget::modal, QDialog | |
*/ | |
Qt::WindowModality QWidget::windowModality() const | |
{ | |
return static_cast<Qt::WindowModality>(data->window_modality); | |
} | |
void QWidget::setWindowModality(Qt::WindowModality windowModality) | |
{ | |
data->window_modality = windowModality; | |
// setModal_sys() will be called by setAttribute() | |
setAttribute(Qt::WA_ShowModal, (data->window_modality != Qt::NonModal)); | |
setAttribute(Qt::WA_SetWindowModality, true); | |
} | |
/*! | |
\fn bool QWidget::underMouse() const | |
Returns true if the widget is under the mouse cursor; otherwise | |
returns false. | |
This value is not updated properly during drag and drop | |
operations. | |
\sa enterEvent(), leaveEvent() | |
*/ | |
/*! | |
\property QWidget::minimized | |
\brief whether this widget is minimized (iconified) | |
This property is only relevant for windows. | |
By default, this property is false. | |
\sa showMinimized(), visible, show(), hide(), showNormal(), maximized | |
*/ | |
bool QWidget::isMinimized() const | |
{ return data->window_state & Qt::WindowMinimized; } | |
/*! | |
Shows the widget minimized, as an icon. | |
Calling this function only affects \l{isWindow()}{windows}. | |
\sa showNormal(), showMaximized(), show(), hide(), isVisible(), | |
isMinimized() | |
*/ | |
void QWidget::showMinimized() | |
{ | |
bool isMin = isMinimized(); | |
if (isMin && isVisible()) | |
return; | |
ensurePolished(); | |
#ifdef QT3_SUPPORT | |
if (parent()) | |
QApplication::sendPostedEvents(parent(), QEvent::ChildInserted); | |
#endif | |
if (!isMin) | |
setWindowState((windowState() & ~Qt::WindowActive) | Qt::WindowMinimized); | |
show(); | |
} | |
/*! | |
\property QWidget::maximized | |
\brief whether this widget is maximized | |
This property is only relevant for windows. | |
\note Due to limitations on some window systems, this does not always | |
report the expected results (e.g., if the user on X11 maximizes the | |
window via the window manager, Qt has no way of distinguishing this | |
from any other resize). This is expected to improve as window manager | |
protocols evolve. | |
By default, this property is false. | |
\sa windowState(), showMaximized(), visible, show(), hide(), showNormal(), minimized | |
*/ | |
bool QWidget::isMaximized() const | |
{ return data->window_state & Qt::WindowMaximized; } | |
/*! | |
Returns the current window state. The window state is a OR'ed | |
combination of Qt::WindowState: Qt::WindowMinimized, | |
Qt::WindowMaximized, Qt::WindowFullScreen, and Qt::WindowActive. | |
\sa Qt::WindowState setWindowState() | |
*/ | |
Qt::WindowStates QWidget::windowState() const | |
{ | |
return Qt::WindowStates(data->window_state); | |
} | |
/*!\internal | |
The function sets the window state on child widgets similar to | |
setWindowState(). The difference is that the window state changed | |
event has the isOverride() flag set. It exists mainly to keep | |
Q3Workspace working. | |
*/ | |
void QWidget::overrideWindowState(Qt::WindowStates newstate) | |
{ | |
QWindowStateChangeEvent e(Qt::WindowStates(data->window_state), true); | |
data->window_state = newstate; | |
QApplication::sendEvent(this, &e); | |
} | |
/*! | |
\fn void QWidget::setWindowState(Qt::WindowStates windowState) | |
Sets the window state to \a windowState. The window state is a OR'ed | |
combination of Qt::WindowState: Qt::WindowMinimized, | |
Qt::WindowMaximized, Qt::WindowFullScreen, and Qt::WindowActive. | |
If the window is not visible (i.e. isVisible() returns false), the | |
window state will take effect when show() is called. For visible | |
windows, the change is immediate. For example, to toggle between | |
full-screen and normal mode, use the following code: | |
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 0 | |
In order to restore and activate a minimized window (while | |
preserving its maximized and/or full-screen state), use the following: | |
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 1 | |
Calling this function will hide the widget. You must call show() to make | |
the widget visible again. | |
\note On some window systems Qt::WindowActive is not immediate, and may be | |
ignored in certain cases. | |
When the window state changes, the widget receives a changeEvent() | |
of type QEvent::WindowStateChange. | |
\sa Qt::WindowState windowState() | |
*/ | |
/*! | |
\property QWidget::fullScreen | |
\brief whether the widget is shown in full screen mode | |
A widget in full screen mode occupies the whole screen area and does not | |
display window decorations, such as a title bar. | |
By default, this property is false. | |
\sa windowState(), minimized, maximized | |
*/ | |
bool QWidget::isFullScreen() const | |
{ return data->window_state & Qt::WindowFullScreen; } | |
/*! | |
Shows the widget in full-screen mode. | |
Calling this function only affects \l{isWindow()}{windows}. | |
To return from full-screen mode, call showNormal(). | |
Full-screen mode works fine under Windows, but has certain | |
problems under X. These problems are due to limitations of the | |
ICCCM protocol that specifies the communication between X11 | |
clients and the window manager. ICCCM simply does not understand | |
the concept of non-decorated full-screen windows. Therefore, the | |
best we can do is to request a borderless window and place and | |
resize it to fill the entire screen. Depending on the window | |
manager, this may or may not work. The borderless window is | |
requested using MOTIF hints, which are at least partially | |
supported by virtually all modern window managers. | |
An alternative would be to bypass the window manager entirely and | |
create a window with the Qt::X11BypassWindowManagerHint flag. This | |
has other severe problems though, like totally broken keyboard focus | |
and very strange effects on desktop changes or when the user raises | |
other windows. | |
X11 window managers that follow modern post-ICCCM specifications | |
support full-screen mode properly. | |
\sa showNormal(), showMaximized(), show(), hide(), isVisible() | |
*/ | |
void QWidget::showFullScreen() | |
{ | |
#ifdef Q_WS_MAC | |
// If the unified toolbar is enabled, we have to disable it before going fullscreen. | |
QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this); | |
if (mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()) { | |
mainWindow->setUnifiedTitleAndToolBarOnMac(false); | |
QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout()); | |
mainLayout->activateUnifiedToolbarAfterFullScreen = true; | |
} | |
#endif // Q_WS_MAC | |
ensurePolished(); | |
#ifdef QT3_SUPPORT | |
if (parent()) | |
QApplication::sendPostedEvents(parent(), QEvent::ChildInserted); | |
#endif | |
setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowMaximized)) | |
| Qt::WindowFullScreen); | |
show(); | |
activateWindow(); | |
} | |
/*! | |
Shows the widget maximized. | |
Calling this function only affects \l{isWindow()}{windows}. | |
On X11, this function may not work properly with certain window | |
managers. See the \l{Window Geometry} documentation for an explanation. | |
\sa setWindowState(), showNormal(), showMinimized(), show(), hide(), isVisible() | |
*/ | |
void QWidget::showMaximized() | |
{ | |
ensurePolished(); | |
#ifdef QT3_SUPPORT | |
if (parent()) | |
QApplication::sendPostedEvents(parent(), QEvent::ChildInserted); | |
#endif | |
setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen)) | |
| Qt::WindowMaximized); | |
#ifdef Q_WS_MAC | |
// If the unified toolbar was enabled before going fullscreen, we have to enable it back. | |
QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this); | |
if (mainWindow) | |
{ | |
QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout()); | |
if (mainLayout->activateUnifiedToolbarAfterFullScreen) { | |
mainWindow->setUnifiedTitleAndToolBarOnMac(true); | |
mainLayout->activateUnifiedToolbarAfterFullScreen = false; | |
} | |
} | |
#endif // Q_WS_MAC | |
show(); | |
} | |
/*! | |
Restores the widget after it has been maximized or minimized. | |
Calling this function only affects \l{isWindow()}{windows}. | |
\sa setWindowState(), showMinimized(), showMaximized(), show(), hide(), isVisible() | |
*/ | |
void QWidget::showNormal() | |
{ | |
ensurePolished(); | |
#ifdef QT3_SUPPORT | |
if (parent()) | |
QApplication::sendPostedEvents(parent(), QEvent::ChildInserted); | |
#endif | |
setWindowState(windowState() & ~(Qt::WindowMinimized | |
| Qt::WindowMaximized | |
| Qt::WindowFullScreen)); | |
#ifdef Q_WS_MAC | |
// If the unified toolbar was enabled before going fullscreen, we have to enable it back. | |
QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this); | |
if (mainWindow) | |
{ | |
QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout()); | |
if (mainLayout->activateUnifiedToolbarAfterFullScreen) { | |
mainWindow->setUnifiedTitleAndToolBarOnMac(true); | |
mainLayout->activateUnifiedToolbarAfterFullScreen = false; | |
} | |
} | |
#endif // Q_WS_MAC | |
show(); | |
} | |
/*! | |
Returns true if this widget would become enabled if \a ancestor is | |
enabled; otherwise returns false. | |
This is the case if neither the widget itself nor every parent up | |
to but excluding \a ancestor has been explicitly disabled. | |
isEnabledTo(0) is equivalent to isEnabled(). | |
\sa setEnabled() enabled | |
*/ | |
bool QWidget::isEnabledTo(QWidget* ancestor) const | |
{ | |
const QWidget * w = this; | |
while (!w->testAttribute(Qt::WA_ForceDisabled) | |
&& !w->isWindow() | |
&& w->parentWidget() | |
&& w->parentWidget() != ancestor) | |
w = w->parentWidget(); | |
return !w->testAttribute(Qt::WA_ForceDisabled); | |
} | |
#ifndef QT_NO_ACTION | |
/*! | |
Appends the action \a action to this widget's list of actions. | |
All QWidgets have a list of \l{QAction}s, however they can be | |
represented graphically in many different ways. The default use of | |
the QAction list (as returned by actions()) is to create a context | |
QMenu. | |
A QWidget should only have one of each action and adding an action | |
it already has will not cause the same action to be in the widget twice. | |
The ownership of \a action is not transferred to this QWidget. | |
\sa removeAction(), insertAction(), actions(), QMenu | |
*/ | |
void QWidget::addAction(QAction *action) | |
{ | |
insertAction(0, action); | |
} | |
/*! | |
Appends the actions \a actions to this widget's list of actions. | |
\sa removeAction(), QMenu, addAction() | |
*/ | |
void QWidget::addActions(QList<QAction*> actions) | |
{ | |
for(int i = 0; i < actions.count(); i++) | |
insertAction(0, actions.at(i)); | |
} | |
/*! | |
Inserts the action \a action to this widget's list of actions, | |
before the action \a before. It appends the action if \a before is 0 or | |
\a before is not a valid action for this widget. | |
A QWidget should only have one of each action. | |
\sa removeAction(), addAction(), QMenu, contextMenuPolicy, actions() | |
*/ | |
void QWidget::insertAction(QAction *before, QAction *action) | |
{ | |
if(!action) { | |
qWarning("QWidget::insertAction: Attempt to insert null action"); | |
return; | |
} | |
Q_D(QWidget); | |
if(d->actions.contains(action)) | |
removeAction(action); | |
int pos = d->actions.indexOf(before); | |
if (pos < 0) { | |
before = 0; | |
pos = d->actions.size(); | |
} | |
d->actions.insert(pos, action); | |
QActionPrivate *apriv = action->d_func(); | |
apriv->widgets.append(this); | |
QActionEvent e(QEvent::ActionAdded, action, before); | |
QApplication::sendEvent(this, &e); | |
} | |
/*! | |
Inserts the actions \a actions to this widget's list of actions, | |
before the action \a before. It appends the action if \a before is 0 or | |
\a before is not a valid action for this widget. | |
A QWidget can have at most one of each action. | |
\sa removeAction(), QMenu, insertAction(), contextMenuPolicy | |
*/ | |
void QWidget::insertActions(QAction *before, QList<QAction*> actions) | |
{ | |
for(int i = 0; i < actions.count(); ++i) | |
insertAction(before, actions.at(i)); | |
} | |
/*! | |
Removes the action \a action from this widget's list of actions. | |
\sa insertAction(), actions(), insertAction() | |
*/ | |
void QWidget::removeAction(QAction *action) | |
{ | |
if (!action) | |
return; | |
Q_D(QWidget); | |
QActionPrivate *apriv = action->d_func(); | |
apriv->widgets.removeAll(this); | |
if (d->actions.removeAll(action)) { | |
QActionEvent e(QEvent::ActionRemoved, action); | |
QApplication::sendEvent(this, &e); | |
} | |
} | |
/*! | |
Returns the (possibly empty) list of this widget's actions. | |
\sa contextMenuPolicy, insertAction(), removeAction() | |
*/ | |
QList<QAction*> QWidget::actions() const | |
{ | |
Q_D(const QWidget); | |
return d->actions; | |
} | |
#endif // QT_NO_ACTION | |
/*! | |
\fn bool QWidget::isEnabledToTLW() const | |
\obsolete | |
This function is deprecated. It is equivalent to isEnabled() | |
*/ | |
/*! | |
\property QWidget::enabled | |
\brief whether the widget is enabled | |
An enabled widget handles keyboard and mouse events; a disabled | |
widget does not. | |
Some widgets display themselves differently when they are | |
disabled. For example a button might draw its label grayed out. If | |
your widget needs to know when it becomes enabled or disabled, you | |
can use the changeEvent() with type QEvent::EnabledChange. | |
Disabling a widget implicitly disables all its children. Enabling | |
respectively enables all child widgets unless they have been | |
explicitly disabled. | |
By default, this property is true. | |
\sa isEnabledTo(), QKeyEvent, QMouseEvent, changeEvent() | |
*/ | |
void QWidget::setEnabled(bool enable) | |
{ | |
Q_D(QWidget); | |
setAttribute(Qt::WA_ForceDisabled, !enable); | |
d->setEnabled_helper(enable); | |
} | |
void QWidgetPrivate::setEnabled_helper(bool enable) | |
{ | |
Q_Q(QWidget); | |
if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->isEnabled()) | |
return; // nothing we can do | |
if (enable != q->testAttribute(Qt::WA_Disabled)) | |
return; // nothing to do | |
q->setAttribute(Qt::WA_Disabled, !enable); | |
updateSystemBackground(); | |
if (!enable && q->window()->focusWidget() == q) { | |
bool parentIsEnabled = (!q->parentWidget() || q->parentWidget()->isEnabled()); | |
if (!parentIsEnabled || !q->focusNextChild()) | |
q->clearFocus(); | |
} | |
Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceDisabled : Qt::WA_Disabled; | |
for (int i = 0; i < children.size(); ++i) { | |
QWidget *w = qobject_cast<QWidget *>(children.at(i)); | |
if (w && !w->testAttribute(attribute)) | |
w->d_func()->setEnabled_helper(enable); | |
} | |
#if defined(Q_WS_X11) | |
if (q->testAttribute(Qt::WA_SetCursor) || q->isWindow()) { | |
// enforce the windows behavior of clearing the cursor on | |
// disabled widgets | |
qt_x11_enforce_cursor(q); | |
} | |
#endif | |
#if defined(Q_WS_MAC) | |
setEnabled_helper_sys(enable); | |
#endif | |
#ifndef QT_NO_IM | |
if (q->testAttribute(Qt::WA_InputMethodEnabled) && q->hasFocus()) { | |
QWidget *focusWidget = effectiveFocusWidget(); | |
QInputContext *qic = focusWidget->d_func()->inputContext(); | |
if (enable) { | |
if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) | |
qic->setFocusWidget(focusWidget); | |
} else { | |
qic->reset(); | |
qic->setFocusWidget(0); | |
} | |
} | |
#endif //QT_NO_IM | |
QEvent e(QEvent::EnabledChange); | |
QApplication::sendEvent(q, &e); | |
#ifdef QT3_SUPPORT | |
q->enabledChange(!enable); // compatibility | |
#endif | |
} | |
/*! | |
\property QWidget::acceptDrops | |
\brief whether drop events are enabled for this widget | |
Setting this property to true announces to the system that this | |
widget \e may be able to accept drop events. | |
If the widget is the desktop (windowType() == Qt::Desktop), this may | |
fail if another application is using the desktop; you can call | |
acceptDrops() to test if this occurs. | |
\warning Do not modify this property in a drag and drop event handler. | |
By default, this property is false. | |
\sa {Drag and Drop} | |
*/ | |
bool QWidget::acceptDrops() const | |
{ | |
return testAttribute(Qt::WA_AcceptDrops); | |
} | |
void QWidget::setAcceptDrops(bool on) | |
{ | |
setAttribute(Qt::WA_AcceptDrops, on); | |
} | |
/*! | |
\fn void QWidget::enabledChange(bool) | |
\internal | |
\obsolete | |
*/ | |
/*! | |
\fn void QWidget::paletteChange(const QPalette &) | |
\internal | |
\obsolete | |
*/ | |
/*! | |
\fn void QWidget::fontChange(const QFont &) | |
\internal | |
\obsolete | |
*/ | |
/*! | |
\fn void QWidget::windowActivationChange(bool) | |
\internal | |
\obsolete | |
*/ | |
/*! | |
\fn void QWidget::languageChange() | |
\obsolete | |
*/ | |
/*! | |
\fn void QWidget::styleChange(QStyle& style) | |
\internal | |
\obsolete | |
*/ | |
/*! | |
Disables widget input events if \a disable is true; otherwise | |
enables input events. | |
See the \l enabled documentation for more information. | |
\sa isEnabledTo(), QKeyEvent, QMouseEvent, changeEvent() | |
*/ | |
void QWidget::setDisabled(bool disable) | |
{ | |
setEnabled(!disable); | |
} | |
/*! | |
\property QWidget::frameGeometry | |
\brief geometry of the widget relative to its parent including any | |
window frame | |
See the \l{Window Geometry} documentation for an overview of geometry | |
issues with windows. | |
By default, this property contains a value that depends on the user's | |
platform and screen geometry. | |
\sa geometry() x() y() pos() | |
*/ | |
QRect QWidget::frameGeometry() const | |
{ | |
Q_D(const QWidget); | |
if (isWindow() && ! (windowType() == Qt::Popup)) { | |
QRect fs = d->frameStrut(); | |
return QRect(data->crect.x() - fs.left(), | |
data->crect.y() - fs.top(), | |
data->crect.width() + fs.left() + fs.right(), | |
data->crect.height() + fs.top() + fs.bottom()); | |
} | |
return data->crect; | |
} | |
/*! | |
\property QWidget::x | |
\brief the x coordinate of the widget relative to its parent including | |
any window frame | |
See the \l{Window Geometry} documentation for an overview of geometry | |
issues with windows. | |
By default, this property has a value of 0. | |
\sa frameGeometry, y, pos | |
*/ | |
int QWidget::x() const | |
{ | |
Q_D(const QWidget); | |
if (isWindow() && ! (windowType() == Qt::Popup)) | |
return data->crect.x() - d->frameStrut().left(); | |
return data->crect.x(); | |
} | |
/*! | |
\property QWidget::y | |
\brief the y coordinate of the widget relative to its parent and | |
including any window frame | |
See the \l{Window Geometry} documentation for an overview of geometry | |
issues with windows. | |
By default, this property has a value of 0. | |
\sa frameGeometry, x, pos | |
*/ | |
int QWidget::y() const | |
{ | |
Q_D(const QWidget); | |
if (isWindow() && ! (windowType() == Qt::Popup)) | |
return data->crect.y() - d->frameStrut().top(); | |
return data->crect.y(); | |
} | |
/*! | |
\property QWidget::pos | |
\brief the position of the widget within its parent widget | |
If the widget is a window, the position is that of the widget on | |
the desktop, including its frame. | |
When changing the position, the widget, if visible, receives a | |
move event (moveEvent()) immediately. If the widget is not | |
currently visible, it is guaranteed to receive an event before it | |
is shown. | |
By default, this property contains a position that refers to the | |
origin. | |
\warning Calling move() or setGeometry() inside moveEvent() can | |
lead to infinite recursion. | |
See the \l{Window Geometry} documentation for an overview of geometry | |
issues with windows. | |
\sa frameGeometry, size x(), y() | |
*/ | |
QPoint QWidget::pos() const | |
{ | |
Q_D(const QWidget); | |
if (isWindow() && ! (windowType() == Qt::Popup)) { | |
QRect fs = d->frameStrut(); | |
return QPoint(data->crect.x() - fs.left(), data->crect.y() - fs.top()); | |
} | |
return data->crect.topLeft(); | |
} | |
/*! | |
\property QWidget::geometry | |
\brief the geometry of the widget relative to its parent and | |
excluding the window frame | |
When changing the geometry, the widget, if visible, receives a | |
move event (moveEvent()) and/or a resize event (resizeEvent()) | |
immediately. If the widget is not currently visible, it is | |
guaranteed to receive appropriate events before it is shown. | |
The size component is adjusted if it lies outside the range | |
defined by minimumSize() and maximumSize(). | |
\warning Calling setGeometry() inside resizeEvent() or moveEvent() | |
can lead to infinite recursion. | |
See the \l{Window Geometry} documentation for an overview of geometry | |
issues with windows. | |
By default, this property contains a value that depends on the user's | |
platform and screen geometry. | |
\sa frameGeometry(), rect(), move(), resize(), moveEvent(), | |
resizeEvent(), minimumSize(), maximumSize() | |
*/ | |
/*! | |
\property QWidget::normalGeometry | |
\brief the geometry of the widget as it will appear when shown as | |
a normal (not maximized or full screen) top-level widget | |
For child widgets this property always holds an empty rectangle. | |
By default, this property contains an empty rectangle. | |
\sa QWidget::windowState(), QWidget::geometry | |
*/ | |
/*! | |
\property QWidget::size | |
\brief the size of the widget excluding any window frame | |
If the widget is visible when it is being resized, it receives a resize event | |
(resizeEvent()) immediately. If the widget is not currently | |
visible, it is guaranteed to receive an event before it is shown. | |
The size is adjusted if it lies outside the range defined by | |
minimumSize() and maximumSize(). | |
By default, this property contains a value that depends on the user's | |
platform and screen geometry. | |
\warning Calling resize() or setGeometry() inside resizeEvent() can | |
lead to infinite recursion. | |
\note Setting the size to \c{QSize(0, 0)} will cause the widget to not | |
appear on screen. This also applies to windows. | |
\sa pos, geometry, minimumSize, maximumSize, resizeEvent(), adjustSize() | |
*/ | |
/*! | |
\property QWidget::width | |
\brief the width of the widget excluding any window frame | |
See the \l{Window Geometry} documentation for an overview of geometry | |
issues with windows. | |
\note Do not use this function to find the width of a screen on | |
a \l{QDesktopWidget}{multiple screen desktop}. Read | |
\l{QDesktopWidget#Screen Geometry}{this note} for details. | |
By default, this property contains a value that depends on the user's | |
platform and screen geometry. | |
\sa geometry, height, size | |
*/ | |
/*! | |
\property QWidget::height | |
\brief the height of the widget excluding any window frame | |
See the \l{Window Geometry} documentation for an overview of geometry | |
issues with windows. | |
\note Do not use this function to find the height of a screen | |
on a \l{QDesktopWidget}{multiple screen desktop}. Read | |
\l{QDesktopWidget#Screen Geometry}{this note} for details. | |
By default, this property contains a value that depends on the user's | |
platform and screen geometry. | |
\sa geometry, width, size | |
*/ | |
/*! | |
\property QWidget::rect | |
\brief the internal geometry of the widget excluding any window | |
frame | |
The rect property equals QRect(0, 0, width(), height()). | |
See the \l{Window Geometry} documentation for an overview of geometry | |
issues with windows. | |
By default, this property contains a value that depends on the user's | |
platform and screen geometry. | |
\sa size | |
*/ | |
QRect QWidget::normalGeometry() const | |
{ | |
Q_D(const QWidget); | |
if (!d->extra || !d->extra->topextra) | |
return QRect(); | |
if (!isMaximized() && !isFullScreen()) | |
return geometry(); | |
return d->topData()->normalGeometry; | |
} | |
/*! | |
\property QWidget::childrenRect | |
\brief the bounding rectangle of the widget's children | |
Hidden children are excluded. | |
By default, for a widget with no children, this property contains a | |
rectangle with zero width and height located at the origin. | |
\sa childrenRegion() geometry() | |
*/ | |
QRect QWidget::childrenRect() const | |
{ | |
Q_D(const QWidget); | |
QRect r(0, 0, 0, 0); | |
for (int i = 0; i < d->children.size(); ++i) { | |
QWidget *w = qobject_cast<QWidget *>(d->children.at(i)); | |
if (w && !w->isWindow() && !w->isHidden()) | |
r |= w->geometry(); | |
} | |
return r; | |
} | |
/*! | |
\property QWidget::childrenRegion | |
\brief the combined region occupied by the widget's children | |
Hidden children are excluded. | |
By default, for a widget with no children, this property contains an | |
empty region. | |
\sa childrenRect() geometry() mask() | |
*/ | |
QRegion QWidget::childrenRegion() const | |
{ | |
Q_D(const QWidget); | |
QRegion r; | |
for (int i = 0; i < d->children.size(); ++i) { | |
QWidget *w = qobject_cast<QWidget *>(d->children.at(i)); | |
if (w && !w->isWindow() && !w->isHidden()) { | |
QRegion mask = w->mask(); | |
if (mask.isEmpty()) | |
r |= w->geometry(); | |
else | |
r |= mask.translated(w->pos()); | |
} | |
} | |
return r; | |
} | |
/*! | |
\property QWidget::minimumSize | |
\brief the widget's minimum size | |
The widget cannot be resized to a smaller size than the minimum | |
widget size. The widget's size is forced to the minimum size if | |
the current size is smaller. | |
The minimum size set by this function will override the minimum size | |
defined by QLayout. In order to unset the minimum size, use a | |
value of \c{QSize(0, 0)}. | |
By default, this property contains a size with zero width and height. | |
\sa minimumWidth, minimumHeight, maximumSize, sizeIncrement | |
*/ | |
QSize QWidget::minimumSize() const | |
{ | |
Q_D(const QWidget); | |
return d->extra ? QSize(d->extra->minw, d->extra->minh) : QSize(0, 0); | |
} | |
/*! | |
\property QWidget::maximumSize | |
\brief the widget's maximum size in pixels | |
The widget cannot be resized to a larger size than the maximum | |
widget size. | |
By default, this property contains a size in which both width and height | |
have values of 16777215. | |
\note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size | |
of widgets. | |
\sa maximumWidth, maximumHeight, minimumSize, sizeIncrement | |
*/ | |
QSize QWidget::maximumSize() const | |
{ | |
Q_D(const QWidget); | |
return d->extra ? QSize(d->extra->maxw, d->extra->maxh) | |
: QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); | |
} | |
/*! | |
\property QWidget::minimumWidth | |
\brief the widget's minimum width in pixels | |
This property corresponds to the width held by the \l minimumSize property. | |
By default, this property has a value of 0. | |
\sa minimumSize, minimumHeight | |
*/ | |
/*! | |
\property QWidget::minimumHeight | |
\brief the widget's minimum height in pixels | |
This property corresponds to the height held by the \l minimumSize property. | |
By default, this property has a value of 0. | |
\sa minimumSize, minimumWidth | |
*/ | |
/*! | |
\property QWidget::maximumWidth | |
\brief the widget's maximum width in pixels | |
This property corresponds to the width held by the \l maximumSize property. | |
By default, this property contains a value of 16777215. | |
\note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size | |
of widgets. | |
\sa maximumSize, maximumHeight | |
*/ | |
/*! | |
\property QWidget::maximumHeight | |
\brief the widget's maximum height in pixels | |
This property corresponds to the height held by the \l maximumSize property. | |
By default, this property contains a value of 16777215. | |
\note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size | |
of widgets. | |
\sa maximumSize, maximumWidth | |
*/ | |
/*! | |
\property QWidget::sizeIncrement | |
\brief the size increment of the widget | |
When the user resizes the window, the size will move in steps of | |
sizeIncrement().width() pixels horizontally and | |
sizeIncrement.height() pixels vertically, with baseSize() as the | |
basis. Preferred widget sizes are for non-negative integers \e i | |
and \e j: | |
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 2 | |
Note that while you can set the size increment for all widgets, it | |
only affects windows. | |
By default, this property contains a size with zero width and height. | |
\warning The size increment has no effect under Windows, and may | |
be disregarded by the window manager on X11. | |
\sa size, minimumSize, maximumSize | |
*/ | |
QSize QWidget::sizeIncrement() const | |
{ | |
Q_D(const QWidget); | |
return (d->extra && d->extra->topextra) | |
? QSize(d->extra->topextra->incw, d->extra->topextra->inch) | |
: QSize(0, 0); | |
} | |
/*! | |
\property QWidget::baseSize | |
\brief the base size of the widget | |
The base size is used to calculate a proper widget size if the | |
widget defines sizeIncrement(). | |
By default, for a newly-created widget, this property contains a size with | |
zero width and height. | |
\sa setSizeIncrement() | |
*/ | |
QSize QWidget::baseSize() const | |
{ | |
Q_D(const QWidget); | |
return (d->extra != 0 && d->extra->topextra != 0) | |
? QSize(d->extra->topextra->basew, d->extra->topextra->baseh) | |
: QSize(0, 0); | |
} | |
bool QWidgetPrivate::setMinimumSize_helper(int &minw, int &minh) | |
{ | |
Q_Q(QWidget); | |
#ifdef Q_WS_QWS | |
if (q->isWindow()) { | |
const QRect maxWindowRect = QApplication::desktop()->availableGeometry(QApplication::desktop()->screenNumber(q)); | |
if (!maxWindowRect.isEmpty()) { | |
// ### This is really just a work-around. Layout shouldn't be | |
// asking for minimum sizes bigger than the screen. | |
if (minw > maxWindowRect.width()) | |
minw = maxWindowRect.width(); | |
if (minh > maxWindowRect.height()) | |
minh = maxWindowRect.height(); | |
} | |
} | |
#endif | |
int mw = minw, mh = minh; | |
if (mw == QWIDGETSIZE_MAX) | |
mw = 0; | |
if (mh == QWIDGETSIZE_MAX) | |
mh = 0; | |
if (minw > QWIDGETSIZE_MAX || minh > QWIDGETSIZE_MAX) { | |
qWarning("QWidget::setMinimumSize: (%s/%s) " | |
"The largest allowed size is (%d,%d)", | |
q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX, | |
QWIDGETSIZE_MAX); | |
minw = mw = qMin<int>(minw, QWIDGETSIZE_MAX); | |
minh = mh = qMin<int>(minh, QWIDGETSIZE_MAX); | |
} | |
if (minw < 0 || minh < 0) { | |
qWarning("QWidget::setMinimumSize: (%s/%s) Negative sizes (%d,%d) " | |
"are not possible", | |
q->objectName().toLocal8Bit().data(), q->metaObject()->className(), minw, minh); | |
minw = mw = qMax(minw, 0); | |
minh = mh = qMax(minh, 0); | |
} | |
createExtra(); | |
if (extra->minw == mw && extra->minh == mh) | |
return false; | |
extra->minw = mw; | |
extra->minh = mh; | |
extra->explicitMinSize = (mw ? Qt::Horizontal : 0) | (mh ? Qt::Vertical : 0); | |
return true; | |
} | |
/*! | |
\overload | |
This function corresponds to setMinimumSize(QSize(minw, minh)). | |
Sets the minimum width to \a minw and the minimum height to \a | |
minh. | |
*/ | |
void QWidget::setMinimumSize(int minw, int minh) | |
{ | |
Q_D(QWidget); | |
if (!d->setMinimumSize_helper(minw, minh)) | |
return; | |
if (isWindow()) | |
d->setConstraints_sys(); | |
if (minw > width() || minh > height()) { | |
bool resized = testAttribute(Qt::WA_Resized); | |
bool maximized = isMaximized(); | |
resize(qMax(minw,width()), qMax(minh,height())); | |
setAttribute(Qt::WA_Resized, resized); //not a user resize | |
if (maximized) | |
data->window_state = data->window_state | Qt::WindowMaximized; | |
} | |
#ifndef QT_NO_GRAPHICSVIEW | |
if (d->extra) { | |
if (d->extra->proxyWidget) | |
d->extra->proxyWidget->setMinimumSize(minw, minh); | |
} | |
#endif | |
d->updateGeometry_helper(d->extra->minw == d->extra->maxw && d->extra->minh == d->extra->maxh); | |
} | |
bool QWidgetPrivate::setMaximumSize_helper(int &maxw, int &maxh) | |
{ | |
Q_Q(QWidget); | |
if (maxw > QWIDGETSIZE_MAX || maxh > QWIDGETSIZE_MAX) { | |
qWarning("QWidget::setMaximumSize: (%s/%s) " | |
"The largest allowed size is (%d,%d)", | |
q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX, | |
QWIDGETSIZE_MAX); | |
maxw = qMin<int>(maxw, QWIDGETSIZE_MAX); | |
maxh = qMin<int>(maxh, QWIDGETSIZE_MAX); | |
} | |
if (maxw < 0 || maxh < 0) { | |
qWarning("QWidget::setMaximumSize: (%s/%s) Negative sizes (%d,%d) " | |
"are not possible", | |
q->objectName().toLocal8Bit().data(), q->metaObject()->className(), maxw, maxh); | |
maxw = qMax(maxw, 0); | |
maxh = qMax(maxh, 0); | |
} | |
createExtra(); | |
if (extra->maxw == maxw && extra->maxh == maxh) | |
return false; | |
extra->maxw = maxw; | |
extra->maxh = maxh; | |
extra->explicitMaxSize = (maxw != QWIDGETSIZE_MAX ? Qt::Horizontal : 0) | | |
(maxh != QWIDGETSIZE_MAX ? Qt::Vertical : 0); | |
return true; | |
} | |
/*! | |
\overload | |
This function corresponds to setMaximumSize(QSize(\a maxw, \a | |
maxh)). Sets the maximum width to \a maxw and the maximum height | |
to \a maxh. | |
*/ | |
void QWidget::setMaximumSize(int maxw, int maxh) | |
{ | |
Q_D(QWidget); | |
if (!d->setMaximumSize_helper(maxw, maxh)) | |
return; | |
if (isWindow()) | |
d->setConstraints_sys(); | |
if (maxw < width() || maxh < height()) { | |
bool resized = testAttribute(Qt::WA_Resized); | |
resize(qMin(maxw,width()), qMin(maxh,height())); | |
setAttribute(Qt::WA_Resized, resized); //not a user resize | |
} | |
#ifndef QT_NO_GRAPHICSVIEW | |
if (d->extra) { | |
if (d->extra->proxyWidget) | |
d->extra->proxyWidget->setMaximumSize(maxw, maxh); | |
} | |
#endif | |
d->updateGeometry_helper(d->extra->minw == d->extra->maxw && d->extra->minh == d->extra->maxh); | |
} | |
/*! | |
\overload | |
Sets the x (width) size increment to \a w and the y (height) size | |
increment to \a h. | |
*/ | |
void QWidget::setSizeIncrement(int w, int h) | |
{ | |
Q_D(QWidget); | |
d->createTLExtra(); | |
QTLWExtra* x = d->topData(); | |
if (x->incw == w && x->inch == h) | |
return; | |
x->incw = w; | |
x->inch = h; | |
if (isWindow()) | |
d->setConstraints_sys(); | |
} | |
/*! | |
\overload | |
This corresponds to setBaseSize(QSize(\a basew, \a baseh)). Sets | |
the widgets base size to width \a basew and height \a baseh. | |
*/ | |
void QWidget::setBaseSize(int basew, int baseh) | |
{ | |
Q_D(QWidget); | |
d->createTLExtra(); | |
QTLWExtra* x = d->topData(); | |
if (x->basew == basew && x->baseh == baseh) | |
return; | |
x->basew = basew; | |
x->baseh = baseh; | |
if (isWindow()) | |
d->setConstraints_sys(); | |
} | |
/*! | |
Sets both the minimum and maximum sizes of the widget to \a s, | |
thereby preventing it from ever growing or shrinking. | |
This will override the default size constraints set by QLayout. | |
To remove constraints, set the size to QWIDGETSIZE_MAX. | |
Alternatively, if you want the widget to have a | |
fixed size based on its contents, you can call | |
QLayout::setSizeConstraint(QLayout::SetFixedSize); | |
\sa maximumSize, minimumSize | |
*/ | |
void QWidget::setFixedSize(const QSize & s) | |
{ | |
setFixedSize(s.width(), s.height()); | |
} | |
/*! | |
\fn void QWidget::setFixedSize(int w, int h) | |
\overload | |
Sets the width of the widget to \a w and the height to \a h. | |
*/ | |
void QWidget::setFixedSize(int w, int h) | |
{ | |
Q_D(QWidget); | |
#ifdef Q_WS_QWS | |
// temporary fix for 4.3.x. | |
// Should move the embedded spesific contraints in setMinimumSize_helper into QLayout | |
int tmpW = w; | |
int tmpH = h; | |
bool minSizeSet = d->setMinimumSize_helper(tmpW, tmpH); | |
#else | |
bool minSizeSet = d->setMinimumSize_helper(w, h); | |
#endif | |
bool maxSizeSet = d->setMaximumSize_helper(w, h); | |
if (!minSizeSet && !maxSizeSet) | |
return; | |
if (isWindow()) | |
d->setConstraints_sys(); | |
else | |
d->updateGeometry_helper(true); | |
if (w != QWIDGETSIZE_MAX || h != QWIDGETSIZE_MAX) | |
resize(w, h); | |
} | |
void QWidget::setMinimumWidth(int w) | |
{ | |
Q_D(QWidget); | |
d->createExtra(); | |
uint expl = d->extra->explicitMinSize | (w ? Qt::Horizontal : 0); | |
setMinimumSize(w, minimumSize().height()); | |
d->extra->explicitMinSize = expl; | |
} | |
void QWidget::setMinimumHeight(int h) | |
{ | |
Q_D(QWidget); | |
d->createExtra(); | |
uint expl = d->extra->explicitMinSize | (h ? Qt::Vertical : 0); | |
setMinimumSize(minimumSize().width(), h); | |
d->extra->explicitMinSize = expl; | |
} | |
void QWidget::setMaximumWidth(int w) | |
{ | |
Q_D(QWidget); | |
d->createExtra(); | |
uint expl = d->extra->explicitMaxSize | (w == QWIDGETSIZE_MAX ? 0 : Qt::Horizontal); | |
setMaximumSize(w, maximumSize().height()); | |
d->extra->explicitMaxSize = expl; | |
} | |
void QWidget::setMaximumHeight(int h) | |
{ | |
Q_D(QWidget); | |
d->createExtra(); | |
uint expl = d->extra->explicitMaxSize | (h == QWIDGETSIZE_MAX ? 0 : Qt::Vertical); | |
setMaximumSize(maximumSize().width(), h); | |
d->extra->explicitMaxSize = expl; | |
} | |
/*! | |
Sets both the minimum and maximum width of the widget to \a w | |
without changing the heights. Provided for convenience. | |
\sa sizeHint() minimumSize() maximumSize() setFixedSize() | |
*/ | |
void QWidget::setFixedWidth(int w) | |
{ | |
Q_D(QWidget); | |
d->createExtra(); | |
uint explMin = d->extra->explicitMinSize | Qt::Horizontal; | |
uint explMax = d->extra->explicitMaxSize | Qt::Horizontal; | |
setMinimumSize(w, minimumSize().height()); | |
setMaximumSize(w, maximumSize().height()); | |
d->extra->explicitMinSize = explMin; | |
d->extra->explicitMaxSize = explMax; | |
} | |
/*! | |
Sets both the minimum and maximum heights of the widget to \a h | |
without changing the widths. Provided for convenience. | |
\sa sizeHint() minimumSize() maximumSize() setFixedSize() | |
*/ | |
void QWidget::setFixedHeight(int h) | |
{ | |
Q_D(QWidget); | |
d->createExtra(); | |
uint explMin = d->extra->explicitMinSize | Qt::Vertical; | |
uint explMax = d->extra->explicitMaxSize | Qt::Vertical; | |
setMinimumSize(minimumSize().width(), h); | |
setMaximumSize(maximumSize().width(), h); | |
d->extra->explicitMinSize = explMin; | |
d->extra->explicitMaxSize = explMax; | |
} | |
/*! | |
Translates the widget coordinate \a pos to the coordinate system | |
of \a parent. The \a parent must not be 0 and must be a parent | |
of the calling widget. | |
\sa mapFrom() mapToParent() mapToGlobal() underMouse() | |
*/ | |
QPoint QWidget::mapTo(QWidget * parent, const QPoint & pos) const | |
{ | |
QPoint p = pos; | |
if (parent) { | |
const QWidget * w = this; | |
while (w != parent) { | |
Q_ASSERT_X(w, "QWidget::mapTo(QWidget *parent, const QPoint &pos)", | |
"parent must be in parent hierarchy"); | |
p = w->mapToParent(p); | |
w = w->parentWidget(); | |
} | |
} | |
return p; | |
} | |
/*! | |
Translates the widget coordinate \a pos from the coordinate system | |
of \a parent to this widget's coordinate system. The \a parent | |
must not be 0 and must be a parent of the calling widget. | |
\sa mapTo() mapFromParent() mapFromGlobal() underMouse() | |
*/ | |
QPoint QWidget::mapFrom(QWidget * parent, const QPoint & pos) const | |
{ | |
QPoint p(pos); | |
if (parent) { | |
const QWidget * w = this; | |
while (w != parent) { | |
Q_ASSERT_X(w, "QWidget::mapFrom(QWidget *parent, const QPoint &pos)", | |
"parent must be in parent hierarchy"); | |
p = w->mapFromParent(p); | |
w = w->parentWidget(); | |
} | |
} | |
return p; | |
} | |
/*! | |
Translates the widget coordinate \a pos to a coordinate in the | |
parent widget. | |
Same as mapToGlobal() if the widget has no parent. | |
\sa mapFromParent() mapTo() mapToGlobal() underMouse() | |
*/ | |
QPoint QWidget::mapToParent(const QPoint &pos) const | |
{ | |
return pos + data->crect.topLeft(); | |
} | |
/*! | |
Translates the parent widget coordinate \a pos to widget | |
coordinates. | |
Same as mapFromGlobal() if the widget has no parent. | |
\sa mapToParent() mapFrom() mapFromGlobal() underMouse() | |
*/ | |
QPoint QWidget::mapFromParent(const QPoint &pos) const | |
{ | |
return pos - data->crect.topLeft(); | |
} | |
/*! | |
Returns the window for this widget, i.e. the next ancestor widget | |
that has (or could have) a window-system frame. | |
If the widget is a window, the widget itself is returned. | |
Typical usage is changing the window title: | |
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 3 | |
\sa isWindow() | |
*/ | |
QWidget *QWidget::window() const | |
{ | |
QWidget *w = (QWidget *)this; | |
QWidget *p = w->parentWidget(); | |
while (!w->isWindow() && p) { | |
w = p; | |
p = p->parentWidget(); | |
} | |
return w; | |
} | |
/*! | |
\since 4.4 | |
Returns the native parent for this widget, i.e. the next ancestor widget | |
that has a system identifier, or 0 if it does not have any native parent. | |
\sa effectiveWinId() | |
*/ | |
QWidget *QWidget::nativeParentWidget() const | |
{ | |
QWidget *parent = parentWidget(); | |
while (parent && !parent->internalWinId()) | |
parent = parent->parentWidget(); | |
return parent; | |
} | |
/*! \fn QWidget *QWidget::topLevelWidget() const | |
\obsolete | |
Use window() instead. | |
*/ | |
#ifdef QT3_SUPPORT | |
/*! | |
Returns the color role used for painting the widget's background. | |
Use QPalette(backgroundRole(()) instead. | |
*/ | |
Qt::BackgroundMode QWidget::backgroundMode() const | |
{ | |
if (testAttribute(Qt::WA_NoSystemBackground)) | |
return Qt::NoBackground; | |
switch(backgroundRole()) { | |
case QPalette::WindowText: | |
return Qt::PaletteForeground; | |
case QPalette::Button: | |
return Qt::PaletteButton; | |
case QPalette::Light: | |
return Qt::PaletteLight; | |
case QPalette::Midlight: | |
return Qt::PaletteMidlight; | |
case QPalette::Dark: | |
return Qt::PaletteDark; | |
case QPalette::Mid: | |
return Qt::PaletteMid; | |
case QPalette::Text: | |
return Qt::PaletteText; | |
case QPalette::BrightText: | |
return Qt::PaletteBrightText; | |
case QPalette::Base: | |
return Qt::PaletteBase; | |
case QPalette::Window: | |
return Qt::PaletteBackground; | |
case QPalette::Shadow: | |
return Qt::PaletteShadow; | |
case QPalette::Highlight: | |
return Qt::PaletteHighlight; | |
case QPalette::HighlightedText: | |
return Qt::PaletteHighlightedText; | |
case QPalette::ButtonText: | |
return Qt::PaletteButtonText; | |
case QPalette::Link: | |
return Qt::PaletteLink; | |
case QPalette::LinkVisited: | |
return Qt::PaletteLinkVisited; | |
default: | |
break; | |
} | |
return Qt::NoBackground; | |
} | |
/*! | |
\fn void QWidget::setBackgroundMode(Qt::BackgroundMode | |
widgetBackground, Qt::BackgroundMode paletteBackground) | |
Sets the color role used for painting the widget's background to | |
background mode \a widgetBackground. The \a paletteBackground mode | |
parameter is ignored. | |
*/ | |
void QWidget::setBackgroundMode(Qt::BackgroundMode m, Qt::BackgroundMode) | |
{ | |
Q_D(QWidget); | |
if(m == Qt::NoBackground) { | |
setAttribute(Qt::WA_NoSystemBackground, true); | |
return; | |
} | |
setAttribute(Qt::WA_NoSystemBackground, false); | |
d->fg_role = QPalette::NoRole; | |
QPalette::ColorRole role = d->bg_role; | |
switch(m) { | |
case Qt::FixedColor: | |
case Qt::FixedPixmap: | |
break; | |
case Qt::PaletteForeground: | |
role = QPalette::WindowText; | |
break; | |
case Qt::PaletteButton: | |
role = QPalette::Button; | |
break; | |
case Qt::PaletteLight: | |
role = QPalette::Light; | |
break; | |
case Qt::PaletteMidlight: | |
role = QPalette::Midlight; | |
break; | |
case Qt::PaletteDark: | |
role = QPalette::Dark; | |
break; | |
case Qt::PaletteMid: | |
role = QPalette::Mid; | |
break; | |
case Qt::PaletteText: | |
role = QPalette::Text; | |
break; | |
case Qt::PaletteBrightText: | |
role = QPalette::BrightText; | |
break; | |
case Qt::PaletteBase: | |
role = QPalette::Base; | |
break; | |
case Qt::PaletteBackground: | |
role = QPalette::Window; | |
break; | |
case Qt::PaletteShadow: | |
role = QPalette::Shadow; | |
break; | |
case Qt::PaletteHighlight: | |
role = QPalette::Highlight; | |
break; | |
case Qt::PaletteHighlightedText: | |
role = QPalette::HighlightedText; | |
break; | |
case Qt::PaletteButtonText: | |
role = QPalette::ButtonText; | |
break; | |
case Qt::PaletteLink: | |
role = QPalette::Link; | |
break; | |
case Qt::PaletteLinkVisited: | |
role = QPalette::LinkVisited; | |
break; | |
case Qt::X11ParentRelative: | |
d->fg_role = role = QPalette::NoRole; | |
default: | |
break; | |
} | |
setBackgroundRole(role); | |
} | |
/*! | |
The widget mapper is no longer part of the public API. | |
*/ | |
QT3_SUPPORT QWidgetMapper *QWidget::wmapper() { return QWidgetPrivate::mapper; } | |
#endif | |
/*! | |
Returns the background role of the widget. | |
The background role defines the brush from the widget's \l palette that | |
is used to render the background. | |
If no explicit background role is set, the widget inherts its parent | |
widget's background role. | |
\sa setBackgroundRole(), foregroundRole() | |
*/ | |
QPalette::ColorRole QWidget::backgroundRole() const | |
{ | |
const QWidget *w = this; | |
do { | |
QPalette::ColorRole role = w->d_func()->bg_role; | |
if (role != QPalette::NoRole) | |
return role; | |
if (w->isWindow() || w->windowType() == Qt::SubWindow) | |
break; | |
w = w->parentWidget(); | |
} while (w); | |
return QPalette::Window; | |
} | |
/*! | |
Sets the background role of the widget to \a role. | |
The background role defines the brush from the widget's \l palette that | |
is used to render the background. | |
If \a role is QPalette::NoRole, then the widget inherits its | |
parent's background role. | |
Note that styles are free to choose any color from the palette. | |
You can modify the palette or set a style sheet if you don't | |
achieve the result you want with setBackgroundRole(). | |
\sa backgroundRole(), foregroundRole() | |
*/ | |
void QWidget::setBackgroundRole(QPalette::ColorRole role) | |
{ | |
Q_D(QWidget); | |
d->bg_role = role; | |
d->updateSystemBackground(); | |
d->propagatePaletteChange(); | |
d->updateIsOpaque(); | |
} | |
/*! | |
Returns the foreground role. | |
The foreground role defines the color from the widget's \l palette that | |
is used to draw the foreground. | |
If no explicit foreground role is set, the function returns a role | |
that contrasts with the background role. | |
\sa setForegroundRole(), backgroundRole() | |
*/ | |
QPalette::ColorRole QWidget::foregroundRole() const | |
{ | |
Q_D(const QWidget); | |
QPalette::ColorRole rl = QPalette::ColorRole(d->fg_role); | |
if (rl != QPalette::NoRole) | |
return rl; | |
QPalette::ColorRole role = QPalette::WindowText; | |
switch (backgroundRole()) { | |
case QPalette::Button: | |
role = QPalette::ButtonText; | |
break; | |
case QPalette::Base: | |
role = QPalette::Text; | |
break; | |
case QPalette::Dark: | |
case QPalette::Shadow: | |
role = QPalette::Light; | |
break; | |
case QPalette::Highlight: | |
role = QPalette::HighlightedText; | |
break; | |
case QPalette::ToolTipBase: | |
role = QPalette::ToolTipText; | |
break; | |
default: | |
; | |
} | |
return role; | |
} | |
/*! | |
Sets the foreground role of the widget to \a role. | |
The foreground role defines the color from the widget's \l palette that | |
is used to draw the foreground. | |
If \a role is QPalette::NoRole, the widget uses a foreground role | |
that contrasts with the background role. | |
Note that styles are free to choose any color from the palette. | |
You can modify the palette or set a style sheet if you don't | |
achieve the result you want with setForegroundRole(). | |
\sa foregroundRole(), backgroundRole() | |
*/ | |
void QWidget::setForegroundRole(QPalette::ColorRole role) | |
{ | |
Q_D(QWidget); | |
d->fg_role = role; | |
d->updateSystemBackground(); | |
d->propagatePaletteChange(); | |
} | |
/*! | |
\property QWidget::palette | |
\brief the widget's palette | |
This property describes the widget's palette. The palette is used by the | |
widget's style when rendering standard components, and is available as a | |
means to ensure that custom widgets can maintain consistency with the | |
native platform's look and feel. It's common that different platforms, or | |
different styles, have different palettes. | |
When you assign a new palette to a widget, the color roles from this | |
palette are combined with the widget's default palette to form the | |
widget's final palette. The palette entry for the widget's background role | |
is used to fill the widget's background (see QWidget::autoFillBackground), | |
and the foreground role initializes QPainter's pen. | |
The default depends on the system environment. QApplication maintains a | |
system/theme palette which serves as a default for all widgets. There may | |
also be special palette defaults for certain types of widgets (e.g., on | |
Windows XP and Vista, all classes that derive from QMenuBar have a special | |
default palette). You can also define default palettes for widgets | |
yourself by passing a custom palette and the name of a widget to | |
QApplication::setPalette(). Finally, the style always has the option of | |
polishing the palette as it's assigned (see QStyle::polish()). | |
QWidget propagates explicit palette roles from parent to child. If you | |
assign a brush or color to a specific role on a palette and assign that | |
palette to a widget, that role will propagate to all the widget's | |
children, overriding any system defaults for that role. Note that palettes | |
by default don't propagate to windows (see isWindow()) unless the | |
Qt::WA_WindowPropagation attribute is enabled. | |
QWidget's palette propagation is similar to its font propagation. | |
The current style, which is used to render the content of all standard Qt | |
widgets, is free to choose colors and brushes from the widget palette, or | |
in some cases, to ignore the palette (partially, or completely). In | |
particular, certain styles like GTK style, Mac style, Windows XP, and | |
Vista style, depend on third party APIs to render the content of widgets, | |
and these styles typically do not follow the palette. Because of this, | |
assigning roles to a widget's palette is not guaranteed to change the | |
appearance of the widget. Instead, you may choose to apply a \l | |
styleSheet. You can refer to our Knowledge Base article | |
\l{http://qt.nokia.com/developer/knowledgebase/22}{here} for more | |
information. | |
\warning Do not use this function in conjunction with \l{Qt Style Sheets}. | |
When using style sheets, the palette of a widget can be customized using | |
the "color", "background-color", "selection-color", | |
"selection-background-color" and "alternate-background-color". | |
\sa QApplication::palette(), QWidget::font() | |
*/ | |
const QPalette &QWidget::palette() const | |
{ | |
if (!isEnabled()) { | |
data->pal.setCurrentColorGroup(QPalette::Disabled); | |
} else if ((!isVisible() || isActiveWindow()) | |
#if defined(Q_OS_WIN) && !defined(Q_WS_WINCE) | |
&& !QApplicationPrivate::isBlockedByModal(const_cast<QWidget *>(this)) | |
#endif | |
) { | |
data->pal.setCurrentColorGroup(QPalette::Active); | |
} else { | |
#ifdef Q_WS_MAC | |
extern bool qt_mac_can_clickThrough(const QWidget *); //qwidget_mac.cpp | |
if (qt_mac_can_clickThrough(this)) | |
data->pal.setCurrentColorGroup(QPalette::Active); | |
else | |
#endif | |
data->pal.setCurrentColorGroup(QPalette::Inactive); | |
} | |
return data->pal; | |
} | |
void QWidget::setPalette(const QPalette &palette) | |
{ | |
Q_D(QWidget); | |
setAttribute(Qt::WA_SetPalette, palette.resolve() != 0); | |
// Determine which palette is inherited from this widget's ancestors and | |
// QApplication::palette, resolve this against \a palette (attributes from | |
// the inherited palette are copied over this widget's palette). Then | |
// propagate this palette to this widget's children. | |
QPalette naturalPalette = d->naturalWidgetPalette(d->inheritedPaletteResolveMask); | |
QPalette resolvedPalette = palette.resolve(naturalPalette); | |
d->setPalette_helper(resolvedPalette); | |
} | |
/*! | |
\internal | |
Returns the palette that the widget \a w inherits from its ancestors and | |
QApplication::palette. \a inheritedMask is the combination of the widget's | |
ancestors palette request masks (i.e., which attributes from the parent | |
widget's palette are implicitly imposed on this widget by the user). Note | |
that this font does not take into account the palette set on \a w itself. | |
*/ | |
QPalette QWidgetPrivate::naturalWidgetPalette(uint inheritedMask) const | |
{ | |
Q_Q(const QWidget); | |
QPalette naturalPalette = QApplication::palette(q); | |
if (!q->testAttribute(Qt::WA_StyleSheet) | |
&& (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation) | |
#ifndef QT_NO_GRAPHICSVIEW | |
|| (extra && extra->proxyWidget) | |
#endif //QT_NO_GRAPHICSVIEW | |
)) { | |
if (QWidget *p = q->parentWidget()) { | |
if (!p->testAttribute(Qt::WA_StyleSheet)) { | |
if (!naturalPalette.isCopyOf(QApplication::palette())) { | |
QPalette inheritedPalette = p->palette(); | |
inheritedPalette.resolve(inheritedMask); | |
naturalPalette = inheritedPalette.resolve(naturalPalette); | |
} else { | |
naturalPalette = p->palette(); | |
} | |
} | |
} | |
#ifndef QT_NO_GRAPHICSVIEW | |
else if (extra && extra->proxyWidget) { | |
QPalette inheritedPalette = extra->proxyWidget->palette(); | |
inheritedPalette.resolve(inheritedMask); | |
naturalPalette = inheritedPalette.resolve(naturalPalette); | |
} | |
#endif //QT_NO_GRAPHICSVIEW | |
} | |
naturalPalette.resolve(0); | |
return naturalPalette; | |
} | |
/*! | |
\internal | |
Determine which palette is inherited from this widget's ancestors and | |
QApplication::palette, resolve this against this widget's palette | |
(attributes from the inherited palette are copied over this widget's | |
palette). Then propagate this palette to this widget's children. | |
*/ | |
void QWidgetPrivate::resolvePalette() | |
{ | |
QPalette naturalPalette = naturalWidgetPalette(inheritedPaletteResolveMask); | |
QPalette resolvedPalette = data.pal.resolve(naturalPalette); | |
setPalette_helper(resolvedPalette); | |
} | |
void QWidgetPrivate::setPalette_helper(const QPalette &palette) | |
{ | |
Q_Q(QWidget); | |
if (data.pal == palette && data.pal.resolve() == palette.resolve()) | |
return; | |
data.pal = palette; | |
updateSystemBackground(); | |
propagatePaletteChange(); | |
updateIsOpaque(); | |
q->update(); | |
updateIsOpaque(); | |
} | |
/*! | |
\property QWidget::font | |
\brief the font currently set for the widget | |
This property describes the widget's requested font. The font is used by | |
the widget's style when rendering standard components, and is available as | |
a means to ensure that custom widgets can maintain consistency with the | |
native platform's look and feel. It's common that different platforms, or | |
different styles, define different fonts for an application. | |
When you assign a new font to a widget, the properties from this font are | |
combined with the widget's default font to form the widget's final | |
font. You can call fontInfo() to get a copy of the widget's final | |
font. The final font is also used to initialize QPainter's font. | |
The default depends on the system environment. QApplication maintains a | |
system/theme font which serves as a default for all widgets. There may | |
also be special font defaults for certain types of widgets. You can also | |
define default fonts for widgets yourself by passing a custom font and the | |
name of a widget to QApplication::setFont(). Finally, the font is matched | |
against Qt's font database to find the best match. | |
QWidget propagates explicit font properties from parent to child. If you | |
change a specific property on a font and assign that font to a widget, | |
that property will propagate to all the widget's children, overriding any | |
system defaults for that property. Note that fonts by default don't | |
propagate to windows (see isWindow()) unless the Qt::WA_WindowPropagation | |
attribute is enabled. | |
QWidget's font propagation is similar to its palette propagation. | |
The current style, which is used to render the content of all standard Qt | |
widgets, is free to choose to use the widget font, or in some cases, to | |
ignore it (partially, or completely). In particular, certain styles like | |
GTK style, Mac style, Windows XP, and Vista style, apply special | |
modifications to the widget font to match the platform's native look and | |
feel. Because of this, assigning properties to a widget's font is not | |
guaranteed to change the appearance of the widget. Instead, you may choose | |
to apply a \l styleSheet. | |
\note If \l{Qt Style Sheets} are used on the same widget as setFont(), | |
style sheets will take precedence if the settings conflict. | |
\sa fontInfo(), fontMetrics() | |
*/ | |
void QWidget::setFont(const QFont &font) | |
{ | |
Q_D(QWidget); | |
#ifndef QT_NO_STYLE_STYLESHEET | |
const QStyleSheetStyle* style; | |
if (d->extra && (style = qobject_cast<const QStyleSheetStyle*>(d->extra->style))) { | |
style->saveWidgetFont(this, font); | |
} | |
#endif | |
setAttribute(Qt::WA_SetFont, font.resolve() != 0); | |
// Determine which font is inherited from this widget's ancestors and | |
// QApplication::font, resolve this against \a font (attributes from the | |
// inherited font are copied over). Then propagate this font to this | |
// widget's children. | |
QFont naturalFont = d->naturalWidgetFont(d->inheritedFontResolveMask); | |
QFont resolvedFont = font.resolve(naturalFont); | |
d->setFont_helper(resolvedFont); | |
} | |
/* | |
\internal | |
Returns the font that the widget \a w inherits from its ancestors and | |
QApplication::font. \a inheritedMask is the combination of the widget's | |
ancestors font request masks (i.e., which attributes from the parent | |
widget's font are implicitly imposed on this widget by the user). Note | |
that this font does not take into account the font set on \a w itself. | |
### Stylesheet has a different font propagation mechanism. When a stylesheet | |
is applied, fonts are not propagated anymore | |
*/ | |
QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const | |
{ | |
Q_Q(const QWidget); | |
QFont naturalFont = QApplication::font(q); | |
if (!q->testAttribute(Qt::WA_StyleSheet) | |
&& (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation) | |
#ifndef QT_NO_GRAPHICSVIEW | |
|| (extra && extra->proxyWidget) | |
#endif //QT_NO_GRAPHICSVIEW | |
)) { | |
if (QWidget *p = q->parentWidget()) { | |
if (!p->testAttribute(Qt::WA_StyleSheet)) { | |
if (!naturalFont.isCopyOf(QApplication::font())) { | |
QFont inheritedFont = p->font(); | |
inheritedFont.resolve(inheritedMask); | |
naturalFont = inheritedFont.resolve(naturalFont); | |
} else { | |
naturalFont = p->font(); | |
} | |
} | |
} | |
#ifndef QT_NO_GRAPHICSVIEW | |
else if (extra && extra->proxyWidget) { | |
QFont inheritedFont = extra->proxyWidget->font(); | |
inheritedFont.resolve(inheritedMask); | |
naturalFont = inheritedFont.resolve(naturalFont); | |
} | |
#endif //QT_NO_GRAPHICSVIEW | |
} | |
naturalFont.resolve(0); | |
return naturalFont; | |
} | |
/*! | |
\internal | |
Determine which font is implicitly imposed on this widget by its ancestors | |
and QApplication::font, resolve this against its own font (attributes from | |
the implicit font are copied over). Then propagate this font to this | |
widget's children. | |
*/ | |
void QWidgetPrivate::resolveFont() | |
{ | |
QFont naturalFont = naturalWidgetFont(inheritedFontResolveMask); | |
QFont resolvedFont = data.fnt.resolve(naturalFont); | |
setFont_helper(resolvedFont); | |
} | |
/*! | |
\internal | |
Assign \a font to this widget, and propagate it to all children, except | |
style sheet widgets (handled differently) and windows that don't enable | |
window propagation. \a implicitMask is the union of all ancestor widgets' | |
font request masks, and determines which attributes from this widget's | |
font should propagate. | |
*/ | |
void QWidgetPrivate::updateFont(const QFont &font) | |
{ | |
Q_Q(QWidget); | |
#ifndef QT_NO_STYLE_STYLESHEET | |
const QStyleSheetStyle* cssStyle; | |
cssStyle = extra ? qobject_cast<const QStyleSheetStyle*>(extra->style) : 0; | |
#endif | |
#ifdef QT3_SUPPORT | |
QFont old = data.fnt; | |
#endif | |
data.fnt = QFont(font, q); | |
#if defined(Q_WS_X11) | |
// make sure the font set on this widget is associated with the correct screen | |
data.fnt.x11SetScreen(xinfo.screen()); | |
#endif | |
// Combine new mask with natural mask and propagate to children. | |
#ifndef QT_NO_GRAPHICSVIEW | |
if (!q->parentWidget() && extra && extra->proxyWidget) { | |
QGraphicsProxyWidget *p = extra->proxyWidget; | |
inheritedFontResolveMask = p->d_func()->inheritedFontResolveMask | p->font().resolve(); | |
} else | |
#endif //QT_NO_GRAPHICSVIEW | |
if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) { | |
inheritedFontResolveMask = 0; | |
} | |
uint newMask = data.fnt.resolve() | inheritedFontResolveMask; | |
for (int i = 0; i < children.size(); ++i) { | |
QWidget *w = qobject_cast<QWidget*>(children.at(i)); | |
if (w) { | |
if (0) { | |
#ifndef QT_NO_STYLE_STYLESHEET | |
} else if (w->testAttribute(Qt::WA_StyleSheet)) { | |
// Style sheets follow a different font propagation scheme. | |
if (cssStyle) | |
cssStyle->updateStyleSheetFont(w); | |
#endif | |
} else if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) { | |
// Propagate font changes. | |
QWidgetPrivate *wd = w->d_func(); | |
wd->inheritedFontResolveMask = newMask; | |
wd->resolveFont(); | |
} | |
} | |
} | |
#ifndef QT_NO_STYLE_STYLESHEET | |
if (cssStyle) { | |
cssStyle->updateStyleSheetFont(q); | |
} | |
#endif | |
QEvent e(QEvent::FontChange); | |
QApplication::sendEvent(q, &e); | |
#ifdef QT3_SUPPORT | |
q->fontChange(old); | |
#endif | |
} | |
void QWidgetPrivate::setLayoutDirection_helper(Qt::LayoutDirection direction) | |
{ | |
Q_Q(QWidget); | |
if ( (direction == Qt::RightToLeft) == q->testAttribute(Qt::WA_RightToLeft)) | |
return; | |
q->setAttribute(Qt::WA_RightToLeft, (direction == Qt::RightToLeft)); | |
if (!children.isEmpty()) { | |
for (int i = 0; i < children.size(); ++i) { | |
QWidget *w = qobject_cast<QWidget*>(children.at(i)); | |
if (w && !w->isWindow() && !w->testAttribute(Qt::WA_SetLayoutDirection)) | |
w->d_func()->setLayoutDirection_helper(direction); | |
} | |
} | |
QEvent e(QEvent::LayoutDirectionChange); | |
QApplication::sendEvent(q, &e); | |
} | |
void QWidgetPrivate::resolveLayoutDirection() | |
{ | |
Q_Q(const QWidget); | |
if (!q->testAttribute(Qt::WA_SetLayoutDirection)) | |
setLayoutDirection_helper(q->isWindow() ? QApplication::layoutDirection() : q->parentWidget()->layoutDirection()); | |
} | |
/*! | |
\property QWidget::layoutDirection | |
\brief the layout direction for this widget | |
By default, this property is set to Qt::LeftToRight. | |
When the layout direction is set on a widget, it will propagate to | |
the widget's children, but not to a child that is a window and not | |
to a child for which setLayoutDirection() has been explicitly | |
called. Also, child widgets added \e after setLayoutDirection() | |
has been called for the parent do not inherit the parent's layout | |
direction. | |
This method no longer affects text layout direction since Qt 4.7. | |
\sa QApplication::layoutDirection | |
*/ | |
void QWidget::setLayoutDirection(Qt::LayoutDirection direction) | |
{ | |
Q_D(QWidget); | |
if (direction == Qt::LayoutDirectionAuto) { | |
unsetLayoutDirection(); | |
return; | |
} | |
setAttribute(Qt::WA_SetLayoutDirection); | |
d->setLayoutDirection_helper(direction); | |
} | |
Qt::LayoutDirection QWidget::layoutDirection() const | |
{ | |
return testAttribute(Qt::WA_RightToLeft) ? Qt::RightToLeft : Qt::LeftToRight; | |
} | |
void QWidget::unsetLayoutDirection() | |
{ | |
Q_D(QWidget); | |
setAttribute(Qt::WA_SetLayoutDirection, false); | |
d->resolveLayoutDirection(); | |
} | |
/*! | |
\fn QFontMetrics QWidget::fontMetrics() const | |
Returns the font metrics for the widget's current font. | |
Equivalent to QFontMetrics(widget->font()). | |
\sa font(), fontInfo(), setFont() | |
*/ | |
/*! | |
\fn QFontInfo QWidget::fontInfo() const | |
Returns the font info for the widget's current font. | |
Equivalent to QFontInto(widget->font()). | |
\sa font(), fontMetrics(), setFont() | |
*/ | |
/*! | |
\property QWidget::cursor | |
\brief the cursor shape for this widget | |
The mouse cursor will assume this shape when it's over this | |
widget. See the \link Qt::CursorShape list of predefined cursor | |
objects\endlink for a range of useful shapes. | |
An editor widget might use an I-beam cursor: | |
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 6 | |
If no cursor has been set, or after a call to unsetCursor(), the | |
parent's cursor is used. | |
By default, this property contains a cursor with the Qt::ArrowCursor | |
shape. | |
Some underlying window implementations will reset the cursor if it | |
leaves a widget even if the mouse is grabbed. If you want to have | |
a cursor set for all widgets, even when outside the window, consider | |
QApplication::setOverrideCursor(). | |
\sa QApplication::setOverrideCursor() | |
*/ | |
#ifndef QT_NO_CURSOR | |
QCursor QWidget::cursor() const | |
{ | |
Q_D(const QWidget); | |
if (testAttribute(Qt::WA_SetCursor)) | |
return (d->extra && d->extra->curs) | |
? *d->extra->curs | |
: QCursor(Qt::ArrowCursor); | |
if (isWindow() || !parentWidget()) | |
return QCursor(Qt::ArrowCursor); | |
return parentWidget()->cursor(); | |
} | |
void QWidget::setCursor(const QCursor &cursor) | |
{ | |
Q_D(QWidget); | |
// On Mac we must set the cursor even if it is the ArrowCursor. | |
#if !defined(Q_WS_MAC) && !defined(Q_WS_QWS) | |
if (cursor.shape() != Qt::ArrowCursor | |
|| (d->extra && d->extra->curs)) | |
#endif | |
{ | |
d->createExtra(); | |
QCursor *newCursor = new QCursor(cursor); | |
delete d->extra->curs; | |
d->extra->curs = newCursor; | |
} | |
setAttribute(Qt::WA_SetCursor); | |
d->setCursor_sys(cursor); | |
QEvent event(QEvent::CursorChange); | |
QApplication::sendEvent(this, &event); | |
} | |
void QWidget::unsetCursor() | |
{ | |
Q_D(QWidget); | |
if (d->extra) { | |
delete d->extra->curs; | |
d->extra->curs = 0; | |
} | |
if (!isWindow()) | |
setAttribute(Qt::WA_SetCursor, false); | |
d->unsetCursor_sys(); | |
QEvent event(QEvent::CursorChange); | |
QApplication::sendEvent(this, &event); | |
} | |
#endif | |
/*! | |
\enum QWidget::RenderFlag | |
This enum describes how to render the widget when calling QWidget::render(). | |
\value DrawWindowBackground If you enable this option, the widget's background | |
is rendered into the target even if autoFillBackground is not set. By default, | |
this option is enabled. | |
\value DrawChildren If you enable this option, the widget's children | |
are rendered recursively into the target. By default, this option is enabled. | |
\value IgnoreMask If you enable this option, the widget's QWidget::mask() | |
is ignored when rendering into the target. By default, this option is disabled. | |
\since 4.3 | |
*/ | |
/*! | |
\since 4.3 | |
Renders the \a sourceRegion of this widget into the \a target | |
using \a renderFlags to determine how to render. Rendering | |
starts at \a targetOffset in the \a target. For example: | |
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 7 | |
If \a sourceRegion is a null region, this function will use QWidget::rect() as | |
the region, i.e. the entire widget. | |
Ensure that you call QPainter::end() for the \a target device's | |
active painter (if any) before rendering. For example: | |
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 8 | |
\note To obtain the contents of an OpenGL widget, use QGLWidget::grabFrameBuffer() | |
or QGLWidget::renderPixmap() instead. | |
*/ | |
void QWidget::render(QPaintDevice *target, const QPoint &targetOffset, | |
const QRegion &sourceRegion, RenderFlags renderFlags) | |
{ | |
d_func()->render(target, targetOffset, sourceRegion, renderFlags, false); | |
} | |
/*! | |
\overload | |
Renders the widget into the \a painter's QPainter::device(). | |
Transformations and settings applied to the \a painter will be used | |
when rendering. | |
\note The \a painter must be active. On Mac OS X the widget will be | |
rendered into a QPixmap and then drawn by the \a painter. | |
\sa QPainter::device() | |
*/ | |
void QWidget::render(QPainter *painter, const QPoint &targetOffset, | |
const QRegion &sourceRegion, RenderFlags renderFlags) | |
{ | |
if (!painter) { | |
qWarning("QWidget::render: Null pointer to painter"); | |
return; | |
} | |
if (!painter->isActive()) { | |
qWarning("QWidget::render: Cannot render with an inactive painter"); | |
return; | |
} | |
const qreal opacity = painter->opacity(); | |
if (qFuzzyIsNull(opacity)) | |
return; // Fully transparent. | |
Q_D(QWidget); | |
const bool inRenderWithPainter = d->extra && d->extra->inRenderWithPainter; | |
const QRegion toBePainted = !inRenderWithPainter ? d->prepareToRender(sourceRegion, renderFlags) | |
: sourceRegion; | |
if (toBePainted.isEmpty()) | |
return; | |
if (!d->extra) | |
d->createExtra(); | |
d->extra->inRenderWithPainter = true; | |
#ifdef Q_WS_MAC | |
d->render_helper(painter, targetOffset, toBePainted, renderFlags); | |
#else | |
QPaintEngine *engine = painter->paintEngine(); | |
Q_ASSERT(engine); | |
QPaintEnginePrivate *enginePriv = engine->d_func(); | |
Q_ASSERT(enginePriv); | |
QPaintDevice *target = engine->paintDevice(); | |
Q_ASSERT(target); | |
// Render via a pixmap when dealing with non-opaque painters or printers. | |
if (!inRenderWithPainter && (opacity < 1.0 || (target->devType() == QInternal::Printer))) { | |
d->render_helper(painter, targetOffset, toBePainted, renderFlags); | |
d->extra->inRenderWithPainter = false; | |
return; | |
} | |
// Set new shared painter. | |
QPainter *oldPainter = d->sharedPainter(); | |
d->setSharedPainter(painter); | |
// Save current system clip, viewport and transform, | |
const QTransform oldTransform = enginePriv->systemTransform; | |
const QRegion oldSystemClip = enginePriv->systemClip; | |
const QRegion oldSystemViewport = enginePriv->systemViewport; | |
// This ensures that all painting triggered by render() is clipped to the current engine clip. | |
if (painter->hasClipping()) { | |
const QRegion painterClip = painter->deviceTransform().map(painter->clipRegion()); | |
enginePriv->setSystemViewport(oldSystemClip.isEmpty() ? painterClip : oldSystemClip & painterClip); | |
} else { | |
enginePriv->setSystemViewport(oldSystemClip); | |
} | |
render(target, targetOffset, toBePainted, renderFlags); | |
// Restore system clip, viewport and transform. | |
enginePriv->systemClip = oldSystemClip; | |
enginePriv->setSystemViewport(oldSystemViewport); | |
enginePriv->setSystemTransform(oldTransform); | |
// Restore shared painter. | |
d->setSharedPainter(oldPainter); | |
#endif | |
d->extra->inRenderWithPainter = false; | |
} | |
/*! | |
\brief The graphicsEffect function returns a pointer to the | |
widget's graphics effect. | |
If the widget has no graphics effect, 0 is returned. | |
\since 4.6 | |
\sa setGraphicsEffect() | |
*/ | |
#ifndef QT_NO_GRAPHICSEFFECT | |
QGraphicsEffect *QWidget::graphicsEffect() const | |
{ | |
Q_D(const QWidget); | |
return d->graphicsEffect; | |
} | |
#endif //QT_NO_GRAPHICSEFFECT | |
/*! | |
\brief The setGraphicsEffect function is for setting the widget's graphics effect. | |
Sets \a effect as the widget's effect. If there already is an effect installed | |
on this widget, QWidget will delete the existing effect before installing | |
the new \a effect. | |
If \a effect is the installed on a different widget, setGraphicsEffect() will remove | |
the effect from the widget and install it on this widget. | |
QWidget takes ownership of \a effect. | |
\note This function will apply the effect on itself and all its children. | |
\since 4.6 | |
\sa graphicsEffect() | |
*/ | |
#ifndef QT_NO_GRAPHICSEFFECT | |
void QWidget::setGraphicsEffect(QGraphicsEffect *effect) | |
{ | |
Q_D(QWidget); | |
if (d->graphicsEffect == effect) | |
return; | |
if (d->graphicsEffect) { | |
d->invalidateBuffer(rect()); | |
delete d->graphicsEffect; | |
d->graphicsEffect = 0; | |
} | |
if (effect) { | |
// Set new effect. | |
QGraphicsEffectSourcePrivate *sourced = new QWidgetEffectSourcePrivate(this); | |
QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced); | |
d->graphicsEffect = effect; | |
effect->d_func()->setGraphicsEffectSource(source); | |
update(); | |
} | |
d->updateIsOpaque(); | |
} | |
#endif //QT_NO_GRAPHICSEFFECT | |
bool QWidgetPrivate::isAboutToShow() const | |
{ | |
if (data.in_show) | |
return true; | |
Q_Q(const QWidget); | |
if (q->isHidden()) | |
return false; | |
// The widget will be shown if any of its ancestors are about to show. | |
QWidget *parent = q->parentWidget(); | |
return parent ? parent->d_func()->isAboutToShow() : false; | |
} | |
QRegion QWidgetPrivate::prepareToRender(const QRegion ®ion, QWidget::RenderFlags renderFlags) | |
{ | |
Q_Q(QWidget); | |
const bool isVisible = q->isVisible(); | |
// Make sure the widget is laid out correctly. | |
if (!isVisible && !isAboutToShow()) { | |
QWidget *topLevel = q->window(); | |
(void)topLevel->d_func()->topData(); // Make sure we at least have top-data. | |
topLevel->ensurePolished(); | |
// Invalidate the layout of hidden ancestors (incl. myself) and pretend | |
// they're not explicitly hidden. | |
QWidget *widget = q; | |
QWidgetList hiddenWidgets; | |
while (widget) { | |
if (widget->isHidden()) { | |
widget->setAttribute(Qt::WA_WState_Hidden, false); | |
hiddenWidgets.append(widget); | |
if (!widget->isWindow() && widget->parentWidget()->d_func()->layout) | |
widget->d_func()->updateGeometry_helper(true); | |
} | |
widget = widget->parentWidget(); | |
} | |
// Activate top-level layout. | |
if (topLevel->d_func()->layout) | |
topLevel->d_func()->layout->activate(); | |
// Adjust size if necessary. | |
QTLWExtra *topLevelExtra = topLevel->d_func()->maybeTopData(); | |
if (topLevelExtra && !topLevelExtra->sizeAdjusted | |
&& !topLevel->testAttribute(Qt::WA_Resized)) { | |
topLevel->adjustSize(); | |
topLevel->setAttribute(Qt::WA_Resized, false); | |
} | |
// Activate child layouts. | |
topLevel->d_func()->activateChildLayoutsRecursively(); | |
// We're not cheating with WA_WState_Hidden anymore. | |
for (int i = 0; i < hiddenWidgets.size(); ++i) { | |
QWidget *widget = hiddenWidgets.at(i); | |
widget->setAttribute(Qt::WA_WState_Hidden); | |
if (!widget->isWindow() && widget->parentWidget()->d_func()->layout) | |
widget->parentWidget()->d_func()->layout->invalidate(); | |
} | |
} else if (isVisible) { | |
q->window()->d_func()->sendPendingMoveAndResizeEvents(true, true); | |
} | |
// Calculate the region to be painted. | |
QRegion toBePainted = !region.isEmpty() ? region : QRegion(q->rect()); | |
if (!(renderFlags & QWidget::IgnoreMask) && extra && extra->hasMask) | |
toBePainted &= extra->mask; | |
return toBePainted; | |
} | |
void QWidgetPrivate::render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &toBePainted, | |
QWidget::RenderFlags renderFlags) | |
{ | |
Q_ASSERT(painter); | |
Q_ASSERT(!toBePainted.isEmpty()); | |
Q_Q(QWidget); | |
#ifndef Q_WS_MAC | |
const QTransform originalTransform = painter->worldTransform(); | |
const bool useDeviceCoordinates = originalTransform.isScaling(); | |
if (!useDeviceCoordinates) { | |
#endif | |
// Render via a pixmap. | |
const QRect rect = toBePainted.boundingRect(); | |
const QSize size = rect.size(); | |
if (size.isNull()) | |
return; | |
QPixmap pixmap(size); | |
if (!(renderFlags & QWidget::DrawWindowBackground) || !isOpaque) | |
pixmap.fill(Qt::transparent); | |
q->render(&pixmap, QPoint(), toBePainted, renderFlags); | |
const bool restore = !(painter->renderHints() & QPainter::SmoothPixmapTransform); | |
painter->setRenderHints(QPainter::SmoothPixmapTransform, true); | |
painter->drawPixmap(targetOffset, pixmap); | |
if (restore) | |
painter->setRenderHints(QPainter::SmoothPixmapTransform, false); | |
#ifndef Q_WS_MAC | |
} else { | |
// Render via a pixmap in device coordinates (to avoid pixmap scaling). | |
QTransform transform = originalTransform; | |
transform.translate(targetOffset.x(), targetOffset.y()); | |
QPaintDevice *device = painter->device(); | |
Q_ASSERT(device); | |
// Calculate device rect. | |
const QRectF rect(toBePainted.boundingRect()); | |
QRect deviceRect = transform.mapRect(QRectF(0, 0, rect.width(), rect.height())).toAlignedRect(); | |
deviceRect &= QRect(0, 0, device->width(), device->height()); | |
QPixmap pixmap(deviceRect.size()); | |
pixmap.fill(Qt::transparent); | |
// Create a pixmap device coordinate painter. | |
QPainter pixmapPainter(&pixmap); | |
pixmapPainter.setRenderHints(painter->renderHints()); | |
transform *= QTransform::fromTranslate(-deviceRect.x(), -deviceRect.y()); | |
pixmapPainter.setTransform(transform); | |
q->render(&pixmapPainter, QPoint(), toBePainted, renderFlags); | |
pixmapPainter.end(); | |
// And then draw the pixmap. | |
painter->setTransform(QTransform()); | |
painter->drawPixmap(deviceRect.topLeft(), pixmap); | |
painter->setTransform(originalTransform); | |
} | |
#endif | |
} | |
void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags, | |
QPainter *sharedPainter, QWidgetBackingStore *backingStore) | |
{ | |
if (rgn.isEmpty()) | |
return; | |
Q_Q(QWidget); | |
#ifndef QT_NO_GRAPHICSEFFECT | |
if (graphicsEffect && graphicsEffect->isEnabled()) { | |
QGraphicsEffectSource *source = graphicsEffect->d_func()->source; | |
QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *> | |
(source->d_func()); | |
if (!sourced->context) { | |
QWidgetPaintContext context(pdev, rgn, offset, flags, sharedPainter, backingStore); | |
sourced->context = &context; | |
if (!sharedPainter) { | |
QPaintEngine *paintEngine = pdev->paintEngine(); | |
paintEngine->d_func()->systemClip = rgn.translated(offset); | |
QPainter p(pdev); | |
p.translate(offset); | |
context.painter = &p; | |
graphicsEffect->draw(&p); | |
paintEngine->d_func()->systemClip = QRegion(); | |
} else { | |
context.painter = sharedPainter; | |
if (sharedPainter->worldTransform() != sourced->lastEffectTransform) { | |
sourced->invalidateCache(); | |
sourced->lastEffectTransform = sharedPainter->worldTransform(); | |
} | |
sharedPainter->save(); | |
sharedPainter->translate(offset); | |
graphicsEffect->draw(sharedPainter); | |
sharedPainter->restore(); | |
} | |
sourced->context = 0; | |
return; | |
} | |
} | |
#endif //QT_NO_GRAFFICSEFFECT | |
const bool asRoot = flags & DrawAsRoot; | |
const bool alsoOnScreen = flags & DrawPaintOnScreen; | |
const bool recursive = flags & DrawRecursive; | |
const bool alsoInvisible = flags & DrawInvisible; | |
Q_ASSERT(sharedPainter ? sharedPainter->isActive() : true); | |
QRegion toBePainted(rgn); | |
if (asRoot && !alsoInvisible) | |
toBePainted &= clipRect(); //(rgn & visibleRegion()); | |
if (!(flags & DontSubtractOpaqueChildren)) | |
subtractOpaqueChildren(toBePainted, q->rect()); | |
if (!toBePainted.isEmpty()) { | |
bool onScreen = paintOnScreen(); | |
if (!onScreen || alsoOnScreen) { | |
//update the "in paint event" flag | |
if (q->testAttribute(Qt::WA_WState_InPaintEvent)) | |
qWarning("QWidget::repaint: Recursive repaint detected"); | |
q->setAttribute(Qt::WA_WState_InPaintEvent); | |
//clip away the new area | |
#ifndef QT_NO_PAINT_DEBUG | |
bool flushed = QWidgetBackingStore::flushPaint(q, toBePainted); | |
#endif | |
QPaintEngine *paintEngine = pdev->paintEngine(); | |
if (paintEngine) { | |
setRedirected(pdev, -offset); | |
#ifdef Q_WS_MAC | |
// (Alien support) Special case for Mac when redirecting: If the paint device | |
// is of the Widget type we need to set WA_WState_InPaintEvent since painting | |
// outside the paint event is not supported on QWidgets. The attributeis | |
// restored further down. | |
if (pdev->devType() == QInternal::Widget) | |
static_cast<QWidget *>(pdev)->setAttribute(Qt::WA_WState_InPaintEvent); | |
#endif | |
if (sharedPainter) | |
paintEngine->d_func()->systemClip = toBePainted; | |
else | |
paintEngine->d_func()->systemRect = q->data->crect; | |
//paint the background | |
if ((asRoot || q->autoFillBackground() || onScreen || q->testAttribute(Qt::WA_StyledBackground)) | |
&& !q->testAttribute(Qt::WA_OpaquePaintEvent) && !q->testAttribute(Qt::WA_NoSystemBackground)) { | |
QPainter p(q); | |
paintBackground(&p, toBePainted, (asRoot || onScreen) ? flags | DrawAsRoot : 0); | |
} | |
if (!sharedPainter) | |
paintEngine->d_func()->systemClip = toBePainted.translated(offset); | |
if (!onScreen && !asRoot && !isOpaque && q->testAttribute(Qt::WA_TintedBackground)) { | |
QPainter p(q); | |
QColor tint = q->palette().window().color(); | |
tint.setAlphaF(qreal(.6)); | |
p.fillRect(toBePainted.boundingRect(), tint); | |
} | |
} | |
#if 0 | |
qDebug() << "painting" << q << "opaque ==" << isOpaque(); | |
qDebug() << "clipping to" << toBePainted << "location == " << offset | |
<< "geometry ==" << QRect(q->mapTo(q->window(), QPoint(0, 0)), q->size()); | |
#endif | |
//actually send the paint event | |
QPaintEvent e(toBePainted); | |
QCoreApplication::sendSpontaneousEvent(q, &e); | |
#if !defined(Q_WS_MAC) && !defined(Q_WS_QWS) | |
if (backingStore && !onScreen && !asRoot && (q->internalWinId() || !q->nativeParentWidget()->isWindow())) | |
backingStore->markDirtyOnScreen(toBePainted, q, offset); | |
#endif | |
//restore | |
if (paintEngine) { | |
#ifdef Q_WS_MAC | |
if (pdev->devType() == QInternal::Widget) | |
static_cast<QWidget *>(pdev)->setAttribute(Qt::WA_WState_InPaintEvent, false); | |
#endif | |
restoreRedirected(); | |
if (!sharedPainter) | |
paintEngine->d_func()->systemRect = QRect(); | |
else | |
paintEngine->d_func()->currentClipWidget = 0; | |
paintEngine->d_func()->systemClip = QRegion(); | |
} | |
q->setAttribute(Qt::WA_WState_InPaintEvent, false); | |
if (q->paintingActive() && !q->testAttribute(Qt::WA_PaintOutsidePaintEvent)) | |
qWarning("QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent"); | |
if (paintEngine && paintEngine->autoDestruct()) { | |
delete paintEngine; | |
} | |
#ifndef QT_NO_PAINT_DEBUG | |
if (flushed) | |
QWidgetBackingStore::unflushPaint(q, toBePainted); | |
#endif | |
} else if (q->isWindow()) { | |
QPaintEngine *engine = pdev->paintEngine(); | |
if (engine) { | |
QPainter p(pdev); | |
p.setClipRegion(toBePainted); | |
const QBrush bg = q->palette().brush(QPalette::Window); | |
if (bg.style() == Qt::TexturePattern) | |
p.drawTiledPixmap(q->rect(), bg.texture()); | |
else | |
p.fillRect(q->rect(), bg); | |
if (engine->autoDestruct()) | |
delete engine; | |
} | |
} | |
} | |
if (recursive && !children.isEmpty()) { | |
paintSiblingsRecursive(pdev, children, children.size() - 1, rgn, offset, flags & ~DrawAsRoot | |
#ifdef Q_BACKINGSTORE_SUBSURFACES | |
, q->windowSurface() | |
#endif | |
, sharedPainter, backingStore); | |
} | |
} | |
void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset, | |
const QRegion &sourceRegion, QWidget::RenderFlags renderFlags, | |
bool readyToRender) | |
{ | |
if (!target) { | |
qWarning("QWidget::render: null pointer to paint device"); | |
return; | |
} | |
const bool inRenderWithPainter = extra && extra->inRenderWithPainter; | |
QRegion paintRegion = !inRenderWithPainter && !readyToRender | |
? prepareToRender(sourceRegion, renderFlags) | |
: sourceRegion; | |
if (paintRegion.isEmpty()) | |
return; | |
#ifndef Q_WS_MAC | |
QPainter *oldSharedPainter = inRenderWithPainter ? sharedPainter() : 0; | |
// Use the target's shared painter if set (typically set when doing | |
// "other->render(widget);" in the widget's paintEvent. | |
if (target->devType() == QInternal::Widget) { | |
QWidgetPrivate *targetPrivate = static_cast<QWidget *>(target)->d_func(); | |
if (targetPrivate->extra && targetPrivate->extra->inRenderWithPainter) { | |
QPainter *targetPainter = targetPrivate->sharedPainter(); | |
if (targetPainter && targetPainter->isActive()) | |
setSharedPainter(targetPainter); | |
} | |
} | |
#endif | |
// Use the target's redirected device if set and adjust offset and paint | |
// region accordingly. This is typically the case when people call render | |
// from the paintEvent. | |
QPoint offset = targetOffset; | |
offset -= paintRegion.boundingRect().topLeft(); | |
QPoint redirectionOffset; | |
QPaintDevice *redirected = 0; | |
if (target->devType() == QInternal::Widget) | |
redirected = static_cast<QWidget *>(target)->d_func()->redirected(&redirectionOffset); | |
if (!redirected) | |
redirected = QPainter::redirected(target, &redirectionOffset); | |
if (redirected) { | |
target = redirected; | |
offset -= redirectionOffset; | |
} | |
if (!inRenderWithPainter) { // Clip handled by shared painter (in qpainter.cpp). | |
if (QPaintEngine *targetEngine = target->paintEngine()) { | |
const QRegion targetSystemClip = targetEngine->systemClip(); | |
if (!targetSystemClip.isEmpty()) | |
paintRegion &= targetSystemClip.translated(-offset); | |
} | |
} | |
// Set backingstore flags. | |
int flags = DrawPaintOnScreen | DrawInvisible; | |
if (renderFlags & QWidget::DrawWindowBackground) | |
flags |= DrawAsRoot; | |
if (renderFlags & QWidget::DrawChildren) | |
flags |= DrawRecursive; | |
else | |
flags |= DontSubtractOpaqueChildren; | |
#ifdef Q_WS_QWS | |
flags |= DontSetCompositionMode; | |
#endif | |
if (target->devType() == QInternal::Printer) { | |
QPainter p(target); | |
render_helper(&p, targetOffset, paintRegion, renderFlags); | |
return; | |
} | |
#ifndef Q_WS_MAC | |
// Render via backingstore. | |
drawWidget(target, paintRegion, offset, flags, sharedPainter()); | |
// Restore shared painter. | |
if (oldSharedPainter) | |
setSharedPainter(oldSharedPainter); | |
#else | |
// Render via backingstore (no shared painter). | |
drawWidget(target, paintRegion, offset, flags, 0); | |
#endif | |
} | |
void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& siblings, int index, const QRegion &rgn, | |
const QPoint &offset, int flags | |
#ifdef Q_BACKINGSTORE_SUBSURFACES | |
, const QWindowSurface *currentSurface | |
#endif | |
, QPainter *sharedPainter, QWidgetBackingStore *backingStore) | |
{ | |
QWidget *w = 0; | |
QRect boundingRect; | |
bool dirtyBoundingRect = true; | |
const bool exludeOpaqueChildren = (flags & DontDrawOpaqueChildren); | |
do { | |
QWidget *x = qobject_cast<QWidget*>(siblings.at(index)); | |
if (x && !(exludeOpaqueChildren && x->d_func()->isOpaque) && !x->isHidden() && !x->isWindow()) { | |
if (dirtyBoundingRect) { | |
boundingRect = rgn.boundingRect(); | |
dirtyBoundingRect = false; | |
} | |
if (qRectIntersects(boundingRect, x->d_func()->effectiveRectFor(x->data->crect))) { | |
#ifdef Q_BACKINGSTORE_SUBSURFACES | |
if (x->windowSurface() == currentSurface) | |
#endif | |
{ | |
w = x; | |
break; | |
} | |
} | |
} | |
--index; | |
} while (index >= 0); | |
if (!w) | |
return; | |
QWidgetPrivate *wd = w->d_func(); | |
const QPoint widgetPos(w->data->crect.topLeft()); | |
const bool hasMask = wd->extra && wd->extra->hasMask && !wd->graphicsEffect; | |
if (index > 0) { | |
QRegion wr(rgn); | |
if (wd->isOpaque) | |
wr -= hasMask ? wd->extra->mask.translated(widgetPos) : w->data->crect; | |
paintSiblingsRecursive(pdev, siblings, --index, wr, offset, flags | |
#ifdef Q_BACKINGSTORE_SUBSURFACES | |
, currentSurface | |
#endif | |
, sharedPainter, backingStore); | |
} | |
if (w->updatesEnabled() | |
#ifndef QT_NO_GRAPHICSVIEW | |
&& (!w->d_func()->extra || !w->d_func()->extra->proxyWidget) | |
#endif //QT_NO_GRAPHICSVIEW | |
) { | |
QRegion wRegion(rgn); | |
wRegion &= wd->effectiveRectFor(w->data->crect); | |
wRegion.translate(-widgetPos); | |
if (hasMask) | |
wRegion &= wd->extra->mask; | |
wd->drawWidget(pdev, wRegion, offset + widgetPos, flags, sharedPainter, backingStore); | |
} | |
} | |
#ifndef QT_NO_GRAPHICSEFFECT | |
QRectF QWidgetEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const | |
{ | |
if (system != Qt::DeviceCoordinates) | |
return m_widget->rect(); | |
if (!context) { | |
// Device coordinates without context not yet supported. | |
qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context"); | |
return QRectF(); | |
} | |
return context->painter->worldTransform().mapRect(m_widget->rect()); | |
} | |
void QWidgetEffectSourcePrivate::draw(QPainter *painter) | |
{ | |
if (!context || context->painter != painter) { | |
m_widget->render(painter); | |
return; | |
} | |
// The region saved in the context is neither clipped to the rect | |
// nor the mask, so we have to clip it here before calling drawWidget. | |
QRegion toBePainted = context->rgn; | |
toBePainted &= m_widget->rect(); | |
QWidgetPrivate *wd = qt_widget_private(m_widget); | |
if (wd->extra && wd->extra->hasMask) | |
toBePainted &= wd->extra->mask; | |
wd->drawWidget(context->pdev, toBePainted, context->offset, context->flags, | |
context->sharedPainter, context->backingStore); | |
} | |
QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset, | |
QGraphicsEffect::PixmapPadMode mode) const | |
{ | |
const bool deviceCoordinates = (system == Qt::DeviceCoordinates); | |
if (!context && deviceCoordinates) { | |
// Device coordinates without context not yet supported. | |
qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context"); | |
return QPixmap(); | |
} | |
QPoint pixmapOffset; | |
QRectF sourceRect = m_widget->rect(); | |
if (deviceCoordinates) { | |
const QTransform &painterTransform = context->painter->worldTransform(); | |
sourceRect = painterTransform.mapRect(sourceRect); | |
pixmapOffset = painterTransform.map(pixmapOffset); | |
} | |
QRect effectRect; | |
if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) | |
effectRect = m_widget->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect(); | |
else if (mode == QGraphicsEffect::PadToTransparentBorder) | |
effectRect = sourceRect.adjusted(-1, -1, 1, 1).toAlignedRect(); | |
else | |
effectRect = sourceRect.toAlignedRect(); | |
if (offset) | |
*offset = effectRect.topLeft(); | |
pixmapOffset -= effectRect.topLeft(); | |
QPixmap pixmap(effectRect.size()); | |
pixmap.fill(Qt::transparent); | |
m_widget->render(&pixmap, pixmapOffset, QRegion(), QWidget::DrawChildren); | |
return pixmap; | |
} | |
#endif //QT_NO_GRAPHICSEFFECT | |
#ifndef QT_NO_GRAPHICSVIEW | |
/*! | |
\internal | |
Finds the nearest widget embedded in a graphics proxy widget along the chain formed by this | |
widget and its ancestors. The search starts at \a origin (inclusive). | |
If successful, the function returns the proxy that embeds the widget, or 0 if no embedded | |
widget was found. | |
*/ | |
QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget *origin) | |
{ | |
if (origin) { | |
QWExtra *extra = origin->d_func()->extra; | |
if (extra && extra->proxyWidget) | |
return extra->proxyWidget; | |
return nearestGraphicsProxyWidget(origin->parentWidget()); | |
} | |
return 0; | |
} | |
#endif | |
/*! | |
\property QWidget::locale | |
\brief the widget's locale | |
\since 4.3 | |
As long as no special locale has been set, this is either | |
the parent's locale or (if this widget is a top level widget), | |
the default locale. | |
If the widget displays dates or numbers, these should be formatted | |
using the widget's locale. | |
\sa QLocale QLocale::setDefault() | |
*/ | |
void QWidgetPrivate::setLocale_helper(const QLocale &loc, bool forceUpdate) | |
{ | |
Q_Q(QWidget); | |
if (locale == loc && !forceUpdate) | |
return; | |
locale = loc; | |
if (!children.isEmpty()) { | |
for (int i = 0; i < children.size(); ++i) { | |
QWidget *w = qobject_cast<QWidget*>(children.at(i)); | |
if (!w) | |
continue; | |
if (w->testAttribute(Qt::WA_SetLocale)) | |
continue; | |
if (w->isWindow() && !w->testAttribute(Qt::WA_WindowPropagation)) | |
continue; | |
w->d_func()->setLocale_helper(loc, forceUpdate); | |
} | |
} | |
QEvent e(QEvent::LocaleChange); | |
QApplication::sendEvent(q, &e); | |
} | |
void QWidget::setLocale(const QLocale &locale) | |
{ | |
Q_D(QWidget); | |
setAttribute(Qt::WA_SetLocale); | |
d->setLocale_helper(locale); | |
} | |
QLocale QWidget::locale() const | |
{ | |
Q_D(const QWidget); | |
return d->locale; | |
} | |
void QWidgetPrivate::resolveLocale() | |
{ | |
Q_Q(const QWidget); | |
if (!q->testAttribute(Qt::WA_SetLocale)) { | |
setLocale_helper(q->isWindow() | |
? QLocale() | |
: q->parentWidget()->locale()); | |
} | |
} | |
void QWidget::unsetLocale() | |
{ | |
Q_D(QWidget); | |
setAttribute(Qt::WA_SetLocale, false); | |
d->resolveLocale(); | |
} | |
static QString constructWindowTitleFromFilePath(const QString &filePath) | |
{ | |
QFileInfo fi(filePath); | |
QString windowTitle = fi.fileName() + QLatin1String("[*]"); | |
#ifndef Q_WS_MAC | |
QString appName = QApplication::applicationName(); | |
if (!appName.isEmpty()) | |
windowTitle += QLatin1Char(' ') + QChar(0x2014) + QLatin1Char(' ') + appName; | |
#endif | |
return windowTitle; | |
} | |
/*! | |
\property QWidget::windowTitle | |
\brief the window title (caption) | |
This property only makes sense for top-level widgets, such as | |
windows and dialogs. If no caption has been set, the title is based of the | |
\l windowFilePath. If neither of these is set, then the title is | |
an empty string. | |
If you use the \l windowModified mechanism, the window title must | |
contain a "[*]" placeholder, which indicates where the '*' should | |
appear. Normally, it should appear right after the file name | |
(e.g., "document1.txt[*] - Text Editor"). If the \l | |
windowModified property is false (the default), the placeholder | |
is simply removed. | |
\sa windowIcon, windowIconText, windowModified, windowFilePath | |
*/ | |
QString QWidget::windowTitle() const | |
{ | |
Q_D(const QWidget); | |
if (d->extra && d->extra->topextra) { | |
if (!d->extra->topextra->caption.isEmpty()) | |
return d->extra->topextra->caption; | |
if (!d->extra->topextra->filePath.isEmpty()) | |
return constructWindowTitleFromFilePath(d->extra->topextra->filePath); | |
} | |
return QString(); | |
} | |
/*! | |
Returns a modified window title with the [*] place holder | |
replaced according to the rules described in QWidget::setWindowTitle | |
This function assumes that "[*]" can be quoted by another | |
"[*]", so it will replace two place holders by one and | |
a single last one by either "*" or nothing depending on | |
the modified flag. | |
\internal | |
*/ | |
QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widget) | |
{ | |
Q_ASSERT(widget); | |
#ifdef QT_EVAL | |
extern QString qt_eval_adapt_window_title(const QString &title); | |
QString cap = qt_eval_adapt_window_title(title); | |
#else | |
QString cap = title; | |
#endif | |
if (cap.isEmpty()) | |
return cap; | |
QLatin1String placeHolder("[*]"); | |
int placeHolderLength = 3; // QLatin1String doesn't have length() | |
int index = cap.indexOf(placeHolder); | |
// here the magic begins | |
while (index != -1) { | |
index += placeHolderLength; | |
int count = 1; | |
while (cap.indexOf(placeHolder, index) == index) { | |
++count; | |
index += placeHolderLength; | |
} | |
if (count%2) { // odd number of [*] -> replace last one | |
int lastIndex = cap.lastIndexOf(placeHolder, index - 1); | |
if (widget->isWindowModified() | |
&& widget->style()->styleHint(QStyle::SH_TitleBar_ModifyNotification, 0, widget)) | |
cap.replace(lastIndex, 3, QWidget::tr("*")); | |
else | |
cap.remove(lastIndex, 3); | |
} | |
index = cap.indexOf(placeHolder, index); | |
} | |
cap.replace(QLatin1String("[*][*]"), placeHolder); | |
return cap; | |
} | |
void QWidgetPrivate::setWindowTitle_helper(const QString &title) | |
{ | |
Q_Q(QWidget); | |
if (q->testAttribute(Qt::WA_WState_Created)) | |
setWindowTitle_sys(qt_setWindowTitle_helperHelper(title, q)); | |
} | |
void QWidgetPrivate::setWindowIconText_helper(const QString &title) | |
{ | |
Q_Q(QWidget); | |
if (q->testAttribute(Qt::WA_WState_Created)) | |
setWindowIconText_sys(qt_setWindowTitle_helperHelper(title, q)); | |
} | |
void QWidget::setWindowIconText(const QString &iconText) | |
{ | |
if (QWidget::windowIconText() == iconText) | |
return; | |
Q_D(QWidget); | |
d->topData()->iconText = iconText; | |
d->setWindowIconText_helper(iconText); | |
QEvent e(QEvent::IconTextChange); | |
QApplication::sendEvent(this, &e); | |
} | |
void QWidget::setWindowTitle(const QString &title) | |
{ | |
if (QWidget::windowTitle() == title && !title.isEmpty() && !title.isNull()) | |
return; | |
Q_D(QWidget); | |
d->topData()->caption = title; | |
d->setWindowTitle_helper(title); | |
QEvent e(QEvent::WindowTitleChange); | |
QApplication::sendEvent(this, &e); | |
} | |
/*! | |
\property QWidget::windowIcon | |
\brief the widget's icon | |
This property only makes sense for windows. If no icon | |
has been set, windowIcon() returns the application icon | |
(QApplication::windowIcon()). | |
\sa windowIconText, windowTitle | |
*/ | |
QIcon QWidget::windowIcon() const | |
{ | |
const QWidget *w = this; | |
while (w) { | |
const QWidgetPrivate *d = w->d_func(); | |
if (d->extra && d->extra->topextra && d->extra->topextra->icon) | |
return *d->extra->topextra->icon; | |
w = w->parentWidget(); | |
} | |
return QApplication::windowIcon(); | |
} | |
void QWidgetPrivate::setWindowIcon_helper() | |
{ | |
QEvent e(QEvent::WindowIconChange); | |
QApplication::sendEvent(q_func(), &e); | |
for (int i = 0; i < children.size(); ++i) { | |
QWidget *w = qobject_cast<QWidget *>(children.at(i)); | |
if (w && !w->isWindow()) | |
QApplication::sendEvent(w, &e); | |
} | |
} | |
void QWidget::setWindowIcon(const QIcon &icon) | |
{ | |
Q_D(QWidget); | |
setAttribute(Qt::WA_SetWindowIcon, !icon.isNull()); | |
d->createTLExtra(); | |
if (!d->extra->topextra->icon) | |
d->extra->topextra->icon = new QIcon(); | |
*d->extra->topextra->icon = icon; | |
delete d->extra->topextra->iconPixmap; | |
d->extra->topextra->iconPixmap = 0; | |
d->setWindowIcon_sys(); | |
d->setWindowIcon_helper(); | |
} | |
/*! | |
\property QWidget::windowIconText | |
\brief the widget's icon text | |
This property only makes sense for windows. If no icon | |
text has been set, this functions returns an empty string. | |
\sa windowIcon, windowTitle | |
*/ | |
QString QWidget::windowIconText() const | |
{ | |
Q_D(const QWidget); | |
return (d->extra && d->extra->topextra) ? d->extra->topextra->iconText : QString(); | |
} | |
/*! | |
\property QWidget::windowFilePath | |
\since 4.4 | |
\brief the file path associated with a widget | |
This property only makes sense for windows. It associates a file path with | |
a window. If you set the file path, but have not set the window title, Qt | |
sets the window title to contain a string created using the following | |
components. | |
On Mac OS X: | |
\list | |
\o The file name of the specified path, obtained using QFileInfo::fileName(). | |
\endlist | |
On Windows and X11: | |
\list | |
\o The file name of the specified path, obtained using QFileInfo::fileName(). | |
\o An optional \c{*} character, if the \l windowModified property is set. | |
\o The \c{0x2014} unicode character, padded either side by spaces. | |
\o The application name, obtained from the application's | |
\l{QCoreApplication::}{applicationName} property. | |
\endlist | |
If the window title is set at any point, then the window title takes precedence and | |
will be shown instead of the file path string. | |
Additionally, on Mac OS X, this has an added benefit that it sets the | |
\l{http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGWindows/chapter_17_section_3.html}{proxy icon} | |
for the window, assuming that the file path exists. | |
If no file path is set, this property contains an empty string. | |
By default, this property contains an empty string. | |
\sa windowTitle, windowIcon | |
*/ | |
QString QWidget::windowFilePath() const | |
{ | |
Q_D(const QWidget); | |
return (d->extra && d->extra->topextra) ? d->extra->topextra->filePath : QString(); | |
} | |
void QWidget::setWindowFilePath(const QString &filePath) | |
{ | |
if (filePath == windowFilePath()) | |
return; | |
Q_D(QWidget); | |
d->createTLExtra(); | |
d->extra->topextra->filePath = filePath; | |
d->setWindowFilePath_helper(filePath); | |
} | |
void QWidgetPrivate::setWindowFilePath_helper(const QString &filePath) | |
{ | |
if (extra->topextra && extra->topextra->caption.isEmpty()) { | |
#ifdef Q_WS_MAC | |
setWindowTitle_helper(QFileInfo(filePath).fileName()); | |
#else | |
Q_Q(QWidget); | |
Q_UNUSED(filePath); | |
setWindowTitle_helper(q->windowTitle()); | |
#endif | |
} | |
#ifdef Q_WS_MAC | |
setWindowFilePath_sys(filePath); | |
#endif | |
} | |
/*! | |
Returns the window's role, or an empty string. | |
\sa windowIcon, windowTitle | |
*/ | |
QString QWidget::windowRole() const | |
{ | |
Q_D(const QWidget); | |
return (d->extra && d->extra->topextra) ? d->extra->topextra->role : QString(); | |
} | |
/*! | |
Sets the window's role to \a role. This only makes sense for | |
windows on X11. | |
*/ | |
void QWidget::setWindowRole(const QString &role) | |
{ | |
#if defined(Q_WS_X11) | |
Q_D(QWidget); | |
d->topData()->role = role; | |
d->setWindowRole(); | |
#else | |
Q_UNUSED(role) | |
#endif | |
} | |
/*! | |
\property QWidget::mouseTracking | |
\brief whether mouse tracking is enabled for the widget | |
If mouse tracking is disabled (the default), the widget only | |
receives mouse move events when at least one mouse button is | |
pressed while the mouse is being moved. | |
If mouse tracking is enabled, the widget receives mouse move | |
events even if no buttons are pressed. | |
\sa mouseMoveEvent() | |
*/ | |
/*! | |
Sets the widget's focus proxy to widget \a w. If \a w is 0, the | |
function resets this widget to have no focus proxy. | |
Some widgets can "have focus", but create a child widget, such as | |
QLineEdit, to actually handle the focus. In this case, the widget | |
can set the line edit to be its focus proxy. | |
setFocusProxy() sets the widget which will actually get focus when | |
"this widget" gets it. If there is a focus proxy, setFocus() and | |
hasFocus() operate on the focus proxy. | |
\sa focusProxy() | |
*/ | |
void QWidget::setFocusProxy(QWidget * w) | |
{ | |
Q_D(QWidget); | |
if (!w && !d->extra) | |
return; | |
for (QWidget* fp = w; fp; fp = fp->focusProxy()) { | |
if (fp == this) { | |
qWarning("QWidget: %s (%s) already in focus proxy chain", metaObject()->className(), objectName().toLocal8Bit().constData()); | |
return; | |
} | |
} | |
d->createExtra(); | |
d->extra->focus_proxy = w; | |
} | |
/*! | |
Returns the focus proxy, or 0 if there is no focus proxy. | |
\sa setFocusProxy() | |
*/ | |
QWidget * QWidget::focusProxy() const | |
{ | |
Q_D(const QWidget); | |
return d->extra ? (QWidget *)d->extra->focus_proxy : 0; | |
} | |
/*! | |
\property QWidget::focus | |
\brief whether this widget (or its focus proxy) has the keyboard | |
input focus | |
By default, this property is false. | |
\note Obtaining the value of this property for a widget is effectively equivalent | |
to checking whether QApplication::focusWidget() refers to the widget. | |
\sa setFocus(), clearFocus(), setFocusPolicy(), QApplication::focusWidget() | |
*/ | |
bool QWidget::hasFocus() const | |
{ | |
const QWidget* w = this; | |
while (w->d_func()->extra && w->d_func()->extra->focus_proxy) | |
w = w->d_func()->extra->focus_proxy; | |
if (QWidget *window = w->window()) { | |
#ifndef QT_NO_GRAPHICSVIEW | |
QWExtra *e = window->d_func()->extra; | |
if (e && e->proxyWidget && e->proxyWidget->hasFocus() && window->focusWidget() == w) | |
return true; | |
#endif | |
} | |
return (QApplication::focusWidget() == w); | |
} | |
/*! | |
Gives the keyboard input focus to this widget (or its focus | |
proxy) if this widget or one of its parents is the \link | |
isActiveWindow() active window\endlink. The \a reason argument will | |
be passed into any focus event sent from this function, it is used | |
to give an explanation of what caused the widget to get focus. | |
If the window is not active, the widget will be given the focus when | |
the window becomes active. | |
First, a focus out event is sent to the focus widget (if any) to | |
tell it that it is about to lose the focus. Then a focus in event | |
is sent to this widget to tell it that it just received the focus. | |
(Nothing happens if the focus in and focus out widgets are the | |
same.) | |
\note On embedded platforms, setFocus() will not cause an input panel | |
to be opened by the input method. If you want this to happen, you | |
have to send a QEvent::RequestSoftwareInputPanel event to the | |
widget yourself. | |
setFocus() gives focus to a widget regardless of its focus policy, | |
but does not clear any keyboard grab (see grabKeyboard()). | |
Be aware that if the widget is hidden, it will not accept focus | |
until it is shown. | |
\warning If you call setFocus() in a function which may itself be | |
called from focusOutEvent() or focusInEvent(), you may get an | |
infinite recursion. | |
\sa hasFocus(), clearFocus(), focusInEvent(), focusOutEvent(), | |
setFocusPolicy(), focusWidget(), QApplication::focusWidget(), grabKeyboard(), | |
grabMouse(), {Keyboard Focus}, QEvent::RequestSoftwareInputPanel | |
*/ | |
void QWidget::setFocus(Qt::FocusReason reason) | |
{ | |
if (!isEnabled()) | |
return; | |
QWidget *f = this; | |
while (f->d_func()->extra && f->d_func()->extra->focus_proxy) | |
f = f->d_func()->extra->focus_proxy; | |
if (QApplication::focusWidget() == f | |
#if defined(Q_WS_WIN) | |
&& GetFocus() == f->internalWinId() | |
#endif | |
) | |
return; | |
#ifndef QT_NO_GRAPHICSVIEW | |
QWidget *previousProxyFocus = 0; | |
if (QWExtra *topData = window()->d_func()->extra) { | |
if (topData->proxyWidget && topData->proxyWidget->hasFocus()) { | |
previousProxyFocus = topData->proxyWidget->widget()->focusWidget(); | |
if (previousProxyFocus && previousProxyFocus->focusProxy()) | |
previousProxyFocus = previousProxyFocus->focusProxy(); | |
if (previousProxyFocus == this && !topData->proxyWidget->d_func()->proxyIsGivingFocus) | |
return; | |
} | |
} | |
#endif | |
QWidget *w = f; | |
if (isHidden()) { | |
while (w && w->isHidden()) { | |
w->d_func()->focus_child = f; | |
w = w->isWindow() ? 0 : w->parentWidget(); | |
} | |
} else { | |
while (w) { | |
w->d_func()->focus_child = f; | |
w = w->isWindow() ? 0 : w->parentWidget(); | |
} | |
} | |
#ifndef QT_NO_GRAPHICSVIEW | |
// Update proxy state | |
if (QWExtra *topData = window()->d_func()->extra) { | |
if (topData->proxyWidget && !topData->proxyWidget->hasFocus()) { | |
topData->proxyWidget->d_func()->focusFromWidgetToProxy = 1; | |
topData->proxyWidget->setFocus(reason); | |
topData->proxyWidget->d_func()->focusFromWidgetToProxy = 0; | |
} | |
} | |
#endif | |
if (f->isActiveWindow()) { | |
QApplicationPrivate::setFocusWidget(f, reason); | |
#ifndef QT_NO_ACCESSIBILITY | |
# ifdef Q_OS_WIN | |
// The negation of the condition in setFocus_sys | |
if (!(testAttribute(Qt::WA_WState_Created) && window()->windowType() != Qt::Popup && internalWinId())) | |
//setFocusWidget will already post a focus event for us (that the AT client receives) on Windows | |
# endif | |
QAccessible::updateAccessibility(f, 0, QAccessible::Focus); | |
#endif | |
#ifndef QT_NO_GRAPHICSVIEW | |
if (QWExtra *topData = window()->d_func()->extra) { | |
if (topData->proxyWidget) { | |
if (previousProxyFocus && previousProxyFocus != f) { | |
// Send event to self | |
QFocusEvent event(QEvent::FocusOut, reason); | |
QPointer<QWidget> that = previousProxyFocus; | |
QApplication::sendEvent(previousProxyFocus, &event); | |
if (that) | |
QApplication::sendEvent(that->style(), &event); | |
} | |
if (!isHidden()) { | |
#ifndef QT_NO_GRAPHICSVIEW | |
// Update proxy state | |
if (QWExtra *topData = window()->d_func()->extra) | |
if (topData->proxyWidget && topData->proxyWidget->hasFocus()) | |
topData->proxyWidget->d_func()->updateProxyInputMethodAcceptanceFromWidget(); | |
#endif | |
// Send event to self | |
QFocusEvent event(QEvent::FocusIn, reason); | |
QPointer<QWidget> that = f; | |
QApplication::sendEvent(f, &event); | |
if (that) | |
QApplication::sendEvent(that->style(), &event); | |
} | |
} | |
} | |
#endif | |
} | |
} | |
/*! | |
\fn void QWidget::setFocus() | |
\overload | |
Gives the keyboard input focus to this widget (or its focus | |
proxy) if this widget or one of its parents is the | |
\l{isActiveWindow()}{active window}. | |
*/ | |
/*! | |
Takes keyboard input focus from the widget. | |
If the widget has active focus, a \link focusOutEvent() focus out | |
event\endlink is sent to this widget to tell it that it is about | |
to lose the focus. | |
This widget must enable focus setting in order to get the keyboard | |
input focus, i.e. it must call setFocusPolicy(). | |
\sa hasFocus(), setFocus(), focusInEvent(), focusOutEvent(), | |
setFocusPolicy(), QApplication::focusWidget() | |
*/ | |
void QWidget::clearFocus() | |
{ | |
QWidget *w = this; | |
while (w) { | |
if (w->d_func()->focus_child == this) | |
w->d_func()->focus_child = 0; | |
w = w->parentWidget(); | |
} | |
#ifndef QT_NO_GRAPHICSVIEW | |
QWExtra *topData = d_func()->extra; | |
if (topData && topData->proxyWidget) | |
topData->proxyWidget->clearFocus(); | |
#endif | |
if (hasFocus()) { | |
// Update proxy state | |
QApplicationPrivate::setFocusWidget(0, Qt::OtherFocusReason); | |
#if defined(Q_WS_WIN) | |
if (!(windowType() == Qt::Popup) && GetFocus() == internalWinId()) | |
SetFocus(0); | |
else | |
#endif | |
{ | |
#ifndef QT_NO_ACCESSIBILITY | |
QAccessible::updateAccessibility(this, 0, QAccessible::Focus); | |
#endif | |
} | |
} | |
} | |
/*! | |
\fn bool QWidget::focusNextChild() | |
Finds a new widget to give the keyboard focus to, as appropriate | |
for \key Tab, and returns true if it can find a new widget, or | |
false if it can't. | |
\sa focusPreviousChild() | |
*/ | |
/*! | |
\fn bool QWidget::focusPreviousChild() | |
Finds a new widget to give the keyboard focus to, as appropriate | |
for \key Shift+Tab, and returns true if it can find a new widget, | |
or false if it can't. | |
\sa focusNextChild() | |
*/ | |
/*! | |
Finds a new widget to give the keyboard focus to, as appropriate | |
for Tab and Shift+Tab, and returns true if it can find a new | |
widget, or false if it can't. | |
If \a next is true, this function searches forward, if \a next | |
is false, it searches backward. | |
Sometimes, you will want to reimplement this function. For | |
example, a web browser might reimplement it to move its "current | |
active link" forward or backward, and call | |
focusNextPrevChild() only when it reaches the last or | |
first link on the "page". | |
Child widgets call focusNextPrevChild() on their parent widgets, | |
but only the window that contains the child widgets decides where | |
to redirect focus. By reimplementing this function for an object, | |
you thus gain control of focus traversal for all child widgets. | |
\sa focusNextChild(), focusPreviousChild() | |
*/ | |
bool QWidget::focusNextPrevChild(bool next) | |
{ | |
Q_D(QWidget); | |
QWidget* p = parentWidget(); | |
bool isSubWindow = (windowType() == Qt::SubWindow); | |
if (!isWindow() && !isSubWindow && p) | |
return p->focusNextPrevChild(next); | |
#ifndef QT_NO_GRAPHICSVIEW | |
if (d->extra && d->extra->proxyWidget) | |
return d->extra->proxyWidget->focusNextPrevChild(next); | |
#endif | |
QWidget *w = QApplicationPrivate::focusNextPrevChild_helper(this, next); | |
if (!w) return false; | |
w->setFocus(next ? Qt::TabFocusReason : Qt::BacktabFocusReason); | |
return true; | |
} | |
/*! | |
Returns the last child of this widget that setFocus had been | |
called on. For top level widgets this is the widget that will get | |
focus in case this window gets activated | |
This is not the same as QApplication::focusWidget(), which returns | |
the focus widget in the currently active window. | |
*/ | |
QWidget *QWidget::focusWidget() const | |
{ | |
return const_cast<QWidget *>(d_func()->focus_child); | |
} | |
/*! | |
Returns the next widget in this widget's focus chain. | |
\sa previousInFocusChain() | |
*/ | |
QWidget *QWidget::nextInFocusChain() const | |
{ | |
return const_cast<QWidget *>(d_func()->focus_next); | |
} | |
/*! | |
\brief The previousInFocusChain function returns the previous | |
widget in this widget's focus chain. | |
\sa nextInFocusChain() | |
\since 4.6 | |
*/ | |
QWidget *QWidget::previousInFocusChain() const | |
{ | |
return const_cast<QWidget *>(d_func()->focus_prev); | |
} | |
/*! | |
\property QWidget::isActiveWindow | |
\brief whether this widget's window is the active window | |
The active window is the window that contains the widget that has | |
keyboard focus (The window may still have focus if it has no | |
widgets or none of its widgets accepts keyboard focus). | |
When popup windows are visible, this property is true for both the | |
active window \e and for the popup. | |
By default, this property is false. | |
\sa activateWindow(), QApplication::activeWindow() | |
*/ | |
bool QWidget::isActiveWindow() const | |
{ | |
QWidget *tlw = window(); | |
if(tlw == QApplication::activeWindow() || (isVisible() && (tlw->windowType() == Qt::Popup))) | |
return true; | |
#ifndef QT_NO_GRAPHICSVIEW | |
if (QWExtra *tlwExtra = tlw->d_func()->extra) { | |
if (isVisible() && tlwExtra->proxyWidget) | |
return tlwExtra->proxyWidget->isActiveWindow(); | |
} | |
#endif | |
#ifdef Q_WS_MAC | |
extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp | |
if(qt_mac_is_macdrawer(tlw) && | |
tlw->parentWidget() && tlw->parentWidget()->isActiveWindow()) | |
return true; | |
extern bool qt_mac_insideKeyWindow(const QWidget *); //qwidget_mac.cpp | |
if (QApplication::testAttribute(Qt::AA_MacPluginApplication) && qt_mac_insideKeyWindow(tlw)) | |
return true; | |
#endif | |
if(style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, this)) { | |
if(tlw->windowType() == Qt::Tool && | |
!tlw->isModal() && | |
(!tlw->parentWidget() || tlw->parentWidget()->isActiveWindow())) | |
return true; | |
QWidget *w = QApplication::activeWindow(); | |
while(w && tlw->windowType() == Qt::Tool && | |
!w->isModal() && w->parentWidget()) { | |
w = w->parentWidget()->window(); | |
if(w == tlw) | |
return true; | |
} | |
} | |
#if defined(Q_WS_WIN32) | |
HWND active = GetActiveWindow(); | |
if (!tlw->testAttribute(Qt::WA_WState_Created)) | |
return false; | |
return active == tlw->internalWinId() || ::IsChild(active, tlw->internalWinId()); | |
#else | |
return false; | |
#endif | |
} | |
/*! | |
Puts the \a second widget after the \a first widget in the focus order. | |
Note that since the tab order of the \a second widget is changed, you | |
should order a chain like this: | |
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 9 | |
\e not like this: | |
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 10 | |
If \a first or \a second has a focus proxy, setTabOrder() | |
correctly substitutes the proxy. | |
\sa setFocusPolicy(), setFocusProxy(), {Keyboard Focus} | |
*/ | |
void QWidget::setTabOrder(QWidget* first, QWidget *second) | |
{ | |
if (!first || !second || first->focusPolicy() == Qt::NoFocus || second->focusPolicy() == Qt::NoFocus) | |
return; | |
if (first->window() != second->window()) { | |
qWarning("QWidget::setTabOrder: 'first' and 'second' must be in the same window"); | |
return; | |
} | |
QWidget *fp = first->focusProxy(); | |
if (fp) { | |
// If first is redirected, set first to the last child of first | |
// that can take keyboard focus so that second is inserted after | |
// that last child, and the focus order within first is (more | |
// likely to be) preserved. | |
QList<QWidget *> l = qFindChildren<QWidget *>(first); | |
for (int i = l.size()-1; i >= 0; --i) { | |
QWidget * next = l.at(i); | |
if (next->window() == fp->window()) { | |
fp = next; | |
if (fp->focusPolicy() != Qt::NoFocus) | |
break; | |
} | |
} | |
first = fp; | |
} | |
if (fp == second) | |
return; | |
if (QWidget *sp = second->focusProxy()) | |
second = sp; | |
// QWidget *fp = first->d_func()->focus_prev; | |
QWidget *fn = first->d_func()->focus_next; | |
if (fn == second || first == second) | |
return; | |
QWidget *sp = second->d_func()->focus_prev; | |
QWidget *sn = second->d_func()->focus_next; | |
fn->d_func()->focus_prev = second; | |
first->d_func()->focus_next = second; | |
second->d_func()->focus_next = fn; | |
second->d_func()->focus_prev = first; | |
sp->d_func()->focus_next = sn; | |
sn->d_func()->focus_prev = sp; | |
Q_ASSERT(first->d_func()->focus_next->d_func()->focus_prev == first); | |
Q_ASSERT(first->d_func()->focus_prev->d_func()->focus_next == first); | |
Q_ASSERT(second->d_func()->focus_next->d_func()->focus_prev == second); | |
Q_ASSERT(second->d_func()->focus_prev->d_func()->focus_next == second); | |
} | |
/*!\internal | |
Moves the relevant subwidgets of this widget from the \a oldtlw's | |
tab chain to that of the new parent, if there's anything to move and | |
we're really moving | |
This function is called from QWidget::reparent() *after* the widget | |
has been reparented. | |
\sa reparent() | |
*/ | |
void QWidgetPrivate::reparentFocusWidgets(QWidget * oldtlw) | |
{ | |
Q_Q(QWidget); | |
if (oldtlw == q->window()) | |
return; // nothing to do | |
if(focus_child) | |
focus_child->clearFocus(); | |
// separate the focus chain into new (children of myself) and old (the rest) | |
QWidget *firstOld = 0; | |
//QWidget *firstNew = q; //invariant | |
QWidget *o = 0; // last in the old list | |
QWidget *n = q; // last in the new list | |
bool prevWasNew = true; | |
QWidget *w = focus_next; | |
//Note: for efficiency, we do not maintain the list invariant inside the loop | |
//we append items to the relevant list, and we optimize by not changing pointers | |
//when subsequent items are going into the same list. | |
while (w != q) { | |
bool currentIsNew = q->isAncestorOf(w); | |
if (currentIsNew) { | |
if (!prevWasNew) { | |
//prev was old -- append to new list | |
n->d_func()->focus_next = w; | |
w->d_func()->focus_prev = n; | |
} | |
n = w; | |
} else { | |
if (prevWasNew) { | |
//prev was new -- append to old list, if there is one | |
if (o) { | |
o->d_func()->focus_next = w; | |
w->d_func()->focus_prev = o; | |
} else { | |
// "create" the old list | |
firstOld = w; | |
} | |
} | |
o = w; | |
} | |
w = w->d_func()->focus_next; | |
prevWasNew = currentIsNew; | |
} | |
//repair the old list: | |
if (firstOld) { | |
o->d_func()->focus_next = firstOld; | |
firstOld->d_func()->focus_prev = o; | |
} | |
if (!q->isWindow()) { | |
QWidget *topLevel = q->window(); | |
//insert new chain into toplevel's chain | |
QWidget *prev = topLevel->d_func()->focus_prev; | |
topLevel->d_func()->focus_prev = n; | |
prev->d_func()->focus_next = q; | |
focus_prev = prev; | |
n->d_func()->focus_next = topLevel; | |
} else { | |
//repair the new list | |
n->d_func()->focus_next = q; | |
focus_prev = n; | |
} | |
} | |
/*!\internal | |
Measures the shortest distance from a point to a rect. | |
This function is called from QDesktopwidget::screen(QPoint) to find the | |
closest screen for a point. | |
In directional KeypadNavigation, it is called to find the closest | |
widget to the current focus widget center. | |
*/ | |
int QWidgetPrivate::pointToRect(const QPoint &p, const QRect &r) | |
{ | |
int dx = 0; | |
int dy = 0; | |
if (p.x() < r.left()) | |
dx = r.left() - p.x(); | |
else if (p.x() > r.right()) | |
dx = p.x() - r.right(); | |
if (p.y() < r.top()) | |
dy = r.top() - p.y(); | |
else if (p.y() > r.bottom()) | |
dy = p.y() - r.bottom(); | |
return dx + dy; | |
} | |
/*! | |
\property QWidget::frameSize | |
\brief the size of the widget including any window frame | |
By default, this property contains a value that depends on the user's | |
platform and screen geometry. | |
*/ | |
QSize QWidget::frameSize() const | |
{ | |
Q_D(const QWidget); | |
if (isWindow() && !(windowType() == Qt::Popup)) { | |
QRect fs = d->frameStrut(); | |
return QSize(data->crect.width() + fs.left() + fs.right(), | |
data->crect.height() + fs.top() + fs.bottom()); | |
} | |
return data->crect.size(); | |
} | |
/*! \fn void QWidget::move(int x, int y) | |
\overload | |
This corresponds to move(QPoint(\a x, \a y)). | |
*/ | |
void QWidget::move(const QPoint &p) | |
{ | |
Q_D(QWidget); | |
setAttribute(Qt::WA_Moved); | |
if (isWindow()) | |
d->topData()->posFromMove = true; | |
if (testAttribute(Qt::WA_WState_Created)) { | |
d->setGeometry_sys(p.x() + geometry().x() - QWidget::x(), | |
p.y() + geometry().y() - QWidget::y(), | |
width(), height(), true); | |
d->setDirtyOpaqueRegion(); | |
} else { | |
data->crect.moveTopLeft(p); // no frame yet | |
setAttribute(Qt::WA_PendingMoveEvent); | |
} | |
} | |
/*! \fn void QWidget::resize(int w, int h) | |
\overload | |
This corresponds to resize(QSize(\a w, \a h)). | |
*/ | |
void QWidget::resize(const QSize &s) | |
{ | |
Q_D(QWidget); | |
setAttribute(Qt::WA_Resized); | |
if (testAttribute(Qt::WA_WState_Created)) { | |
d->setGeometry_sys(geometry().x(), geometry().y(), s.width(), s.height(), false); | |
d->setDirtyOpaqueRegion(); | |
} else { | |
data->crect.setSize(s.boundedTo(maximumSize()).expandedTo(minimumSize())); | |
setAttribute(Qt::WA_PendingResizeEvent); | |
} | |
} | |
void QWidget::setGeometry(const QRect &r) | |
{ | |
Q_D(QWidget); | |
setAttribute(Qt::WA_Resized); | |
setAttribute(Qt::WA_Moved); | |
if (isWindow()) | |
d->topData()->posFromMove = false; | |
if (testAttribute(Qt::WA_WState_Created)) { | |
d->setGeometry_sys(r.x(), r.y(), r.width(), r.height(), true); | |
d->setDirtyOpaqueRegion(); | |
} else { | |
data->crect.setTopLeft(r.topLeft()); | |
data->crect.setSize(r.size().boundedTo(maximumSize()).expandedTo(minimumSize())); | |
setAttribute(Qt::WA_PendingMoveEvent); | |
setAttribute(Qt::WA_PendingResizeEvent); | |
} | |
} | |
/*! | |
\since 4.2 | |
Saves the current geometry and state for top-level widgets. | |
To save the geometry when the window closes, you can | |
implement a close event like this: | |
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 11 | |
See the \l{Window Geometry} documentation for an overview of geometry | |
issues with windows. | |
Use QMainWindow::saveState() to save the geometry and the state of | |
toolbars and dock widgets. | |
\sa restoreGeometry(), QMainWindow::saveState(), QMainWindow::restoreState() | |
*/ | |
QByteArray QWidget::saveGeometry() const | |
{ | |
#ifdef QT_MAC_USE_COCOA | |
// We check if the window was maximized during this invocation. If so, we need to record the | |
// starting position as 0,0. | |
Q_D(const QWidget); | |
QRect newFramePosition = frameGeometry(); | |
QRect newNormalPosition = normalGeometry(); | |
if(d->topData()->wasMaximized && !(windowState() & Qt::WindowMaximized)) { | |
// Change the starting position | |
newFramePosition.moveTo(0, 0); | |
newNormalPosition.moveTo(0, 0); | |
} | |
#endif // QT_MAC_USE_COCOA | |
QByteArray array; | |
QDataStream stream(&array, QIODevice::WriteOnly); | |
stream.setVersion(QDataStream::Qt_4_0); | |
const quint32 magicNumber = 0x1D9D0CB; | |
quint16 majorVersion = 1; | |
quint16 minorVersion = 0; | |
stream << magicNumber | |
<< majorVersion | |
<< minorVersion | |
#ifdef QT_MAC_USE_COCOA | |
<< newFramePosition | |
<< newNormalPosition | |
#else | |
<< frameGeometry() | |
<< normalGeometry() | |
#endif // QT_MAC_USE_COCOA | |
<< qint32(QApplication::desktop()->screenNumber(this)) | |
<< quint8(windowState() & Qt::WindowMaximized) | |
<< quint8(windowState() & Qt::WindowFullScreen); | |
return array; | |
} | |
/*! | |
\since 4.2 | |
Restores the geometry and state top-level widgets stored in the | |
byte array \a geometry. Returns true on success; otherwise | |
returns false. | |
If the restored geometry is off-screen, it will be modified to be | |
inside the available screen geometry. | |
To restore geometry saved using QSettings, you can use code like | |
this: | |
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 12 | |
See the \l{Window Geometry} documentation for an overview of geometry | |
issues with windows. | |
Use QMainWindow::restoreState() to restore the geometry and the | |
state of toolbars and dock widgets. | |
\sa saveGeometry(), QSettings, QMainWindow::saveState(), QMainWindow::restoreState() | |
*/ | |
bool QWidget::restoreGeometry(const QByteArray &geometry) | |
{ | |
if (geometry.size() < 4) | |
return false; | |
QDataStream stream(geometry); | |
stream.setVersion(QDataStream::Qt_4_0); | |
const quint32 magicNumber = 0x1D9D0CB; | |
quint32 storedMagicNumber; | |
stream >> storedMagicNumber; | |
if (storedMagicNumber != magicNumber) | |
return false; | |
const quint16 currentMajorVersion = 1; | |
quint16 majorVersion = 0; | |
quint16 minorVersion = 0; | |
stream >> majorVersion >> minorVersion; | |
if (majorVersion != currentMajorVersion) | |
return false; | |
// (Allow all minor versions.) | |
QRect restoredFrameGeometry; | |
QRect restoredNormalGeometry; | |
qint32 restoredScreenNumber; | |
quint8 maximized; | |
quint8 fullScreen; | |
stream >> restoredFrameGeometry | |
>> restoredNormalGeometry | |
>> restoredScreenNumber | |
>> maximized | |
>> fullScreen; | |
const int frameHeight = 20; | |
if (!restoredFrameGeometry.isValid()) | |
restoredFrameGeometry = QRect(QPoint(0,0), sizeHint()); | |
if (!restoredNormalGeometry.isValid()) | |
restoredNormalGeometry = QRect(QPoint(0, frameHeight), sizeHint()); | |
if (!restoredNormalGeometry.isValid()) { | |
// use the widget's adjustedSize if the sizeHint() doesn't help | |
restoredNormalGeometry.setSize(restoredNormalGeometry | |
.size() | |
.expandedTo(d_func()->adjustedSize())); | |
} | |
const QDesktopWidget * const desktop = QApplication::desktop(); | |
if (restoredScreenNumber >= desktop->numScreens()) | |
restoredScreenNumber = desktop->primaryScreen(); | |
const QRect availableGeometry = desktop->availableGeometry(restoredScreenNumber); | |
// Modify the restored geometry if we are about to restore to coordinates | |
// that would make the window "lost". This happens if: | |
// - The restored geometry is completely oustside the available geometry | |
// - The title bar is outside the available geometry. | |
// - (Mac only) The window is higher than the available geometry. It must | |
// be possible to bring the size grip on screen by moving the window. | |
#ifdef Q_WS_MAC | |
restoredFrameGeometry.setHeight(qMin(restoredFrameGeometry.height(), availableGeometry.height())); | |
restoredNormalGeometry.setHeight(qMin(restoredNormalGeometry.height(), availableGeometry.height() - frameHeight)); | |
#endif | |
if (!restoredFrameGeometry.intersects(availableGeometry)) { | |
restoredFrameGeometry.moveBottom(qMin(restoredFrameGeometry.bottom(), availableGeometry.bottom())); | |
restoredFrameGeometry.moveLeft(qMax(restoredFrameGeometry.left(), availableGeometry.left())); | |
restoredFrameGeometry.moveRight(qMin(restoredFrameGeometry.right(), availableGeometry.right())); | |
} | |
restoredFrameGeometry.moveTop(qMax(restoredFrameGeometry.top(), availableGeometry.top())); | |
if (!restoredNormalGeometry.intersects(availableGeometry)) { | |
restoredNormalGeometry.moveBottom(qMin(restoredNormalGeometry.bottom(), availableGeometry.bottom())); | |
restoredNormalGeometry.moveLeft(qMax(restoredNormalGeometry.left(), availableGeometry.left())); | |
restoredNormalGeometry.moveRight(qMin(restoredNormalGeometry.right(), availableGeometry.right())); | |
} | |
restoredNormalGeometry.moveTop(qMax(restoredNormalGeometry.top(), availableGeometry.top() + frameHeight)); | |
if (maximized || fullScreen) { | |
// set geomerty before setting the window state to make | |
// sure the window is maximized to the right screen. | |
setGeometry(restoredNormalGeometry); | |
Qt::WindowStates ws = windowState(); | |
if (maximized) | |
ws |= Qt::WindowMaximized; | |
if (fullScreen) | |
ws |= Qt::WindowFullScreen; | |
setWindowState(ws); | |
d_func()->topData()->normalGeometry = restoredNormalGeometry; | |
} else { | |
QPoint offset; | |
#ifdef Q_WS_X11 | |
if (isFullScreen()) | |
offset = d_func()->topData()->fullScreenOffset; | |
#endif | |
setWindowState(windowState() & ~(Qt::WindowMaximized | Qt::WindowFullScreen)); | |
move(restoredFrameGeometry.topLeft() + offset); | |
resize(restoredNormalGeometry.size()); | |
} | |
return true; | |
} | |
/*!\fn void QWidget::setGeometry(int x, int y, int w, int h) | |
\overload | |
This corresponds to setGeometry(QRect(\a x, \a y, \a w, \a h)). | |
*/ | |
/*! | |
Sets the margins around the contents of the widget to have the sizes | |
\a left, \a top, \a right, and \a bottom. The margins are used by | |
the layout system, and may be used by subclasses to specify the area | |
to draw in (e.g. excluding the frame). | |
Changing the margins will trigger a resizeEvent(). | |
\sa contentsRect(), getContentsMargins() | |
*/ | |
void QWidget::setContentsMargins(int left, int top, int right, int bottom) | |
{ | |
Q_D(QWidget); | |
if (left == d->leftmargin && top == d->topmargin | |
&& right == d->rightmargin && bottom == d->bottommargin) | |
return; | |
d->leftmargin = left; | |
d->topmargin = top; | |
d->rightmargin = right; | |
d->bottommargin = bottom; | |
if (QLayout *l=d->layout) | |
l->update(); //force activate; will do updateGeometry | |
else | |
updateGeometry(); | |
// ### Qt 5: compat, remove | |
if (isVisible()) { | |
update(); | |
QResizeEvent e(data->crect.size(), data->crect.size()); | |
QApplication::sendEvent(this, &e); | |
} else { | |
setAttribute(Qt::WA_PendingResizeEvent, true); | |
} | |
QEvent e(QEvent::ContentsRectChange); | |
QApplication::sendEvent(this, &e); | |
} | |
/*! | |
\overload | |
\since 4.6 | |
\brief The setContentsMargins function sets the margins around the | |
widget's contents. | |
Sets the margins around the contents of the widget to have the | |
sizes determined by \a margins. The margins are | |
used by the layout system, and may be used by subclasses to | |
specify the area to draw in (e.g. excluding the frame). | |
Changing the margins will trigger a resizeEvent(). | |
\sa contentsRect(), getContentsMargins() | |
*/ | |
void QWidget::setContentsMargins(const QMargins &margins) | |
{ | |
setContentsMargins(margins.left(), margins.top(), | |
margins.right(), margins.bottom()); | |
} | |
/*! | |
Returns the widget's contents margins for \a left, \a top, \a | |
right, and \a bottom. | |
\sa setContentsMargins(), contentsRect() | |
*/ | |
void QWidget::getContentsMargins(int *left, int *top, int *right, int *bottom) const | |
{ | |
Q_D(const QWidget); | |
if (left) | |
*left = d->leftmargin; | |
if (top) | |
*top = d->topmargin; | |
if (right) | |
*right = d->rightmargin; | |
if (bottom) | |
*bottom = d->bottommargin; | |
} | |
/*! | |
\since 4.6 | |
\brief The contentsMargins function returns the widget's contents margins. | |
\sa getContentsMargins(), setContentsMargins(), contentsRect() | |
*/ | |
QMargins QWidget::contentsMargins() const | |
{ | |
Q_D(const QWidget); | |
return QMargins(d->leftmargin, d->topmargin, d->rightmargin, d->bottommargin); | |
} | |
/*! | |
Returns the area inside the widget's margins. | |
\sa setContentsMargins(), getContentsMargins() | |
*/ | |
QRect QWidget::contentsRect() const | |
{ | |
Q_D(const QWidget); | |
return QRect(QPoint(d->leftmargin, d->topmargin), | |
QPoint(data->crect.width() - 1 - d->rightmargin, | |
data->crect.height() - 1 - d->bottommargin)); | |
} | |
/*! | |
\fn void QWidget::customContextMenuRequested(const QPoint &pos) | |
This signal is emitted when the widget's \l contextMenuPolicy is | |
Qt::CustomContextMenu, and the user has requested a context menu on | |
the widget. The position \a pos is the position of the context menu | |
event that the widget receives. Normally this is in widget | |
coordinates. The exception to this rule is QAbstractScrollArea and | |
its subclasses that map the context menu event to coordinates of the | |
\link QAbstractScrollArea::viewport() viewport() \endlink . | |
\sa mapToGlobal() QMenu contextMenuPolicy | |
*/ | |
/*! | |
\property QWidget::contextMenuPolicy | |
\brief how the widget shows a context menu | |
The default value of this property is Qt::DefaultContextMenu, | |
which means the contextMenuEvent() handler is called. Other values | |
are Qt::NoContextMenu, Qt::PreventContextMenu, | |
Qt::ActionsContextMenu, and Qt::CustomContextMenu. With | |
Qt::CustomContextMenu, the signal customContextMenuRequested() is | |
emitted. | |
\sa contextMenuEvent(), customContextMenuRequested(), actions() | |
*/ | |
Qt::ContextMenuPolicy QWidget::contextMenuPolicy() const | |
{ | |
return (Qt::ContextMenuPolicy)data->context_menu_policy; | |
} | |
void QWidget::setContextMenuPolicy(Qt::ContextMenuPolicy policy) | |
{ | |
data->context_menu_policy = (uint) policy; | |
} | |
/*! | |
\property QWidget::focusPolicy | |
\brief the way the widget accepts keyboard focus | |
The policy is Qt::TabFocus if the widget accepts keyboard | |
focus by tabbing, Qt::ClickFocus if the widget accepts | |
focus by clicking, Qt::StrongFocus if it accepts both, and | |
Qt::NoFocus (the default) if it does not accept focus at | |
all. | |
You must enable keyboard focus for a widget if it processes | |
keyboard events. This is normally done from the widget's | |
constructor. For instance, the QLineEdit constructor calls | |
setFocusPolicy(Qt::StrongFocus). | |
If the widget has a focus proxy, then the focus policy will | |
be propagated to it. | |
\sa focusInEvent(), focusOutEvent(), keyPressEvent(), keyReleaseEvent(), enabled | |
*/ | |
Qt::FocusPolicy QWidget::focusPolicy() const | |
{ | |
return (Qt::FocusPolicy)data->focus_policy; | |
} | |
void QWidget::setFocusPolicy(Qt::FocusPolicy policy) | |
{ | |
data->focus_policy = (uint) policy; | |
Q_D(QWidget); | |
if (d->extra && d->extra->focus_proxy) | |
d->extra->focus_proxy->setFocusPolicy(policy); | |
} | |
/*! | |
\property QWidget::updatesEnabled | |
\brief whether updates are enabled | |
An updates enabled widget receives paint events and has a system | |
background; a disabled widget does not. This also implies that | |
calling update() and repaint() has no effect if updates are | |
disabled. | |
By default, this property is true. | |
setUpdatesEnabled() is normally used to disable updates for a | |
short period of time, for instance to avoid screen flicker during | |
large changes. In Qt, widgets normally do not generate screen | |
flicker, but on X11 the server might erase regions on the screen | |
when widgets get hidden before they can be replaced by other | |
widgets. Disabling updates solves this. | |
Example: | |
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 13 | |
Disabling a widget implicitly disables all its children. Enabling a widget | |
enables all child widgets \e except top-level widgets or those that | |
have been explicitly disabled. Re-enabling updates implicitly calls | |
update() on the widget. | |
\sa paintEvent() | |
*/ | |
void QWidget::setUpdatesEnabled(bool enable) | |
{ | |
Q_D(QWidget); | |
setAttribute(Qt::WA_ForceUpdatesDisabled, !enable); | |
d->setUpdatesEnabled_helper(enable); | |
} | |
/*! \fn void QWidget::show() | |
Shows the widget and its child widgets. This function is | |
equivalent to setVisible(true). | |
\sa raise(), showEvent(), hide(), setVisible(), showMinimized(), showMaximized(), | |
showNormal(), isVisible() | |
*/ | |
/*! \internal | |
Makes the widget visible in the isVisible() meaning of the word. | |
It is only called for toplevels or widgets with visible parents. | |
*/ | |
void QWidgetPrivate::show_recursive() | |
{ | |
Q_Q(QWidget); | |
// polish if necessary | |
if (!q->testAttribute(Qt::WA_WState_Created)) | |
createRecursively(); | |
q->ensurePolished(); | |
#ifdef QT3_SUPPORT | |
if(sendChildEvents) | |
QApplication::sendPostedEvents(q, QEvent::ChildInserted); | |
#endif | |
if (!q->isWindow() && q->parentWidget()->d_func()->layout && !q->parentWidget()->data->in_show) | |
q->parentWidget()->d_func()->layout->activate(); | |
// activate our layout before we and our children become visible | |
if (layout) | |
layout->activate(); | |
show_helper(); | |
} | |
void QWidgetPrivate::sendPendingMoveAndResizeEvents(bool recursive, bool disableUpdates) | |
{ | |
Q_Q(QWidget); | |
disableUpdates = disableUpdates && q->updatesEnabled(); | |
if (disableUpdates) | |
q->setAttribute(Qt::WA_UpdatesDisabled); | |
if (q->testAttribute(Qt::WA_PendingMoveEvent)) { | |
QMoveEvent e(data.crect.topLeft(), data.crect.topLeft()); | |
QApplication::sendEvent(q, &e); | |
q->setAttribute(Qt::WA_PendingMoveEvent, false); | |
} | |
if (q->testAttribute(Qt::WA_PendingResizeEvent)) { | |
QResizeEvent e(data.crect.size(), QSize()); | |
QApplication::sendEvent(q, &e); | |
q->setAttribute(Qt::WA_PendingResizeEvent, false); | |
} | |
if (disableUpdates) | |
q->setAttribute(Qt::WA_UpdatesDisabled, false); | |
if (!recursive) | |
return; | |
for (int i = 0; i < children.size(); ++i) { | |
if (QWidget *child = qobject_cast<QWidget *>(children.at(i))) | |
child->d_func()->sendPendingMoveAndResizeEvents(recursive, disableUpdates); | |
} | |
} | |
void QWidgetPrivate::activateChildLayoutsRecursively() | |
{ | |
sendPendingMoveAndResizeEvents(false, true); | |
for (int i = 0; i < children.size(); ++i) { | |
QWidget *child = qobject_cast<QWidget *>(children.at(i)); | |
if (!child || child->isHidden() || child->isWindow()) | |
continue; | |
child->ensurePolished(); | |
// Activate child's layout | |
QWidgetPrivate *childPrivate = child->d_func(); | |
if (childPrivate->layout) | |
childPrivate->layout->activate(); | |
// Pretend we're visible. | |
const bool wasVisible = child->isVisible(); | |
if (!wasVisible) | |
child->setAttribute(Qt::WA_WState_Visible); | |
// Do the same for all my children. | |
childPrivate->activateChildLayoutsRecursively(); | |
// We're not cheating anymore. | |
if (!wasVisible) | |
child->setAttribute(Qt::WA_WState_Visible, false); | |
} | |
} | |
void QWidgetPrivate::show_helper() | |
{ | |
Q_Q(QWidget); | |
data.in_show = true; // qws optimization | |
// make sure we receive pending move and resize events | |
sendPendingMoveAndResizeEvents(); | |
// become visible before showing all children | |
q->setAttribute(Qt::WA_WState_Visible); | |
// finally show all children recursively | |
showChildren(false); | |
#ifdef QT3_SUPPORT | |
if (q->parentWidget() && sendChildEvents) | |
QApplication::sendPostedEvents(q->parentWidget(), | |
QEvent::ChildInserted); | |
#endif | |
// popup handling: new popups and tools need to be raised, and | |
// existing popups must be closed. Also propagate the current | |
// windows's KeyboardFocusChange status. | |
if (q->isWindow()) { | |
if ((q->windowType() == Qt::Tool) || (q->windowType() == Qt::Popup) || q->windowType() == Qt::ToolTip) { | |
q->raise(); | |
if (q->parentWidget() && q->parentWidget()->window()->testAttribute(Qt::WA_KeyboardFocusChange)) | |
q->setAttribute(Qt::WA_KeyboardFocusChange); | |
} else { | |
while (QApplication::activePopupWidget()) { | |
if (!QApplication::activePopupWidget()->close()) | |
break; | |
} | |
} | |
} | |
// Automatic embedding of child windows of widgets already embedded into | |
// QGraphicsProxyWidget when they are shown the first time. | |
bool isEmbedded = false; | |
#ifndef QT_NO_GRAPHICSVIEW | |
if (q->isWindow()) { | |
isEmbedded = q->graphicsProxyWidget() ? true : false; | |
if (!isEmbedded && !bypassGraphicsProxyWidget(q)) { | |
QGraphicsProxyWidget *ancestorProxy = nearestGraphicsProxyWidget(q->parentWidget()); | |
if (ancestorProxy) { | |
isEmbedded = true; | |
ancestorProxy->d_func()->embedSubWindow(q); | |
} | |
} | |
} | |
#else | |
Q_UNUSED(isEmbedded); | |
#endif | |
// On Windows, show the popup now so that our own focus handling | |
// stores the correct old focus widget even if it's stolen in the | |
// showevent | |
#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN) | |
if (!isEmbedded && q->windowType() == Qt::Popup) | |
qApp->d_func()->openPopup(q); | |
#endif | |
// send the show event before showing the window | |
QShowEvent showEvent; | |
QApplication::sendEvent(q, &showEvent); | |
if (!isEmbedded && q->isModal() && q->isWindow()) | |
// QApplicationPrivate::enterModal *before* show, otherwise the initial | |
// stacking might be wrong | |
QApplicationPrivate::enterModal(q); | |
show_sys(); | |
#if !defined(Q_WS_WIN) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN) | |
if (!isEmbedded && q->windowType() == Qt::Popup) | |
qApp->d_func()->openPopup(q); | |
#endif | |
#ifndef QT_NO_ACCESSIBILITY | |
if (q->windowType() != Qt::ToolTip) // Tooltips are read aloud twice in MS narrator. | |
QAccessible::updateAccessibility(q, 0, QAccessible::ObjectShow); | |
#endif | |
if (QApplicationPrivate::hidden_focus_widget == q) { | |
QApplicationPrivate::hidden_focus_widget = 0; | |
q->setFocus(Qt::OtherFocusReason); | |
} | |
// Process events when showing a Qt::SplashScreen widget before the event loop | |
// is spinnning; otherwise it might not show up on particular platforms. | |
// This makes QSplashScreen behave the same on all platforms. | |
if (!qApp->d_func()->in_exec && q->windowType() == Qt::SplashScreen) | |
QApplication::processEvents(); | |
data.in_show = false; // reset qws optimization | |
} | |
/*! \fn void QWidget::hide() | |
Hides the widget. This function is equivalent to | |
setVisible(false). | |
\note If you are working with QDialog or its subclasses and you invoke | |
the show() function after this function, the dialog will be displayed in | |
its original position. | |
\sa hideEvent(), isHidden(), show(), setVisible(), isVisible(), close() | |
*/ | |
/*!\internal | |
*/ | |
void QWidgetPrivate::hide_helper() | |
{ | |
Q_Q(QWidget); | |
bool isEmbedded = false; | |
#if !defined QT_NO_GRAPHICSVIEW | |
isEmbedded = q->isWindow() && !bypassGraphicsProxyWidget(q) && nearestGraphicsProxyWidget(q->parentWidget()) != 0; | |
#else | |
Q_UNUSED(isEmbedded); | |
#endif | |
if (!isEmbedded && (q->windowType() == Qt::Popup)) | |
qApp->d_func()->closePopup(q); | |
// Move test modal here. Otherwise, a modal dialog could get | |
// destroyed and we lose all access to its parent because we haven't | |
// left modality. (Eg. modal Progress Dialog) | |
if (!isEmbedded && q->isModal() && q->isWindow()) | |
QApplicationPrivate::leaveModal(q); | |
#if defined(Q_WS_WIN) | |
if (q->isWindow() && !(q->windowType() == Qt::Popup) && q->parentWidget() | |
&& !q->parentWidget()->isHidden() && q->isActiveWindow()) | |
q->parentWidget()->activateWindow(); // Activate parent | |
#endif | |
q->setAttribute(Qt::WA_Mapped, false); | |
hide_sys(); | |
bool wasVisible = q->testAttribute(Qt::WA_WState_Visible); | |
if (wasVisible) { | |
q->setAttribute(Qt::WA_WState_Visible, false); | |
} | |
QHideEvent hideEvent; | |
QApplication::sendEvent(q, &hideEvent); | |
hideChildren(false); | |
// next bit tries to move the focus if the focus widget is now | |
// hidden. | |
if (wasVisible) { | |
#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) | |
qApp->d_func()->sendSyntheticEnterLeave(q); | |
#endif | |
QWidget *fw = QApplication::focusWidget(); | |
while (fw && !fw->isWindow()) { | |
if (fw == q) { | |
q->focusNextPrevChild(true); | |
break; | |
} | |
fw = fw->parentWidget(); | |
} | |
} | |
if (QWidgetBackingStore *bs = maybeBackingStore()) | |
bs->removeDirtyWidget(q); | |
#ifndef QT_NO_ACCESSIBILITY | |
if (wasVisible) | |
QAccessible::updateAccessibility(q, 0, QAccessible::ObjectHide); | |
#endif | |
} | |
/*! | |
\fn bool QWidget::isHidden() const | |
Returns true if the widget is hidden, otherwise returns false. | |
A hidden widget will only become visible when show() is called on | |
it. It will not be automatically shown when the parent is shown. | |
To check visibility, use !isVisible() instead (notice the exclamation mark). | |
isHidden() implies !isVisible(), but a widget can be not visible | |
and not hidden at the same time. This is the case for widgets that are children of | |
widgets that are not visible. | |
Widgets are hidden if: | |
\list | |
\o they were created as independent windows, | |
\o they were created as children of visible widgets, | |
\o hide() or setVisible(false) was called. | |
\endlist | |
*/ | |
void QWidget::setVisible(bool visible) | |
{ | |
if (visible) { // show | |
if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden)) | |
return; | |
Q_D(QWidget); | |
// Designer uses a trick to make grabWidget work without showing | |
if (!isWindow() && parentWidget() && parentWidget()->isVisible() | |
&& !parentWidget()->testAttribute(Qt::WA_WState_Created)) | |
parentWidget()->window()->d_func()->createRecursively(); | |
//we have to at least create toplevels before applyX11SpecificCommandLineArguments | |
//but not children of non-visible parents | |
QWidget *pw = parentWidget(); | |
if (!testAttribute(Qt::WA_WState_Created) | |
&& (isWindow() || pw->testAttribute(Qt::WA_WState_Created))) { | |
create(); | |
} | |
#if defined(Q_WS_X11) | |
if (windowType() == Qt::Window) | |
QApplicationPrivate::applyX11SpecificCommandLineArguments(this); | |
#elif defined(Q_WS_QWS) | |
if (windowType() == Qt::Window) | |
QApplicationPrivate::applyQWSSpecificCommandLineArguments(this); | |
#endif | |
bool wasResized = testAttribute(Qt::WA_Resized); | |
Qt::WindowStates initialWindowState = windowState(); | |
// polish if necessary | |
ensurePolished(); | |
// remember that show was called explicitly | |
setAttribute(Qt::WA_WState_ExplicitShowHide); | |
// whether we need to inform the parent widget immediately | |
bool needUpdateGeometry = !isWindow() && testAttribute(Qt::WA_WState_Hidden); | |
// we are no longer hidden | |
setAttribute(Qt::WA_WState_Hidden, false); | |
if (needUpdateGeometry) | |
d->updateGeometry_helper(true); | |
#ifdef QT3_SUPPORT | |
QApplication::sendPostedEvents(this, QEvent::ChildInserted); | |
#endif | |
// activate our layout before we and our children become visible | |
if (d->layout) | |
d->layout->activate(); | |
if (!isWindow()) { | |
QWidget *parent = parentWidget(); | |
while (parent && parent->isVisible() && parent->d_func()->layout && !parent->data->in_show) { | |
parent->d_func()->layout->activate(); | |
if (parent->isWindow()) | |
break; | |
parent = parent->parentWidget(); | |
} | |
if (parent) | |
parent->d_func()->setDirtyOpaqueRegion(); | |
} | |
// adjust size if necessary | |
if (!wasResized | |
&& (isWindow() || !parentWidget()->d_func()->layout)) { | |
if (isWindow()) { | |
adjustSize(); | |
if (windowState() != initialWindowState) | |
setWindowState(initialWindowState); | |
} else { | |
adjustSize(); | |
} | |
setAttribute(Qt::WA_Resized, false); | |
} | |
setAttribute(Qt::WA_KeyboardFocusChange, false); | |
if (isWindow() || parentWidget()->isVisible()) { | |
// remove posted quit events when showing a new window | |
QCoreApplication::removePostedEvents(qApp, QEvent::Quit); | |
d->show_helper(); | |
#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) | |
qApp->d_func()->sendSyntheticEnterLeave(this); | |
#endif | |
} | |
QEvent showToParentEvent(QEvent::ShowToParent); | |
QApplication::sendEvent(this, &showToParentEvent); | |
} else { // hide | |
if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden)) | |
return; | |
#if defined(Q_WS_WIN) | |
// reset WS_DISABLED style in a Blocked window | |
if(isWindow() && testAttribute(Qt::WA_WState_Created) | |
&& QApplicationPrivate::isBlockedByModal(this)) | |
{ | |
LONG dwStyle = GetWindowLong(winId(), GWL_STYLE); | |
dwStyle &= ~WS_DISABLED; | |
SetWindowLong(winId(), GWL_STYLE, dwStyle); | |
} | |
#endif | |
if (QApplicationPrivate::hidden_focus_widget == this) | |
QApplicationPrivate::hidden_focus_widget = 0; | |
Q_D(QWidget); | |
// hw: The test on getOpaqueRegion() needs to be more intelligent | |
// currently it doesn't work if the widget is hidden (the region will | |
// be clipped). The real check should be testing the cached region | |
// (and dirty flag) directly. | |
if (!isWindow() && parentWidget()) // && !d->getOpaqueRegion().isEmpty()) | |
parentWidget()->d_func()->setDirtyOpaqueRegion(); | |
setAttribute(Qt::WA_WState_Hidden); | |
setAttribute(Qt::WA_WState_ExplicitShowHide); | |
if (testAttribute(Qt::WA_WState_Created)) | |
d->hide_helper(); | |
// invalidate layout similar to updateGeometry() | |
if (!isWindow() && parentWidget()) { | |
if (parentWidget()->d_func()->layout) | |
parentWidget()->d_func()->layout->invalidate(); | |
else if (parentWidget()->isVisible()) | |
QApplication::postEvent(parentWidget(), new QEvent(QEvent::LayoutRequest)); | |
} | |
QEvent hideToParentEvent(QEvent::HideToParent); | |
QApplication::sendEvent(this, &hideToParentEvent); | |
} | |
} | |
/*!\fn void QWidget::setHidden(bool hidden) | |
Convenience function, equivalent to setVisible(!\a hidden). | |
*/ | |
/*!\fn void QWidget::setShown(bool shown) | |
Use setVisible(\a shown) instead. | |
*/ | |
void QWidgetPrivate::_q_showIfNotHidden() | |
{ | |
Q_Q(QWidget); | |
if ( !(q->isHidden() && q->testAttribute(Qt::WA_WState_ExplicitShowHide)) ) | |
q->setVisible(true); | |
} | |
void QWidgetPrivate::showChildren(bool spontaneous) | |
{ | |
QList<QObject*> childList = children; | |
for (int i = 0; i < childList.size(); ++i) { | |
QWidget *widget = qobject_cast<QWidget*>(childList.at(i)); | |
if (!widget | |
|| widget->isWindow() | |
|| widget->testAttribute(Qt::WA_WState_Hidden)) | |
continue; | |
if (spontaneous) { | |
widget->setAttribute(Qt::WA_Mapped); | |
widget->d_func()->showChildren(true); | |
QShowEvent e; | |
QApplication::sendSpontaneousEvent(widget, &e); | |
} else { | |
if (widget->testAttribute(Qt::WA_WState_ExplicitShowHide)) | |
widget->d_func()->show_recursive(); | |
else | |
widget->show(); | |
} | |
} | |
} | |
void QWidgetPrivate::hideChildren(bool spontaneous) | |
{ | |
QList<QObject*> childList = children; | |
for (int i = 0; i < childList.size(); ++i) { | |
QWidget *widget = qobject_cast<QWidget*>(childList.at(i)); | |
if (!widget || widget->isWindow() || widget->testAttribute(Qt::WA_WState_Hidden)) | |
continue; | |
#ifdef QT_MAC_USE_COCOA | |
// Before doing anything we need to make sure that we don't leave anything in a non-consistent state. | |
// When hiding a widget we need to make sure that no mouse_down events are active, because | |
// the mouse_up event will never be received by a hidden widget or one of its descendants. | |
// The solution is simple, before going through with this we check if there are any mouse_down events in | |
// progress, if so we check if it is related to this widget or not. If so, we just reset the mouse_down and | |
// then we continue. | |
// In X11 and Windows we send a mouse_release event, however we don't do that here because we were already | |
// ignoring that from before. I.e. Carbon did not send the mouse release event, so we will not send the | |
// mouse release event. There are two ways to interpret this: | |
// 1. If we don't send the mouse release event, the widget might get into an inconsistent state, i.e. it | |
// might be waiting for a release event that will never arrive. | |
// 2. If we send the mouse release event, then the widget might decide to trigger an action that is not | |
// supposed to trigger because it is not visible. | |
if(widget == qt_button_down) | |
qt_button_down = 0; | |
#endif // QT_MAC_USE_COCOA | |
if (spontaneous) | |
widget->setAttribute(Qt::WA_Mapped, false); | |
else | |
widget->setAttribute(Qt::WA_WState_Visible, false); | |
widget->d_func()->hideChildren(spontaneous); | |
QHideEvent e; | |
if (spontaneous) { | |
QApplication::sendSpontaneousEvent(widget, &e); | |
} else { | |
QApplication::sendEvent(widget, &e); | |
if (widget->internalWinId() | |
&& widget->testAttribute(Qt::WA_DontCreateNativeAncestors)) { | |
// hide_sys() on an ancestor won't have any affect on this | |
// widget, so it needs an explicit hide_sys() of its own | |
widget->d_func()->hide_sys(); | |
} | |
} | |
#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) | |
qApp->d_func()->sendSyntheticEnterLeave(widget); | |
#endif | |
#ifndef QT_NO_ACCESSIBILITY | |
if (!spontaneous) | |
QAccessible::updateAccessibility(widget, 0, QAccessible::ObjectHide); | |
#endif | |
} | |
} | |
bool QWidgetPrivate::close_helper(CloseMode mode) | |
{ | |
if (data.is_closing) | |
return true; | |
Q_Q(QWidget); | |
data.is_closing = 1; | |
QPointer<QWidget> that = q; | |
QPointer<QWidget> parentWidget = q->parentWidget(); | |
#ifdef QT3_SUPPORT | |
bool isMain = (QApplicationPrivate::main_widget == q); | |
#endif | |
bool quitOnClose = q->testAttribute(Qt::WA_QuitOnClose); | |
if (mode != CloseNoEvent) { | |
QCloseEvent e; | |
if (mode == CloseWithSpontaneousEvent) | |
QApplication::sendSpontaneousEvent(q, &e); | |
else | |
QApplication::sendEvent(q, &e); | |
if (!that.isNull() && !e.isAccepted()) { | |
data.is_closing = 0; | |
return false; | |
} | |
} | |
if (!that.isNull() && !q->isHidden()) | |
q->hide(); | |
#ifdef QT3_SUPPORT | |
if (isMain) | |
QApplication::quit(); | |
#endif | |
// Attempt to close the application only if this has WA_QuitOnClose set and a non-visible parent | |
quitOnClose = quitOnClose && (parentWidget.isNull() || !parentWidget->isVisible()); | |
if (quitOnClose) { | |
/* if there is no non-withdrawn primary window left (except | |
the ones without QuitOnClose), we emit the lastWindowClosed | |
signal */ | |
QWidgetList list = QApplication::topLevelWidgets(); | |
bool lastWindowClosed = true; | |
for (int i = 0; i < list.size(); ++i) { | |
QWidget *w = list.at(i); | |
if (!w->isVisible() || w->parentWidget() || !w->testAttribute(Qt::WA_QuitOnClose)) | |
continue; | |
lastWindowClosed = false; | |
break; | |
} | |
if (lastWindowClosed) | |
QApplicationPrivate::emitLastWindowClosed(); | |
} | |
if (!that.isNull()) { | |
data.is_closing = 0; | |
if (q->testAttribute(Qt::WA_DeleteOnClose)) { | |
q->setAttribute(Qt::WA_DeleteOnClose, false); | |
q->deleteLater(); | |
} | |
} | |
return true; | |
} | |
/*! | |
Closes this widget. Returns true if the widget was closed; | |
otherwise returns false. | |
First it sends the widget a QCloseEvent. The widget is \link | |
hide() hidden\endlink if it \link QCloseEvent::accept() | |
accepts\endlink the close event. If it \link QCloseEvent::ignore() | |
ignores\endlink the event, nothing happens. The default | |
implementation of QWidget::closeEvent() accepts the close event. | |
If the widget has the Qt::WA_DeleteOnClose flag, the widget | |
is also deleted. A close events is delivered to the widget no | |
matter if the widget is visible or not. | |
The \l QApplication::lastWindowClosed() signal is emitted when the | |
last visible primary window (i.e. window with no parent) with the | |
Qt::WA_QuitOnClose attribute set is closed. By default this | |
attribute is set for all widgets except transient windows such as | |
splash screens, tool windows, and popup menus. | |
*/ | |
bool QWidget::close() | |
{ | |
return d_func()->close_helper(QWidgetPrivate::CloseWithEvent); | |
} | |
/*! | |
\property QWidget::visible | |
\brief whether the widget is visible | |
Calling setVisible(true) or show() sets the widget to visible | |
status if all its parent widgets up to the window are visible. If | |
an ancestor is not visible, the widget won't become visible until | |
all its ancestors are shown. If its size or position has changed, | |
Qt guarantees that a widget gets move and resize events just | |
before it is shown. If the widget has not been resized yet, Qt | |
will adjust the widget's size to a useful default using | |
adjustSize(). | |
Calling setVisible(false) or hide() hides a widget explicitly. An | |
explicitly hidden widget will never become visible, even if all | |
its ancestors become visible, unless you show it. | |
A widget receives show and hide events when its visibility status | |
changes. Between a hide and a show event, there is no need to | |
waste CPU cycles preparing or displaying information to the user. | |
A video application, for example, might simply stop generating new | |
frames. | |
A widget that happens to be obscured by other windows on the | |
screen is considered to be visible. The same applies to iconified | |
windows and windows that exist on another virtual | |
desktop (on platforms that support this concept). A widget | |
receives spontaneous show and hide events when its mapping status | |
is changed by the window system, e.g. a spontaneous hide event | |
when the user minimizes the window, and a spontaneous show event | |
when the window is restored again. | |
You almost never have to reimplement the setVisible() function. If | |
you need to change some settings before a widget is shown, use | |
showEvent() instead. If you need to do some delayed initialization | |
use the Polish event delivered to the event() function. | |
\sa show(), hide(), isHidden(), isVisibleTo(), isMinimized(), | |
showEvent(), hideEvent() | |
*/ | |
/*! | |
Returns true if this widget would become visible if \a ancestor is | |
shown; otherwise returns false. | |
The true case occurs if neither the widget itself nor any parent | |
up to but excluding \a ancestor has been explicitly hidden. | |
This function will still return true if the widget is obscured by | |
other windows on the screen, but could be physically visible if it | |
or they were to be moved. | |
isVisibleTo(0) is identical to isVisible(). | |
\sa show() hide() isVisible() | |
*/ | |
bool QWidget::isVisibleTo(QWidget* ancestor) const | |
{ | |
if (!ancestor) | |
return isVisible(); | |
const QWidget * w = this; | |
while (!w->isHidden() | |
&& !w->isWindow() | |
&& w->parentWidget() | |
&& w->parentWidget() != ancestor) | |
w = w->parentWidget(); | |
return !w->isHidden(); | |
} | |
#ifdef QT3_SUPPORT | |
/*! | |
Use visibleRegion() instead. | |
*/ | |
QRect QWidget::visibleRect() const | |
{ | |
return d_func()->clipRect(); | |
} | |
#endif | |
/*! | |
Returns the unobscured region where paint events can occur. | |
For visible widgets, this is an approximation of the area not | |
covered by other widgets; otherwise, this is an empty region. | |
The repaint() function calls this function if necessary, so in | |
general you do not need to call it. | |
*/ | |
QRegion QWidget::visibleRegion() const | |
{ | |
Q_D(const QWidget); | |
QRect clipRect = d->clipRect(); | |
if (clipRect.isEmpty()) | |
return QRegion(); | |
QRegion r(clipRect); | |
d->subtractOpaqueChildren(r, clipRect); | |
d->subtractOpaqueSiblings(r); | |
#ifdef Q_WS_QWS | |
const QWSWindowSurface *surface = static_cast<const QWSWindowSurface*>(windowSurface()); | |
if (surface) { | |
const QPoint offset = mapTo(surface->window(), QPoint()); | |
r &= surface->clipRegion().translated(-offset); | |
} | |
#endif | |
return r; | |
} | |
QSize QWidgetPrivate::adjustedSize() const | |
{ | |
Q_Q(const QWidget); | |
QSize s = q->sizeHint(); | |
if (q->isWindow()) { | |
Qt::Orientations exp; | |
if (layout) { | |
if (layout->hasHeightForWidth()) | |
s.setHeight(layout->totalHeightForWidth(s.width())); | |
exp = layout->expandingDirections(); | |
} else | |
{ | |
if (q->sizePolicy().hasHeightForWidth()) | |
s.setHeight(q->heightForWidth(s.width())); | |
exp = q->sizePolicy().expandingDirections(); | |
} | |
if (exp & Qt::Horizontal) | |
s.setWidth(qMax(s.width(), 200)); | |
if (exp & Qt::Vertical) | |
s.setHeight(qMax(s.height(), 100)); | |
#if defined(Q_WS_X11) | |
QRect screen = QApplication::desktop()->screenGeometry(q->x11Info().screen()); | |
#else // all others | |
QRect screen = QApplication::desktop()->screenGeometry(q->pos()); | |
#endif | |
#if defined (Q_WS_WINCE) || defined (Q_OS_SYMBIAN) | |
s.setWidth(qMin(s.width(), screen.width())); | |
s.setHeight(qMin(s.height(), screen.height())); | |
#else | |
s.setWidth(qMin(s.width(), screen.width()*2/3)); | |
s.setHeight(qMin(s.height(), screen.height()*2/3)); | |
#endif | |
if (QTLWExtra *extra = maybeTopData()) | |
extra->sizeAdjusted = true; | |
} | |
if (!s.isValid()) { | |
QRect r = q->childrenRect(); // get children rectangle | |
if (r.isNull()) | |
return s; | |
s = r.size() + QSize(2 * r.x(), 2 * r.y()); | |
} | |
return s; | |
} | |
/*! | |
Adjusts the size of the widget to fit its contents. | |
This function uses sizeHint() if it is valid, i.e., the size hint's width | |
and height are \>= 0. Otherwise, it sets the size to the children | |
rectangle that covers all child widgets (the union of all child widget | |
rectangles). | |
For windows, the screen size is also taken into account. If the sizeHint() | |
is less than (200, 100) and the size policy is \l{QSizePolicy::Expanding} | |
{expanding}, the window will be at least (200, 100). The maximum size of | |
a window is 2/3 of the screen's width and height. | |
\sa sizeHint(), childrenRect() | |
*/ | |
void QWidget::adjustSize() | |
{ | |
Q_D(QWidget); | |
ensurePolished(); | |
QSize s = d->adjustedSize(); | |
if (d->layout) | |
d->layout->activate(); | |
if (s.isValid()) | |
resize(s); | |
} | |
/*! | |
\property QWidget::sizeHint | |
\brief the recommended size for the widget | |
If the value of this property is an invalid size, no size is | |
recommended. | |
The default implementation of sizeHint() returns an invalid size | |
if there is no layout for this widget, and returns the layout's | |
preferred size otherwise. | |
\sa QSize::isValid(), minimumSizeHint(), sizePolicy(), | |
setMinimumSize(), updateGeometry() | |
*/ | |
QSize QWidget::sizeHint() const | |
{ | |
Q_D(const QWidget); | |
if (d->layout) | |
return d->layout->totalSizeHint(); | |
return QSize(-1, -1); | |
} | |
/*! | |
\property QWidget::minimumSizeHint | |
\brief the recommended minimum size for the widget | |
If the value of this property is an invalid size, no minimum size | |
is recommended. | |
The default implementation of minimumSizeHint() returns an invalid | |
size if there is no layout for this widget, and returns the | |
layout's minimum size otherwise. Most built-in widgets reimplement | |
minimumSizeHint(). | |
\l QLayout will never resize a widget to a size smaller than the | |
minimum size hint unless minimumSize() is set or the size policy is | |
set to QSizePolicy::Ignore. If minimumSize() is set, the minimum | |
size hint will be ignored. | |
\sa QSize::isValid(), resize(), setMinimumSize(), sizePolicy() | |
*/ | |
QSize QWidget::minimumSizeHint() const | |
{ | |
Q_D(const QWidget); | |
if (d->layout) | |
return d->layout->totalMinimumSize(); | |
return QSize(-1, -1); | |
} | |
/*! | |
\fn QWidget *QWidget::parentWidget() const | |
Returns the parent of this widget, or 0 if it does not have any | |
parent widget. | |
*/ | |
/*! | |
Returns true if this widget is a parent, (or grandparent and so on | |
to any level), of the given \a child, and both widgets are within | |
the same window; otherwise returns false. | |
*/ | |
bool QWidget::isAncestorOf(const QWidget *child) const | |
{ | |
while (child) { | |
if (child == this) | |
return true; | |
if (child->isWindow()) | |
return false; | |
child = child->parentWidget(); | |
} | |
return false; | |
} | |
#if defined(Q_WS_WIN) | |
inline void setDisabledStyle(QWidget *w, bool setStyle) | |
{ | |
// set/reset WS_DISABLED style. | |
if(w && w->isWindow() && w->isVisible() && w->isEnabled()) { | |
LONG dwStyle = GetWindowLong(w->winId(), GWL_STYLE); | |
LONG newStyle = dwStyle; | |
if (setStyle) | |
newStyle |= WS_DISABLED; | |
else | |
newStyle &= ~WS_DISABLED; | |
if (newStyle != dwStyle) { | |
SetWindowLong(w->winId(), GWL_STYLE, newStyle); | |
// we might need to repaint in some situations (eg. menu) | |
w->repaint(); | |
} | |
} | |
} | |
#endif | |
/***************************************************************************** | |
QWidget event handling | |
*****************************************************************************/ | |
/*! | |
This is the main event handler; it handles event \a event. You can | |
reimplement this function in a subclass, but we recommend using | |
one of the specialized event handlers instead. | |
Key press and release events are treated differently from other | |
events. event() checks for Tab and Shift+Tab and tries to move the | |
focus appropriately. If there is no widget to move the focus to | |
(or the key press is not Tab or Shift+Tab), event() calls | |
keyPressEvent(). | |
Mouse and tablet event handling is also slightly special: only | |
when the widget is \l enabled, event() will call the specialized | |
handlers such as mousePressEvent(); otherwise it will discard the | |
event. | |
This function returns true if the event was recognized, otherwise | |
it returns false. If the recognized event was accepted (see \l | |
QEvent::accepted), any further processing such as event | |
propagation to the parent widget stops. | |
\sa closeEvent(), focusInEvent(), focusOutEvent(), enterEvent(), | |
keyPressEvent(), keyReleaseEvent(), leaveEvent(), | |
mouseDoubleClickEvent(), mouseMoveEvent(), mousePressEvent(), | |
mouseReleaseEvent(), moveEvent(), paintEvent(), resizeEvent(), | |
QObject::event(), QObject::timerEvent() | |
*/ | |
bool QWidget::event(QEvent *event) | |
{ | |
Q_D(QWidget); | |
// ignore mouse events when disabled | |
if (!isEnabled()) { | |
switch(event->type()) { | |
case QEvent::TabletPress: | |
case QEvent::TabletRelease: | |
case QEvent::TabletMove: | |
case QEvent::MouseButtonPress: | |
case QEvent::MouseButtonRelease: | |
case QEvent::MouseButtonDblClick: | |
case QEvent::MouseMove: | |
case QEvent::TouchBegin: | |
case QEvent::TouchUpdate: | |
case QEvent::TouchEnd: | |
case QEvent::ContextMenu: | |
#ifndef QT_NO_WHEELEVENT | |
case QEvent::Wheel: | |
#endif | |
return false; | |
default: | |
break; | |
} | |
} | |
switch (event->type()) { | |
case QEvent::MouseMove: | |
mouseMoveEvent((QMouseEvent*)event); | |
break; | |
case QEvent::MouseButtonPress: | |
// Don't reset input context here. Whether reset or not is | |
// a responsibility of input method. reset() will be | |
// called by mouseHandler() of input method if necessary | |
// via mousePressEvent() of text widgets. | |
#if 0 | |
resetInputContext(); | |
#endif | |
mousePressEvent((QMouseEvent*)event); | |
break; | |
case QEvent::MouseButtonRelease: | |
mouseReleaseEvent((QMouseEvent*)event); | |
break; | |
case QEvent::MouseButtonDblClick: | |
mouseDoubleClickEvent((QMouseEvent*)event); | |
break; | |
#ifndef QT_NO_WHEELEVENT | |
case QEvent::Wheel: | |
wheelEvent((QWheelEvent*)event); | |
break; | |
#endif | |
#ifndef QT_NO_TABLETEVENT | |
case QEvent::TabletMove: | |
case QEvent::TabletPress: | |
case QEvent::TabletRelease: | |
tabletEvent((QTabletEvent*)event); | |
break; | |
#endif | |
#ifdef QT3_SUPPORT | |
case QEvent::Accel: | |
event->ignore(); | |
return false; | |
#endif | |
case QEvent::KeyPress: { | |
QKeyEvent *k = (QKeyEvent *)event; | |
bool res = false; | |
if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier? | |
if (k->key() == Qt::Key_Backtab | |
|| (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier))) | |
res = focusNextPrevChild(false); | |
else if (k->key() == Qt::Key_Tab) | |
res = focusNextPrevChild(true); | |
if (res) | |
break; | |
} | |
keyPressEvent(k); | |
#ifdef QT_KEYPAD_NAVIGATION | |
if (!k->isAccepted() && QApplication::keypadNavigationEnabled() | |
&& !(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::ShiftModifier))) { | |
if (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder) { | |
if (k->key() == Qt::Key_Up) | |
res = focusNextPrevChild(false); | |
else if (k->key() == Qt::Key_Down) | |
res = focusNextPrevChild(true); | |
} else if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) { | |
if (k->key() == Qt::Key_Up) | |
res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionNorth); | |
else if (k->key() == Qt::Key_Right) | |
res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionEast); | |
else if (k->key() == Qt::Key_Down) | |
res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionSouth); | |
else if (k->key() == Qt::Key_Left) | |
res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionWest); | |
} | |
if (res) { | |
k->accept(); | |
break; | |
} | |
} | |
#endif | |
#ifndef QT_NO_WHATSTHIS | |
if (!k->isAccepted() | |
&& k->modifiers() & Qt::ShiftModifier && k->key() == Qt::Key_F1 | |
&& d->whatsThis.size()) { | |
QWhatsThis::showText(mapToGlobal(inputMethodQuery(Qt::ImMicroFocus).toRect().center()), d->whatsThis, this); | |
k->accept(); | |
} | |
#endif | |
} | |
break; | |
case QEvent::KeyRelease: | |
keyReleaseEvent((QKeyEvent*)event); | |
// fall through | |
case QEvent::ShortcutOverride: | |
break; | |
case QEvent::InputMethod: | |
inputMethodEvent((QInputMethodEvent *) event); | |
break; | |
case QEvent::PolishRequest: | |
ensurePolished(); | |
break; | |
case QEvent::Polish: { | |
style()->polish(this); | |
setAttribute(Qt::WA_WState_Polished); | |
if (!QApplication::font(this).isCopyOf(QApplication::font())) | |
d->resolveFont(); | |
if (!QApplication::palette(this).isCopyOf(QApplication::palette())) | |
d->resolvePalette(); | |
#ifdef QT3_SUPPORT | |
if(d->sendChildEvents) | |
QApplication::sendPostedEvents(this, QEvent::ChildInserted); | |
#endif | |
} | |
break; | |
case QEvent::ApplicationWindowIconChange: | |
if (isWindow() && !testAttribute(Qt::WA_SetWindowIcon)) { | |
d->setWindowIcon_sys(); | |
d->setWindowIcon_helper(); | |
} | |
break; | |
case QEvent::FocusIn: | |
#ifdef QT_SOFTKEYS_ENABLED | |
QSoftKeyManager::updateSoftKeys(); | |
#endif | |
focusInEvent((QFocusEvent*)event); | |
break; | |
case QEvent::FocusOut: | |
focusOutEvent((QFocusEvent*)event); | |
break; | |
case QEvent::Enter: | |
#ifndef QT_NO_STATUSTIP | |
if (d->statusTip.size()) { | |
QStatusTipEvent tip(d->statusTip); | |
QApplication::sendEvent(const_cast<QWidget *>(this), &tip); | |
} | |
#endif | |
enterEvent(event); | |
break; | |
case QEvent::Leave: | |
#ifndef QT_NO_STATUSTIP | |
if (d->statusTip.size()) { | |
QString empty; | |
QStatusTipEvent tip(empty); | |
QApplication::sendEvent(const_cast<QWidget *>(this), &tip); | |
} | |
#endif | |
leaveEvent(event); | |
break; | |
case QEvent::HoverEnter: | |
case QEvent::HoverLeave: | |
update(); | |
break; | |
case QEvent::Paint: | |
// At this point the event has to be delivered, regardless | |
// whether the widget isVisible() or not because it | |
// already went through the filters | |
paintEvent((QPaintEvent*)event); | |
break; | |
case QEvent::Move: | |
moveEvent((QMoveEvent*)event); | |
break; | |
case QEvent::Resize: | |
resizeEvent((QResizeEvent*)event); | |
break; | |
case QEvent::Close: | |
closeEvent((QCloseEvent *)event); | |
break; | |
#ifndef QT_NO_CONTEXTMENU | |
case QEvent::ContextMenu: | |
switch (data->context_menu_policy) { | |
case Qt::PreventContextMenu: | |
break; | |
case Qt::DefaultContextMenu: | |
contextMenuEvent(static_cast<QContextMenuEvent *>(event)); | |
break; | |
case Qt::CustomContextMenu: | |
emit customContextMenuRequested(static_cast<QContextMenuEvent *>(event)->pos()); | |
break; | |
#ifndef QT_NO_MENU | |
case Qt::ActionsContextMenu: | |
if (d->actions.count()) { | |
QMenu::exec(d->actions, static_cast<QContextMenuEvent *>(event)->globalPos(), | |
0, this); | |
break; | |
} | |
// fall through | |
#endif | |
default: | |
event->ignore(); | |
break; | |
} | |
break; | |
#endif // QT_NO_CONTEXTMENU | |
#ifndef QT_NO_DRAGANDDROP | |
case QEvent::Drop: | |
dropEvent((QDropEvent*) event); | |
break; | |
case QEvent::DragEnter: | |
dragEnterEvent((QDragEnterEvent*) event); | |
break; | |
case QEvent::DragMove: | |
dragMoveEvent((QDragMoveEvent*) event); | |
break; | |
case QEvent::DragLeave: | |
dragLeaveEvent((QDragLeaveEvent*) event); | |
break; | |
#endif | |
case QEvent::Show: | |
showEvent((QShowEvent*) event); | |
break; | |
case QEvent::Hide: | |
hideEvent((QHideEvent*) event); | |
break; | |
case QEvent::ShowWindowRequest: | |
if (!isHidden()) | |
d->show_sys(); | |
break; | |
case QEvent::ApplicationFontChange: | |
d->resolveFont(); | |
break; | |
case QEvent::ApplicationPaletteChange: | |
if (!(windowType() == Qt::Desktop)) | |
d->resolvePalette(); | |
break; | |
case QEvent::ToolBarChange: | |
case QEvent::ActivationChange: | |
case QEvent::EnabledChange: | |
case QEvent::FontChange: | |
case QEvent::StyleChange: | |
case QEvent::PaletteChange: | |
case QEvent::WindowTitleChange: | |
case QEvent::IconTextChange: | |
case QEvent::ModifiedChange: | |
case QEvent::MouseTrackingChange: | |
case QEvent::ParentChange: | |
case QEvent::WindowStateChange: | |
case QEvent::LocaleChange: | |
case QEvent::MacSizeChange: | |
case QEvent::ContentsRectChange: | |
changeEvent(event); | |
break; | |
case QEvent::WindowActivate: | |
case QEvent::WindowDeactivate: { | |
#ifdef QT3_SUPPORT | |
windowActivationChange(event->type() != QEvent::WindowActivate); | |
#endif | |
if (isVisible() && !palette().isEqual(QPalette::Active, QPalette::Inactive)) | |
update(); | |
QList<QObject*> childList = d->children; | |
for (int i = 0; i < childList.size(); ++i) { | |
QWidget *w = qobject_cast<QWidget *>(childList.at(i)); | |
if (w && w->isVisible() && !w->isWindow()) | |
QApplication::sendEvent(w, event); | |
} | |
#ifdef QT_SOFTKEYS_ENABLED | |
if (isWindow()) | |
QSoftKeyManager::updateSoftKeys(); | |
#endif | |
break; } | |
case QEvent::LanguageChange: | |
#ifdef QT3_SUPPORT | |
languageChange(); | |
#endif | |
changeEvent(event); | |
{ | |
QList<QObject*> childList = d->children; | |
for (int i = 0; i < childList.size(); ++i) { | |
QObject *o = childList.at(i); | |
if (o) | |
QApplication::sendEvent(o, event); | |
} | |
} | |
update(); | |
break; | |
case QEvent::ApplicationLayoutDirectionChange: | |
d->resolveLayoutDirection(); | |
break; | |
case QEvent::LayoutDirectionChange: | |
if (d->layout) | |
d->layout->invalidate(); | |
update(); | |
changeEvent(event); | |
break; | |
case QEvent::UpdateRequest: | |
d->syncBackingStore(); | |
break; | |
case QEvent::UpdateLater: | |
update(static_cast<QUpdateLaterEvent*>(event)->region()); | |
break; | |
case QEvent::WindowBlocked: | |
case QEvent::WindowUnblocked: | |
{ | |
QList<QObject*> childList = d->children; | |
for (int i = 0; i < childList.size(); ++i) { | |
QObject *o = childList.at(i); | |
if (o && o != QApplication::activeModalWidget()) { | |
if (qobject_cast<QWidget *>(o) && static_cast<QWidget *>(o)->isWindow()) { | |
// do not forward the event to child windows, | |
// QApplication does this for us | |
continue; | |
} | |
QApplication::sendEvent(o, event); | |
} | |
} | |
#if defined(Q_WS_WIN) | |
setDisabledStyle(this, (event->type() == QEvent::WindowBlocked)); | |
#endif | |
} | |
break; | |
#ifndef QT_NO_TOOLTIP | |
case QEvent::ToolTip: | |
if (!d->toolTip.isEmpty()) | |
QToolTip::showText(static_cast<QHelpEvent*>(event)->globalPos(), d->toolTip, this); | |
else | |
event->ignore(); | |
break; | |
#endif | |
#ifndef QT_NO_WHATSTHIS | |
case QEvent::WhatsThis: | |
if (d->whatsThis.size()) | |
QWhatsThis::showText(static_cast<QHelpEvent *>(event)->globalPos(), d->whatsThis, this); | |
else | |
event->ignore(); | |
break; | |
case QEvent::QueryWhatsThis: | |
if (d->whatsThis.isEmpty()) | |
event->ignore(); | |
break; | |
#endif | |
#ifndef QT_NO_ACCESSIBILITY | |
case QEvent::AccessibilityDescription: | |
case QEvent::AccessibilityHelp: { | |
QAccessibleEvent *ev = static_cast<QAccessibleEvent *>(event); | |
if (ev->child()) | |
return false; | |
switch (ev->type()) { | |
#ifndef QT_NO_TOOLTIP | |
case QEvent::AccessibilityDescription: | |
ev->setValue(d->toolTip); | |
break; | |
#endif | |
#ifndef QT_NO_WHATSTHIS | |
case QEvent::AccessibilityHelp: | |
ev->setValue(d->whatsThis); | |
break; | |
#endif | |
default: | |
return false; | |
} | |
break; } | |
#endif | |
case QEvent::EmbeddingControl: | |
d->topData()->frameStrut.setCoords(0 ,0, 0, 0); | |
data->fstrut_dirty = false; | |
#if defined(Q_WS_WIN) || defined(Q_WS_X11) | |
d->topData()->embedded = 1; | |
#endif | |
break; | |
#ifndef QT_NO_ACTION | |
case QEvent::ActionAdded: | |
case QEvent::ActionRemoved: | |
case QEvent::ActionChanged: | |
#ifdef QT_SOFTKEYS_ENABLED | |
QSoftKeyManager::updateSoftKeys(); | |
#endif | |
actionEvent((QActionEvent*)event); | |
break; | |
#endif | |
case QEvent::KeyboardLayoutChange: | |
{ | |
changeEvent(event); | |
// inform children of the change | |
QList<QObject*> childList = d->children; | |
for (int i = 0; i < childList.size(); ++i) { | |
QWidget *w = qobject_cast<QWidget *>(childList.at(i)); | |
if (w && w->isVisible() && !w->isWindow()) | |
QApplication::sendEvent(w, event); | |
} | |
break; | |
} | |
#ifdef Q_WS_MAC | |
case QEvent::MacGLWindowChange: | |
d->needWindowChange = false; | |
break; | |
#endif | |
case QEvent::TouchBegin: | |
case QEvent::TouchUpdate: | |
case QEvent::TouchEnd: | |
{ | |
#ifndef Q_WS_MAC | |
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event); | |
const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().first(); | |
if (touchPoint.isPrimary() || touchEvent->deviceType() == QTouchEvent::TouchPad) | |
break; | |
// fake a mouse event! | |
QEvent::Type eventType = QEvent::None; | |
switch (touchEvent->type()) { | |
case QEvent::TouchBegin: | |
eventType = QEvent::MouseButtonPress; | |
break; | |
case QEvent::TouchUpdate: | |
eventType = QEvent::MouseMove; | |
break; | |
case QEvent::TouchEnd: | |
eventType = QEvent::MouseButtonRelease; | |
break; | |
default: | |
Q_ASSERT(!true); | |
break; | |
} | |
if (eventType == QEvent::None) | |
break; | |
QMouseEvent mouseEvent(eventType, | |
touchPoint.pos().toPoint(), | |
touchPoint.screenPos().toPoint(), | |
Qt::LeftButton, | |
Qt::LeftButton, | |
touchEvent->modifiers()); | |
(void) QApplication::sendEvent(this, &mouseEvent); | |
#endif // Q_WS_MAC | |
break; | |
} | |
#ifndef QT_NO_GESTURES | |
case QEvent::Gesture: | |
event->ignore(); | |
break; | |
#endif | |
#ifndef QT_NO_PROPERTIES | |
case QEvent::DynamicPropertyChange: { | |
const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName(); | |
if (!qstrncmp(propName, "_q_customDpi", 12) && propName.length() == 13) { | |
uint value = property(propName.constData()).toUInt(); | |
if (!d->extra) | |
d->createExtra(); | |
const char axis = propName.at(12); | |
if (axis == 'X') | |
d->extra->customDpiX = value; | |
else if (axis == 'Y') | |
d->extra->customDpiY = value; | |
d->updateFont(d->data.fnt); | |
} | |
// fall through | |
} | |
#endif | |
default: | |
return QObject::event(event); | |
} | |
return true; | |
} | |
/*! | |
This event handler can be reimplemented to handle state changes. | |
The state being changed in this event can be retrieved through the \a event | |
supplied. | |
Change events include: QEvent::ToolBarChange, | |
QEvent::ActivationChange, QEvent::EnabledChange, QEvent::FontChange, | |
QEvent::StyleChange, QEvent::PaletteChange, | |
QEvent::WindowTitleChange, QEvent::IconTextChange, | |
QEvent::ModifiedChange, QEvent::MouseTrackingChange, | |
QEvent::ParentChange, QEvent::WindowStateChange, | |
QEvent::LanguageChange, QEvent::LocaleChange, | |
QEvent::LayoutDirectionChange. | |
*/ | |
void QWidget::changeEvent(QEvent * event) | |
{ | |
switch(event->type()) { | |
case QEvent::EnabledChange: | |
update(); | |
#ifndef QT_NO_ACCESSIBILITY | |
QAccessible::updateAccessibility(this, 0, QAccessible::StateChanged); | |
#endif | |
break; | |
case QEvent::FontChange: | |
case QEvent::StyleChange: { | |
Q_D(QWidget); | |
update(); | |
updateGeometry(); | |
if (d->layout) | |
d->layout->invalidate(); | |
#ifdef Q_WS_QWS | |
if (isWindow()) | |
d->data.fstrut_dirty = true; | |
#endif | |
break; | |
} | |
case QEvent::PaletteChange: | |
update(); | |
break; | |
#ifdef Q_WS_MAC | |
case QEvent::MacSizeChange: | |
updateGeometry(); | |
break; | |
case QEvent::ToolTipChange: | |
case QEvent::MouseTrackingChange: | |
qt_mac_update_mouseTracking(this); | |
break; | |
#endif | |
default: | |
break; | |
} | |
} | |
/*! | |
This event handler, for event \a event, can be reimplemented in a | |
subclass to receive mouse move events for the widget. | |
If mouse tracking is switched off, mouse move events only occur if | |
a mouse button is pressed while the mouse is being moved. If mouse | |
tracking is switched on, mouse move events occur even if no mouse | |
button is pressed. | |
QMouseEvent::pos() reports the position of the mouse cursor, | |
relative to this widget. For press and release events, the | |
position is usually the same as the position of the last mouse | |
move event, but it might be different if the user's hand shakes. | |
This is a feature of the underlying window system, not Qt. | |
If you want to show a tooltip immediately, while the mouse is | |
moving (e.g., to get the mouse coordinates with QMouseEvent::pos() | |
and show them as a tooltip), you must first enable mouse tracking | |
as described above. Then, to ensure that the tooltip is updated | |
immediately, you must call QToolTip::showText() instead of | |
setToolTip() in your implementation of mouseMoveEvent(). | |
\sa setMouseTracking(), mousePressEvent(), mouseReleaseEvent(), | |
mouseDoubleClickEvent(), event(), QMouseEvent, {Scribble Example} | |
*/ | |
void QWidget::mouseMoveEvent(QMouseEvent *event) | |
{ | |
event->ignore(); | |
} | |
/*! | |
This event handler, for event \a event, can be reimplemented in a | |
subclass to receive mouse press events for the widget. | |
If you create new widgets in the mousePressEvent() the | |
mouseReleaseEvent() may not end up where you expect, depending on | |
the underlying window system (or X11 window manager), the widgets' | |
location and maybe more. | |
The default implementation implements the closing of popup widgets | |
when you click outside the window. For other widget types it does | |
nothing. | |
\sa mouseReleaseEvent(), mouseDoubleClickEvent(), | |
mouseMoveEvent(), event(), QMouseEvent, {Scribble Example} | |
*/ | |
void QWidget::mousePressEvent(QMouseEvent *event) | |
{ | |
event->ignore(); | |
if ((windowType() == Qt::Popup)) { | |
event->accept(); | |
QWidget* w; | |
while ((w = QApplication::activePopupWidget()) && w != this){ | |
w->close(); | |
if (QApplication::activePopupWidget() == w) // widget does not want to disappear | |
w->hide(); // hide at least | |
} | |
if (!rect().contains(event->pos())){ | |
close(); | |
} | |
} | |
} | |
/*! | |
This event handler, for event \a event, can be reimplemented in a | |
subclass to receive mouse release events for the widget. | |
\sa mousePressEvent(), mouseDoubleClickEvent(), | |
mouseMoveEvent(), event(), QMouseEvent, {Scribble Example} | |
*/ | |
void QWidget::mouseReleaseEvent(QMouseEvent *event) | |
{ | |
event->ignore(); | |
} | |
/*! | |
This event handler, for event \a event, can be reimplemented in a | |
subclass to receive mouse double click events for the widget. | |
The default implementation generates a normal mouse press event. | |
\note The widget will also receive mouse press and mouse release | |
events in addition to the double click event. It is up to the | |
developer to ensure that the application interprets these events | |
correctly. | |
\sa mousePressEvent(), mouseReleaseEvent() mouseMoveEvent(), | |
event(), QMouseEvent | |
*/ | |
void QWidget::mouseDoubleClickEvent(QMouseEvent *event) | |
{ | |
mousePressEvent(event); // try mouse press event | |
} | |
#ifndef QT_NO_WHEELEVENT | |
/*! | |
This event handler, for event \a event, can be reimplemented in a | |
subclass to receive wheel events for the widget. | |
If you reimplement this handler, it is very important that you | |
\link QWheelEvent ignore()\endlink the event if you do not handle | |
it, so that the widget's parent can interpret it. | |
The default implementation ignores the event. | |
\sa QWheelEvent::ignore(), QWheelEvent::accept(), event(), | |
QWheelEvent | |
*/ | |
void QWidget::wheelEvent(QWheelEvent *event) | |
{ | |
event->ignore(); | |
} | |
#endif // QT_NO_WHEELEVENT | |
#ifndef QT_NO_TABLETEVENT | |
/*! | |
This event handler, for event \a event, can be reimplemented in a | |
subclass to receive tablet events for the widget. | |
If you reimplement this handler, it is very important that you | |
\link QTabletEvent ignore()\endlink the event if you do not handle | |
it, so that the widget's parent can interpret it. | |
The default implementation ignores the event. | |
\sa QTabletEvent::ignore(), QTabletEvent::accept(), event(), | |
QTabletEvent | |
*/ | |
void QWidget::tabletEvent(QTabletEvent *event) | |
{ | |
event->ignore(); | |
} | |
#endif // QT_NO_TABLETEVENT | |
/*! | |
This event handler, for event \a event, can be reimplemented in a | |
subclass to receive key press events for the widget. | |
A widget must call setFocusPolicy() to accept focus initially and | |
have focus in order to receive a key press event. | |
If you reimplement this handler, it is very important that you | |
call the base class implementation if you do not act upon the key. | |
The default implementation closes popup widgets if the user | |
presses Esc. Otherwise the event is ignored, so that the widget's | |
parent can interpret it. | |
Note that QKeyEvent starts with isAccepted() == true, so you do not | |
need to call QKeyEvent::accept() - just do not call the base class | |
implementation if you act upon the key. | |
\sa keyReleaseEvent(), setFocusPolicy(), | |
focusInEvent(), focusOutEvent(), event(), QKeyEvent, {Tetrix Example} | |
*/ | |
void QWidget::keyPressEvent(QKeyEvent *event) | |
{ | |
if ((windowType() == Qt::Popup) && event->key() == Qt::Key_Escape) { | |
event->accept(); | |
close(); | |
} else { | |
event->ignore(); | |
} | |
} | |
/*! | |
This event handler, for event \a event, can be reimplemented in a | |
subclass to receive key release events for the widget. | |
A widget must \link setFocusPolicy() accept focus\endlink | |
initially and \link hasFocus() have focus\endlink in order to | |
receive a key release event. | |
If you reimplement this handler, it is very important that you | |
call the base class implementation if you do not act upon the key. | |
The default implementation ignores the event, so that the widget's | |
parent can interpret it. | |
Note that QKeyEvent starts with isAccepted() == true, so you do not | |
need to call QKeyEvent::accept() - just do not call the base class | |
implementation if you act upon the key. | |
\sa keyPressEvent(), QKeyEvent::ignore(), setFocusPolicy(), | |
focusInEvent(), focusOutEvent(), event(), QKeyEvent | |
*/ | |
void QWidget::keyReleaseEvent(QKeyEvent *event) | |
{ | |
event->ignore(); | |
} | |
/*! | |
\fn void QWidget::focusInEvent(QFocusEvent *event) | |
This event handler can be reimplemented in a subclass to receive | |
keyboard focus events (focus received) for the widget. The event | |
is passed in the \a event parameter | |
A widget normally must setFocusPolicy() to something other than | |
Qt::NoFocus in order to receive focus events. (Note that the | |
application programmer can call setFocus() on any widget, even | |
those that do not normally accept focus.) | |
The default implementation updates the widget (except for windows | |
that do not specify a focusPolicy()). | |
\sa focusOutEvent(), setFocusPolicy(), keyPressEvent(), | |
keyReleaseEvent(), event(), QFocusEvent | |
*/ | |
void QWidget::focusInEvent(QFocusEvent *) | |
{ | |
if (focusPolicy() != Qt::NoFocus || !isWindow()) { | |
update(); | |
} | |
} | |
/*! | |
\fn void QWidget::focusOutEvent(QFocusEvent *event) | |
This event handler can be reimplemented in a subclass to receive | |
keyboard focus events (focus lost) for the widget. The events is | |
passed in the \a event parameter. | |
A widget normally must setFocusPolicy() to something other than | |
Qt::NoFocus in order to receive focus events. (Note that the | |
application programmer can call setFocus() on any widget, even | |
those that do not normally accept focus.) | |
The default implementation updates the widget (except for windows | |
that do not specify a focusPolicy()). | |
\sa focusInEvent(), setFocusPolicy(), keyPressEvent(), | |
keyReleaseEvent(), event(), QFocusEvent | |
*/ | |
void QWidget::focusOutEvent(QFocusEvent *) | |
{ | |
if (focusPolicy() != Qt::NoFocus || !isWindow()) | |
update(); | |
} | |
/*! | |
\fn void QWidget::enterEvent(QEvent *event) | |
This event handler can be reimplemented in a subclass to receive | |
widget enter events which are passed in the \a event parameter. | |
An event is sent to the widget when the mouse cursor enters the | |
widget. | |
\sa leaveEvent(), mouseMoveEvent(), event() | |
*/ | |
void QWidget::enterEvent(QEvent *) | |
{ | |
} | |
/*! | |
\fn void QWidget::leaveEvent(QEvent *event) | |
This event handler can be reimplemented in a subclass to receive | |
widget leave events which are passed in the \a event parameter. | |
A leave event is sent to the widget when the mouse cursor leaves | |
the widget. | |
\sa enterEvent(), mouseMoveEvent(), event() | |
*/ | |
void QWidget::leaveEvent(QEvent *) | |
{ | |
} | |
/*! | |
\fn void QWidget::paintEvent(QPaintEvent *event) | |
This event handler can be reimplemented in a subclass to receive paint | |
events passed in \a event. | |
A paint event is a request to repaint all or part of a widget. It can | |
happen for one of the following reasons: | |
\list | |
\o repaint() or update() was invoked, | |
\o the widget was obscured and has now been uncovered, or | |
\o many other reasons. | |
\endlist | |
Many widgets can simply repaint their entire surface when asked to, but | |
some slow widgets need to optimize by painting only the requested region: | |
QPaintEvent::region(). This speed optimization does not change the result, | |
as painting is clipped to that region during event processing. QListView | |
and QTableView do this, for example. | |
Qt also tries to speed up painting by merging multiple paint events into | |
one. When update() is called several times or the window system sends | |
several paint events, Qt merges these events into one event with a larger | |
region (see QRegion::united()). The repaint() function does not permit this | |
optimization, so we suggest using update() whenever possible. | |
When the paint event occurs, the update region has normally been erased, so | |
you are painting on the widget's background. | |
The background can be set using setBackgroundRole() and setPalette(). | |
Since Qt 4.0, QWidget automatically double-buffers its painting, so there | |
is no need to write double-buffering code in paintEvent() to avoid flicker. | |
\bold{Note for the X11 platform}: It is possible to toggle global double | |
buffering by calling \c qt_x11_set_global_double_buffer(). For example, | |
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 14 | |
\note Generally, you should refrain from calling update() or repaint() | |
\bold{inside} a paintEvent(). For example, calling update() or repaint() on | |
children inside a paintevent() results in undefined behavior; the child may | |
or may not get a paint event. | |
\warning If you are using a custom paint engine without Qt's backingstore, | |
Qt::WA_PaintOnScreen must be set. Otherwise, QWidget::paintEngine() will | |
never be called; the backingstore will be used instead. | |
\sa event(), repaint(), update(), QPainter, QPixmap, QPaintEvent, | |
{Analog Clock Example} | |
*/ | |
void QWidget::paintEvent(QPaintEvent *) | |
{ | |
} | |
/*! | |
\fn void QWidget::moveEvent(QMoveEvent *event) | |
This event handler can be reimplemented in a subclass to receive | |
widget move events which are passed in the \a event parameter. | |
When the widget receives this event, it is already at the new | |
position. | |
The old position is accessible through QMoveEvent::oldPos(). | |
\sa resizeEvent(), event(), move(), QMoveEvent | |
*/ | |
void QWidget::moveEvent(QMoveEvent *) | |
{ | |
} | |
/*! | |
This event handler can be reimplemented in a subclass to receive | |
widget resize events which are passed in the \a event parameter. | |
When resizeEvent() is called, the widget already has its new | |
geometry. The old size is accessible through | |
QResizeEvent::oldSize(). | |
The widget will be erased and receive a paint event immediately | |
after processing the resize event. No drawing need be (or should | |
be) done inside this handler. | |
\sa moveEvent(), event(), resize(), QResizeEvent, paintEvent(), | |
{Scribble Example} | |
*/ | |
void QWidget::resizeEvent(QResizeEvent * /* event */) | |
{ | |
} | |
#ifndef QT_NO_ACTION | |
/*! | |
\fn void QWidget::actionEvent(QActionEvent *event) | |
This event handler is called with the given \a event whenever the | |
widget's actions are changed. | |
\sa addAction(), insertAction(), removeAction(), actions(), QActionEvent | |
*/ | |
void QWidget::actionEvent(QActionEvent *) | |
{ | |
} | |
#endif | |
/*! | |
This event handler is called with the given \a event when Qt receives a window | |
close request for a top-level widget from the window system. | |
By default, the event is accepted and the widget is closed. You can reimplement | |
this function to change the way the widget responds to window close requests. | |
For example, you can prevent the window from closing by calling \l{QEvent::}{ignore()} | |
on all events. | |
Main window applications typically use reimplementations of this function to check | |
whether the user's work has been saved and ask for permission before closing. | |
For example, the \l{Application Example} uses a helper function to determine whether | |
or not to close the window: | |
\snippet mainwindows/application/mainwindow.cpp 3 | |
\snippet mainwindows/application/mainwindow.cpp 4 | |
\sa event(), hide(), close(), QCloseEvent, {Application Example} | |
*/ | |
void QWidget::closeEvent(QCloseEvent *event) | |
{ | |
event->accept(); | |
} | |
#ifndef QT_NO_CONTEXTMENU | |
/*! | |
This event handler, for event \a event, can be reimplemented in a | |
subclass to receive widget context menu events. | |
The handler is called when the widget's \l contextMenuPolicy is | |
Qt::DefaultContextMenu. | |
The default implementation ignores the context event. | |
See the \l QContextMenuEvent documentation for more details. | |
\sa event(), QContextMenuEvent customContextMenuRequested() | |
*/ | |
void QWidget::contextMenuEvent(QContextMenuEvent *event) | |
{ | |
event->ignore(); | |
} | |
#endif // QT_NO_CONTEXTMENU | |
/*! | |
This event handler, for event \a event, can be reimplemented in a | |
subclass to receive Input Method composition events. This handler | |
is called when the state of the input method changes. | |
Note that when creating custom text editing widgets, the | |
Qt::WA_InputMethodEnabled window attribute must be set explicitly | |
(using the setAttribute() function) in order to receive input | |
method events. | |
The default implementation calls event->ignore(), which rejects the | |
Input Method event. See the \l QInputMethodEvent documentation for more | |
details. | |
\sa event(), QInputMethodEvent | |
*/ | |
void QWidget::inputMethodEvent(QInputMethodEvent *event) | |
{ | |
event->ignore(); | |
} | |
/*! | |
This method is only relevant for input widgets. It is used by the | |
input method to query a set of properties of the widget to be | |
able to support complex input method operations as support for | |
surrounding text and reconversions. | |
\a query specifies which property is queried. | |
\sa inputMethodEvent(), QInputMethodEvent, QInputContext, inputMethodHints | |
*/ | |
QVariant QWidget::inputMethodQuery(Qt::InputMethodQuery query) const | |
{ | |
switch(query) { | |
case Qt::ImMicroFocus: | |
return QRect(width()/2, 0, 1, height()); | |
case Qt::ImFont: | |
return font(); | |
case Qt::ImAnchorPosition: | |
// Fallback. | |
return inputMethodQuery(Qt::ImCursorPosition); | |
default: | |
return QVariant(); | |
} | |
} | |
/*! | |
\property QWidget::inputMethodHints | |
\brief What input method specific hints the widget has. | |
This is only relevant for input widgets. It is used by | |
the input method to retrieve hints as to how the input method | |
should operate. For example, if the Qt::ImhFormattedNumbersOnly flag | |
is set, the input method may change its visual components to reflect | |
that only numbers can be entered. | |
\note The flags are only hints, so the particular input method | |
implementation is free to ignore them. If you want to be | |
sure that a certain type of characters are entered, | |
you should also set a QValidator on the widget. | |
The default value is Qt::ImhNone. | |
\since 4.6 | |
\sa inputMethodQuery(), QInputContext | |
*/ | |
Qt::InputMethodHints QWidget::inputMethodHints() const | |
{ | |
#ifndef QT_NO_IM | |
const QWidgetPrivate *priv = d_func(); | |
while (priv->inheritsInputMethodHints) { | |
priv = priv->q_func()->parentWidget()->d_func(); | |
Q_ASSERT(priv); | |
} | |
return priv->imHints; | |
#else //QT_NO_IM | |
return 0; | |
#endif //QT_NO_IM | |
} | |
void QWidget::setInputMethodHints(Qt::InputMethodHints hints) | |
{ | |
#ifndef QT_NO_IM | |
Q_D(QWidget); | |
d->imHints = hints; | |
// Optimization to update input context only it has already been created. | |
if (d->ic || qApp->d_func()->inputContext) { | |
QInputContext *ic = inputContext(); | |
if (ic) | |
ic->update(); | |
} | |
#endif //QT_NO_IM | |
} | |
#ifndef QT_NO_DRAGANDDROP | |
/*! | |
\fn void QWidget::dragEnterEvent(QDragEnterEvent *event) | |
This event handler is called when a drag is in progress and the | |
mouse enters this widget. The event is passed in the \a event parameter. | |
If the event is ignored, the widget won't receive any \l{dragMoveEvent()}{drag | |
move events}. | |
See the \link dnd.html Drag-and-drop documentation\endlink for an | |
overview of how to provide drag-and-drop in your application. | |
\sa QDrag, QDragEnterEvent | |
*/ | |
void QWidget::dragEnterEvent(QDragEnterEvent *) | |
{ | |
} | |
/*! | |
\fn void QWidget::dragMoveEvent(QDragMoveEvent *event) | |
This event handler is called if a drag is in progress, and when | |
any of the following conditions occur: the cursor enters this widget, | |
the cursor moves within this widget, or a modifier key is pressed on | |
the keyboard while this widget has the focus. The event is passed | |
in the \a event parameter. | |
See the \link dnd.html Drag-and-drop documentation\endlink for an | |
overview of how to provide drag-and-drop in your application. | |
\sa QDrag, QDragMoveEvent | |
*/ | |
void QWidget::dragMoveEvent(QDragMoveEvent *) | |
{ | |
} | |
/*! | |
\fn void QWidget::dragLeaveEvent(QDragLeaveEvent *event) | |
This event handler is called when a drag is in progress and the | |
mouse leaves this widget. The event is passed in the \a event | |
parameter. | |
See the \link dnd.html Drag-and-drop documentation\endlink for an | |
overview of how to provide drag-and-drop in your application. | |
\sa QDrag, QDragLeaveEvent | |
*/ | |
void QWidget::dragLeaveEvent(QDragLeaveEvent *) | |
{ | |
} | |
/*! | |
\fn void QWidget::dropEvent(QDropEvent *event) | |
This event handler is called when the drag is dropped on this | |
widget. The event is passed in the \a event parameter. | |
See the \link dnd.html Drag-and-drop documentation\endlink for an | |
overview of how to provide drag-and-drop in your application. | |
\sa QDrag, QDropEvent | |
*/ | |
void QWidget::dropEvent(QDropEvent *) | |
{ | |
} | |
#endif // QT_NO_DRAGANDDROP | |
/*! | |
\fn void QWidget::showEvent(QShowEvent *event) | |
This event handler can be reimplemented in a subclass to receive | |
widget show events which are passed in the \a event parameter. | |
Non-spontaneous show events are sent to widgets immediately | |
before they are shown. The spontaneous show events of windows are | |
delivered afterwards. | |
Note: A widget receives spontaneous show and hide events when its | |
mapping status is changed by the window system, e.g. a spontaneous | |
hide event when the user minimizes the window, and a spontaneous | |
show event when the window is restored again. After receiving a | |
spontaneous hide event, a widget is still considered visible in | |
the sense of isVisible(). | |
\sa visible, event(), QShowEvent | |
*/ | |
void QWidget::showEvent(QShowEvent *) | |
{ | |
} | |
/*! | |
\fn void QWidget::hideEvent(QHideEvent *event) | |
This event handler can be reimplemented in a subclass to receive | |
widget hide events. The event is passed in the \a event parameter. | |
Hide events are sent to widgets immediately after they have been | |
hidden. | |
Note: A widget receives spontaneous show and hide events when its | |
mapping status is changed by the window system, e.g. a spontaneous | |
hide event when the user minimizes the window, and a spontaneous | |
show event when the window is restored again. After receiving a | |
spontaneous hide event, a widget is still considered visible in | |
the sense of isVisible(). | |
\sa visible, event(), QHideEvent | |
*/ | |
void QWidget::hideEvent(QHideEvent *) | |
{ | |
} | |
/* | |
\fn QWidget::x11Event(MSG *) | |
This special event handler can be reimplemented in a subclass to receive | |
native X11 events. | |
In your reimplementation of this function, if you want to stop Qt from | |
handling the event, return true. If you return false, this native event | |
is passed back to Qt, which translates it into a Qt event and sends it to | |
the widget. | |
\note Events are only delivered to this event handler if the widget is | |
native. | |
\warning This function is not portable. | |
\sa QApplication::x11EventFilter(), QWidget::winId() | |
*/ | |
#if defined(Q_WS_MAC) | |
/*! | |
\fn bool QWidget::macEvent(EventHandlerCallRef caller, EventRef event) | |
This special event handler can be reimplemented in a subclass to | |
receive native Macintosh events. | |
The parameters are a bit different depending if Qt is build against Carbon | |
or Cocoa. In Carbon, \a caller and \a event are the corresponding | |
EventHandlerCallRef and EventRef that correspond to the Carbon event | |
handlers that are installed. In Cocoa, \a caller is always 0 and the | |
EventRef is the EventRef generated from the NSEvent. | |
In your reimplementation of this function, if you want to stop the | |
event being handled by Qt, return true. If you return false, this | |
native event is passed back to Qt, which translates the event into | |
a Qt event and sends it to the widget. | |
\warning This function is not portable. | |
\warning This function was not called inside of Qt until Qt 4.4. | |
If you need compatibility with earlier versions of Qt, consider QApplication::macEventFilter() instead. | |
\sa QApplication::macEventFilter() | |
*/ | |
bool QWidget::macEvent(EventHandlerCallRef, EventRef) | |
{ | |
return false; | |
} | |
#endif | |
#if defined(Q_WS_WIN) | |
/*! | |
This special event handler can be reimplemented in a subclass to | |
receive native Windows events which are passed in the \a message | |
parameter. | |
In your reimplementation of this function, if you want to stop the | |
event being handled by Qt, return true and set \a result to the value | |
that the window procedure should return. If you return false, this | |
native event is passed back to Qt, which translates the event into | |
a Qt event and sends it to the widget. | |
\warning This function is not portable. | |
\sa QApplication::winEventFilter() | |
*/ | |
bool QWidget::winEvent(MSG *message, long *result) | |
{ | |
Q_UNUSED(message); | |
Q_UNUSED(result); | |
return false; | |
} | |
#endif | |
#if defined(Q_WS_X11) | |
/*! | |
\fn bool QWidget::x11Event(XEvent *event) | |
This special event handler can be reimplemented in a subclass to receive | |
native X11 events passed in the \a event parameter. | |
In your reimplementation of this function, if you want to stop Qt from | |
handling the event, return true. If you return false, this native event | |
is passed back to Qt, which translates it into a Qt event and sends it to | |
the widget. | |
\note Events are only delivered to this event handler if the widget is | |
native. | |
\warning This function is not portable. | |
\sa QApplication::x11EventFilter(), QWidget::winId() | |
*/ | |
bool QWidget::x11Event(XEvent *) | |
{ | |
return false; | |
} | |
#endif | |
#if defined(Q_WS_QWS) | |
/*! | |
\fn bool QWidget::qwsEvent(QWSEvent *event) | |
This special event handler can be reimplemented in a subclass to | |
receive native Qt for Embedded Linux events which are passed in the | |
\a event parameter. | |
In your reimplementation of this function, if you want to stop the | |
event being handled by Qt, return true. If you return false, this | |
native event is passed back to Qt, which translates the event into | |
a Qt event and sends it to the widget. | |
\warning This function is not portable. | |
\sa QApplication::qwsEventFilter() | |
*/ | |
bool QWidget::qwsEvent(QWSEvent *) | |
{ | |
return false; | |
} | |
#endif | |
/*! | |
Ensures that the widget has been polished by QStyle (i.e., has a | |
proper font and palette). | |
QWidget calls this function after it has been fully constructed | |
but before it is shown the very first time. You can call this | |
function if you want to ensure that the widget is polished before | |
doing an operation, e.g., the correct font size might be needed in | |
the widget's sizeHint() reimplementation. Note that this function | |
\e is called from the default implementation of sizeHint(). | |
Polishing is useful for final initialization that must happen after | |
all constructors (from base classes as well as from subclasses) | |
have been called. | |
If you need to change some settings when a widget is polished, | |
reimplement event() and handle the QEvent::Polish event type. | |
\bold{Note:} The function is declared const so that it can be called from | |
other const functions (e.g., sizeHint()). | |
\sa event() | |
*/ | |
void QWidget::ensurePolished() const | |
{ | |
Q_D(const QWidget); | |
const QMetaObject *m = metaObject(); | |
if (m == d->polished) | |
return; | |
d->polished = m; | |
QEvent e(QEvent::Polish); | |
QCoreApplication::sendEvent(const_cast<QWidget *>(this), &e); | |
// polish children after 'this' | |
QList<QObject*> children = d->children; | |
for (int i = 0; i < children.size(); ++i) { | |
QObject *o = children.at(i); | |
if(!o->isWidgetType()) | |
continue; | |
if (QWidget *w = qobject_cast<QWidget *>(o)) | |
w->ensurePolished(); | |
} | |
if (d->parent && d->sendChildEvents) { | |
QChildEvent e(QEvent::ChildPolished, const_cast<QWidget *>(this)); | |
QCoreApplication::sendEvent(d->parent, &e); | |
} | |
} | |
/*! | |
Returns the mask currently set on a widget. If no mask is set the | |
return value will be an empty region. | |
\sa setMask(), clearMask(), QRegion::isEmpty(), {Shaped Clock Example} | |
*/ | |
QRegion QWidget::mask() const | |
{ | |
Q_D(const QWidget); | |
return d->extra ? d->extra->mask : QRegion(); | |
} | |
/*! | |
Returns the layout manager that is installed on this widget, or 0 | |
if no layout manager is installed. | |
The layout manager sets the geometry of the widget's children | |
that have been added to the layout. | |
\sa setLayout(), sizePolicy(), {Layout Management} | |
*/ | |
QLayout *QWidget::layout() const | |
{ | |
return d_func()->layout; | |
} | |
/*! | |
\fn void QWidget::setLayout(QLayout *layout) | |
Sets the layout manager for this widget to \a layout. | |
If there already is a layout manager installed on this widget, | |
QWidget won't let you install another. You must first delete the | |
existing layout manager (returned by layout()) before you can | |
call setLayout() with the new layout. | |
If \a layout is the layout manger on a different widget, setLayout() | |
will reparent the layout and make it the layout manager for this widget. | |
Example: | |
\snippet examples/uitools/textfinder/textfinder.cpp 3b | |
An alternative to calling this function is to pass this widget to | |
the layout's constructor. | |
The QWidget will take ownership of \a layout. | |
\sa layout(), {Layout Management} | |
*/ | |
void QWidget::setLayout(QLayout *l) | |
{ | |
if (!l) { | |
qWarning("QWidget::setLayout: Cannot set layout to 0"); | |
return; | |
} | |
if (layout()) { | |
if (layout() != l) | |
qWarning("QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", which already has a" | |
" layout", l->objectName().toLocal8Bit().data(), metaObject()->className(), | |
objectName().toLocal8Bit().data()); | |
return; | |
} | |
QObject *oldParent = l->parent(); | |
if (oldParent && oldParent != this) { | |
if (oldParent->isWidgetType()) { | |
// Steal the layout off a widget parent. Takes effect when | |
// morphing laid-out container widgets in Designer. | |
QWidget *oldParentWidget = static_cast<QWidget *>(oldParent); | |
oldParentWidget->takeLayout(); | |
} else { | |
qWarning("QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", when the QLayout already has a parent", | |
l->objectName().toLocal8Bit().data(), metaObject()->className(), | |
objectName().toLocal8Bit().data()); | |
return; | |
} | |
} | |
Q_D(QWidget); | |
l->d_func()->topLevel = true; | |
d->layout = l; | |
if (oldParent != this) { | |
l->setParent(this); | |
l->d_func()->reparentChildWidgets(this); | |
l->invalidate(); | |
} | |
if (isWindow() && d->maybeTopData()) | |
d->topData()->sizeAdjusted = false; | |
} | |
/*! | |
\fn QLayout *QWidget::takeLayout() | |
Remove the layout from the widget. | |
\since 4.5 | |
*/ | |
QLayout *QWidget::takeLayout() | |
{ | |
Q_D(QWidget); | |
QLayout *l = layout(); | |
if (!l) | |
return 0; | |
d->layout = 0; | |
l->setParent(0); | |
return l; | |
} | |
/*! | |
\property QWidget::sizePolicy | |
\brief the default layout behavior of the widget | |
If there is a QLayout that manages this widget's children, the | |
size policy specified by that layout is used. If there is no such | |
QLayout, the result of this function is used. | |
The default policy is Preferred/Preferred, which means that the | |
widget can be freely resized, but prefers to be the size | |
sizeHint() returns. Button-like widgets set the size policy to | |
specify that they may stretch horizontally, but are fixed | |
vertically. The same applies to lineedit controls (such as | |
QLineEdit, QSpinBox or an editable QComboBox) and other | |
horizontally orientated widgets (such as QProgressBar). | |
QToolButton's are normally square, so they allow growth in both | |
directions. Widgets that support different directions (such as | |
QSlider, QScrollBar or QHeader) specify stretching in the | |
respective direction only. Widgets that can provide scroll bars | |
(usually subclasses of QScrollArea) tend to specify that they can | |
use additional space, and that they can make do with less than | |
sizeHint(). | |
\sa sizeHint() QLayout QSizePolicy updateGeometry() | |
*/ | |
QSizePolicy QWidget::sizePolicy() const | |
{ | |
Q_D(const QWidget); | |
return d->size_policy; | |
} | |
void QWidget::setSizePolicy(QSizePolicy policy) | |
{ | |
Q_D(QWidget); | |
setAttribute(Qt::WA_WState_OwnSizePolicy); | |
if (policy == d->size_policy) | |
return; | |
d->size_policy = policy; | |
#ifndef QT_NO_GRAPHICSVIEW | |
if (QWExtra *extra = d->extra) { | |
if (extra->proxyWidget) | |
extra->proxyWidget->setSizePolicy(policy); | |
} | |
#endif | |
updateGeometry(); | |
if (isWindow() && d->maybeTopData()) | |
d->topData()->sizeAdjusted = false; | |
} | |
/*! | |
\fn void QWidget::setSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical) | |
\overload | |
Sets the size policy of the widget to \a horizontal and \a | |
vertical, with standard stretch and no height-for-width. | |
\sa QSizePolicy::QSizePolicy() | |
*/ | |
/*! | |
Returns the preferred height for this widget, given the width \a w. | |
If this widget has a layout, the default implementation returns | |
the layout's preferred height. if there is no layout, the default | |
implementation returns -1 indicating that the preferred height | |
does not depend on the width. | |
*/ | |
int QWidget::heightForWidth(int w) const | |
{ | |
if (layout() && layout()->hasHeightForWidth()) | |
return layout()->totalHeightForWidth(w); | |
return -1; | |
} | |
/*! | |
\fn QWidget *QWidget::childAt(int x, int y) const | |
Returns the visible child widget at the position (\a{x}, \a{y}) | |
in the widget's coordinate system. If there is no visible child | |
widget at the specified position, the function returns 0. | |
*/ | |
/*! | |
\overload | |
Returns the visible child widget at point \a p in the widget's own | |
coordinate system. | |
*/ | |
QWidget *QWidget::childAt(const QPoint &p) const | |
{ | |
return d_func()->childAt_helper(p, false); | |
} | |
QWidget *QWidgetPrivate::childAt_helper(const QPoint &p, bool ignoreChildrenInDestructor) const | |
{ | |
if (children.isEmpty()) | |
return 0; | |
#ifdef Q_WS_MAC | |
Q_Q(const QWidget); | |
// Unified tool bars on the Mac require special handling since they live outside | |
// QMainWindow's geometry(). See commit: 35667fd45ada49269a5987c235fdedfc43e92bb8 | |
bool includeFrame = q->isWindow() && qobject_cast<const QMainWindow *>(q) | |
&& static_cast<const QMainWindow *>(q)->unifiedTitleAndToolBarOnMac(); | |
if (includeFrame) | |
return childAtRecursiveHelper(p, ignoreChildrenInDestructor, includeFrame); | |
#endif | |
if (!pointInsideRectAndMask(p)) | |
return 0; | |
return childAtRecursiveHelper(p, ignoreChildrenInDestructor); | |
} | |
QWidget *QWidgetPrivate::childAtRecursiveHelper(const QPoint &p, bool ignoreChildrenInDestructor, bool includeFrame) const | |
{ | |
#ifndef Q_WS_MAC | |
Q_UNUSED(includeFrame); | |
#endif | |
for (int i = children.size() - 1; i >= 0; --i) { | |
QWidget *child = qobject_cast<QWidget *>(children.at(i)); | |
if (!child || child->isWindow() || child->isHidden() || child->testAttribute(Qt::WA_TransparentForMouseEvents) | |
|| (ignoreChildrenInDestructor && child->data->in_destructor)) { | |
continue; | |
} | |
// Map the point 'p' from parent coordinates to child coordinates. | |
QPoint childPoint = p; | |
#ifdef Q_WS_MAC | |
// 'includeFrame' is true if the child's parent is a top-level QMainWindow with an unified tool bar. | |
// An unified tool bar on the Mac lives outside QMainWindow's geometry(), so a normal | |
// QWidget::mapFromParent won't do the trick. | |
if (includeFrame && qobject_cast<QToolBar *>(child)) | |
childPoint = qt_mac_nativeMapFromParent(child, p); | |
else | |
#endif | |
childPoint -= child->data->crect.topLeft(); | |
// Check if the point hits the child. | |
if (!child->d_func()->pointInsideRectAndMask(childPoint)) | |
continue; | |
// Do the same for the child's descendants. | |
if (QWidget *w = child->d_func()->childAtRecursiveHelper(childPoint, ignoreChildrenInDestructor)) | |
return w; | |
// We have found our target; namely the child at position 'p'. | |
return child; | |
} | |
return 0; | |
} | |
void QWidgetPrivate::updateGeometry_helper(bool forceUpdate) | |
{ | |
Q_Q(QWidget); | |
if (widgetItem) | |
widgetItem->invalidateSizeCache(); | |
QWidget *parent; | |
if (forceUpdate || !extra || extra->minw != extra->maxw || extra->minh != extra->maxh) { | |
if (!q->isWindow() && !q->isHidden() && (parent = q->parentWidget())) { | |
if (parent->d_func()->layout) | |
parent->d_func()->layout->invalidate(); | |
else if (parent->isVisible()) | |
QApplication::postEvent(parent, new QEvent(QEvent::LayoutRequest)); | |
} | |
} | |
} | |
/*! | |
Notifies the layout system that this widget has changed and may | |
need to change geometry. | |
Call this function if the sizeHint() or sizePolicy() have changed. | |
For explicitly hidden widgets, updateGeometry() is a no-op. The | |
layout system will be notified as soon as the widget is shown. | |
*/ | |
void QWidget::updateGeometry() | |
{ | |
Q_D(QWidget); | |
d->updateGeometry_helper(false); | |
} | |
/*! \property QWidget::windowFlags | |
Window flags are a combination of a type (e.g. Qt::Dialog) and | |
zero or more hints to the window system (e.g. | |
Qt::FramelessWindowHint). | |
If the widget had type Qt::Widget or Qt::SubWindow and becomes a | |
window (Qt::Window, Qt::Dialog, etc.), it is put at position (0, | |
0) on the desktop. If the widget is a window and becomes a | |
Qt::Widget or Qt::SubWindow, it is put at position (0, 0) | |
relative to its parent widget. | |
\note This function calls setParent() when changing the flags for | |
a window, causing the widget to be hidden. You must call show() to make | |
the widget visible again.. | |
\sa windowType(), {Window Flags Example} | |
*/ | |
void QWidget::setWindowFlags(Qt::WindowFlags flags) | |
{ | |
if (data->window_flags == flags) | |
return; | |
Q_D(QWidget); | |
if ((data->window_flags | flags) & Qt::Window) { | |
// the old type was a window and/or the new type is a window | |
QPoint oldPos = pos(); | |
bool visible = isVisible(); | |
setParent(parentWidget(), flags); | |
// if both types are windows or neither of them are, we restore | |
// the old position | |
if (!((data->window_flags ^ flags) & Qt::Window) | |
&& (visible || testAttribute(Qt::WA_Moved))) { | |
move(oldPos); | |
} | |
// for backward-compatibility we change Qt::WA_QuitOnClose attribute value only when the window was recreated. | |
d->adjustQuitOnCloseAttribute(); | |
} else { | |
data->window_flags = flags; | |
} | |
} | |
/*! | |
Sets the window flags for the widget to \a flags, | |
\e without telling the window system. | |
\warning Do not call this function unless you really know what | |
you're doing. | |
\sa setWindowFlags() | |
*/ | |
void QWidget::overrideWindowFlags(Qt::WindowFlags flags) | |
{ | |
data->window_flags = flags; | |
} | |
/*! | |
\fn Qt::WindowType QWidget::windowType() const | |
Returns the window type of this widget. This is identical to | |
windowFlags() & Qt::WindowType_Mask. | |
\sa windowFlags | |
*/ | |
/*! | |
Sets the parent of the widget to \a parent, and resets the window | |
flags. The widget is moved to position (0, 0) in its new parent. | |
If the new parent widget is in a different window, the | |
reparented widget and its children are appended to the end of the | |
\l{setFocusPolicy()}{tab chain} of the new parent | |
widget, in the same internal order as before. If one of the moved | |
widgets had keyboard focus, setParent() calls clearFocus() for that | |
widget. | |
If the new parent widget is in the same window as the | |
old parent, setting the parent doesn't change the tab order or | |
keyboard focus. | |
If the "new" parent widget is the old parent widget, this function | |
does nothing. | |
\note The widget becomes invisible as part of changing its parent, | |
even if it was previously visible. You must call show() to make the | |
widget visible again. | |
\warning It is very unlikely that you will ever need this | |
function. If you have a widget that changes its content | |
dynamically, it is far easier to use \l QStackedWidget. | |
\sa setWindowFlags() | |
*/ | |
void QWidget::setParent(QWidget *parent) | |
{ | |
if (parent == parentWidget()) | |
return; | |
setParent((QWidget*)parent, windowFlags() & ~Qt::WindowType_Mask); | |
} | |
/*! | |
\overload | |
This function also takes widget flags, \a f as an argument. | |
*/ | |
void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) | |
{ | |
Q_D(QWidget); | |
d->inSetParent = true; | |
bool resized = testAttribute(Qt::WA_Resized); | |
bool wasCreated = testAttribute(Qt::WA_WState_Created); | |
QWidget *oldtlw = window(); | |
QWidget *desktopWidget = 0; | |
if (parent && parent->windowType() == Qt::Desktop) | |
desktopWidget = parent; | |
bool newParent = (parent != parentWidget()) || !wasCreated || desktopWidget; | |
#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN) | |
if (newParent && parent && !desktopWidget) { | |
if (testAttribute(Qt::WA_NativeWindow) && !qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings)) | |
parent->d_func()->enforceNativeChildren(); | |
else if (parent->d_func()->nativeChildrenForced() || parent->testAttribute(Qt::WA_PaintOnScreen)) | |
setAttribute(Qt::WA_NativeWindow); | |
} | |
#endif | |
if (wasCreated) { | |
if (!testAttribute(Qt::WA_WState_Hidden)) { | |
hide(); | |
setAttribute(Qt::WA_WState_ExplicitShowHide, false); | |
} | |
if (newParent) { | |
QEvent e(QEvent::ParentAboutToChange); | |
QApplication::sendEvent(this, &e); | |
} | |
} | |
if (newParent && isAncestorOf(focusWidget())) | |
focusWidget()->clearFocus(); | |
QTLWExtra *oldTopExtra = window()->d_func()->maybeTopData(); | |
QWidgetBackingStoreTracker *oldBsTracker = oldTopExtra ? &oldTopExtra->backingStore : 0; | |
d->setParent_sys(parent, f); | |
QTLWExtra *topExtra = window()->d_func()->maybeTopData(); | |
QWidgetBackingStoreTracker *bsTracker = topExtra ? &topExtra->backingStore : 0; | |
if (oldBsTracker && oldBsTracker != bsTracker) | |
oldBsTracker->unregisterWidgetSubtree(this); | |
if (desktopWidget) | |
parent = 0; | |
#ifdef Q_BACKINGSTORE_SUBSURFACES | |
QTLWExtra *extra = d->maybeTopData(); | |
QWindowSurface *windowSurface = (extra ? extra->windowSurface : 0); | |
if (newParent && windowSurface) { | |
QWidgetBackingStore *oldBs = oldtlw->d_func()->maybeBackingStore(); | |
if (oldBs) | |
oldBs->subSurfaces.removeAll(windowSurface); | |
if (parent) { | |
QWidgetBackingStore *newBs = parent->d_func()->maybeBackingStore(); | |
if (newBs) | |
newBs->subSurfaces.append(windowSurface); | |
} | |
} | |
#endif | |
if (QWidgetBackingStore *oldBs = oldtlw->d_func()->maybeBackingStore()) { | |
if (newParent) | |
oldBs->removeDirtyWidget(this); | |
// Move the widget and all its static children from | |
// the old backing store to the new one. | |
oldBs->moveStaticWidgets(this); | |
} | |
if ((QApplicationPrivate::app_compile_version < 0x040200 | |
|| QApplicationPrivate::testAttribute(Qt::AA_ImmediateWidgetCreation)) | |
&& !testAttribute(Qt::WA_WState_Created)) | |
create(); | |
d->reparentFocusWidgets(oldtlw); | |
setAttribute(Qt::WA_Resized, resized); | |
if (!testAttribute(Qt::WA_StyleSheet) | |
&& (!parent || !parent->testAttribute(Qt::WA_StyleSheet))) { | |
d->resolveFont(); | |
d->resolvePalette(); | |
} | |
d->resolveLayoutDirection(); | |
d->resolveLocale(); | |
// Note: GL widgets under WGL or EGL will always need a ParentChange | |
// event to handle recreation/rebinding of the GL context, hence the | |
// (f & Qt::MSWindowsOwnDC) clause (which is set on QGLWidgets on all | |
// platforms). | |
if (newParent | |
#if defined(Q_WS_WIN) || defined(QT_OPENGL_ES) | |
|| (f & Qt::MSWindowsOwnDC) | |
#endif | |
) { | |
// propagate enabled updates enabled state to non-windows | |
if (!isWindow()) { | |
if (!testAttribute(Qt::WA_ForceDisabled)) | |
d->setEnabled_helper(parent ? parent->isEnabled() : true); | |
if (!testAttribute(Qt::WA_ForceUpdatesDisabled)) | |
d->setUpdatesEnabled_helper(parent ? parent->updatesEnabled() : true); | |
} | |
d->inheritStyle(); | |
// send and post remaining QObject events | |
if (parent && d->sendChildEvents) { | |
QChildEvent e(QEvent::ChildAdded, this); | |
QApplication::sendEvent(parent, &e); | |
#ifdef QT3_SUPPORT | |
if (parent->d_func()->pendingChildInsertedEvents.isEmpty()) { | |
QApplication::postEvent(parent, | |
new QEvent(QEvent::ChildInsertedRequest), | |
Qt::HighEventPriority); | |
} | |
parent->d_func()->pendingChildInsertedEvents.append(this); | |
#endif | |
} | |
//### already hidden above ---> must probably do something smart on the mac | |
// #ifdef Q_WS_MAC | |
// extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp | |
// if(!qt_mac_is_macdrawer(q)) //special case | |
// q->setAttribute(Qt::WA_WState_Hidden); | |
// #else | |
// q->setAttribute(Qt::WA_WState_Hidden); | |
//#endif | |
if (parent && d->sendChildEvents && d->polished) { | |
QChildEvent e(QEvent::ChildPolished, this); | |
QCoreApplication::sendEvent(parent, &e); | |
} | |
QEvent e(QEvent::ParentChange); | |
QApplication::sendEvent(this, &e); | |
} | |
if (!wasCreated) { | |
if (isWindow() || parentWidget()->isVisible()) | |
setAttribute(Qt::WA_WState_Hidden, true); | |
else if (!testAttribute(Qt::WA_WState_ExplicitShowHide)) | |
setAttribute(Qt::WA_WState_Hidden, false); | |
} | |
d->updateIsOpaque(); | |
#ifndef QT_NO_GRAPHICSVIEW | |
// Embed the widget into a proxy if the parent is embedded. | |
// ### Doesn't handle reparenting out of an embedded widget. | |
if (oldtlw->graphicsProxyWidget()) { | |
if (QGraphicsProxyWidget *ancestorProxy = d->nearestGraphicsProxyWidget(oldtlw)) | |
ancestorProxy->d_func()->unembedSubWindow(this); | |
} | |
if (isWindow() && parent && !graphicsProxyWidget() && !bypassGraphicsProxyWidget(this)) { | |
if (QGraphicsProxyWidget *ancestorProxy = d->nearestGraphicsProxyWidget(parent)) | |
ancestorProxy->d_func()->embedSubWindow(this); | |
} | |
#endif | |
d->inSetParent = false; | |
} | |
/*! | |
Scrolls the widget including its children \a dx pixels to the | |
right and \a dy downward. Both \a dx and \a dy may be negative. | |
After scrolling, the widgets will receive paint events for | |
the areas that need to be repainted. For widgets that Qt knows to | |
be opaque, this is only the newly exposed parts. | |
For example, if an opaque widget is scrolled 8 pixels to the left, | |
only an 8-pixel wide stripe at the right edge needs updating. | |
Since widgets propagate the contents of their parents by default, | |
you need to set the \l autoFillBackground property, or use | |
setAttribute() to set the Qt::WA_OpaquePaintEvent attribute, to make | |
a widget opaque. | |
For widgets that use contents propagation, a scroll will cause an | |
update of the entire scroll area. | |
\sa {Transparency and Double Buffering} | |
*/ | |
void QWidget::scroll(int dx, int dy) | |
{ | |
if ((!updatesEnabled() && children().size() == 0) || !isVisible()) | |
return; | |
if (dx == 0 && dy == 0) | |
return; | |
Q_D(QWidget); | |
#ifndef QT_NO_GRAPHICSVIEW | |
if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(this)) { | |
// Graphics View maintains its own dirty region as a list of rects; | |
// until we can connect item updates directly to the view, we must | |
// separately add a translated dirty region. | |
if (!d->dirty.isEmpty()) { | |
foreach (const QRect &rect, (d->dirty.translated(dx, dy)).rects()) | |
proxy->update(rect); | |
} | |
proxy->scroll(dx, dy, proxy->subWidgetRect(this)); | |
return; | |
} | |
#endif | |
d->setDirtyOpaqueRegion(); | |
d->scroll_sys(dx, dy); | |
} | |
/*! | |
\overload | |
This version only scrolls \a r and does not move the children of | |
the widget. | |
If \a r is empty or invalid, the result is undefined. | |
\sa QScrollArea | |
*/ | |
void QWidget::scroll(int dx, int dy, const QRect &r) | |
{ | |
if ((!updatesEnabled() && children().size() == 0) || !isVisible()) | |
return; | |
if (dx == 0 && dy == 0) | |
return; | |
Q_D(QWidget); | |
#ifndef QT_NO_GRAPHICSVIEW | |
if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(this)) { | |
// Graphics View maintains its own dirty region as a list of rects; | |
// until we can connect item updates directly to the view, we must | |
// separately add a translated dirty region. | |
if (!d->dirty.isEmpty()) { | |
foreach (const QRect &rect, (d->dirty.translated(dx, dy) & r).rects()) | |
proxy->update(rect); | |
} | |
proxy->scroll(dx, dy, r.translated(proxy->subWidgetRect(this).topLeft().toPoint())); | |
return; | |
} | |
#endif | |
d->scroll_sys(dx, dy, r); | |
} | |
/*! | |
Repaints the widget directly by calling paintEvent() immediately, | |
unless updates are disabled or the widget is hidden. | |
We suggest only using repaint() if you need an immediate repaint, | |
for example during animation. In almost all circumstances update() | |
is better, as it permits Qt to optimize for speed and minimize | |
flicker. | |
\warning If you call repaint() in a function which may itself be | |
called from paintEvent(), you may get infinite recursion. The | |
update() function never causes recursion. | |
\sa update(), paintEvent(), setUpdatesEnabled() | |
*/ | |
void QWidget::repaint() | |
{ | |
repaint(rect()); | |
} | |
/*! \overload | |
This version repaints a rectangle (\a x, \a y, \a w, \a h) inside | |
the widget. | |
If \a w is negative, it is replaced with \c{width() - x}, and if | |
\a h is negative, it is replaced width \c{height() - y}. | |
*/ | |
void QWidget::repaint(int x, int y, int w, int h) | |
{ | |
if (x > data->crect.width() || y > data->crect.height()) | |
return; | |
if (w < 0) | |
w = data->crect.width() - x; | |
if (h < 0) | |
h = data->crect.height() - y; | |
repaint(QRect(x, y, w, h)); | |
} | |
/*! \overload | |
This version repaints a rectangle \a rect inside the widget. | |
*/ | |
void QWidget::repaint(const QRect &rect) | |
{ | |
Q_D(QWidget); | |
if (testAttribute(Qt::WA_WState_ConfigPending)) { | |
update(rect); | |
return; | |
} | |
if (!isVisible() || !updatesEnabled() || rect.isEmpty()) | |
return; | |
if (hasBackingStoreSupport()) { | |
QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); | |
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { | |
tlwExtra->inRepaint = true; | |
tlwExtra->backingStore->markDirty(rect, this, true); | |
tlwExtra->inRepaint = false; | |
} | |
} else { | |
d->repaint_sys(rect); | |
} | |
} | |
/*! | |
\overload | |
This version repaints a region \a rgn inside the widget. | |
*/ | |
void QWidget::repaint(const QRegion &rgn) | |
{ | |
Q_D(QWidget); | |
if (testAttribute(Qt::WA_WState_ConfigPending)) { | |
update(rgn); | |
return; | |
} | |
if (!isVisible() || !updatesEnabled() || rgn.isEmpty()) | |
return; | |
if (hasBackingStoreSupport()) { | |
QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); | |
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { | |
tlwExtra->inRepaint = true; | |
tlwExtra->backingStore->markDirty(rgn, this, true); | |
tlwExtra->inRepaint = false; | |
} | |
} else { | |
d->repaint_sys(rgn); | |
} | |
} | |
/*! | |
Updates the widget unless updates are disabled or the widget is | |
hidden. | |
This function does not cause an immediate repaint; instead it | |
schedules a paint event for processing when Qt returns to the main | |
event loop. This permits Qt to optimize for more speed and less | |
flicker than a call to repaint() does. | |
Calling update() several times normally results in just one | |
paintEvent() call. | |
Qt normally erases the widget's area before the paintEvent() call. | |
If the Qt::WA_OpaquePaintEvent widget attribute is set, the widget is | |
responsible for painting all its pixels with an opaque color. | |
\sa repaint() paintEvent(), setUpdatesEnabled(), {Analog Clock Example} | |
*/ | |
void QWidget::update() | |
{ | |
update(rect()); | |
} | |
/*! \fn void QWidget::update(int x, int y, int w, int h) | |
\overload | |
This version updates a rectangle (\a x, \a y, \a w, \a h) inside | |
the widget. | |
*/ | |
/*! | |
\overload | |
This version updates a rectangle \a rect inside the widget. | |
*/ | |
void QWidget::update(const QRect &rect) | |
{ | |
if (!isVisible() || !updatesEnabled() || rect.isEmpty()) | |
return; | |
if (testAttribute(Qt::WA_WState_InPaintEvent)) { | |
QApplication::postEvent(this, new QUpdateLaterEvent(rect)); | |
return; | |
} | |
if (hasBackingStoreSupport()) { | |
QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); | |
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) | |
tlwExtra->backingStore->markDirty(rect, this); | |
} else { | |
d_func()->repaint_sys(rect); | |
} | |
} | |
/*! | |
\overload | |
This version repaints a region \a rgn inside the widget. | |
*/ | |
void QWidget::update(const QRegion &rgn) | |
{ | |
if (!isVisible() || !updatesEnabled() || rgn.isEmpty()) | |
return; | |
if (testAttribute(Qt::WA_WState_InPaintEvent)) { | |
QApplication::postEvent(this, new QUpdateLaterEvent(rgn)); | |
return; | |
} | |
if (hasBackingStoreSupport()) { | |
QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); | |
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) | |
tlwExtra->backingStore->markDirty(rgn, this); | |
} else { | |
d_func()->repaint_sys(rgn); | |
} | |
} | |
#ifdef QT3_SUPPORT | |
/*! | |
Clear the rectangle at point (\a x, \a y) of width \a w and height | |
\a h. | |
\warning This is best done in a paintEvent(). | |
*/ | |
void QWidget::erase_helper(int x, int y, int w, int h) | |
{ | |
if (testAttribute(Qt::WA_NoSystemBackground) || testAttribute(Qt::WA_UpdatesDisabled) || !testAttribute(Qt::WA_WState_Visible)) | |
return; | |
if (w < 0) | |
w = data->crect.width() - x; | |
if (h < 0) | |
h = data->crect.height() - y; | |
if (w != 0 && h != 0) { | |
QPainter p(this); | |
p.eraseRect(QRect(x, y, w, h)); | |
} | |
} | |
/*! | |
\overload | |
Clear the given region, \a rgn. | |
Drawing may only take place in a QPaintEvent. Overload | |
paintEvent() to do your erasing and call update() to schedule a | |
replaint whenever necessary. See also QPainter. | |
*/ | |
void QWidget::erase(const QRegion& rgn) | |
{ | |
if (testAttribute(Qt::WA_NoSystemBackground) || testAttribute(Qt::WA_UpdatesDisabled) || !testAttribute(Qt::WA_WState_Visible)) | |
return; | |
QPainter p(this); | |
p.setClipRegion(rgn); | |
p.eraseRect(rgn.boundingRect()); | |
} | |
void QWidget::drawText_helper(int x, int y, const QString &str) | |
{ | |
if(!testAttribute(Qt::WA_WState_Visible)) | |
return; | |
QPainter paint(this); | |
paint.drawText(x, y, str); | |
} | |
/*! | |
Closes the widget. | |
Use the no-argument overload instead. | |
*/ | |
bool QWidget::close(bool alsoDelete) | |
{ | |
QPointer<QWidget> that = this; | |
bool accepted = close(); | |
if (alsoDelete && accepted && that) | |
deleteLater(); | |
return accepted; | |
} | |
void QWidget::setIcon(const QPixmap &i) | |
{ | |
setWindowIcon(i); | |
} | |
/*! | |
Return's the widget's icon. | |
Use windowIcon() instead. | |
*/ | |
const QPixmap *QWidget::icon() const | |
{ | |
Q_D(const QWidget); | |
return (d->extra && d->extra->topextra) ? d->extra->topextra->iconPixmap : 0; | |
} | |
#endif // QT3_SUPPORT | |
/*! | |
\internal | |
This just sets the corresponding attribute bit to 1 or 0 | |
*/ | |
static void setAttribute_internal(Qt::WidgetAttribute attribute, bool on, QWidgetData *data, | |
QWidgetPrivate *d) | |
{ | |
if (attribute < int(8*sizeof(uint))) { | |
if (on) | |
data->widget_attributes |= (1<<attribute); | |
else | |
data->widget_attributes &= ~(1<<attribute); | |
} else { | |
const int x = attribute - 8*sizeof(uint); | |
const int int_off = x / (8*sizeof(uint)); | |
if (on) | |
d->high_attributes[int_off] |= (1<<(x-(int_off*8*sizeof(uint)))); | |
else | |
d->high_attributes[int_off] &= ~(1<<(x-(int_off*8*sizeof(uint)))); | |
} | |
} | |
/*! | |
Sets the attribute \a attribute on this widget if \a on is true; | |
otherwise clears the attribute. | |
\sa testAttribute() | |
*/ | |
void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) | |
{ | |
if (testAttribute(attribute) == on) | |
return; | |
Q_D(QWidget); | |
Q_ASSERT_X(sizeof(d->high_attributes)*8 >= (Qt::WA_AttributeCount - sizeof(uint)*8), | |
"QWidget::setAttribute(WidgetAttribute, bool)", | |
"QWidgetPrivate::high_attributes[] too small to contain all attributes in WidgetAttribute"); | |
#ifdef Q_WS_WIN | |
// ### Don't use PaintOnScreen+paintEngine() to do native painting in 5.0 | |
if (attribute == Qt::WA_PaintOnScreen && on && !inherits("QGLWidget")) { | |
// see qwidget_win.cpp, ::paintEngine for details | |
paintEngine(); | |
if (d->noPaintOnScreen) | |
return; | |
} | |
#endif | |
setAttribute_internal(attribute, on, data, d); | |
switch (attribute) { | |
#ifndef QT_NO_DRAGANDDROP | |
case Qt::WA_AcceptDrops: { | |
if (on && !testAttribute(Qt::WA_DropSiteRegistered)) | |
setAttribute(Qt::WA_DropSiteRegistered, true); | |
else if (!on && (isWindow() || !parentWidget() || !parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))) | |
setAttribute(Qt::WA_DropSiteRegistered, false); | |
QEvent e(QEvent::AcceptDropsChange); | |
QApplication::sendEvent(this, &e); | |
break; | |
} | |
case Qt::WA_DropSiteRegistered: { | |
d->registerDropSite(on); | |
for (int i = 0; i < d->children.size(); ++i) { | |
QWidget *w = qobject_cast<QWidget *>(d->children.at(i)); | |
if (w && !w->isWindow() && !w->testAttribute(Qt::WA_AcceptDrops) && w->testAttribute(Qt::WA_DropSiteRegistered) != on) | |
w->setAttribute(Qt::WA_DropSiteRegistered, on); | |
} | |
break; | |
} | |
#endif | |
case Qt::WA_NoChildEventsForParent: | |
d->sendChildEvents = !on; | |
break; | |
case Qt::WA_NoChildEventsFromChildren: | |
d->receiveChildEvents = !on; | |
break; | |
case Qt::WA_MacBrushedMetal: | |
#ifdef Q_WS_MAC | |
d->setStyle_helper(style(), false, true); // Make sure things get unpolished/polished correctly. | |
// fall through since changing the metal attribute affects the opaque size grip. | |
case Qt::WA_MacOpaqueSizeGrip: | |
d->macUpdateOpaqueSizeGrip(); | |
break; | |
case Qt::WA_MacShowFocusRect: | |
if (hasFocus()) { | |
clearFocus(); | |
setFocus(); | |
} | |
break; | |
case Qt::WA_Hover: | |
qt_mac_update_mouseTracking(this); | |
break; | |
#endif | |
case Qt::WA_MacAlwaysShowToolWindow: | |
#ifdef Q_WS_MAC | |
d->macUpdateHideOnSuspend(); | |
#endif | |
break; | |
case Qt::WA_MacNormalSize: | |
case Qt::WA_MacSmallSize: | |
case Qt::WA_MacMiniSize: | |
#ifdef Q_WS_MAC | |
{ | |
// We can only have one of these set at a time | |
const Qt::WidgetAttribute MacSizes[] = { Qt::WA_MacNormalSize, Qt::WA_MacSmallSize, | |
Qt::WA_MacMiniSize }; | |
for (int i = 0; i < 3; ++i) { | |
if (MacSizes[i] != attribute) | |
setAttribute_internal(MacSizes[i], false, data, d); | |
} | |
d->macUpdateSizeAttribute(); | |
} | |
#endif | |
break; | |
case Qt::WA_ShowModal: | |
if (!on) { | |
if (isVisible()) | |
QApplicationPrivate::leaveModal(this); | |
// reset modality type to Modeless when clearing WA_ShowModal | |
data->window_modality = Qt::NonModal; | |
} else if (data->window_modality == Qt::NonModal) { | |
// determine the modality type if it hasn't been set prior | |
// to setting WA_ShowModal. set the default to WindowModal | |
// if we are the child of a group leader; otherwise use | |
// ApplicationModal. | |
QWidget *w = parentWidget(); | |
if (w) | |
w = w->window(); | |
while (w && !w->testAttribute(Qt::WA_GroupLeader)) { | |
w = w->parentWidget(); | |
if (w) | |
w = w->window(); | |
} | |
data->window_modality = (w && w->testAttribute(Qt::WA_GroupLeader)) | |
? Qt::WindowModal | |
: Qt::ApplicationModal; | |
// Some window managers does not allow us to enter modal after the | |
// window is showing. Therefore, to be consistent, we cannot call | |
// QApplicationPrivate::enterModal(this) here. The window must be | |
// hidden before changing modality. | |
} | |
if (testAttribute(Qt::WA_WState_Created)) { | |
// don't call setModal_sys() before create_sys() | |
d->setModal_sys(); | |
} | |
break; | |
case Qt::WA_MouseTracking: { | |
QEvent e(QEvent::MouseTrackingChange); | |
QApplication::sendEvent(this, &e); | |
break; } | |
case Qt::WA_NativeWindow: { | |
#ifndef QT_NO_IM | |
QWidget *focusWidget = d->effectiveFocusWidget(); | |
QInputContext *ic = 0; | |
if (on && !internalWinId() && hasFocus() | |
&& focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) { | |
ic = focusWidget->d_func()->inputContext(); | |
if (ic) { | |
ic->reset(); | |
ic->setFocusWidget(0); | |
} | |
} | |
if (!qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings) && parentWidget()) | |
parentWidget()->d_func()->enforceNativeChildren(); | |
if (on && !internalWinId() && testAttribute(Qt::WA_WState_Created)) | |
d->createWinId(); | |
if (ic && isEnabled() && focusWidget->isEnabled() | |
&& focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) { | |
ic->setFocusWidget(focusWidget); | |
} | |
#endif //QT_NO_IM | |
break; | |
} | |
case Qt::WA_PaintOnScreen: | |
d->updateIsOpaque(); | |
#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN) | |
// Recreate the widget if it's already created as an alien widget and | |
// WA_PaintOnScreen is enabled. Paint on screen widgets must have win id. | |
// So must their children. | |
if (on) { | |
setAttribute(Qt::WA_NativeWindow); | |
d->enforceNativeChildren(); | |
} | |
#endif | |
// fall through | |
case Qt::WA_OpaquePaintEvent: | |
d->updateIsOpaque(); | |
break; | |
case Qt::WA_NoSystemBackground: | |
d->updateIsOpaque(); | |
// fall through... | |
case Qt::WA_UpdatesDisabled: | |
d->updateSystemBackground(); | |
break; | |
case Qt::WA_TransparentForMouseEvents: | |
#ifdef Q_WS_MAC | |
d->macUpdateIgnoreMouseEvents(); | |
#endif | |
break; | |
case Qt::WA_InputMethodEnabled: { | |
#ifndef QT_NO_IM | |
QWidget *focusWidget = d->effectiveFocusWidget(); | |
QInputContext *ic = focusWidget->d_func()->assignedInputContext(); | |
if (!ic && (!on || hasFocus())) | |
ic = focusWidget->d_func()->inputContext(); | |
if (ic) { | |
if (on && hasFocus() && ic->focusWidget() != focusWidget && isEnabled() | |
&& focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) { | |
ic->setFocusWidget(focusWidget); | |
} else if (!on && ic->focusWidget() == focusWidget) { | |
ic->reset(); | |
ic->setFocusWidget(0); | |
} | |
} | |
#endif //QT_NO_IM | |
break; | |
} | |
case Qt::WA_WindowPropagation: | |
d->resolvePalette(); | |
d->resolveFont(); | |
d->resolveLocale(); | |
break; | |
#ifdef Q_WS_X11 | |
case Qt::WA_NoX11EventCompression: | |
if (!d->extra) | |
d->createExtra(); | |
d->extra->compress_events = on; | |
break; | |
case Qt::WA_X11OpenGLOverlay: | |
d->updateIsOpaque(); | |
break; | |
case Qt::WA_X11DoNotAcceptFocus: | |
if (testAttribute(Qt::WA_WState_Created)) | |
d->updateX11AcceptFocus(); | |
break; | |
#endif | |
case Qt::WA_DontShowOnScreen: { | |
if (on && isVisible()) { | |
// Make sure we keep the current state and only hide the widget | |
// from the desktop. show_sys will only update platform specific | |
// attributes at this point. | |
d->hide_sys(); | |
#ifdef Q_WS_QWS | |
// Release the region for this window from qws if the widget has | |
// been shown before the attribute was set. | |
if (QWSWindowSurface *surface = static_cast<QWSWindowSurface *>(windowSurface())) { | |
QWidget::qwsDisplay()->requestRegion(surface->winId(), surface->key(), | |
surface->permanentState(), QRegion()); | |
} | |
#endif | |
d->show_sys(); | |
} | |
break; | |
} | |
#ifdef Q_WS_X11 | |
case Qt::WA_X11NetWmWindowTypeDesktop: | |
case Qt::WA_X11NetWmWindowTypeDock: | |
case Qt::WA_X11NetWmWindowTypeToolBar: | |
case Qt::WA_X11NetWmWindowTypeMenu: | |
case Qt::WA_X11NetWmWindowTypeUtility: | |
case Qt::WA_X11NetWmWindowTypeSplash: | |
case Qt::WA_X11NetWmWindowTypeDialog: | |
case Qt::WA_X11NetWmWindowTypeDropDownMenu: | |
case Qt::WA_X11NetWmWindowTypePopupMenu: | |
case Qt::WA_X11NetWmWindowTypeToolTip: | |
case Qt::WA_X11NetWmWindowTypeNotification: | |
case Qt::WA_X11NetWmWindowTypeCombo: | |
case Qt::WA_X11NetWmWindowTypeDND: | |
if (testAttribute(Qt::WA_WState_Created)) | |
d->setNetWmWindowTypes(); | |
break; | |
#endif | |
case Qt::WA_StaticContents: | |
if (QWidgetBackingStore *bs = d->maybeBackingStore()) { | |
if (on) | |
bs->addStaticWidget(this); | |
else | |
bs->removeStaticWidget(this); | |
} | |
break; | |
case Qt::WA_TranslucentBackground: | |
if (on) { | |
setAttribute(Qt::WA_NoSystemBackground); | |
d->updateIsTranslucent(); | |
} | |
break; | |
case Qt::WA_AcceptTouchEvents: | |
#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN) | |
if (on) | |
d->registerTouchWindow(); | |
#endif | |
break; | |
case Qt::WA_LockPortraitOrientation: | |
case Qt::WA_LockLandscapeOrientation: | |
case Qt::WA_AutoOrientation: { | |
const Qt::WidgetAttribute orientations[3] = { | |
Qt::WA_LockPortraitOrientation, | |
Qt::WA_LockLandscapeOrientation, | |
Qt::WA_AutoOrientation | |
}; | |
if (on) { | |
// We can only have one of these set at a time | |
for (int i = 0; i < 3; ++i) { | |
if (orientations[i] != attribute) | |
setAttribute_internal(orientations[i], false, data, d); | |
} | |
} | |
#ifdef Q_WS_S60 | |
CAknAppUiBase* appUi = static_cast<CAknAppUiBase*>(CEikonEnv::Static()->EikAppUi()); | |
const CAknAppUiBase::TAppUiOrientation s60orientations[] = { | |
CAknAppUiBase::EAppUiOrientationPortrait, | |
CAknAppUiBase::EAppUiOrientationLandscape, | |
CAknAppUiBase::EAppUiOrientationAutomatic | |
}; | |
CAknAppUiBase::TAppUiOrientation s60orientation = CAknAppUiBase::EAppUiOrientationUnspecified; | |
for (int i = 0; i < 3; ++i) { | |
if (testAttribute(orientations[i])) { | |
s60orientation = s60orientations[i]; | |
break; | |
} | |
} | |
QT_TRAP_THROWING(appUi->SetOrientationL(s60orientation)); | |
S60->orientationSet = true; | |
QSymbianControl *window = static_cast<QSymbianControl *>(internalWinId()); | |
if (window) | |
window->ensureFixNativeOrientation(); | |
#endif | |
break; | |
} | |
default: | |
break; | |
} | |
} | |
/*! \fn bool QWidget::testAttribute(Qt::WidgetAttribute attribute) const | |
Returns true if attribute \a attribute is set on this widget; | |
otherwise returns false. | |
\sa setAttribute() | |
*/ | |
bool QWidget::testAttribute_helper(Qt::WidgetAttribute attribute) const | |
{ | |
Q_D(const QWidget); | |
const int x = attribute - 8*sizeof(uint); | |
const int int_off = x / (8*sizeof(uint)); | |
return (d->high_attributes[int_off] & (1<<(x-(int_off*8*sizeof(uint))))); | |
} | |
/*! | |
\property QWidget::windowOpacity | |
\brief The level of opacity for the window. | |
The valid range of opacity is from 1.0 (completely opaque) to | |
0.0 (completely transparent). | |
By default the value of this property is 1.0. | |
This feature is available on Embedded Linux, Mac OS X, Windows, | |
and X11 platforms that support the Composite extension. | |
This feature is not available on Windows CE. | |
Note that under X11 you need to have a composite manager running, | |
and the X11 specific _NET_WM_WINDOW_OPACITY atom needs to be | |
supported by the window manager you are using. | |
\warning Changing this property from opaque to transparent might issue a | |
paint event that needs to be processed before the window is displayed | |
correctly. This affects mainly the use of QPixmap::grabWindow(). Also note | |
that semi-transparent windows update and resize significantly slower than | |
opaque windows. | |
\sa setMask() | |
*/ | |
qreal QWidget::windowOpacity() const | |
{ | |
Q_D(const QWidget); | |
return (isWindow() && d->maybeTopData()) ? d->maybeTopData()->opacity / 255. : 1.0; | |
} | |
void QWidget::setWindowOpacity(qreal opacity) | |
{ | |
Q_D(QWidget); | |
if (!isWindow()) | |
return; | |
opacity = qBound(qreal(0.0), opacity, qreal(1.0)); | |
QTLWExtra *extra = d->topData(); | |
extra->opacity = uint(opacity * 255); | |
setAttribute(Qt::WA_WState_WindowOpacitySet); | |
#ifndef Q_WS_QWS | |
if (!testAttribute(Qt::WA_WState_Created)) | |
return; | |
#endif | |
#ifndef QT_NO_GRAPHICSVIEW | |
if (QGraphicsProxyWidget *proxy = graphicsProxyWidget()) { | |
// Avoid invalidating the cache if set. | |
if (proxy->cacheMode() == QGraphicsItem::NoCache) | |
proxy->update(); | |
else if (QGraphicsScene *scene = proxy->scene()) | |
scene->update(proxy->sceneBoundingRect()); | |
return; | |
} | |
#endif | |
d->setWindowOpacity_sys(opacity); | |
} | |
/*! | |
\property QWidget::windowModified | |
\brief whether the document shown in the window has unsaved changes | |
A modified window is a window whose content has changed but has | |
not been saved to disk. This flag will have different effects | |
varied by the platform. On Mac OS X the close button will have a | |
modified look; on other platforms, the window title will have an | |
'*' (asterisk). | |
The window title must contain a "[*]" placeholder, which | |
indicates where the '*' should appear. Normally, it should appear | |
right after the file name (e.g., "document1.txt[*] - Text | |
Editor"). If the window isn't modified, the placeholder is simply | |
removed. | |
Note that if a widget is set as modified, all its ancestors will | |
also be set as modified. However, if you call \c | |
{setWindowModified(false)} on a widget, this will not propagate to | |
its parent because other children of the parent might have been | |
modified. | |
\sa windowTitle, {Application Example}, {SDI Example}, {MDI Example} | |
*/ | |
bool QWidget::isWindowModified() const | |
{ | |
return testAttribute(Qt::WA_WindowModified); | |
} | |
void QWidget::setWindowModified(bool mod) | |
{ | |
Q_D(QWidget); | |
setAttribute(Qt::WA_WindowModified, mod); | |
#ifndef Q_WS_MAC | |
if (!windowTitle().contains(QLatin1String("[*]")) && mod) | |
qWarning("QWidget::setWindowModified: The window title does not contain a '[*]' placeholder"); | |
#endif | |
d->setWindowTitle_helper(windowTitle()); | |
d->setWindowIconText_helper(windowIconText()); | |
#ifdef Q_WS_MAC | |
d->setWindowModified_sys(mod); | |
#endif | |
QEvent e(QEvent::ModifiedChange); | |
QApplication::sendEvent(this, &e); | |
} | |
#ifndef QT_NO_TOOLTIP | |
/*! | |
\property QWidget::toolTip | |
\brief the widget's tooltip | |
Note that by default tooltips are only shown for widgets that are | |
children of the active window. You can change this behavior by | |
setting the attribute Qt::WA_AlwaysShowToolTips on the \e window, | |
not on the widget with the tooltip. | |
If you want to control a tooltip's behavior, you can intercept the | |
event() function and catch the QEvent::ToolTip event (e.g., if you | |
want to customize the area for which the tooltip should be shown). | |
By default, this property contains an empty string. | |
\sa QToolTip statusTip whatsThis | |
*/ | |
void QWidget::setToolTip(const QString &s) | |
{ | |
Q_D(QWidget); | |
d->toolTip = s; | |
QEvent event(QEvent::ToolTipChange); | |
QApplication::sendEvent(this, &event); | |
} | |
QString QWidget::toolTip() const | |
{ | |
Q_D(const QWidget); | |
return d->toolTip; | |
} | |
#endif // QT_NO_TOOLTIP | |
#ifndef QT_NO_STATUSTIP | |
/*! | |
\property QWidget::statusTip | |
\brief the widget's status tip | |
By default, this property contains an empty string. | |
\sa toolTip whatsThis | |
*/ | |
void QWidget::setStatusTip(const QString &s) | |
{ | |
Q_D(QWidget); | |
d->statusTip = s; | |
} | |
QString QWidget::statusTip() const | |
{ | |
Q_D(const QWidget); | |
return d->statusTip; | |
} | |
#endif // QT_NO_STATUSTIP | |
#ifndef QT_NO_WHATSTHIS | |
/*! | |
\property QWidget::whatsThis | |
\brief the widget's What's This help text. | |
By default, this property contains an empty string. | |
\sa QWhatsThis QWidget::toolTip QWidget::statusTip | |
*/ | |
void QWidget::setWhatsThis(const QString &s) | |
{ | |
Q_D(QWidget); | |
d->whatsThis = s; | |
} | |
QString QWidget::whatsThis() const | |
{ | |
Q_D(const QWidget); | |
return d->whatsThis; | |
} | |
#endif // QT_NO_WHATSTHIS | |
#ifndef QT_NO_ACCESSIBILITY | |
/*! | |
\property QWidget::accessibleName | |
\brief the widget's name as seen by assistive technologies | |
This property is used by accessible clients to identify, find, or announce | |
the widget for accessible clients. | |
By default, this property contains an empty string. | |
\sa QAccessibleInterface::text() | |
*/ | |
void QWidget::setAccessibleName(const QString &name) | |
{ | |
Q_D(QWidget); | |
d->accessibleName = name; | |
} | |
QString QWidget::accessibleName() const | |
{ | |
Q_D(const QWidget); | |
return d->accessibleName; | |
} | |
/*! | |
\property QWidget::accessibleDescription | |
\brief the widget's description as seen by assistive technologies | |
By default, this property contains an empty string. | |
\sa QAccessibleInterface::text() | |
*/ | |
void QWidget::setAccessibleDescription(const QString &description) | |
{ | |
Q_D(QWidget); | |
d->accessibleDescription = description; | |
} | |
QString QWidget::accessibleDescription() const | |
{ | |
Q_D(const QWidget); | |
return d->accessibleDescription; | |
} | |
#endif // QT_NO_ACCESSIBILITY | |
#ifndef QT_NO_SHORTCUT | |
/*! | |
Adds a shortcut to Qt's shortcut system that watches for the given | |
\a key sequence in the given \a context. If the \a context is | |
Qt::ApplicationShortcut, the shortcut applies to the application as a | |
whole. Otherwise, it is either local to this widget, Qt::WidgetShortcut, | |
or to the window itself, Qt::WindowShortcut. | |
If the same \a key sequence has been grabbed by several widgets, | |
when the \a key sequence occurs a QEvent::Shortcut event is sent | |
to all the widgets to which it applies in a non-deterministic | |
order, but with the ``ambiguous'' flag set to true. | |
\warning You should not normally need to use this function; | |
instead create \l{QAction}s with the shortcut key sequences you | |
require (if you also want equivalent menu options and toolbar | |
buttons), or create \l{QShortcut}s if you just need key sequences. | |
Both QAction and QShortcut handle all the event filtering for you, | |
and provide signals which are triggered when the user triggers the | |
key sequence, so are much easier to use than this low-level | |
function. | |
\sa releaseShortcut() setShortcutEnabled() | |
*/ | |
int QWidget::grabShortcut(const QKeySequence &key, Qt::ShortcutContext context) | |
{ | |
Q_ASSERT(qApp); | |
if (key.isEmpty()) | |
return 0; | |
setAttribute(Qt::WA_GrabbedShortcut); | |
return qApp->d_func()->shortcutMap.addShortcut(this, key, context); | |
} | |
/*! | |
Removes the shortcut with the given \a id from Qt's shortcut | |
system. The widget will no longer receive QEvent::Shortcut events | |
for the shortcut's key sequence (unless it has other shortcuts | |
with the same key sequence). | |
\warning You should not normally need to use this function since | |
Qt's shortcut system removes shortcuts automatically when their | |
parent widget is destroyed. It is best to use QAction or | |
QShortcut to handle shortcuts, since they are easier to use than | |
this low-level function. Note also that this is an expensive | |
operation. | |
\sa grabShortcut() setShortcutEnabled() | |
*/ | |
void QWidget::releaseShortcut(int id) | |
{ | |
Q_ASSERT(qApp); | |
if (id) | |
qApp->d_func()->shortcutMap.removeShortcut(id, this, 0); | |
} | |
/*! | |
If \a enable is true, the shortcut with the given \a id is | |
enabled; otherwise the shortcut is disabled. | |
\warning You should not normally need to use this function since | |
Qt's shortcut system enables/disables shortcuts automatically as | |
widgets become hidden/visible and gain or lose focus. It is best | |
to use QAction or QShortcut to handle shortcuts, since they are | |
easier to use than this low-level function. | |
\sa grabShortcut() releaseShortcut() | |
*/ | |
void QWidget::setShortcutEnabled(int id, bool enable) | |
{ | |
Q_ASSERT(qApp); | |
if (id) | |
qApp->d_func()->shortcutMap.setShortcutEnabled(enable, id, this, 0); | |
} | |
/*! | |
\since 4.2 | |
If \a enable is true, auto repeat of the shortcut with the | |
given \a id is enabled; otherwise it is disabled. | |
\sa grabShortcut() releaseShortcut() | |
*/ | |
void QWidget::setShortcutAutoRepeat(int id, bool enable) | |
{ | |
Q_ASSERT(qApp); | |
if (id) | |
qApp->d_func()->shortcutMap.setShortcutAutoRepeat(enable, id, this, 0); | |
} | |
#endif // QT_NO_SHORTCUT | |
/*! | |
Updates the widget's micro focus. | |
\sa QInputContext | |
*/ | |
void QWidget::updateMicroFocus() | |
{ | |
#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) | |
Q_D(QWidget); | |
// and optimization to update input context only it has already been created. | |
if (d->assignedInputContext() || qApp->d_func()->inputContext) { | |
QInputContext *ic = inputContext(); | |
if (ic) | |
ic->update(); | |
} | |
#endif | |
#ifndef QT_NO_ACCESSIBILITY | |
// ##### is this correct | |
QAccessible::updateAccessibility(this, 0, QAccessible::StateChanged); | |
#endif | |
} | |
#if defined (Q_WS_WIN) | |
/*! | |
Returns the window system handle of the widget, for low-level | |
access. Using this function is not portable. | |
An HDC acquired with getDC() has to be released with releaseDC(). | |
\warning Using this function is not portable. | |
*/ | |
HDC QWidget::getDC() const | |
{ | |
Q_D(const QWidget); | |
if (d->hd) | |
return (HDC) d->hd; | |
return GetDC(winId()); | |
} | |
/*! | |
Releases the HDC \a hdc acquired by a previous call to getDC(). | |
\warning Using this function is not portable. | |
*/ | |
void QWidget::releaseDC(HDC hdc) const | |
{ | |
Q_D(const QWidget); | |
// If its the widgets own dc, it will be released elsewhere. If | |
// its a different HDC we release it and issue a warning if it | |
// fails. | |
if (hdc != d->hd && !ReleaseDC(winId(), hdc)) | |
qErrnoWarning("QWidget::releaseDC(): failed to release HDC"); | |
} | |
#else | |
/*! | |
Returns the window system handle of the widget, for low-level | |
access. Using this function is not portable. | |
The HANDLE type varies with platform; see \c qwindowdefs.h for | |
details. | |
*/ | |
Qt::HANDLE QWidget::handle() const | |
{ | |
Q_D(const QWidget); | |
if (!internalWinId() && testAttribute(Qt::WA_WState_Created)) | |
(void)winId(); // enforce native window | |
return d->hd; | |
} | |
#endif | |
/*! | |
Raises this widget to the top of the parent widget's stack. | |
After this call the widget will be visually in front of any | |
overlapping sibling widgets. | |
\note When using activateWindow(), you can call this function to | |
ensure that the window is stacked on top. | |
\sa lower(), stackUnder() | |
*/ | |
void QWidget::raise() | |
{ | |
Q_D(QWidget); | |
if (!isWindow()) { | |
QWidget *p = parentWidget(); | |
const int parentChildCount = p->d_func()->children.size(); | |
if (parentChildCount < 2) | |
return; | |
const int from = p->d_func()->children.indexOf(this); | |
Q_ASSERT(from >= 0); | |
// Do nothing if the widget is already in correct stacking order _and_ created. | |
if (from != parentChildCount -1) | |
p->d_func()->children.move(from, parentChildCount - 1); | |
if (!testAttribute(Qt::WA_WState_Created) && p->testAttribute(Qt::WA_WState_Created)) | |
create(); | |
else if (from == parentChildCount - 1) | |
return; | |
QRegion region(rect()); | |
d->subtractOpaqueSiblings(region); | |
d->invalidateBuffer(region); | |
} | |
if (testAttribute(Qt::WA_WState_Created)) | |
d->raise_sys(); | |
QEvent e(QEvent::ZOrderChange); | |
QApplication::sendEvent(this, &e); | |
} | |
/*! | |
Lowers the widget to the bottom of the parent widget's stack. | |
After this call the widget will be visually behind (and therefore | |
obscured by) any overlapping sibling widgets. | |
\sa raise(), stackUnder() | |
*/ | |
void QWidget::lower() | |
{ | |
Q_D(QWidget); | |
if (!isWindow()) { | |
QWidget *p = parentWidget(); | |
const int parentChildCount = p->d_func()->children.size(); | |
if (parentChildCount < 2) | |
return; | |
const int from = p->d_func()->children.indexOf(this); | |
Q_ASSERT(from >= 0); | |
// Do nothing if the widget is already in correct stacking order _and_ created. | |
if (from != 0) | |
p->d_func()->children.move(from, 0); | |
if (!testAttribute(Qt::WA_WState_Created) && p->testAttribute(Qt::WA_WState_Created)) | |
create(); | |
else if (from == 0) | |
return; | |
} | |
if (testAttribute(Qt::WA_WState_Created)) | |
d->lower_sys(); | |
QEvent e(QEvent::ZOrderChange); | |
QApplication::sendEvent(this, &e); | |
} | |
/*! | |
Places the widget under \a w in the parent widget's stack. | |
To make this work, the widget itself and \a w must be siblings. | |
\sa raise(), lower() | |
*/ | |
void QWidget::stackUnder(QWidget* w) | |
{ | |
Q_D(QWidget); | |
QWidget *p = parentWidget(); | |
if (!w || isWindow() || p != w->parentWidget() || this == w) | |
return; | |
if (p) { | |
int from = p->d_func()->children.indexOf(this); | |
int to = p->d_func()->children.indexOf(w); | |
Q_ASSERT(from >= 0); | |
Q_ASSERT(to >= 0); | |
if (from < to) | |
--to; | |
// Do nothing if the widget is already in correct stacking order _and_ created. | |
if (from != to) | |
p->d_func()->children.move(from, to); | |
if (!testAttribute(Qt::WA_WState_Created) && p->testAttribute(Qt::WA_WState_Created)) | |
create(); | |
else if (from == to) | |
return; | |
} | |
if (testAttribute(Qt::WA_WState_Created)) | |
d->stackUnder_sys(w); | |
QEvent e(QEvent::ZOrderChange); | |
QApplication::sendEvent(this, &e); | |
} | |
void QWidget::styleChange(QStyle&) { } | |
void QWidget::enabledChange(bool) { } // compat | |
void QWidget::paletteChange(const QPalette &) { } // compat | |
void QWidget::fontChange(const QFont &) { } // compat | |
void QWidget::windowActivationChange(bool) { } // compat | |
void QWidget::languageChange() { } // compat | |
/*! | |
\enum QWidget::BackgroundOrigin | |
\compat | |
\value WidgetOrigin | |
\value ParentOrigin | |
\value WindowOrigin | |
\value AncestorOrigin | |
*/ | |
/*! | |
\fn bool QWidget::isVisibleToTLW() const | |
Use isVisible() instead. | |
*/ | |
/*! | |
\fn void QWidget::iconify() | |
Use showMinimized() instead. | |
*/ | |
/*! | |
\fn void QWidget::constPolish() const | |
Use ensurePolished() instead. | |
*/ | |
/*! | |
\fn void QWidget::reparent(QWidget *parent, Qt::WindowFlags f, const QPoint &p, bool showIt) | |
Use setParent() to change the parent or the widget's widget flags; | |
use move() to move the widget, and use show() to show the widget. | |
*/ | |
/*! | |
\fn void QWidget::reparent(QWidget *parent, const QPoint &p, bool showIt) | |
Use setParent() to change the parent; use move() to move the | |
widget, and use show() to show the widget. | |
*/ | |
/*! | |
\fn void QWidget::recreate(QWidget *parent, Qt::WindowFlags f, const QPoint & p, bool showIt) | |
Use setParent() to change the parent or the widget's widget flags; | |
use move() to move the widget, and use show() to show the widget. | |
*/ | |
/*! | |
\fn bool QWidget::hasMouse() const | |
Use testAttribute(Qt::WA_UnderMouse) instead. | |
*/ | |
/*! | |
\fn bool QWidget::ownCursor() const | |
Use testAttribute(Qt::WA_SetCursor) instead. | |
*/ | |
/*! | |
\fn bool QWidget::ownFont() const | |
Use testAttribute(Qt::WA_SetFont) instead. | |
*/ | |
/*! | |
\fn void QWidget::unsetFont() | |
Use setFont(QFont()) instead. | |
*/ | |
/*! | |
\fn bool QWidget::ownPalette() const | |
Use testAttribute(Qt::WA_SetPalette) instead. | |
*/ | |
/*! | |
\fn void QWidget::unsetPalette() | |
Use setPalette(QPalette()) instead. | |
*/ | |
/*! | |
\fn void QWidget::setEraseColor(const QColor &color) | |
Use the palette instead. | |
\oldcode | |
widget->setEraseColor(color); | |
\newcode | |
QPalette palette; | |
palette.setColor(widget->backgroundRole(), color); | |
widget->setPalette(palette); | |
\endcode | |
*/ | |
/*! | |
\fn void QWidget::setErasePixmap(const QPixmap &pixmap) | |
Use the palette instead. | |
\oldcode | |
widget->setErasePixmap(pixmap); | |
\newcode | |
QPalette palette; | |
palette.setBrush(widget->backgroundRole(), QBrush(pixmap)); | |
widget->setPalette(palette); | |
\endcode | |
*/ | |
/*! | |
\fn void QWidget::setPaletteForegroundColor(const QColor &color) | |
Use the palette directly. | |
\oldcode | |
widget->setPaletteForegroundColor(color); | |
\newcode | |
QPalette palette; | |
palette.setColor(widget->foregroundRole(), color); | |
widget->setPalette(palette); | |
\endcode | |
*/ | |
/*! | |
\fn void QWidget::setPaletteBackgroundColor(const QColor &color) | |
Use the palette directly. | |
\oldcode | |
widget->setPaletteBackgroundColor(color); | |
\newcode | |
QPalette palette; | |
palette.setColor(widget->backgroundRole(), color); | |
widget->setPalette(palette); | |
\endcode | |
*/ | |
/*! | |
\fn void QWidget::setPaletteBackgroundPixmap(const QPixmap &pixmap) | |
Use the palette directly. | |
\oldcode | |
widget->setPaletteBackgroundPixmap(pixmap); | |
\newcode | |
QPalette palette; | |
palette.setBrush(widget->backgroundRole(), QBrush(pixmap)); | |
widget->setPalette(palette); | |
\endcode | |
*/ | |
/*! | |
\fn void QWidget::setBackgroundPixmap(const QPixmap &pixmap) | |
Use the palette instead. | |
\oldcode | |
widget->setBackgroundPixmap(pixmap); | |
\newcode | |
QPalette palette; | |
palette.setBrush(widget->backgroundRole(), QBrush(pixmap)); | |
widget->setPalette(palette); | |
\endcode | |
*/ | |
/*! | |
\fn void QWidget::setBackgroundColor(const QColor &color) | |
Use the palette instead. | |
\oldcode | |
widget->setBackgroundColor(color); | |
\newcode | |
QPalette palette; | |
palette.setColor(widget->backgroundRole(), color); | |
widget->setPalette(palette); | |
\endcode | |
*/ | |
/*! | |
\fn QColorGroup QWidget::colorGroup() const | |
Use QColorGroup(palette()) instead. | |
*/ | |
/*! | |
\fn QWidget *QWidget::parentWidget(bool sameWindow) const | |
Use the no-argument overload instead. | |
*/ | |
/*! | |
\fn void QWidget::setKeyCompression(bool b) | |
Use setAttribute(Qt::WA_KeyCompression, b) instead. | |
*/ | |
/*! | |
\fn void QWidget::setFont(const QFont &f, bool b) | |
Use the single-argument overload instead. | |
*/ | |
/*! | |
\fn void QWidget::setPalette(const QPalette &p, bool b) | |
Use the single-argument overload instead. | |
*/ | |
/*! | |
\fn void QWidget::setBackgroundOrigin(BackgroundOrigin background) | |
\obsolete | |
*/ | |
/*! | |
\fn BackgroundOrigin QWidget::backgroundOrigin() const | |
\obsolete | |
Always returns \c WindowOrigin. | |
*/ | |
/*! | |
\fn QPoint QWidget::backgroundOffset() const | |
\obsolete | |
Always returns QPoint(). | |
*/ | |
/*! | |
\fn void QWidget::repaint(bool b) | |
The boolean parameter \a b is ignored. Use the no-argument overload instead. | |
*/ | |
/*! | |
\fn void QWidget::repaint(int x, int y, int w, int h, bool b) | |
The boolean parameter \a b is ignored. Use the four-argument overload instead. | |
*/ | |
/*! | |
\fn void QWidget::repaint(const QRect &r, bool b) | |
The boolean parameter \a b is ignored. Use the single rect-argument overload instead. | |
*/ | |
/*! | |
\fn void QWidget::repaint(const QRegion &rgn, bool b) | |
The boolean parameter \a b is ignored. Use the single region-argument overload instead. | |
*/ | |
/*! | |
\fn void QWidget::erase() | |
Drawing may only take place in a QPaintEvent. Overload | |
paintEvent() to do your erasing and call update() to schedule a | |
replaint whenever necessary. See also QPainter. | |
*/ | |
/*! | |
\fn void QWidget::erase(int x, int y, int w, int h) | |
Drawing may only take place in a QPaintEvent. Overload | |
paintEvent() to do your erasing and call update() to schedule a | |
replaint whenever necessary. See also QPainter. | |
*/ | |
/*! | |
\fn void QWidget::erase(const QRect &rect) | |
Drawing may only take place in a QPaintEvent. Overload | |
paintEvent() to do your erasing and call update() to schedule a | |
replaint whenever necessary. See also QPainter. | |
*/ | |
/*! | |
\fn void QWidget::drawText(const QPoint &p, const QString &s) | |
Drawing may only take place in a QPaintEvent. Overload | |
paintEvent() to do your drawing and call update() to schedule a | |
replaint whenever necessary. See also QPainter. | |
*/ | |
/*! | |
\fn void QWidget::drawText(int x, int y, const QString &s) | |
Drawing may only take place in a QPaintEvent. Overload | |
paintEvent() to do your drawing and call update() to schedule a | |
replaint whenever necessary. See also QPainter. | |
*/ | |
/*! | |
\fn QWidget *QWidget::childAt(const QPoint &p, bool includeThis) const | |
Use the single point argument overload instead. | |
*/ | |
/*! | |
\fn void QWidget::setCaption(const QString &c) | |
Use setWindowTitle() instead. | |
*/ | |
/*! | |
\fn void QWidget::setIcon(const QPixmap &i) | |
Use setWindowIcon() instead. | |
*/ | |
/*! | |
\fn void QWidget::setIconText(const QString &it) | |
Use setWindowIconText() instead. | |
*/ | |
/*! | |
\fn QString QWidget::caption() const | |
Use windowTitle() instead. | |
*/ | |
/*! | |
\fn QString QWidget::iconText() const | |
Use windowIconText() instead. | |
*/ | |
/*! | |
\fn bool QWidget::isTopLevel() const | |
\obsolete | |
Use isWindow() instead. | |
*/ | |
/*! | |
\fn bool QWidget::isRightToLeft() const | |
\internal | |
*/ | |
/*! | |
\fn bool QWidget::isLeftToRight() const | |
\internal | |
*/ | |
/*! | |
\fn void QWidget::setInputMethodEnabled(bool enabled) | |
Use setAttribute(Qt::WA_InputMethodEnabled, \a enabled) instead. | |
*/ | |
/*! | |
\fn bool QWidget::isInputMethodEnabled() const | |
Use testAttribute(Qt::WA_InputMethodEnabled) instead. | |
*/ | |
/*! | |
\fn void QWidget::setActiveWindow() | |
Use activateWindow() instead. | |
*/ | |
/*! | |
\fn bool QWidget::isShown() const | |
Use !isHidden() instead (notice the exclamation mark), or use isVisible() to check whether the widget is visible. | |
*/ | |
/*! | |
\fn bool QWidget::isDialog() const | |
Use windowType() == Qt::Dialog instead. | |
*/ | |
/*! | |
\fn bool QWidget::isPopup() const | |
Use windowType() == Qt::Popup instead. | |
*/ | |
/*! | |
\fn bool QWidget::isDesktop() const | |
Use windowType() == Qt::Desktop instead. | |
*/ | |
/*! | |
\fn void QWidget::polish() | |
Use ensurePolished() instead. | |
*/ | |
/*! | |
\fn QWidget *QWidget::childAt(int x, int y, bool includeThis) const | |
Use the childAt() overload that doesn't have an \a includeThis parameter. | |
\oldcode | |
return widget->childAt(x, y, true); | |
\newcode | |
QWidget *child = widget->childAt(x, y, true); | |
if (child) | |
return child; | |
if (widget->rect().contains(x, y)) | |
return widget; | |
\endcode | |
*/ | |
/*! | |
\fn void QWidget::setSizePolicy(QSizePolicy::Policy hor, QSizePolicy::Policy ver, bool hfw) | |
\compat | |
Use the \l sizePolicy property and heightForWidth() function instead. | |
*/ | |
/*! | |
\fn bool QWidget::isUpdatesEnabled() const | |
\compat | |
Use the \l updatesEnabled property instead. | |
*/ | |
/*! | |
\macro QWIDGETSIZE_MAX | |
\relates QWidget | |
Defines the maximum size for a QWidget object. | |
The largest allowed size for a widget is QSize(QWIDGETSIZE_MAX, | |
QWIDGETSIZE_MAX), i.e. QSize (16777215,16777215). | |
\sa QWidget::setMaximumSize() | |
*/ | |
/*! | |
\fn QWidget::setupUi(QWidget *widget) | |
Sets up the user interface for the specified \a widget. | |
\note This function is available with widgets that derive from user | |
interface descriptions created using \l{uic}. | |
\sa {Using a Designer UI File in Your Application} | |
*/ | |
QRect QWidgetPrivate::frameStrut() const | |
{ | |
Q_Q(const QWidget); | |
if (!q->isWindow() || (q->windowType() == Qt::Desktop) || q->testAttribute(Qt::WA_DontShowOnScreen)) { | |
// x2 = x1 + w - 1, so w/h = 1 | |
return QRect(0, 0, 1, 1); | |
} | |
if (data.fstrut_dirty | |
#ifndef Q_WS_WIN | |
// ### Fix properly for 4.3 | |
&& q->isVisible() | |
#endif | |
&& q->testAttribute(Qt::WA_WState_Created)) | |
const_cast<QWidgetPrivate *>(this)->updateFrameStrut(); | |
return maybeTopData() ? maybeTopData()->frameStrut : QRect(); | |
} | |
#ifdef QT_KEYPAD_NAVIGATION | |
/*! | |
\internal | |
Changes the focus from the current focusWidget to a widget in | |
the \a direction. | |
Returns true, if there was a widget in that direction | |
*/ | |
bool QWidgetPrivate::navigateToDirection(Direction direction) | |
{ | |
QWidget *targetWidget = widgetInNavigationDirection(direction); | |
if (targetWidget) | |
targetWidget->setFocus(); | |
return (targetWidget != 0); | |
} | |
/*! | |
\internal | |
Searches for a widget that is positioned in the \a direction, starting | |
from the current focusWidget. | |
Returns the pointer to a found widget or 0, if there was no widget in | |
that direction. | |
*/ | |
QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction) | |
{ | |
const QWidget *sourceWidget = QApplication::focusWidget(); | |
if (!sourceWidget) | |
return 0; | |
const QRect sourceRect = sourceWidget->rect().translated(sourceWidget->mapToGlobal(QPoint())); | |
const int sourceX = | |
(direction == DirectionNorth || direction == DirectionSouth) ? | |
(sourceRect.left() + (sourceRect.right() - sourceRect.left()) / 2) | |
:(direction == DirectionEast ? sourceRect.right() : sourceRect.left()); | |
const int sourceY = | |
(direction == DirectionEast || direction == DirectionWest) ? | |
(sourceRect.top() + (sourceRect.bottom() - sourceRect.top()) / 2) | |
:(direction == DirectionSouth ? sourceRect.bottom() : sourceRect.top()); | |
const QPoint sourcePoint(sourceX, sourceY); | |
const QPoint sourceCenter = sourceRect.center(); | |
const QWidget *sourceWindow = sourceWidget->window(); | |
QWidget *targetWidget = 0; | |
int shortestDistance = INT_MAX; | |
foreach(QWidget *targetCandidate, QApplication::allWidgets()) { | |
const QRect targetCandidateRect = targetCandidate->rect().translated(targetCandidate->mapToGlobal(QPoint())); | |
// For focus proxies, the child widget handling the focus can have keypad navigation focus, | |
// but the owner of the proxy cannot. | |
// Additionally, empty widgets should be ignored. | |
if (targetCandidate->focusProxy() || targetCandidateRect.isEmpty()) | |
continue; | |
// Only navigate to a target widget that... | |
if ( targetCandidate != sourceWidget | |
// ...takes the focus, | |
&& targetCandidate->focusPolicy() & Qt::TabFocus | |
// ...is above if DirectionNorth, | |
&& !(direction == DirectionNorth && targetCandidateRect.bottom() > sourceRect.top()) | |
// ...is on the right if DirectionEast, | |
&& !(direction == DirectionEast && targetCandidateRect.left() < sourceRect.right()) | |
// ...is below if DirectionSouth, | |
&& !(direction == DirectionSouth && targetCandidateRect.top() < sourceRect.bottom()) | |
// ...is on the left if DirectionWest, | |
&& !(direction == DirectionWest && targetCandidateRect.right() > sourceRect.left()) | |
// ...is enabled, | |
&& targetCandidate->isEnabled() | |
// ...is visible, | |
&& targetCandidate->isVisible() | |
// ...is in the same window, | |
&& targetCandidate->window() == sourceWindow) { | |
const int targetCandidateDistance = pointToRect(sourcePoint, targetCandidateRect); | |
if (targetCandidateDistance < shortestDistance) { | |
shortestDistance = targetCandidateDistance; | |
targetWidget = targetCandidate; | |
} | |
} | |
} | |
return targetWidget; | |
} | |
/*! | |
\internal | |
Tells us if it there is currently a reachable widget by keypad navigation in | |
a certain \a orientation. | |
If no navigation is possible, occurring key events in that \a orientation may | |
be used to interact with the value in the focused widget, even though it | |
currently has not the editFocus. | |
\sa QWidgetPrivate::widgetInNavigationDirection(), QWidget::hasEditFocus() | |
*/ | |
bool QWidgetPrivate::canKeypadNavigate(Qt::Orientation orientation) | |
{ | |
return orientation == Qt::Horizontal? | |
(QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionEast) | |
|| QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionWest)) | |
:(QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionNorth) | |
|| QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionSouth)); | |
} | |
/*! | |
\internal | |
Checks, if the \a widget is inside a QTabWidget. If is is inside | |
one, left/right key events will be used to switch between tabs in keypad | |
navigation. If there is no QTabWidget, the horizontal key events can be used | |
to | |
interact with the value in the focused widget, even though it currently has | |
not the editFocus. | |
\sa QWidget::hasEditFocus() | |
*/ | |
bool QWidgetPrivate::inTabWidget(QWidget *widget) | |
{ | |
for (QWidget *tabWidget = widget; tabWidget; tabWidget = tabWidget->parentWidget()) | |
if (qobject_cast<const QTabWidget*>(tabWidget)) | |
return true; | |
return false; | |
} | |
#endif | |
/*! | |
\preliminary | |
\since 4.2 | |
\obsolete | |
Sets the window surface to be the \a surface specified. | |
The QWidget takes will ownership of the \a surface. | |
widget itself is deleted. | |
*/ | |
void QWidget::setWindowSurface(QWindowSurface *surface) | |
{ | |
// ### createWinId() ?? | |
#ifndef Q_BACKINGSTORE_SUBSURFACES | |
if (!isTopLevel()) | |
return; | |
#endif | |
Q_D(QWidget); | |
QTLWExtra *topData = d->topData(); | |
if (topData->windowSurface == surface) | |
return; | |
QWindowSurface *oldSurface = topData->windowSurface; | |
delete topData->windowSurface; | |
topData->windowSurface = surface; | |
QWidgetBackingStore *bs = d->maybeBackingStore(); | |
if (!bs) | |
return; | |
if (isTopLevel()) { | |
if (bs->windowSurface != oldSurface && bs->windowSurface != surface) | |
delete bs->windowSurface; | |
bs->windowSurface = surface; | |
} | |
#ifdef Q_BACKINGSTORE_SUBSURFACES | |
else { | |
bs->subSurfaces.append(surface); | |
} | |
bs->subSurfaces.removeOne(oldSurface); | |
#endif | |
} | |
/*! | |
\preliminary | |
\since 4.2 | |
Returns the QWindowSurface this widget will be drawn into. | |
*/ | |
QWindowSurface *QWidget::windowSurface() const | |
{ | |
Q_D(const QWidget); | |
QTLWExtra *extra = d->maybeTopData(); | |
if (extra && extra->windowSurface) | |
return extra->windowSurface; | |
QWidgetBackingStore *bs = d->maybeBackingStore(); | |
#ifdef Q_BACKINGSTORE_SUBSURFACES | |
if (bs && bs->subSurfaces.isEmpty()) | |
return bs->windowSurface; | |
if (!isTopLevel()) { | |
const QWidget *w = parentWidget(); | |
while (w) { | |
QTLWExtra *extra = w->d_func()->maybeTopData(); | |
if (extra && extra->windowSurface) | |
return extra->windowSurface; | |
if (w->isTopLevel()) | |
break; | |
w = w->parentWidget(); | |
} | |
} | |
#endif // Q_BACKINGSTORE_SUBSURFACES | |
return bs ? bs->windowSurface : 0; | |
} | |
void QWidgetPrivate::getLayoutItemMargins(int *left, int *top, int *right, int *bottom) const | |
{ | |
if (left) | |
*left = (int)leftLayoutItemMargin; | |
if (top) | |
*top = (int)topLayoutItemMargin; | |
if (right) | |
*right = (int)rightLayoutItemMargin; | |
if (bottom) | |
*bottom = (int)bottomLayoutItemMargin; | |
} | |
void QWidgetPrivate::setLayoutItemMargins(int left, int top, int right, int bottom) | |
{ | |
if (leftLayoutItemMargin == left | |
&& topLayoutItemMargin == top | |
&& rightLayoutItemMargin == right | |
&& bottomLayoutItemMargin == bottom) | |
return; | |
Q_Q(QWidget); | |
leftLayoutItemMargin = (signed char)left; | |
topLayoutItemMargin = (signed char)top; | |
rightLayoutItemMargin = (signed char)right; | |
bottomLayoutItemMargin = (signed char)bottom; | |
q->updateGeometry(); | |
} | |
void QWidgetPrivate::setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt) | |
{ | |
Q_Q(QWidget); | |
QStyleOption myOpt; | |
if (!opt) { | |
myOpt.initFrom(q); | |
myOpt.rect.setRect(0, 0, 32768, 32768); // arbitrary | |
opt = &myOpt; | |
} | |
QRect liRect = q->style()->subElementRect(element, opt, q); | |
if (liRect.isValid()) { | |
leftLayoutItemMargin = (signed char)(opt->rect.left() - liRect.left()); | |
topLayoutItemMargin = (signed char)(opt->rect.top() - liRect.top()); | |
rightLayoutItemMargin = (signed char)(liRect.right() - opt->rect.right()); | |
bottomLayoutItemMargin = (signed char)(liRect.bottom() - opt->rect.bottom()); | |
} else { | |
leftLayoutItemMargin = 0; | |
topLayoutItemMargin = 0; | |
rightLayoutItemMargin = 0; | |
bottomLayoutItemMargin = 0; | |
} | |
} | |
// resets the Qt::WA_QuitOnClose attribute to the default value for transient widgets. | |
void QWidgetPrivate::adjustQuitOnCloseAttribute() | |
{ | |
Q_Q(QWidget); | |
if (!q->parentWidget()) { | |
Qt::WindowType type = q->windowType(); | |
if (type == Qt::Widget || type == Qt::SubWindow) | |
type = Qt::Window; | |
if (type != Qt::Widget && type != Qt::Window && type != Qt::Dialog) | |
q->setAttribute(Qt::WA_QuitOnClose, false); | |
} | |
} | |
Q_GUI_EXPORT QWidgetData *qt_qwidget_data(QWidget *widget) | |
{ | |
return widget->data; | |
} | |
Q_GUI_EXPORT QWidgetPrivate *qt_widget_private(QWidget *widget) | |
{ | |
return widget->d_func(); | |
} | |
#ifndef QT_NO_GRAPHICSVIEW | |
/*! | |
\since 4.5 | |
Returns the proxy widget for the corresponding embedded widget in a graphics | |
view; otherwise returns 0. | |
\sa QGraphicsProxyWidget::createProxyForChildWidget(), | |
QGraphicsScene::addWidget() | |
*/ | |
QGraphicsProxyWidget *QWidget::graphicsProxyWidget() const | |
{ | |
Q_D(const QWidget); | |
if (d->extra) { | |
return d->extra->proxyWidget; | |
} | |
return 0; | |
} | |
#endif | |
/*! | |
\typedef QWidgetList | |
\relates QWidget | |
Synonym for QList<QWidget *>. | |
*/ | |
#ifndef QT_NO_GESTURES | |
/*! | |
Subscribes the widget to a given \a gesture with specific \a flags. | |
\sa ungrabGesture(), QGestureEvent | |
\since 4.6 | |
*/ | |
void QWidget::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags) | |
{ | |
Q_D(QWidget); | |
d->gestureContext.insert(gesture, flags); | |
(void)QGestureManager::instance(); // create a gesture manager | |
} | |
/*! | |
Unsubscribes the widget from a given \a gesture type | |
\sa grabGesture(), QGestureEvent | |
\since 4.6 | |
*/ | |
void QWidget::ungrabGesture(Qt::GestureType gesture) | |
{ | |
Q_D(QWidget); | |
if (d->gestureContext.remove(gesture)) { | |
if (QGestureManager *manager = QGestureManager::instance()) | |
manager->cleanupCachedGestures(this, gesture); | |
} | |
} | |
#endif // QT_NO_GESTURES | |
/*! | |
\typedef WId | |
\relates QWidget | |
Platform dependent window identifier. | |
*/ | |
/*! | |
\fn void QWidget::destroy(bool destroyWindow, bool destroySubWindows) | |
Frees up window system resources. Destroys the widget window if \a | |
destroyWindow is true. | |
destroy() calls itself recursively for all the child widgets, | |
passing \a destroySubWindows for the \a destroyWindow parameter. | |
To have more control over destruction of subwidgets, destroy | |
subwidgets selectively first. | |
This function is usually called from the QWidget destructor. | |
*/ | |
/*! | |
\fn QPaintEngine *QWidget::paintEngine() const | |
Returns the widget's paint engine. | |
Note that this function should not be called explicitly by the | |
user, since it's meant for reimplementation purposes only. The | |
function is called by Qt internally, and the default | |
implementation may not always return a valid pointer. | |
*/ | |
/*! | |
\fn QPoint QWidget::mapToGlobal(const QPoint &pos) const | |
Translates the widget coordinate \a pos to global screen | |
coordinates. For example, \c{mapToGlobal(QPoint(0,0))} would give | |
the global coordinates of the top-left pixel of the widget. | |
\sa mapFromGlobal() mapTo() mapToParent() | |
*/ | |
/*! | |
\fn QPoint QWidget::mapFromGlobal(const QPoint &pos) const | |
Translates the global screen coordinate \a pos to widget | |
coordinates. | |
\sa mapToGlobal() mapFrom() mapFromParent() | |
*/ | |
/*! | |
\fn void QWidget::grabMouse() | |
Grabs the mouse input. | |
This widget receives all mouse events until releaseMouse() is | |
called; other widgets get no mouse events at all. Keyboard | |
events are not affected. Use grabKeyboard() if you want to grab | |
that. | |
\warning Bugs in mouse-grabbing applications very often lock the | |
terminal. Use this function with extreme caution, and consider | |
using the \c -nograb command line option while debugging. | |
It is almost never necessary to grab the mouse when using Qt, as | |
Qt grabs and releases it sensibly. In particular, Qt grabs the | |
mouse when a mouse button is pressed and keeps it until the last | |
button is released. | |
\note Only visible widgets can grab mouse input. If isVisible() | |
returns false for a widget, that widget cannot call grabMouse(). | |
\note \bold{(Mac OS X developers)} For \e Cocoa, calling | |
grabMouse() on a widget only works when the mouse is inside the | |
frame of that widget. For \e Carbon, it works outside the widget's | |
frame as well, like for Windows and X11. | |
\sa releaseMouse() grabKeyboard() releaseKeyboard() | |
*/ | |
/*! | |
\fn void QWidget::grabMouse(const QCursor &cursor) | |
\overload grabMouse() | |
Grabs the mouse input and changes the cursor shape. | |
The cursor will assume shape \a cursor (for as long as the mouse | |
focus is grabbed) and this widget will be the only one to receive | |
mouse events until releaseMouse() is called(). | |
\warning Grabbing the mouse might lock the terminal. | |
\note \bold{(Mac OS X developers)} See the note in QWidget::grabMouse(). | |
\sa releaseMouse(), grabKeyboard(), releaseKeyboard(), setCursor() | |
*/ | |
/*! | |
\fn void QWidget::releaseMouse() | |
Releases the mouse grab. | |
\sa grabMouse(), grabKeyboard(), releaseKeyboard() | |
*/ | |
/*! | |
\fn void QWidget::grabKeyboard() | |
Grabs the keyboard input. | |
This widget receives all keyboard events until releaseKeyboard() | |
is called; other widgets get no keyboard events at all. Mouse | |
events are not affected. Use grabMouse() if you want to grab that. | |
The focus widget is not affected, except that it doesn't receive | |
any keyboard events. setFocus() moves the focus as usual, but the | |
new focus widget receives keyboard events only after | |
releaseKeyboard() is called. | |
If a different widget is currently grabbing keyboard input, that | |
widget's grab is released first. | |
\sa releaseKeyboard() grabMouse() releaseMouse() focusWidget() | |
*/ | |
/*! | |
\fn void QWidget::releaseKeyboard() | |
Releases the keyboard grab. | |
\sa grabKeyboard(), grabMouse(), releaseMouse() | |
*/ | |
/*! | |
\fn QWidget *QWidget::mouseGrabber() | |
Returns the widget that is currently grabbing the mouse input. | |
If no widget in this application is currently grabbing the mouse, | |
0 is returned. | |
\sa grabMouse(), keyboardGrabber() | |
*/ | |
/*! | |
\fn QWidget *QWidget::keyboardGrabber() | |
Returns the widget that is currently grabbing the keyboard input. | |
If no widget in this application is currently grabbing the | |
keyboard, 0 is returned. | |
\sa grabMouse(), mouseGrabber() | |
*/ | |
/*! | |
\fn void QWidget::activateWindow() | |
Sets the top-level widget containing this widget to be the active | |
window. | |
An active window is a visible top-level window that has the | |
keyboard input focus. | |
This function performs the same operation as clicking the mouse on | |
the title bar of a top-level window. On X11, the result depends on | |
the Window Manager. If you want to ensure that the window is | |
stacked on top as well you should also call raise(). Note that the | |
window must be visible, otherwise activateWindow() has no effect. | |
On Windows, if you are calling this when the application is not | |
currently the active one then it will not make it the active | |
window. It will change the color of the taskbar entry to indicate | |
that the window has changed in some way. This is because Microsoft | |
does not allow an application to interrupt what the user is currently | |
doing in another application. | |
\sa isActiveWindow(), window(), show() | |
*/ | |
/*! | |
\fn int QWidget::metric(PaintDeviceMetric m) const | |
Internal implementation of the virtual QPaintDevice::metric() | |
function. | |
\a m is the metric to get. | |
*/ | |
/*! | |
\fn void QWidget::setMask(const QRegion ®ion) | |
\overload | |
Causes only the parts of the widget which overlap \a region to be | |
visible. If the region includes pixels outside the rect() of the | |
widget, window system controls in that area may or may not be | |
visible, depending on the platform. | |
Note that this effect can be slow if the region is particularly | |
complex. | |
\sa windowOpacity | |
*/ | |
void QWidget::setMask(const QRegion &newMask) | |
{ | |
Q_D(QWidget); | |
d->createExtra(); | |
if (newMask == d->extra->mask) | |
return; | |
#ifndef QT_NO_BACKINGSTORE | |
const QRegion oldMask(d->extra->mask); | |
#endif | |
d->extra->mask = newMask; | |
d->extra->hasMask = !newMask.isEmpty(); | |
#ifndef QT_MAC_USE_COCOA | |
if (!testAttribute(Qt::WA_WState_Created)) | |
return; | |
#endif | |
d->setMask_sys(newMask); | |
#ifndef QT_NO_BACKINGSTORE | |
if (!isVisible()) | |
return; | |
if (!d->extra->hasMask) { | |
// Mask was cleared; update newly exposed area. | |
QRegion expose(rect()); | |
expose -= oldMask; | |
if (!expose.isEmpty()) { | |
d->setDirtyOpaqueRegion(); | |
update(expose); | |
} | |
return; | |
} | |
if (!isWindow()) { | |
// Update newly exposed area on the parent widget. | |
QRegion parentExpose(rect()); | |
parentExpose -= newMask; | |
if (!parentExpose.isEmpty()) { | |
d->setDirtyOpaqueRegion(); | |
parentExpose.translate(data->crect.topLeft()); | |
parentWidget()->update(parentExpose); | |
} | |
// Update newly exposed area on this widget | |
if (!oldMask.isEmpty()) | |
update(newMask - oldMask); | |
} | |
#endif | |
} | |
/*! | |
\fn void QWidget::setMask(const QBitmap &bitmap) | |
Causes only the pixels of the widget for which \a bitmap has a | |
corresponding 1 bit to be visible. If the region includes pixels | |
outside the rect() of the widget, window system controls in that | |
area may or may not be visible, depending on the platform. | |
Note that this effect can be slow if the region is particularly | |
complex. | |
The following code shows how an image with an alpha channel can be | |
used to generate a mask for a widget: | |
\snippet doc/src/snippets/widget-mask/main.cpp 0 | |
The label shown by this code is masked using the image it contains, | |
giving the appearance that an irregularly-shaped image is being drawn | |
directly onto the screen. | |
Masked widgets receive mouse events only on their visible | |
portions. | |
\sa clearMask(), windowOpacity(), {Shaped Clock Example} | |
*/ | |
void QWidget::setMask(const QBitmap &bitmap) | |
{ | |
setMask(QRegion(bitmap)); | |
} | |
/*! | |
\fn void QWidget::clearMask() | |
Removes any mask set by setMask(). | |
\sa setMask() | |
*/ | |
void QWidget::clearMask() | |
{ | |
setMask(QRegion()); | |
} | |
/*! \fn const QX11Info &QWidget::x11Info() const | |
Returns information about the configuration of the X display used to display | |
the widget. | |
\warning This function is only available on X11. | |
*/ | |
/*! \fn Qt::HANDLE QWidget::x11PictureHandle() const | |
Returns the X11 Picture handle of the widget for XRender | |
support. Use of this function is not portable. This function will | |
return 0 if XRender support is not compiled into Qt, if the | |
XRender extension is not supported on the X11 display, or if the | |
handle could not be created. | |
*/ | |
#ifdef Q_OS_SYMBIAN | |
void QWidgetPrivate::_q_delayedDestroy(WId winId) | |
{ | |
delete winId; | |
} | |
#endif | |
#if QT_MAC_USE_COCOA | |
void QWidgetPrivate::syncUnifiedMode() { | |
// The whole purpose of this method is to keep the unifiedToolbar in sync. | |
// That means making sure we either exchange the drawing methods or we let | |
// the toolbar know that it does not require to draw the baseline. | |
Q_Q(QWidget); | |
// This function makes sense only if this is a top level | |
if(!q->isWindow()) | |
return; | |
OSWindowRef window = qt_mac_window_for(q); | |
if(changeMethods) { | |
// Ok, we are in documentMode. | |
if(originalDrawMethod) | |
qt_mac_replaceDrawRect(window, this); | |
} else { | |
if(!originalDrawMethod) | |
qt_mac_replaceDrawRectOriginal(window, this); | |
} | |
} | |
#endif // QT_MAC_USE_COCOA | |
QT_END_NAMESPACE | |
#include "moc_qwidget.cpp" | |