src/gui/kernel/qwidget.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the QtGui module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 #include "qapplication.h"
00025 #include "qapplication_p.h"
00026 #include "qbrush.h"
00027 #include "qcursor.h"
00028 #include "qdesktopwidget.h"
00029 #include "qevent.h"
00030 #include "qhash.h"
00031 #include "qlayout.h"
00032 #include "qmenu.h"
00033 #include "qmetaobject.h"
00034 #include "qpixmap.h"
00035 #include "qpointer.h"
00036 #include "qstack.h"
00037 #include "qstyle.h"
00038 #include "qstylefactory.h"
00039 #include "qvariant.h"
00040 #include "qwidget.h"
00041 #include "qstyleoption.h"
00042 #ifndef QT_NO_ACCESSIBILITY
00043 #include "qaccessible.h"
00044 #endif
00045 #if defined(Q_WS_WIN)
00046 #include "qt_windows.h"
00047 #endif
00048 #ifdef Q_WS_MAC
00049 # include "qt_mac_p.h"
00050 #endif
00051 #if defined(Q_WS_QWS)
00052 #include "qwsmanager_qws.h"
00053 #include "qpaintengine.h" // for PorterDuff
00054 #endif
00055 #include "qpainter.h"
00056 #include "qtooltip.h"
00057 #include "qwhatsthis.h"
00058 #include "qdebug.h"
00059 #include "private/qstylesheetstyle_p.h"
00060 #include "private/qstyle_p.h"
00061 #include "qinputcontext.h"
00062 
00063 #ifdef Q_WS_WIN
00064 #include <private/qwininputcontext_p.h>
00065 #endif
00066 
00067 #if defined(Q_WS_X11)
00068 #include <private/qpaintengine_x11_p.h>
00069 #include "qx11info_x11.h"
00070 #endif
00071 
00072 #ifndef Q_WS_MAC
00073 #include <private/qbackingstore_p.h>
00074 #endif
00075 
00076 #include "qwidget_p.h"
00077 #include "qaction_p.h"
00078 #include "qlayout_p.h"
00079 
00080 // widget/widget data creation count
00081 //#define QWIDGET_EXTRA_DEBUG
00082 
00083 
00084 QWidgetPrivate::QWidgetPrivate(int version) :
00085         QObjectPrivate(version), extra(0), focus_child(0)
00086         ,layout(0)
00087         ,leftmargin(0), topmargin(0), rightmargin(0), bottommargin(0)
00088         ,fg_role(QPalette::NoRole)
00089         ,bg_role(QPalette::NoRole)
00090         ,hd(0)
00091 #if defined(Q_WS_X11)
00092         ,picture(0)
00093 #elif defined(Q_WS_MAC)
00094         ,cg_hd(0)
00095 #endif
00096         ,polished(0)
00097 
00098         , size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred)
00099 {
00100     if (!qApp) {
00101         qFatal("QWidget: Must construct a QApplication before a QPaintDevice");
00102         return;
00103     }
00104 
00105     if (version != QObjectPrivateVersion)
00106         qFatal("Cannot mix incompatible Qt libraries");
00107 
00108 #ifdef QT_EXPERIMENTAL_REGIONS
00109     dirtyOpaqueChildren = true;
00110 #endif
00111 
00112     isWidget = true;
00113     memset(high_attributes, 0, sizeof(high_attributes));
00114 #ifdef QWIDGET_EXTRA_DEBUG
00115     static int count = 0;
00116     qDebug() << "widgets" << ++count;
00117 #endif
00118 }
00119 
00120 
00121 QWidgetPrivate::~QWidgetPrivate()
00122 {
00123     if (extra)
00124         deleteExtra();
00125 }
00126 
00127 
00138 void QWidgetPrivate::focusInputContext()
00139 {
00140 #ifndef QT_NO_IM
00141     Q_Q(QWidget);
00142     QInputContext *qic = q->inputContext();
00143     if (qic) {
00144   if(qic->focusWidget() != q)
00145       qic->setFocusWidget(q);
00146     }
00147 #endif // QT_NO_IM
00148 }
00149 
00153 void QWidgetPrivate::scrollChildren(int dx, int dy)
00154 {
00155     Q_Q(QWidget);
00156     if (q->children().size() > 0) {        // scroll children
00157         QPoint pd(dx, dy);
00158         QObjectList childObjects = q->children();
00159         for (int i = 0; i < childObjects.size(); ++i) { // move all children
00160             QWidget *w = qobject_cast<QWidget*>(childObjects.at(i));
00161             if (w && !w->isWindow()) {
00162                 QPoint oldp = w->pos();
00163                 QRect  r(w->pos() + pd, w->size());
00164                 w->data->crect = r;
00165 #ifndef Q_WS_QWS
00166                 w->d_func()->setWSGeometry();
00167 #endif
00168                 QMoveEvent e(r.topLeft(), oldp);
00169                 QApplication::sendEvent(w, &e);
00170             }
00171         }
00172     }
00173 }
00174 
00175 
00186 QInputContext *QWidget::inputContext()
00187 {
00188     Q_D(QWidget);
00189     if (!testAttribute(Qt::WA_InputMethodEnabled))
00190         return 0;
00191 
00192 #ifndef QT_NO_IM
00193     if (d->ic)
00194         return d->ic;
00195 #endif
00196     return qApp->inputContext();
00197 }
00198 
00205 void QWidget::setInputContext(QInputContext *context)
00206 {
00207     Q_D(QWidget);
00208     if (!testAttribute(Qt::WA_InputMethodEnabled))
00209         return;
00210 #ifndef QT_NO_IM
00211     if (d->ic)
00212   delete d->ic;
00213     d->ic = context;
00214 #endif
00215 }
00216 
00217 
00224 void QWidget::resetInputContext()
00225 {
00226     if (!hasFocus())
00227         return;
00228 #ifndef QT_NO_IM
00229     QInputContext *qic = this->inputContext();
00230     if( qic )
00231   qic->reset();
00232 #endif // QT_NO_IM
00233 }
00234 
00235 #ifdef QT_KEYPAD_NAVIGATION
00236 QPointer<QWidget> QWidgetPrivate::editingWidget;
00237 
00245 bool QWidget::hasEditFocus() const
00246 {
00247     const QWidget* w = this;
00248     while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
00249         w = w->d_func()->extra->focus_proxy;
00250     return QWidgetPrivate::editingWidget == w;
00251 }
00252 
00265 void QWidget::setEditFocus(bool on)
00266 {
00267     QWidget *f = this;
00268     while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
00269         f = f->d_func()->extra->focus_proxy;
00270 
00271     if (QWidgetPrivate::editingWidget && QWidgetPrivate::editingWidget != f)
00272         QWidgetPrivate::editingWidget->setEditFocus(false);
00273 
00274     if (on && !f->hasFocus())
00275         f->setFocus();
00276 
00277     if ((!on && !QWidgetPrivate::editingWidget)
00278         || (on && QWidgetPrivate::editingWidget == f)) {
00279         update();
00280         return;
00281     }
00282 
00283     if (!on && QWidgetPrivate::editingWidget == f) {
00284         QWidgetPrivate::editingWidget = 0;
00285         QEvent event(QEvent::LeaveEditFocus);
00286         QApplication::sendEvent(f, &event);
00287         QApplication::sendEvent(f->style(), &event);
00288     } else if (on) {
00289         QWidgetPrivate::editingWidget = f;
00290         QEvent event(QEvent::EnterEditFocus);
00291         QApplication::sendEvent(f, &event);
00292         QApplication::sendEvent(f->style(), &event);
00293     }
00294     update();
00295 }
00296 #endif
00297 
00314 bool QWidget::autoFillBackground() const
00315 {
00316     Q_D(const QWidget);
00317     return d->extra && d->extra->autoFillBackground;
00318 }
00319 
00320 void QWidget::setAutoFillBackground(bool enabled)
00321 {
00322     Q_D(QWidget);
00323     if (!d->extra)
00324         d->createExtra();
00325     if (d->extra->autoFillBackground == enabled)
00326         return;
00327 
00328     d->extra->autoFillBackground = enabled;
00329     d->updateIsOpaque();
00330     update();
00331     d->updateIsOpaque();
00332 }
00333 
00749 QWidgetMapper *QWidgetPrivate::mapper = 0;                // widget with wid
00750 QWidgetSet *QWidgetPrivate::uncreatedWidgets = 0;         // widgets with no wid
00751 
00752 
00753 /*****************************************************************************
00754   QWidget utility functions
00755  *****************************************************************************/
00756 
00757 
00758 static QFont qt_naturalWidgetFont(QWidget* w) {
00759     QFont naturalfont = QApplication::font(w);
00760     if (w->parentWidget()
00761         && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
00762         if (!naturalfont.isCopyOf(QApplication::font()))
00763             naturalfont = naturalfont.resolve(w->parentWidget()->font());
00764         else
00765             naturalfont = w->parentWidget()->font();
00766     }
00767     naturalfont.resolve(0);
00768     return naturalfont;
00769 }
00770 
00771 static QPalette qt_naturalWidgetPalette(QWidget* w) {
00772     QPalette naturalpalette = QApplication::palette(w);
00773     if (w->parentWidget()
00774         && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
00775         if (!naturalpalette.isCopyOf(QApplication::palette()))
00776             naturalpalette = naturalpalette.resolve(w->parentWidget()->palette());
00777         else
00778             naturalpalette = w->parentWidget()->palette();
00779     }
00780     naturalpalette.resolve(0);
00781     return naturalpalette;
00782 }
00783 
00784 /*****************************************************************************
00785   QWidget member functions
00786  *****************************************************************************/
00787 
00788 /*
00789     Widget state flags:
00790   \list
00791   \i Qt::WA_WState_Created The widget has a valid winId().
00792   \i Qt::WA_WState_Visible The widget is currently visible.
00793   \i Qt::WA_WState_Hidden The widget is hidden, i.e. it won't
00794   become visible unless you call show() on it. Qt::WA_WState_Hidden
00795   implies !Qt::WA_WState_Visible.
00796   \i Qt::WA_WState_CompressKeys Compress keyboard events.
00797   \i Qt::WA_WState_BlockUpdates Repaints and updates are disabled.
00798   \i Qt::WA_WState_InPaintEvent Currently processing a paint event.
00799   \i Qt::WA_WState_Reparented The widget has been reparented.
00800   \i Qt::WA_WState_ConfigPending A configuration (resize/move) event is pending.
00801   \i Qt::WA_WState_DND (Deprecated) The widget supports drag and drop, see setAcceptDrops().
00802   \endlist
00803 */
00804 
00831 QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
00832     : QObject(*new QWidgetPrivate, 0), QPaintDevice()
00833 {
00834     d_func()->init(parent, f);
00835 }
00836 
00837 #ifdef QT3_SUPPORT
00838 
00842 QWidget::QWidget(QWidget *parent, const char *name, Qt::WindowFlags f)
00843     : QObject(*new QWidgetPrivate, 0), QPaintDevice()
00844 {
00845     d_func()->init(parent , f);
00846     setObjectName(QString::fromAscii(name));
00847 }
00848 #endif
00849 
00852 QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f)
00853     : QObject(dd, 0), QPaintDevice()
00854 {
00855     d_func()->init(parent, f);
00856 }
00857 
00861 int QWidget::devType() const
00862 {
00863     return QInternal::Widget;
00864 }
00865 
00866 
00867 //### w is a "this" ptr, passed as a param because QWorkspace needs special logic
00868 void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w)
00869 {
00870     bool customize =  (flags & (Qt::CustomizeWindowHint
00871             | Qt::FramelessWindowHint
00872             | Qt::WindowTitleHint
00873             | Qt::WindowSystemMenuHint
00874             | Qt::WindowMinimizeButtonHint
00875             | Qt::WindowMaximizeButtonHint
00876             | Qt::WindowContextHelpButtonHint));
00877 
00878     uint type = (flags & Qt::WindowType_Mask);
00879 
00880     if ((type == Qt::Widget || type == Qt::SubWindow) && w && !w->parent()) {
00881         type = Qt::Window;
00882         flags |= Qt::Window;
00883     }
00884 
00885     if (customize)
00886         ;
00887     else if (type == Qt::Dialog || type == Qt::Sheet)
00888         flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowContextHelpButtonHint;
00889     else if (type == Qt::Tool)
00890         flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint;
00891     else
00892         flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint;
00893 
00894 
00895 }
00896 
00897 void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
00898 {
00899     Q_Q(QWidget);
00900     if (qApp->type() == QApplication::Tty)
00901         qFatal("QWidget: Cannot create a QWidget when no GUI is being used");
00902 
00903     Q_ASSERT(uncreatedWidgets);
00904     uncreatedWidgets->insert(q);
00905 
00906     QWidget *desktopWidget = 0;
00907     if (parentWidget && parentWidget->windowType() == Qt::Desktop) {
00908         desktopWidget = parentWidget;
00909         parentWidget = 0;
00910     }
00911 
00912     q->data = &data;
00913 
00914 #ifndef QT_NO_THREAD
00915     if (!q->parent()) {
00916         Q_ASSERT_X(q->thread() == qApp->thread(), "QWidget",
00917                    "Widgets must be created in the GUI thread.");
00918     }
00919 #endif
00920 
00921 #if defined(Q_WS_X11)
00922     if (desktopWidget) {
00923         // make sure the widget is created on the same screen as the
00924         // programmer specified desktop widget
00925         xinfo = desktopWidget->d_func()->xinfo;
00926     }
00927 #else
00928     Q_UNUSED(desktopWidget);
00929 #endif
00930 
00931     data.fstrut_dirty = true;
00932 
00933     data.winid = 0;
00934     data.widget_attributes = 0;
00935     data.window_flags = f;
00936     data.window_state = 0;
00937     data.focus_policy = 0;
00938     data.context_menu_policy = Qt::DefaultContextMenu;
00939     data.window_modality = Qt::NonModal;
00940 
00941     data.sizehint_forced = 0;
00942     data.is_closing = 0;
00943     data.in_show = 0;
00944     data.in_set_window_state = 0;
00945 
00946     q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in create()
00947 
00948     q->setAttribute(Qt::WA_WState_Hidden);
00949 
00950     //give potential windows a bigger "pre-initial" size; create_sys() will give them a new size later
00951     data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,640,480);
00952 
00953     focus_next = focus_prev = q;
00954 
00955     if ((f & Qt::WindowType_Mask) == Qt::Desktop)
00956         q->create();
00957     else if (parentWidget)
00958         q->setParent(parentWidget, data.window_flags);
00959     else {
00960         adjustFlags(data.window_flags, q);
00961         resolveLayoutDirection();
00962     }
00963 #if defined(Q_WS_X11)
00964     data.fnt.x11SetScreen(xinfo.screen());
00965 #endif // Q_WS_X11
00966 
00967     q->setAttribute(Qt::WA_PendingMoveEvent);
00968     q->setAttribute(Qt::WA_PendingResizeEvent);
00969 
00970     if (++QWidgetPrivate::instanceCounter > QWidgetPrivate::maxInstances)
00971         QWidgetPrivate::maxInstances = QWidgetPrivate::instanceCounter;
00972 
00973     if (QApplicationPrivate::app_compile_version < 0x040200
00974         || QApplicationPrivate::testAttribute(Qt::AA_ImmediateWidgetCreation)
00975         || (f & Qt::X11BypassWindowManagerHint))
00976         q->create();
00977 
00978 
00979     QEvent e(QEvent::Create);
00980     QApplication::sendEvent(q, &e);
00981     QApplication::postEvent(q, new QEvent(QEvent::PolishRequest));
00982 
00983     extraPaintEngine = 0;
00984 }
00985 
00986 
00987 
00988 void QWidgetPrivate::createRecursively()
00989 {
00990     Q_Q(QWidget);
00991     q->create(0, true, true);
00992     for (int i = 0; i < children.size(); ++i) {
00993         QWidget *child = qobject_cast<QWidget *>(children.at(i));
00994         if (child && !child->isHidden() && !child->isWindow() && !child->testAttribute(Qt::WA_WState_Created))
00995             child->d_func()->createRecursively();
00996     }
00997 }
00998 
00999 
01000 
01001 
01019 void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
01020 {
01021     Q_D(QWidget);
01022     if (testAttribute(Qt::WA_WState_Created) && window == 0)
01023         return;
01024 
01025     Qt::WindowType type = windowType();
01026     Qt::WindowFlags &flags = data->window_flags;
01027 
01028     if ((type == Qt::Widget || type == Qt::SubWindow) && !parentWidget()) {
01029         type = Qt::Window;
01030         flags |= Qt::Window;
01031     }
01032 
01033     if (parentWidget() && (type & Qt::Window) && !parentWidget()->testAttribute(Qt::WA_WState_Created) && !isModal())
01034         parentWidget()->createWinId();
01035 
01036 #ifdef QT3_SUPPORT
01037     if (flags & Qt::WStaticContents)
01038         setAttribute(Qt::WA_StaticContents);
01039     if (flags & Qt::WDestructiveClose)
01040   setAttribute(Qt::WA_DeleteOnClose);
01041     if (flags & Qt::WShowModal)
01042         setWindowModality(Qt::ApplicationModal);
01043     if (flags & Qt::WMouseNoMask)
01044   setAttribute(Qt::WA_MouseNoMask);
01045     if (flags & Qt::WGroupLeader)
01046   setAttribute(Qt::WA_GroupLeader);
01047     if (flags & Qt::WNoMousePropagation)
01048   setAttribute(Qt::WA_NoMousePropagation);
01049 #endif
01050 
01051     if ( type != Qt::Widget && type != Qt::Window && type != Qt::Dialog)
01052         setAttribute(Qt::WA_QuitOnClose, false);
01053 
01054     setAttribute(Qt::WA_WState_Created);                        // set created flag
01055     d->create_sys(window, initializeWindow, destroyOldWindow);
01056 
01057     // a real toplevel window needs a backing store
01058 #ifndef Q_WS_MAC
01059     if (isWindow()) {
01060         delete d->topData()->backingStore;
01061         d->topData()->backingStore = new QWidgetBackingStore(this);
01062     }
01063 #endif
01064 
01065     d->setModal_sys();
01066 
01067     if (!isWindow() && parentWidget() && parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))
01068         setAttribute(Qt::WA_DropSiteRegistered, true);
01069 
01070 #ifdef QT_EVAL
01071     extern void qt_eval_init_widget(QWidget *w);
01072     qt_eval_init_widget(this);
01073 #endif
01074 
01075     // need to force the resting of the icon after changing parents
01076     if (testAttribute(Qt::WA_SetWindowIcon))
01077         d->setWindowIcon_sys(true);
01078     if (isWindow() && !d->topData()->iconText.isEmpty())
01079         d->setWindowIconText_helper(d->topData()->iconText);
01080     if (windowType() != Qt::Desktop) {
01081         d->updateSystemBackground();
01082 
01083         if (isWindow() && !testAttribute(Qt::WA_SetWindowIcon))
01084             d->setWindowIcon_sys();
01085     }
01086     if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden))
01087         d->hide_helper();
01088 }
01089 
01097 QWidget::~QWidget()
01098 {
01099     Q_D(QWidget);
01100 #if defined (QT_CHECK_STATE)
01101     if (paintingActive())
01102         qWarning("QWidget: %s (%s) deleted while being painted", className(), name());
01103 #endif
01104 
01105     // force acceptDrops false before winId is destroyed.
01106     d->registerDropSite(false);
01107 
01108 #ifndef QT_NO_ACTION
01109     // remove all actions from this widget
01110     for (int i = 0; i < d->actions.size(); ++i) {
01111         QActionPrivate *apriv = d->actions.at(i)->d_func();
01112         apriv->widgets.removeAll(this);
01113     }
01114     d->actions.clear();
01115 #endif
01116 
01117 #ifndef QT_NO_SHORTCUT
01118     // Remove all shortcuts grabbed by this
01119     // widget, unless application is closing
01120     if (!QApplicationPrivate::is_app_closing && testAttribute(Qt::WA_GrabbedShortcut))
01121         qApp->d_func()->shortcutMap.removeShortcut(0, this, QKeySequence());
01122 #endif
01123 
01124     // delete layout while we still are a valid widget
01125     delete d->layout;
01126     // Remove myself from focus list
01127 
01128     Q_ASSERT(d->focus_next->d_func()->focus_prev == this);
01129     Q_ASSERT(d->focus_prev->d_func()->focus_next == this);
01130 
01131     if (d->focus_next != this) {
01132         d->focus_next->d_func()->focus_prev = d->focus_prev;
01133         d->focus_prev->d_func()->focus_next = d->focus_next;
01134         d->focus_next = d->focus_prev = 0;
01135     }
01136 
01137 #ifdef QT3_SUPPORT
01138     if (QApplicationPrivate::main_widget == this) {        // reset main widget
01139         QApplicationPrivate::main_widget = 0;
01140         qApp->quit();
01141     }
01142 #endif
01143 
01144     clearFocus();
01145 
01146     if (isWindow() && isVisible() && internalWinId())
01147         hide();
01148 
01149     // set all QPointers for this object to zero
01150     QObjectPrivate::clearGuards(this);
01151 
01152     if (!d->children.isEmpty())
01153         d->deleteChildren();
01154 
01155     QApplication::removePostedEvents(this);
01156 
01157     destroy();                                        // platform-dependent cleanup
01158 
01159     --QWidgetPrivate::instanceCounter;
01160 
01161     if (QWidgetPrivate::uncreatedWidgets) // might have been deleted by ~QApplication
01162         QWidgetPrivate::uncreatedWidgets->remove(this);
01163 
01164     QEvent e(QEvent::Destroy);
01165     QCoreApplication::sendEvent(this, &e);
01166 }
01167 
01168 int QWidgetPrivate::instanceCounter = 0;  // Current number of widget instances
01169 int QWidgetPrivate::maxInstances = 0;     // Maximum number of widget instances
01170 
01171 void QWidgetPrivate::setWinId(WId id)                // set widget identifier
01172 {
01173     Q_Q(QWidget);
01174     if (mapper && data.winid) {
01175         mapper->remove(data.winid);
01176         uncreatedWidgets->insert(q);
01177     }
01178 
01179     data.winid = id;
01180 #if defined(Q_WS_X11)
01181     hd = id; // X11: hd == ident
01182 #endif
01183     if (mapper && id) {
01184         mapper->insert(data.winid, q);
01185         uncreatedWidgets->remove(q);
01186     }
01187 }
01188 
01189 void QWidgetPrivate::createTLExtra()
01190 {
01191     if (!extra)
01192         createExtra();
01193     if (!extra->topextra) {
01194         QTLWExtra* x = extra->topextra = new QTLWExtra;
01195         x->windowSurface = 0;
01196         x->opacity = 255;
01197         x->posFromMove = false;
01198         x->icon = 0;
01199         x->iconPixmap = 0;
01200         x->frameStrut.setCoords(0, 0, 0, 0);
01201         x->incw = x->inch = 0;
01202         x->basew = x->baseh = 0;
01203         x->normalGeometry = QRect(0,0,-1,-1);
01204 #if defined(Q_WS_X11)
01205         x->embedded = 0;
01206         x->parentWinId = 0;
01207         x->spont_unmapped = 0;
01208         x->dnd = 0;
01209 #endif
01210         x->savedFlags = 0;
01211 #if defined(Q_WS_QWS)
01212         x->inPaintTransaction = false;
01213         x->backingStore = 0;
01214 #if !defined(QT_NO_QWS_MANAGER)
01215         x->qwsManager = 0;
01216 #endif
01217 #endif
01218         createTLSysExtra();
01219 #ifdef QWIDGET_EXTRA_DEBUG
01220     static int count = 0;
01221     qDebug() << "tlextra" << ++count;
01222 #endif
01223     }
01224 }
01225 
01231 void QWidgetPrivate::createExtra()
01232 {
01233     if (!extra) {                                // if not exists
01234         extra = new QWExtra;
01235         extra->minw = extra->minh = 0;
01236         extra->maxw = extra->maxh = QWIDGETSIZE_MAX;
01237         extra->explicitMinSize = 0;
01238         extra->autoFillBackground = 0;
01239 #ifndef QT_NO_CURSOR
01240         extra->curs = 0;
01241 #endif
01242         extra->style = 0;
01243         extra->topextra = 0;
01244         createSysExtra();
01245 #ifdef QWIDGET_EXTRA_DEBUG
01246     static int count = 0;
01247     qDebug() << "extra" << ++count;
01248 #endif
01249     }
01250 }
01251 
01252 
01258 void QWidgetPrivate::deleteExtra()
01259 {
01260     if (extra) {                                // if exists
01261 #ifndef QT_NO_CURSOR
01262         delete extra->curs;
01263 #endif
01264         deleteSysExtra();
01265         if (extra->topextra) {
01266             deleteTLSysExtra();
01267             delete extra->topextra->icon;
01268             delete extra->topextra->iconPixmap;
01269 #if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER)
01270             delete extra->topextra->qwsManager;
01271 #endif
01272             delete extra->topextra;
01273         }
01274         delete extra;
01275         // extra->xic destroyed in QWidget::destroy()
01276         extra = 0;
01277     }
01278 }
01279 
01280 /*
01281   Returns true if the background is inherited; otherwise returns
01282   false.
01283 
01284   Mainly used in the paintOnScreen case.
01285 */
01286 
01287 bool QWidgetPrivate::isBackgroundInherited() const
01288 {
01289     Q_Q(const QWidget);
01290 
01291     // windows do not inherit their background
01292     if (q->isWindow() || q->windowType() == Qt::SubWindow)
01293         return false;
01294 
01295     if (q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_OpaquePaintEvent))
01296         return false;
01297 
01298     const QPalette &pal = q->palette();
01299     QPalette::ColorRole bg = q->backgroundRole();
01300     QBrush brush = pal.brush(bg);
01301 
01302     // non opaque brushes leaves us no choice, we must inherit
01303     if (!q->autoFillBackground() || !brush.isOpaque())
01304         return true;
01305 
01306     if (brush.style() == Qt::SolidPattern) {
01307         // the background is just a solid color. If there is no
01308         // propagated contents, then we claim as performance
01309         // optimization that it was not inheritet. This is the normal
01310         // case in standard Windows or Motif style.
01311         const QWidget *w = q->parentWidget();
01312         if (!w->d_func()->isBackgroundInherited())
01313             return false;
01314     }
01315 
01316     return true;
01317 }
01318 
01319 #ifndef Q_WS_MAC
01320 /*
01321   Returns true if there are widgets above this which overlap with
01322   \a rect, which is in parent's coordinate system (same as crect).
01323 */
01324 
01325 bool QWidgetPrivate::isOverlapped(const QRect &rect) const
01326 {
01327     Q_Q(const QWidget);
01328 
01329     const QWidget *w = q;
01330     QRect r = rect;
01331     while (w) {
01332         if (w->isWindow())
01333             return false;
01334         QWidgetPrivate *pd = w->parentWidget()->d_func();
01335         bool above = false;
01336         for (int i = 0; i < pd->children.size(); ++i) {
01337             QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i));
01338             if (!sibling || !sibling->isVisible() || sibling->isWindow())
01339                 continue;
01340             if (!above) {
01341                 above = (sibling == w);
01342                 continue;
01343             }
01344             if (sibling->data->crect.intersects(r))
01345                 return true;
01346         }
01347         w = w->parentWidget();
01348         r.translate(pd->data.crect.topLeft());
01349     }
01350     return false;
01351 }
01352 #endif
01353 
01354 void QWidgetPrivate::setUpdatesEnabled_helper(bool enable)
01355 {
01356     Q_Q(QWidget);
01357 
01358     if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->updatesEnabled())
01359         return; // nothing we can do
01360 
01361     if (enable != q->testAttribute(Qt::WA_UpdatesDisabled))
01362         return; // nothing to do
01363 
01364     q->setAttribute(Qt::WA_UpdatesDisabled, !enable);
01365     if (enable)
01366         q->update();
01367 
01368     Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceUpdatesDisabled : Qt::WA_UpdatesDisabled;
01369     for (int i = 0; i < children.size(); ++i) {
01370         QWidget *w = qobject_cast<QWidget *>(children.at(i));
01371         if (w && !w->isWindow() && !w->testAttribute(attribute))
01372             w->d_func()->setUpdatesEnabled_helper(enable);
01373     }
01374 }
01375 
01376 void QWidgetPrivate::propagatePaletteChange()
01377 {
01378     Q_Q(QWidget);
01379     QEvent pc(QEvent::PaletteChange);
01380     QApplication::sendEvent(q, &pc);
01381     if(!children.isEmpty()) {
01382         for(int i = 0; i < children.size(); ++i) {
01383             QWidget *w = qobject_cast<QWidget*>(children.at(i));
01384             if (w && (!w->isWindow()
01385                       || w->testAttribute(Qt::WA_WindowPropagation)))
01386                 w->d_func()->resolvePalette();
01387         }
01388     }
01389 #if defined(QT3_SUPPORT)
01390     q->paletteChange(q->palette()); // compatibility
01391 #endif
01392 }
01393 
01394 /*
01395   Returns the widget's clipping rectangle.
01396 */
01397 QRect QWidgetPrivate::clipRect() const
01398 {
01399     Q_Q(const QWidget);
01400     const QWidget * w = q;
01401     if (!w->isVisible())
01402         return QRect();
01403     QRect r = q->rect();
01404     int ox = 0;
01405     int oy = 0;
01406     while (w
01407             && w->isVisible()
01408             && !w->isWindow()
01409             && w->parentWidget()) {
01410         ox -= w->x();
01411         oy -= w->y();
01412         w = w->parentWidget();
01413         r &= QRect(ox, oy, w->width(), w->height());
01414     }
01415     return r;
01416 }
01417 
01418 /*
01419   Returns the widget's clipping region (without siblings).
01420 */
01421 QRegion QWidgetPrivate::clipRegion() const
01422 {
01423     Q_Q(const QWidget);
01424     if (!q->isVisible())
01425         return QRegion();
01426     QRegion r(q->rect());
01427     const QWidget * w = q;
01428     const QWidget *ignoreUpTo;
01429     int ox = 0;
01430     int oy = 0;
01431     while (w
01432            && w->isVisible()
01433            && !w->isWindow()
01434            && w->parentWidget()) {
01435         ox -= w->x();
01436         oy -= w->y();
01437         ignoreUpTo = w;
01438         w = w->parentWidget();
01439         r &= QRegion(ox, oy, w->width(), w->height());
01440 
01441         int i = 0;
01442         while(w->d_func()->children.at(i++) != static_cast<const QObject *>(ignoreUpTo))
01443             ;
01444         for ( ; i < w->d_func()->children.size(); ++i) {
01445             if(QWidget *sibling = qobject_cast<QWidget *>(w->d_func()->children.at(i))) {
01446                 if(sibling->isVisible() && !sibling->isWindow()) {
01447                     QRect siblingRect(ox+sibling->x(), oy+sibling->y(),
01448                                       sibling->width(), sibling->height());
01449                     if(siblingRect.intersects(q->rect()))
01450                         r -= QRegion(siblingRect);
01451                 }
01452             }
01453         }
01454     }
01455     return r;
01456 }
01457 
01458 #ifdef QT_EXPERIMENTAL_REGIONS
01459 void QWidgetPrivate::setDirtyOpaqueRegion()
01460 {
01461     Q_Q(QWidget);
01462 
01463     dirtyOpaqueChildren = true;
01464 
01465     QWidget *parent = q->parentWidget();
01466     if (!parent || parent->isWindow())
01467         return;
01468 
01469     // TODO: instead of setting dirtyflag, manipulate the dirtyregion directly?
01470     QWidgetPrivate *pd = parent->d_func();
01471     if (!pd->dirtyOpaqueChildren)
01472         pd->setDirtyOpaqueRegion();
01473 }
01474 
01475 QRegion QWidgetPrivate::getOpaqueRegion() const
01476 {
01477     Q_Q(const QWidget);
01478 
01479     QRegion clip = q->rect();
01480     if (extra && !extra->mask.isEmpty())
01481         clip &= extra->mask;
01482 
01483     if (isOpaque())
01484         return clip;
01485 
01486     return getOpaqueChildren();
01487 }
01488 
01489 QRegion QWidgetPrivate::getOpaqueChildren() const
01490 {
01491     if (!dirtyOpaqueChildren)
01492         return opaqueChildren;
01493 
01494     opaqueChildren = QRegion();
01495 
01496     for (int i = 0; i < children.size(); ++i) {
01497         QWidget *child = qobject_cast<QWidget *>(children.at(i));
01498         if (!child || !child->isVisible() || child->isWindow())
01499             continue;
01500 
01501         const QPoint offset = child->geometry().topLeft();
01502         opaqueChildren += child->d_func()->getOpaqueRegion().translated(offset);
01503     }
01504 
01505     dirtyOpaqueChildren = false;
01506 
01507     return opaqueChildren;
01508 }
01509 
01510 void QWidgetPrivate::subtractOpaqueChildren(QRegion &rgn, const QRegion &clipRgn, const QPoint &offset, int startIdx) const
01511 {
01512     Q_UNUSED(startIdx);
01513 
01514     const QRegion r = getOpaqueChildren();
01515     if (!r.isEmpty())
01516         rgn -= (r.translated(offset) & clipRgn);
01517 }
01518 
01519 
01520 void QWidgetPrivate::subtractOpaqueSiblings(QRegion &rgn, const QPoint &offset) const
01521 {
01522     Q_UNUSED(rgn);
01523     Q_UNUSED(offset);
01524 }
01525 
01526 #else
01527 void QWidgetPrivate::subtractOpaqueChildren(QRegion &rgn, const QRegion &clipRgn, const QPoint &offset, int startIdx) const
01528 {
01529     for (int i=startIdx; i < children.size(); ++i) {
01530         if (QWidget *child = qobject_cast<QWidget *>(children.at(i))) {
01531             if (child->isVisible() && !child->isWindow()) {
01532                 QRegion childRgn = clipRgn & child->geometry().translated(offset);
01533                 QWidgetPrivate *cd = child->d_func();
01534                 if (cd->extra && !cd->extra->mask.isEmpty())
01535                     childRgn &= cd->extra->mask.translated(offset + cd->data.crect.topLeft());
01536 
01537                 if (childRgn.isEmpty())
01538                     continue;
01539 
01540                 if (cd->isOpaque())
01541                     rgn -= childRgn;
01542                 else
01543                     cd->subtractOpaqueChildren(rgn, childRgn, offset + child->geometry().topLeft());
01544             }
01545         }
01546     }
01547 }
01548 
01549 //subtract any relatives that are higher up than me --- is this too expensive ???
01550 
01551 void QWidgetPrivate::subtractOpaqueSiblings(QRegion &rgn, const QPoint &offset) const
01552 {
01553     Q_Q(const QWidget);
01554 
01555     if (q->isWindow())
01556         return;
01557 
01558     QPoint myOffset = offset - q->data->crect.topLeft();
01559     const QWidgetPrivate *pd = q->parentWidget()->d_func();
01560     pd->subtractOpaqueSiblings(rgn, myOffset);
01561     int idx = pd->children.indexOf(const_cast<QWidget*>(q)) + 1; // argh, list<QObject*> is not compatible with const QObject*
01562     pd->subtractOpaqueChildren(rgn, q->rect(), myOffset, idx);
01563 }
01564 
01565 #endif // QT_EXPERIMENTAL_REGIONS
01566 
01567 bool QWidgetPrivate::hasBackground() const
01568 {
01569     Q_Q(const QWidget);
01570     if (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_PaintOnScreen))
01571         return true;
01572     if (q->testAttribute(Qt::WA_PaintOnScreen))
01573         return true;
01574     if (!q->testAttribute(Qt::WA_OpaquePaintEvent) && !q->testAttribute(Qt::WA_NoSystemBackground)) {
01575         const QPalette &pal = q->palette();
01576         QPalette::ColorRole bg = q->backgroundRole();
01577         QBrush bgBrush = pal.brush(bg);
01578         return (bgBrush.style() != Qt::NoBrush &&
01579                 ((q->isWindow() || q->windowType() == Qt::SubWindow)
01580                  || (QPalette::ColorRole(bg_role) != QPalette::NoRole || (pal.resolve() & (1<<bg)))));
01581     }
01582     return false;
01583 }
01584 
01585 void QWidgetPrivate::updateIsOpaque()
01586 {
01587 #ifdef Q_WS_MAC
01588     Q_Q(QWidget);
01589     extern void qt_mac_set_widget_is_opaque(QWidget*, bool); //qwidget_mac.cpp
01590     qt_mac_set_widget_is_opaque(q, isOpaque());
01591 #endif
01592 }
01593 
01594 bool QWidgetPrivate::isOpaque() const
01595 {
01596     Q_Q(const QWidget);
01597 #ifdef Q_WS_X11
01598     if (q->testAttribute(Qt::WA_X11OpenGLOverlay))
01599   return false;
01600 #endif
01601     if (q->testAttribute(Qt::WA_OpaquePaintEvent)
01602         || q->testAttribute(Qt::WA_PaintOnScreen)
01603         || q->testAttribute(Qt::WA_NoSystemBackground))
01604         return true;
01605 
01606     if (!q->autoFillBackground())
01607         return false;
01608 
01609     const QPalette &pal = q->palette();
01610     QPalette::ColorRole bg = q->backgroundRole();
01611     QBrush bgBrush = pal.brush(bg);
01612     return bgBrush.style() != Qt::NoBrush && bgBrush.isOpaque();
01613 }
01614 
01628 void QPixmap::fill( const QWidget *widget, const QPoint &off )
01629 {
01630     QPainter p(this);
01631     p.translate(-off);
01632     widget->d_func()->paintBackground(&p, QRect(off, size()));
01633 
01634 }
01635 
01636 #ifdef Q_WS_MAC
01637 /*
01638   Fills \a buf with \a r in \a widget. Then blits \a buf on \a res at
01639   position \a offset
01640  */
01641 void QPixmap::grabWidget_helper(QWidget *widget, QPixmap &res, QPixmap &buf,
01642                                 const QRect &r, const QPoint &offset, bool asRoot)
01643 {
01644     if(asRoot || widget->d_func()->hasBackground()) {
01645         buf.fill(widget, r.topLeft());
01646     } else {
01647         QPainter p(&buf);
01648         p.drawPixmap(0, 0, res, r.x()+offset.x(), r.y()+offset.y(), r.width(), r.height());
01649     }
01650 
01651     QPainter::setRedirected(widget, &buf, r.topLeft());
01652     QPaintEvent e(r & widget->rect());
01653     QApplication::sendEvent(widget, &e);
01654     QPainter::restoreRedirected(widget);
01655     {
01656         QPainter pt(&res);
01657         pt.drawPixmap(offset.x(), offset.y(), buf, 0, 0, r.width(), r.height());
01658     }
01659 
01660     const QObjectList children = widget->children();
01661     for (int i = 0; i < children.size(); ++i) {
01662         QWidget *child = static_cast<QWidget*>(children.at(i));
01663         if (!child->isWidgetType() || child->isWindow()
01664             || child->isHidden() || !child->geometry().intersects(r))
01665             continue;
01666         QRect cr = r & child->geometry();
01667         cr.translate(-child->pos());
01668         grabWidget_helper(child, res, buf, cr, offset + child->pos(), false);
01669     }
01670 }
01671 #endif
01672 
01673 void QWidgetPrivate::paintBackground(QPainter *painter, const QRect &rect, bool asRoot) const
01674 {
01675 #define FILL_RECT_WORKAROUND(painter, rect, brush)              \
01676     if (brush.style() == Qt::TexturePattern)                    \
01677         painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft()); \
01678     else                                                        \
01679         painter->fillRect(rect, brush);
01680 
01681     Q_Q(const QWidget);
01682 
01683     const QBrush autoFillBrush = q->palette().brush(q->backgroundRole());
01684 
01685     if (asRoot && !(q->autoFillBackground() && autoFillBrush.isOpaque())) {
01686         const QBrush bg = q->palette().brush(QPalette::Window);
01687 #ifdef Q_WS_QWS
01688         if (painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff))
01689             painter->setCompositionMode(QPainter::CompositionMode_Source); //copy alpha straight in
01690 #endif
01691 
01692         FILL_RECT_WORKAROUND(painter, rect, bg);
01693     }
01694 
01695     if (q->autoFillBackground()) {
01696         FILL_RECT_WORKAROUND(painter, rect, autoFillBrush);
01697     }
01698 }
01699 
01700 
01708 void QWidgetPrivate::deactivateWidgetCleanup()
01709 {
01710     Q_Q(QWidget);
01711     // If this was the active application window, reset it
01712     if (qApp->activeWindow() == q)
01713         qApp->setActiveWindow(0);
01714     // If the is the active mouse press widget, reset it
01715 #ifdef Q_WS_MAC
01716     extern QPointer<QWidget> qt_button_down;
01717 #else
01718     extern QWidget *qt_button_down;
01719 #endif
01720     if (q == qt_button_down)
01721         qt_button_down = 0;
01722 }
01723 
01724 
01734 QWidget *QWidget::find(WId id)
01735 {
01736     return QWidgetPrivate::mapper ? QWidgetPrivate::mapper->value(id, 0) : 0;
01737 }
01738 
01739 
01740 
01760 WId QWidget::winId() const
01761 {
01762     if (!testAttribute(Qt::WA_WState_Created)) {
01763         QWidget *that = const_cast<QWidget*>(this);
01764         that->d_func()->createWinId();
01765         return that->data->winid;
01766     }
01767     return data->winid;
01768 }
01769 
01770 
01771 void QWidgetPrivate::createWinId(WId winid)
01772 {
01773     Q_Q(QWidget);
01774     if (!q->testAttribute(Qt::WA_WState_Created)) {
01775         if (!q->isWindow()) {
01776             QWidgetPrivate *pd = q->parentWidget()->d_func();
01777             if (!q->parentWidget()->testAttribute(Qt::WA_WState_Created))
01778                 pd->createWinId();
01779 
01780             for (int i = 0; i < pd->children.size(); ++i) {
01781                 QWidget *w = qobject_cast<QWidget *>(pd->children.at(i));
01782                 if (w && !w->isWindow() && !w->testAttribute(Qt::WA_WState_Created))
01783                     if (w!=q) {
01784                         w->create();
01785                     } else {
01786                         w->create(winid);
01787                         // if the window has already been created, we
01788                         // need to raise it to its proper stacking position
01789                         if (winid)
01790                             w->raise();
01791                     }
01792             }
01793         } else {
01794             q->create();
01795         }
01796     }
01797 }
01798 
01799 
01806 void QWidget::createWinId()
01807 {
01808     Q_D(QWidget);
01809 //    qWarning("QWidget::createWinId is obsolete, please fix your code.");
01810     d->createWinId();
01811 }
01812 
01813 #ifndef QT_NO_STYLE_STYLESHEET
01814 
01822 QString QWidget::styleSheet() const
01823 {
01824     Q_D(const QWidget);
01825     if (!d->extra)
01826         return QString();
01827     return d->extra->styleSheet;
01828 }
01829 
01830 void QWidget::setStyleSheet(const QString& styleSheet)
01831 {
01832     Q_D(QWidget);
01833     d->createExtra();
01834 
01835     QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(d->extra->style);
01836     d->extra->styleSheet = styleSheet;
01837     if (styleSheet.isEmpty()) { // stylesheet removed
01838         if (!proxy) {
01839             if (qApp->styleSheet().isEmpty())
01840                 return; // no stylesheet here or on the app. what's the story?
01841             // will go down and set the right style
01842         } else {
01843             // we had a proxy before but now our stylesheet is empty. recheck if we need a proxy
01844             d->inheritStyle();
01845             return;
01846         }
01847     }
01848 
01849     if (proxy) { // style sheet update
01850         proxy->repolish(this);
01851         return;
01852     }
01853 
01854     if (testAttribute(Qt::WA_SetStyle)) {
01855         d->setStyle_helper(new QStyleSheetStyle(d->extra->style), true);
01856     } else if (QStyleSheetStyle *appProxy = qobject_cast<QStyleSheetStyle *>(qApp->style())) {
01857         appProxy->repolish(this);
01858     } else {
01859         d->setStyle_helper(new QStyleSheetStyle(0), true);
01860     }
01861 }
01862 
01863 #endif // QT_NO_STYLE_STYLESHEET
01864 
01869 QStyle *QWidget::style() const
01870 {
01871     Q_D(const QWidget);
01872 
01873     if (d->extra && d->extra->style)
01874         return d->extra->style;
01875     return qApp->style();
01876 }
01877 
01893 void QWidget::setStyle(QStyle *style)
01894 {
01895     Q_D(QWidget);
01896     setAttribute(Qt::WA_SetStyle, style != 0);
01897     d->createExtra();
01898 #ifndef QT_NO_STYLE_STYLESHEET
01899     // if we have an application stylesheet or have a proxy already, propagate
01900     if (qobject_cast<QStyleSheetStyle *>(d->extra->style) || !qApp->styleSheet().isEmpty())
01901         d->setStyle_helper(new QStyleSheetStyle(style), true);
01902     else
01903 #endif
01904         d->setStyle_helper(style, false);
01905 }
01906 
01907 void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate)
01908 {
01909     Q_Q(QWidget);
01910     createExtra();
01911     QStyle *oldStyle  = q->style();
01912 #ifndef QT_NO_STYLE_STYLESHEET
01913     QStyle *origStyle = extra->style;
01914 #endif
01915     extra->style = newStyle;
01916 
01917     if (propagate) {
01918         for (int i = 0; i < children.size(); ++i) {
01919             QWidget *c = qobject_cast<QWidget*>(children.at(i));
01920             if (c)
01921                 c->d_func()->inheritStyle();
01922         }
01923     }
01924 
01925     // repolish
01926     if (q->windowType() != Qt::Desktop && polished) {
01927         oldStyle->unpolish(q);
01928         q->style()->polish(q);
01929     }
01930     QEvent e(QEvent::StyleChange);
01931     QApplication::sendEvent(q, &e);
01932 #ifdef QT3_SUPPORT
01933     q->styleChange(*oldStyle);
01934 #endif
01935 
01936 #ifndef QT_NO_STYLE_STYLESHEET
01937     // dereference the old stylesheet style
01938     if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(origStyle))
01939         proxy->deref();
01940 #endif
01941 }
01942 
01943 // Inherits style from the current parent and propagates it as necessary
01944 void QWidgetPrivate::inheritStyle()
01945 {
01946 #ifndef QT_NO_STYLE_STYLESHEET
01947     Q_Q(QWidget);
01948 
01949     QStyleSheetStyle *proxy = extra ? qobject_cast<QStyleSheetStyle *>(extra->style) : 0;
01950 
01951     if (!q->styleSheet().isEmpty()) {
01952         if (!proxy)
01953             proxy = qobject_cast<QStyleSheetStyle *>(qApp->style());
01954         // Since, we have a non-empty stylesheet, we are guaranteed that either we or the
01955         // the application is running a style sheet proxy
01956         Q_ASSERT(proxy);
01957         proxy->repolish(q);
01958         return;
01959     }
01960 
01961     // If we have stylesheet on app or parent has stylesheet style, we need
01962     // to be running a proxy
01963     QStyle *origStyle = proxy ? proxy->base : (extra ? extra->style : 0);
01964     QWidget *parent = q->parentWidget();
01965     QStyle *parentStyle = parent && parent->d_func()->extra ? parent->d_func()->extra->style : 0;
01966     if (!qApp->styleSheet().isEmpty() || qobject_cast<QStyleSheetStyle *>(parentStyle)) {
01967         QStyle *newStyle = parentStyle;
01968         if (q->testAttribute(Qt::WA_SetStyle))
01969             newStyle = new QStyleSheetStyle(origStyle);
01970         else if (QStyleSheetStyle *newProxy = qobject_cast<QStyleSheetStyle *>(newStyle))
01971             newProxy->ref();
01972 
01973         setStyle_helper(newStyle, true);
01974         return;
01975     }
01976 
01977     // So, we have no stylesheet on parent/app and we have an empty stylesheet
01978     // we just need our original style back
01979     if (origStyle == (extra ? extra->style : 0)) // is it any different?
01980         return;
01981 
01982     // We could have inherited the proxy from our parent (which has a custom style)
01983     // In such a case we need to start following the application style (i.e revert
01984     // the propagation behavior of QStyleSheetStyle)
01985     if (!q->testAttribute(Qt::WA_SetStyle))
01986         origStyle = 0;
01987 
01988     setStyle_helper(origStyle, true);
01989 #endif // QT_NO_STYLE_STYLESHEET
01990 }
01991 
01992 #ifdef QT3_SUPPORT
01993 
01998 QStyle* QWidget::setStyle(const QString &style)
01999 {
02000     QStyle *s = QStyleFactory::create(style);
02001     setStyle(s);
02002     return s;
02003 }
02004 #endif
02005 
02055 Qt::WindowModality QWidget::windowModality() const
02056 {
02057     return static_cast<Qt::WindowModality>(data->window_modality);
02058 }
02059 
02060 void QWidget::setWindowModality(Qt::WindowModality windowModality)
02061 {
02062     data->window_modality = windowModality;
02063     // setModal_sys() will be called by setAttribute()
02064     setAttribute(Qt::WA_ShowModal, (data->window_modality != Qt::NonModal));
02065 }
02066 
02087 bool QWidget::isMinimized() const
02088 { return data->window_state & Qt::WindowMinimized; }
02089 
02098 void QWidget::showMinimized()
02099 {
02100     bool isMin = isMinimized();
02101     if (isMin && isVisible())
02102         return;
02103 
02104     ensurePolished();
02105 #ifdef QT3_SUPPORT
02106     if (parent())
02107         QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
02108 #endif
02109 
02110     if (!isMin)
02111         setWindowState((windowState() & ~Qt::WindowActive) | Qt::WindowMinimized);
02112     show();
02113 }
02114 
02129 bool QWidget::isMaximized() const
02130 { return data->window_state & Qt::WindowMaximized; }
02131 
02132 
02133 
02140 Qt::WindowStates QWidget::windowState() const
02141 {
02142     return (Qt::WindowStates)data->window_state;
02143 }
02144 
02152 void QWidget::overrideWindowState(Qt::WindowStates newstate)
02153 {
02154     QWindowStateChangeEvent e((Qt::WindowStates)data->window_state, true);
02155     data->window_state  = newstate;
02156     QApplication::sendEvent(this, &e);
02157 }
02158 
02197 bool QWidget::isFullScreen() const
02198 { return data->window_state & Qt::WindowFullScreen; }
02199 
02229 void QWidget::showFullScreen()
02230 {
02231     ensurePolished();
02232 #ifdef QT3_SUPPORT
02233     if (parent())
02234         QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
02235 #endif
02236 
02237     setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowMaximized))
02238                    | Qt::WindowFullScreen);
02239     show();
02240     activateWindow();
02241 }
02242 
02253 void QWidget::showMaximized()
02254 {
02255     ensurePolished();
02256 #ifdef QT3_SUPPORT
02257     if (parent())
02258         QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
02259 #endif
02260 
02261     setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen))
02262                    | Qt::WindowMaximized);
02263     show();
02264 }
02265 
02273 void QWidget::showNormal()
02274 {
02275     ensurePolished();
02276 #ifdef QT3_SUPPORT
02277     if (parent())
02278         QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
02279 #endif
02280 
02281     setWindowState(windowState() & ~(Qt::WindowMinimized
02282                                      | Qt::WindowMaximized
02283                                      | Qt::WindowFullScreen));
02284     show();
02285 }
02286 
02301 bool QWidget::isEnabledTo(QWidget* ancestor) const
02302 {
02303     const QWidget * w = this;
02304     while (w && !w->testAttribute(Qt::WA_ForceDisabled)
02305             && !w->isWindow()
02306             && w->parentWidget()
02307             && w->parentWidget() != ancestor)
02308         w = w->parentWidget();
02309     return !w->testAttribute(Qt::WA_ForceDisabled);
02310 }
02311 
02312 #ifndef QT_NO_ACTION
02313 
02325 void QWidget::addAction(QAction *action)
02326 {
02327     insertAction(0, action);
02328 }
02329 
02335 void QWidget::addActions(QList<QAction*> actions)
02336 {
02337     for(int i = 0; i < actions.count(); i++)
02338         insertAction(0, actions.at(i));
02339 }
02340 
02350 void QWidget::insertAction(QAction *before, QAction *action)
02351 {
02352     if(!action) {
02353         qWarning("QWidget::insertAction: Attempt to insert null action");
02354         return;
02355     }
02356 
02357     Q_D(QWidget);
02358     if(d->actions.contains(action))
02359         removeAction(action);
02360 
02361     int pos = d->actions.indexOf(before);
02362     if (pos < 0) {
02363         before = 0;
02364         pos = d->actions.size();
02365     }
02366     d->actions.insert(pos, action);
02367 
02368     QActionPrivate *apriv = action->d_func();
02369     apriv->widgets.append(this);
02370 
02371     QActionEvent e(QEvent::ActionAdded, action, before);
02372     QApplication::sendEvent(this, &e);
02373 }
02374 
02384 void QWidget::insertActions(QAction *before, QList<QAction*> actions)
02385 {
02386     for(int i = 0; i < actions.count(); ++i)
02387         insertAction(before, actions.at(i));
02388 }
02389 
02394 void QWidget::removeAction(QAction *action)
02395 {
02396     if (!action)
02397         return;
02398 
02399     Q_D(QWidget);
02400 
02401     QActionPrivate *apriv = action->d_func();
02402     apriv->widgets.removeAll(this);
02403 
02404     if (d->actions.removeAll(action)) {
02405         QActionEvent e(QEvent::ActionRemoved, action);
02406         QApplication::sendEvent(this, &e);
02407     }
02408 }
02409 
02415 QList<QAction*> QWidget::actions() const
02416 {
02417     Q_D(const QWidget);
02418     return d->actions;
02419 }
02420 #endif // QT_NO_ACTION
02421 
02449 void QWidget::setEnabled(bool enable)
02450 {
02451     Q_D(QWidget);
02452     setAttribute(Qt::WA_ForceDisabled, !enable);
02453     d->setEnabled_helper(enable);
02454 }
02455 
02456 void QWidgetPrivate::setEnabled_helper(bool enable)
02457 {
02458     Q_Q(QWidget);
02459 
02460     if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->isEnabled())
02461         return; // nothing we can do
02462 
02463     if (enable != q->testAttribute(Qt::WA_Disabled))
02464         return; // nothing to do
02465 
02466     q->setAttribute(Qt::WA_Disabled, !enable);
02467     updateSystemBackground();
02468 
02469     if (!enable && q->window()->focusWidget() == q) {
02470         bool parentIsEnabled = (!q->parentWidget() || q->parentWidget()->isEnabled());
02471         if (!parentIsEnabled || !q->focusNextChild())
02472             q->clearFocus();
02473     }
02474 
02475     Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceDisabled : Qt::WA_Disabled;
02476     for (int i = 0; i < children.size(); ++i) {
02477         QWidget *w = qobject_cast<QWidget *>(children.at(i));
02478         if (w && !w->testAttribute(attribute))
02479             w->d_func()->setEnabled_helper(enable);
02480     }
02481 #if defined(Q_WS_X11)
02482     if (q->testAttribute(Qt::WA_SetCursor)) {
02483         // enforce the windows behavior of clearing the cursor on
02484         // disabled widgets
02485         extern void qt_x11_enforce_cursor(QWidget * w); // defined in qwidget_x11.cpp
02486         qt_x11_enforce_cursor(q);
02487     }
02488 #endif
02489 #ifdef Q_WS_WIN
02490     QWinInputContext::enable(q, q->testAttribute(Qt::WA_InputMethodEnabled) && enable);
02491 #endif
02492     QEvent e(QEvent::EnabledChange);
02493     QApplication::sendEvent(q, &e);
02494 #ifdef QT3_SUPPORT
02495     q->enabledChange(!enable); // compatibility
02496 #endif
02497 }
02498 
02513 bool QWidget::acceptDrops() const
02514 {
02515     return testAttribute(Qt::WA_AcceptDrops);
02516 }
02517 
02518 void QWidget::setAcceptDrops(bool on)
02519 {
02520     setAttribute(Qt::WA_AcceptDrops, on);
02521 
02522 }
02523 
02573 void QWidget::setDisabled(bool disable)
02574 {
02575     setEnabled(!disable);
02576 }
02577 
02588 QRect QWidget::frameGeometry() const
02589 {
02590     Q_D(const QWidget);
02591     if (isWindow() && ! (windowType() == Qt::Popup)) {
02592         QRect fs = d->frameStrut();
02593         return QRect(data->crect.x() - fs.left(),
02594                      data->crect.y() - fs.top(),
02595                      data->crect.width() + fs.left() + fs.right(),
02596                      data->crect.height() + fs.top() + fs.bottom());
02597     }
02598     return data->crect;
02599 }
02600 
02612 int QWidget::x() const
02613 {
02614     Q_D(const QWidget);
02615     if (isWindow() && ! (windowType() == Qt::Popup))
02616         return data->crect.x() - d->frameStrut().left();
02617     return data->crect.x();
02618 }
02619 
02630 int QWidget::y() const
02631 {
02632     Q_D(const QWidget);
02633     if (isWindow() && ! (windowType() == Qt::Popup))
02634         return data->crect.y() - d->frameStrut().top();
02635     return data->crect.y();
02636 }
02637 
02658 QPoint QWidget::pos() const
02659 {
02660     Q_D(const QWidget);
02661     if (isWindow() && ! (windowType() == Qt::Popup)) {
02662         QRect fs = d->frameStrut();
02663         return QPoint(data->crect.x() - fs.left(), data->crect.y() - fs.top());
02664     }
02665     return data->crect.topLeft();
02666 }
02667 
02755 QRect QWidget::normalGeometry() const
02756 {
02757     Q_D(const QWidget);
02758     if (!d->extra || !d->extra->topextra)
02759         return QRect();
02760 
02761     if (!isMaximized() && !isFullScreen())
02762         return geometry();
02763 
02764     return d->topData()->normalGeometry;
02765 }
02766 
02767 
02777 QRect QWidget::childrenRect() const
02778 {
02779     Q_D(const QWidget);
02780     QRect r(0, 0, 0, 0);
02781     for (int i = 0; i < d->children.size(); ++i) {
02782         QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
02783         if (w && !w->isWindow() && !w->isHidden())
02784             r |= w->geometry();
02785     }
02786     return r;
02787 }
02788 
02798 QRegion QWidget::childrenRegion() const
02799 {
02800     Q_D(const QWidget);
02801     QRegion r;
02802     for (int i = 0; i < d->children.size(); ++i) {
02803         QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
02804         if (w && !w->isWindow() && !w->isHidden()) {
02805             QRegion mask = w->mask();
02806             if (mask.isEmpty())
02807                 r |= w->geometry();
02808             else
02809                 r |= mask.translated(w->pos());
02810         }
02811     }
02812     return r;
02813 }
02814 
02815 
02829 QSize QWidget::minimumSize() const
02830 {
02831     Q_D(const QWidget);
02832     return d->extra ? QSize(d->extra->minw, d->extra->minh) : QSize(0, 0);
02833 }
02834 
02848 QSize QWidget::maximumSize() const
02849 {
02850     Q_D(const QWidget);
02851     return d->extra ? QSize(d->extra->maxw, d->extra->maxh)
02852                  : QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
02853 }
02854 
02855 
02918 QSize QWidget::sizeIncrement() const
02919 {
02920     Q_D(const QWidget);
02921     return (d->extra && d->extra->topextra)
02922         ? QSize(d->extra->topextra->incw, d->extra->topextra->inch)
02923         : QSize(0, 0);
02924 }
02925 
02936 QSize QWidget::baseSize() const
02937 {
02938     Q_D(const QWidget);
02939     return (d->extra != 0 && d->extra->topextra != 0)
02940         ? QSize(d->extra->topextra->basew, d->extra->topextra->baseh)
02941         : QSize(0, 0);
02942 }
02943 
02944 bool QWidgetPrivate::setMinimumSize_helper(int minw, int minh)
02945 {
02946     Q_Q(QWidget);
02947 
02948 #ifdef Q_WS_QWS
02949     if (q->isWindow()) {
02950         QApplicationPrivate *ap = QApplicationPrivate::instance();
02951         const QRect maxWindowRect = ap->maxWindowRect(getScreen());
02952         if (!maxWindowRect.isEmpty()) {
02953             // ### This is really just a work-around. Layout shouldn't be
02954             // asking for minimum sizes bigger than the screen.
02955             if (minw > maxWindowRect.width())
02956                 minw = maxWindowRect.width();
02957             if (minh > maxWindowRect.height())
02958                 minh = maxWindowRect.height();
02959         }
02960     }
02961 #endif
02962     if (minw > QWIDGETSIZE_MAX || minh > QWIDGETSIZE_MAX) {
02963         qWarning("QWidget::setMinimumSize: (%s/%s) "
02964                 "The largest allowed size is (%d,%d)",
02965                  q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
02966                 QWIDGETSIZE_MAX);
02967         minw = qMin<int>(minw, QWIDGETSIZE_MAX);
02968         minh = qMin<int>(minh, QWIDGETSIZE_MAX);
02969     }
02970     if (minw < 0 || minh < 0) {
02971         qWarning("QWidget::setMinimumSize: (%s/%s) Negative sizes (%d,%d) "
02972                 "are not possible",
02973                 q->objectName().toLocal8Bit().data(), q->metaObject()->className(), minw, minh);
02974         minw = qMax(minw, 0);
02975         minh = qMax(minh, 0);
02976     }
02977     createExtra();
02978     if (extra->minw == minw && extra->minh == minh)
02979         return false;
02980     extra->minw = minw;
02981     extra->minh = minh;
02982     extra->explicitMinSize = (minw ? Qt::Horizontal : 0) | (minh ? Qt::Vertical : 0);
02983     return true;
02984 }
02985 
02994 void QWidget::setMinimumSize(int minw, int minh)
02995 {
02996     Q_D(QWidget);
02997     if (!d->setMinimumSize_helper(minw, minh))
02998         return;
02999 
03000     if (isWindow())
03001         d->setConstraints_sys();
03002     if (minw > width() || minh > height()) {
03003         bool resized = testAttribute(Qt::WA_Resized);
03004         bool maximized = isMaximized();
03005         resize(qMax(minw,width()), qMax(minh,height()));
03006         setAttribute(Qt::WA_Resized, resized); //not a user resize
03007         if (maximized)
03008             data->window_state = data->window_state | Qt::WindowMaximized;
03009     }
03010 
03011     updateGeometry();
03012 }
03013 
03014 bool QWidgetPrivate::setMaximumSize_helper(int maxw, int maxh)
03015 {
03016     Q_Q(QWidget);
03017     if (maxw > QWIDGETSIZE_MAX || maxh > QWIDGETSIZE_MAX) {
03018         qWarning("QWidget::setMaximumSize: (%s/%s) "
03019                 "The largest allowed size is (%d,%d)",
03020                  q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
03021                 QWIDGETSIZE_MAX);
03022         maxw = qMin<int>(maxw, QWIDGETSIZE_MAX);
03023         maxh = qMin<int>(maxh, QWIDGETSIZE_MAX);
03024     }
03025     if (maxw < 0 || maxh < 0) {
03026         qWarning("QWidget::setMaximumSize: (%s/%s) Negative sizes (%d,%d) "
03027                 "are not possible",
03028                 q->objectName().toLocal8Bit().data(), q->metaObject()->className(), maxw, maxh);
03029         maxw = qMax(maxw, 0);
03030         maxh = qMax(maxh, 0);
03031     }
03032     createExtra();
03033     if (extra->maxw == maxw && extra->maxh == maxh)
03034         return false;
03035     extra->maxw = maxw;
03036     extra->maxh = maxh;
03037     return true;
03038 }
03039 
03047 void QWidget::setMaximumSize(int maxw, int maxh)
03048 {
03049     Q_D(QWidget);
03050     if (!d->setMaximumSize_helper(maxw, maxh))
03051         return;
03052 
03053     if (isWindow())
03054         d->setConstraints_sys();
03055     if (maxw < width() || maxh < height()) {
03056         bool resized = testAttribute(Qt::WA_Resized);
03057         resize(qMin(maxw,width()), qMin(maxh,height()));
03058         setAttribute(Qt::WA_Resized, resized); //not a user resize
03059     }
03060 
03061     updateGeometry();
03062 }
03063 
03070 void QWidget::setSizeIncrement(int w, int h)
03071 {
03072     Q_D(QWidget);
03073     d->createTLExtra();
03074     QTLWExtra* x = d->topData();
03075     if (x->incw == w && x->inch == h)
03076         return;
03077     x->incw = w;
03078     x->inch = h;
03079     if (isWindow())
03080         d->setConstraints_sys();
03081 }
03082 
03089 void QWidget::setBaseSize(int basew, int baseh)
03090 {
03091     Q_D(QWidget);
03092     d->createTLExtra();
03093     QTLWExtra* x = d->topData();
03094     if (x->basew == basew && x->baseh == baseh)
03095         return;
03096     x->basew = basew;
03097     x->baseh = baseh;
03098     if (isWindow())
03099         d->setConstraints_sys();
03100 }
03101 
03115 void QWidget::setFixedSize(const QSize & s)
03116 {
03117     setFixedSize(s.width(), s.height());
03118 }
03119 
03120 
03128 void QWidget::setFixedSize(int w, int h)
03129 {
03130     Q_D(QWidget);
03131     bool minSizeSet = d->setMinimumSize_helper(w, h);
03132     bool maxSizeSet = d->setMaximumSize_helper(w, h);
03133     if (!minSizeSet && !maxSizeSet)
03134         return;
03135 
03136     if (isWindow())
03137         d->setConstraints_sys();
03138 
03139     resize(w, h);
03140 }
03141 
03142 void QWidget::setMinimumWidth(int w)
03143 {
03144     Q_D(QWidget);
03145     d->createExtra();
03146     uint expl = d->extra->explicitMinSize | (w ? Qt::Horizontal : 0);
03147     setMinimumSize(w, minimumSize().height());
03148     d->extra->explicitMinSize = expl;
03149 }
03150 
03151 void QWidget::setMinimumHeight(int h)
03152 {
03153     Q_D(QWidget);
03154     d->createExtra();
03155     uint expl = d->extra->explicitMinSize | (h ? Qt::Vertical : 0);
03156     setMinimumSize(minimumSize().width(), h);
03157     d->extra->explicitMinSize = expl;
03158 }
03159 
03160 void QWidget::setMaximumWidth(int w)
03161 {
03162     setMaximumSize(w, maximumSize().height());
03163 }
03164 
03165 void QWidget::setMaximumHeight(int h)
03166 {
03167     setMaximumSize(maximumSize().width(), h);
03168 }
03169 
03177 void QWidget::setFixedWidth(int w)
03178 {
03179     Q_D(QWidget);
03180     d->createExtra();
03181     uint expl = d->extra->explicitMinSize | Qt::Horizontal;
03182     setMinimumSize(w, minimumSize().height());
03183     setMaximumSize(w, maximumSize().height());
03184     d->extra->explicitMinSize = expl;
03185 }
03186 
03187 
03195 void QWidget::setFixedHeight(int h)
03196 {
03197     Q_D(QWidget);
03198     d->createExtra();
03199     uint expl = d->extra->explicitMinSize | Qt::Vertical;
03200     setMinimumSize(minimumSize().width(), h);
03201     setMaximumSize(maximumSize().width(), h);
03202     d->extra->explicitMinSize = expl;
03203 }
03204 
03205 
03214 QPoint QWidget::mapTo(QWidget * parent, const QPoint & pos) const
03215 {
03216     QPoint p = pos;
03217     if (parent) {
03218         const QWidget * w = this;
03219         while (w != parent) {
03220             Q_ASSERT_X(w, "QWidget::mapTo(QWidget *parent, const QPoint &pos)",
03221                        "parent must be in parent hierarchy");
03222             p = w->mapToParent(p);
03223             w = w->parentWidget();
03224         }
03225     }
03226     return p;
03227 }
03228 
03229 
03238 QPoint QWidget::mapFrom(QWidget * parent, const QPoint & pos) const
03239 {
03240     QPoint p(pos);
03241     if (parent) {
03242         const QWidget * w = this;
03243         while (w != parent) {
03244             Q_ASSERT_X(w, "QWidget::mapFrom(QWidget *parent, const QPoint &pos)",
03245                        "parent must be in parent hierarchy");
03246 
03247             p = w->mapFromParent(p);
03248             w = w->parentWidget();
03249         }
03250     }
03251     return p;
03252 }
03253 
03254 
03264 QPoint QWidget::mapToParent(const QPoint &pos) const
03265 {
03266     return pos + data->crect.topLeft();
03267 }
03268 
03278 QPoint QWidget::mapFromParent(const QPoint &pos) const
03279 {
03280     return pos - data->crect.topLeft();
03281 }
03282 
03283 
03299 QWidget *QWidget::window() const
03300 {
03301     QWidget *w = (QWidget *)this;
03302     QWidget *p = w->parentWidget();
03303     while (!w->isWindow() && p) {
03304         w = p;
03305         p = p->parentWidget();
03306     }
03307     return w;
03308 }
03309 
03316 #ifdef QT3_SUPPORT
03317 
03322 Qt::BackgroundMode QWidget::backgroundMode() const
03323 {
03324     if (testAttribute(Qt::WA_NoSystemBackground))
03325         return Qt::NoBackground;
03326     switch(backgroundRole()) {
03327     case QPalette::WindowText:
03328         return Qt::PaletteForeground;
03329     case QPalette::Button:
03330         return Qt::PaletteButton;
03331     case QPalette::Light:
03332         return Qt::PaletteLight;
03333     case QPalette::Midlight:
03334         return Qt::PaletteMidlight;
03335     case QPalette::Dark:
03336         return Qt::PaletteDark;
03337     case QPalette::Mid:
03338         return Qt::PaletteMid;
03339     case QPalette::Text:
03340         return Qt::PaletteText;
03341     case QPalette::BrightText:
03342         return Qt::PaletteBrightText;
03343     case QPalette::Base:
03344         return Qt::PaletteBase;
03345     case QPalette::Window:
03346         return Qt::PaletteBackground;
03347     case QPalette::Shadow:
03348         return Qt::PaletteShadow;
03349     case QPalette::Highlight:
03350         return Qt::PaletteHighlight;
03351     case QPalette::HighlightedText:
03352         return Qt::PaletteHighlightedText;
03353     case QPalette::ButtonText:
03354         return Qt::PaletteButtonText;
03355     case QPalette::Link:
03356         return Qt::PaletteLink;
03357     case QPalette::LinkVisited:
03358         return Qt::PaletteLinkVisited;
03359     default:
03360         break;
03361     }
03362     return Qt::NoBackground;
03363 }
03364 
03373 void QWidget::setBackgroundMode(Qt::BackgroundMode m, Qt::BackgroundMode)
03374 {
03375     Q_D(QWidget);
03376     if(m == Qt::NoBackground) {
03377         setAttribute(Qt::WA_NoSystemBackground, true);
03378         return;
03379     }
03380     setAttribute(Qt::WA_NoSystemBackground, false);
03381     d->fg_role = QPalette::NoRole;
03382     QPalette::ColorRole role = d->bg_role;
03383     switch(m) {
03384     case Qt::FixedColor:
03385     case Qt::FixedPixmap:
03386         break;
03387     case Qt::PaletteForeground:
03388         role = QPalette::WindowText;
03389         break;
03390     case Qt::PaletteButton:
03391         role = QPalette::Button;
03392         break;
03393     case Qt::PaletteLight:
03394         role = QPalette::Light;
03395         break;
03396     case Qt::PaletteMidlight:
03397         role = QPalette::Midlight;
03398         break;
03399     case Qt::PaletteDark:
03400         role = QPalette::Dark;
03401         break;
03402     case Qt::PaletteMid:
03403         role = QPalette::Mid;
03404         break;
03405     case Qt::PaletteText:
03406         role = QPalette::Text;
03407         break;
03408     case Qt::PaletteBrightText:
03409         role = QPalette::BrightText;
03410         break;
03411     case Qt::PaletteBase:
03412         role = QPalette::Base;
03413         break;
03414     case Qt::PaletteBackground:
03415         role = QPalette::Window;
03416         break;
03417     case Qt::PaletteShadow:
03418         role = QPalette::Shadow;
03419         break;
03420     case Qt::PaletteHighlight:
03421         role = QPalette::Highlight;
03422         break;
03423     case Qt::PaletteHighlightedText:
03424         role = QPalette::HighlightedText;
03425         break;
03426     case Qt::PaletteButtonText:
03427         role = QPalette::ButtonText;
03428         break;
03429     case Qt::PaletteLink:
03430         role = QPalette::Link;
03431         break;
03432     case Qt::PaletteLinkVisited:
03433         role = QPalette::LinkVisited;
03434         break;
03435     case Qt::X11ParentRelative:
03436         d->fg_role = role = QPalette::NoRole;
03437     default:
03438         break;
03439     }
03440     setBackgroundRole(role);
03441 }
03442 
03446 QT3_SUPPORT QWidgetMapper *QWidget::wmapper() { return QWidgetPrivate::mapper; }
03447 
03448 #endif
03449 
03450 
03462 QPalette::ColorRole QWidget::backgroundRole() const
03463 {
03464 
03465     const QWidget *w = this;
03466     do {
03467         QPalette::ColorRole role = w->d_func()->bg_role;
03468         if (role != QPalette::NoRole)
03469             return role;
03470         if (w->isWindow() || w->windowType() == Qt::SubWindow)
03471             break;
03472         w = w->parentWidget();
03473     } while (w);
03474     return QPalette::Window;
03475 }
03476 
03489 void QWidget::setBackgroundRole(QPalette::ColorRole role)
03490 {
03491     Q_D(QWidget);
03492     d->bg_role = role;
03493     d->updateSystemBackground();
03494     d->propagatePaletteChange();
03495     d->updateIsOpaque();
03496 }
03497 
03509 QPalette::ColorRole QWidget::foregroundRole() const
03510 {
03511     Q_D(const QWidget);
03512     QPalette::ColorRole rl = QPalette::ColorRole(d->fg_role);
03513     if (rl != QPalette::NoRole)
03514         return rl;
03515     QPalette::ColorRole role = QPalette::WindowText;
03516     switch (backgroundRole()) {
03517     case QPalette::Button:
03518         role = QPalette::ButtonText;
03519         break;
03520     case QPalette::Base:
03521         role = QPalette::Text;
03522         break;
03523     case QPalette::Dark:
03524     case QPalette::Shadow:
03525         role = QPalette::Light;
03526         break;
03527     case QPalette::Highlight:
03528         role = QPalette::HighlightedText;
03529         break;
03530     default:
03531         ;
03532     }
03533     return role;
03534 }
03535 
03547 void QWidget::setForegroundRole(QPalette::ColorRole role)
03548 {
03549     Q_D(QWidget);
03550     d->fg_role = role;
03551     d->updateSystemBackground();
03552     d->propagatePaletteChange();
03553 }
03554 
03570 const QPalette &QWidget::palette() const
03571 {
03572     if (!isEnabled()) {
03573         data->pal.setCurrentColorGroup(QPalette::Disabled);
03574     } else if (!isVisible() || isActiveWindow()) {
03575         data->pal.setCurrentColorGroup(QPalette::Active);
03576     } else {
03577 #ifdef Q_WS_MAC
03578         extern bool qt_mac_can_clickThrough(const QWidget *); //qwidget_mac.cpp
03579         if (qt_mac_can_clickThrough(this))
03580             data->pal.setCurrentColorGroup(QPalette::Active);
03581         else
03582 #endif
03583             data->pal.setCurrentColorGroup(QPalette::Inactive);
03584     }
03585     return data->pal;
03586 }
03587 
03588 void QWidget::setPalette(const QPalette &palette)
03589 {
03590     Q_D(QWidget);
03591     setAttribute(Qt::WA_SetPalette, palette.resolve() != 0);
03592     d->setPalette_helper(palette.resolve(qt_naturalWidgetPalette(this)));
03593 }
03594 
03595 void QWidgetPrivate::resolvePalette()
03596 {
03597     Q_Q(QWidget);
03598     setPalette_helper(data.pal.resolve(qt_naturalWidgetPalette(q)));
03599 }
03600 
03601 void QWidgetPrivate::setPalette_helper(const QPalette &palette)
03602 {
03603     Q_Q(QWidget);
03604     if (data.pal == palette && data.pal.resolve() == palette.resolve())
03605         return;
03606     data.pal = palette;
03607     updateSystemBackground();
03608     propagatePaletteChange();
03609     updateIsOpaque();
03610     q->update();
03611     updateIsOpaque();
03612 }
03613 
03614 
03639 void QWidget::setFont(const QFont &font)
03640 {
03641     Q_D(QWidget);
03642     setAttribute(Qt::WA_SetFont, font.resolve() != 0);
03643     d->setFont_helper(font.resolve(qt_naturalWidgetFont(this)));
03644 }
03645 
03646 void QWidgetPrivate::resolveFont()
03647 {
03648     Q_Q(QWidget);
03649     setFont_helper(data.fnt.resolve(qt_naturalWidgetFont(q)));
03650 }
03651 
03652 void QWidgetPrivate::setFont_helper(const QFont &font)
03653 {
03654     if (data.fnt == font && data.fnt.resolve() == font.resolve())
03655         return;
03656 
03657     Q_Q(QWidget);
03658 #ifdef QT3_SUPPORT
03659     QFont old = data.fnt;
03660 #endif
03661     data.fnt = font;
03662 #if defined(Q_WS_X11)
03663     // make sure the font set on this widget is associated with the correct screen
03664     data.fnt.x11SetScreen(xinfo.screen());
03665 #endif
03666     for (int i = 0; i < children.size(); ++i) {
03667         QWidget *w = qobject_cast<QWidget*>(children.at(i));
03668         if (w && (!w->isWindow()
03669                   || w->testAttribute(Qt::WA_WindowPropagation)))
03670             w->d_func()->resolveFont();
03671     }
03672     QEvent e(QEvent::FontChange);
03673     QApplication::sendEvent(q, &e);
03674 #ifdef QT3_SUPPORT
03675     q->fontChange(old);
03676 #endif
03677 }
03678 
03679 void QWidgetPrivate::setLayoutDirection_helper(Qt::LayoutDirection direction)
03680 {
03681     Q_Q(QWidget);
03682 
03683     if ( (direction == Qt::RightToLeft) == q->testAttribute(Qt::WA_RightToLeft))
03684         return;
03685     q->setAttribute(Qt::WA_RightToLeft, (direction == Qt::RightToLeft));
03686     if (!children.isEmpty()) {
03687         for (int i = 0; i < children.size(); ++i) {
03688             QWidget *w = qobject_cast<QWidget*>(children.at(i));
03689             if (w && !w->isWindow() && !w->testAttribute(Qt::WA_SetLayoutDirection))
03690                 w->d_func()->setLayoutDirection_helper(direction);
03691         }
03692     }
03693     QEvent e(QEvent::LayoutDirectionChange);
03694     QApplication::sendEvent(q, &e);
03695 }
03696 
03697 void QWidgetPrivate::resolveLayoutDirection()
03698 {
03699     Q_Q(const QWidget);
03700     if (!q->testAttribute(Qt::WA_SetLayoutDirection))
03701         setLayoutDirection_helper(q->isWindow() ? QApplication::layoutDirection() : q->parentWidget()->layoutDirection());
03702 }
03703 
03711 void QWidget::setLayoutDirection(Qt::LayoutDirection direction)
03712 {
03713     Q_D(QWidget);
03714 
03715     setAttribute(Qt::WA_SetLayoutDirection);
03716     d->setLayoutDirection_helper(direction);
03717 }
03718 
03719 Qt::LayoutDirection QWidget::layoutDirection() const
03720 {
03721     return testAttribute(Qt::WA_RightToLeft) ? Qt::RightToLeft : Qt::LeftToRight;
03722 }
03723 
03724 void QWidget::unsetLayoutDirection()
03725 {
03726     Q_D(QWidget);
03727     setAttribute(Qt::WA_SetLayoutDirection, false);
03728     d->resolveLayoutDirection();
03729 }
03730 
03769 #ifndef QT_NO_CURSOR
03770 QCursor QWidget::cursor() const
03771 {
03772     Q_D(const QWidget);
03773     if (testAttribute(Qt::WA_SetCursor))
03774         return (d->extra && d->extra->curs)
03775             ? *d->extra->curs
03776             : QCursor(Qt::ArrowCursor);
03777     if (isWindow() || !parentWidget())
03778         return QCursor(Qt::ArrowCursor);
03779     return parentWidget()->cursor();
03780 }
03781 
03782 void QWidget::setCursor(const QCursor &cursor)
03783 {
03784     Q_D(QWidget);
03785 // On Mac we must set the cursor even if it is the ArrowCursor.
03786 #ifndef Q_WS_MAC
03787     if (cursor.shape() != Qt::ArrowCursor
03788         || (d->extra && d->extra->curs))
03789 #endif
03790     {
03791         d->createExtra();
03792         delete d->extra->curs;
03793         d->extra->curs = new QCursor(cursor);
03794     }
03795     setAttribute(Qt::WA_SetCursor);
03796     d->setCursor_sys(cursor);
03797 }
03798 
03799 void QWidget::unsetCursor()
03800 {
03801     Q_D(QWidget);
03802     if (d->extra) {
03803         delete d->extra->curs;
03804         d->extra->curs = 0;
03805     }
03806     if (!isWindow())
03807         setAttribute(Qt::WA_SetCursor, false);
03808     d->unsetCursor_sys();
03809 }
03810 
03811 #endif
03812 
03828 QString QWidget::windowTitle() const
03829 {
03830     Q_D(const QWidget);
03831     return d->extra && d->extra->topextra
03832         ? d->extra->topextra->caption
03833         : QString();
03834 }
03835 
03836 QString qt_setWindowTitle_helperHelper(const QString &title, QWidget *widget)
03837 {
03838     Q_ASSERT(widget);
03839 
03840 #ifdef QT_EVAL
03841     extern QString qt_eval_adapt_window_title(const QString &title);
03842     QString cap = qt_eval_adapt_window_title(title);
03843 #else
03844     QString cap = title;
03845 #endif
03846 
03847     QString placeHolder(QLatin1String("[*]"));
03848 
03849     int index = cap.indexOf(placeHolder);
03850 
03851     while (index != -1) {
03852         index += placeHolder.length();
03853         int count = 1;
03854         while (cap.indexOf(placeHolder, index) == index) {
03855             ++count;
03856             index += placeHolder.length();
03857         }
03858 
03859         if (count%2) { // odd number of [*] -> replace last one
03860             int lastIndex = cap.lastIndexOf(placeHolder, index - 1);
03861             if (widget->isWindowModified()
03862              && widget->style()->styleHint(QStyle::SH_TitleBar_ModifyNotification, 0, widget))
03863                 cap.replace(lastIndex, 3, QWidget::tr("*"));
03864             else
03865                 cap.replace(lastIndex, 3, QLatin1String(""));
03866         }
03867 
03868         index = cap.indexOf(placeHolder, index);
03869     }
03870 
03871     cap.replace(QLatin1String("[*][*]"), QLatin1String("[*]"));
03872 
03873     return cap;
03874 }
03875 
03876 void QWidgetPrivate::setWindowTitle_helper(const QString &title)
03877 {
03878     Q_Q(QWidget);
03879     if (!q->testAttribute(Qt::WA_WState_Created))
03880         createWinId();
03881     setWindowTitle_sys(qt_setWindowTitle_helperHelper(title, q));
03882 }
03883 
03884 void QWidgetPrivate::setWindowIconText_helper(const QString &title)
03885 {
03886     Q_Q(QWidget);
03887     if (q->testAttribute(Qt::WA_WState_Created))
03888         setWindowIconText_sys(qt_setWindowTitle_helperHelper(title, q));
03889 }
03890 
03891 void QWidget::setWindowIconText(const QString &iconText)
03892 {
03893     if (QWidget::windowIconText() == iconText)
03894         return;
03895 
03896     Q_D(QWidget);
03897     d->topData()->iconText = iconText;
03898     d->setWindowIconText_helper(iconText);
03899 
03900     QEvent e(QEvent::IconTextChange);
03901     QApplication::sendEvent(this, &e);
03902 }
03903 
03904 void QWidget::setWindowTitle(const QString &title)
03905 {
03906     if (QWidget::windowTitle() == title)
03907         return;
03908 
03909     Q_D(QWidget);
03910     d->topData()->caption = title;
03911     d->setWindowTitle_helper(title);
03912 
03913     QEvent e(QEvent::WindowTitleChange);
03914     QApplication::sendEvent(this, &e);
03915 }
03916 
03927 QIcon QWidget::windowIcon() const
03928 {
03929     const QWidget *w = this;
03930     while (w) {
03931         const QWidgetPrivate *d = w->d_func();
03932         if (d->extra && d->extra->topextra && d->extra->topextra->icon)
03933             return *d->extra->topextra->icon;
03934         w = w->parentWidget();
03935     }
03936     return qApp->windowIcon();
03937 }
03938 
03939 void QWidget::setWindowIcon(const QIcon &icon)
03940 {
03941     Q_D(QWidget);
03942 
03943     setAttribute(Qt::WA_SetWindowIcon, !icon.isNull());
03944     d->createTLExtra();
03945 
03946     if (!d->extra->topextra->icon)
03947         d->extra->topextra->icon = new QIcon();
03948     *d->extra->topextra->icon = icon;
03949 
03950     delete d->extra->topextra->iconPixmap;
03951     d->extra->topextra->iconPixmap = 0;
03952 
03953     d->setWindowIcon_sys();
03954     QEvent e(QEvent::WindowIconChange);
03955     QApplication::sendEvent(this, &e);
03956 }
03957 
03958 
03969 QString QWidget::windowIconText() const
03970 {
03971     Q_D(const QWidget);
03972     return (d->extra && d->extra->topextra) ? d->extra->topextra->iconText : QString();
03973 }
03974 
03981 QString QWidget::windowRole() const
03982 {
03983     Q_D(const QWidget);
03984     return (d->extra && d->extra->topextra) ? d->extra->topextra->role : QString();
03985 }
03986 
03991 void QWidget::setWindowRole(const QString &role)
03992 {
03993 #if defined(Q_WS_X11)
03994     Q_D(QWidget);
03995     d->topData()->role = role;
03996     d->setWindowRole(role.toUtf8().constData());
03997 #else
03998     Q_UNUSED(role)
03999 #endif
04000 }
04001 
04032 void QWidget::setFocusProxy(QWidget * w)
04033 {
04034     Q_D(QWidget);
04035     if (!w && !d->extra)
04036         return;
04037 
04038     for (QWidget* fp  = w; fp; fp = fp->focusProxy()) {
04039         if (fp == this) {
04040             qWarning("QWidget: %s (%s) already in focus proxy chain", metaObject()->className(), objectName().toLocal8Bit().constData());
04041             return;
04042         }
04043     }
04044 
04045     d->createExtra();
04046     d->extra->focus_proxy = w;
04047 }
04048 
04049 
04056 QWidget * QWidget::focusProxy() const
04057 {
04058     Q_D(const QWidget);
04059     return d->extra ? (QWidget *)d->extra->focus_proxy : 0;
04060 }
04061 
04062 
04072 bool QWidget::hasFocus() const
04073 {
04074     const QWidget* w = this;
04075     while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
04076         w = w->d_func()->extra->focus_proxy;
04077     return (QApplication::focusWidget() == w);
04078 }
04079 
04107 void QWidget::setFocus(Qt::FocusReason reason)
04108 {
04109     if (!isEnabled())
04110         return;
04111 
04112     QWidget *f = this;
04113     while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
04114         f = f->d_func()->extra->focus_proxy;
04115 
04116     if (QApplication::focusWidget() == f
04117 #if defined(Q_WS_WIN)
04118         && GetFocus() == f->internalWinId()
04119 #endif
04120        )
04121         return;
04122 
04123     QWidget *w = f;
04124     if (isHidden()) {
04125         while (w && w->isHidden()) {
04126             w->d_func()->focus_child = f;
04127             w = w->isWindow() ? 0 : w->parentWidget();
04128         }
04129     } else {
04130         while (w) {
04131             w->d_func()->focus_child = f;
04132             w = w->isWindow() ? 0 : w->parentWidget();
04133         }
04134     }
04135 
04136     if (f->isActiveWindow()) {
04137         QApplicationPrivate::setFocusWidget(f, reason);
04138 
04139 #if defined(Q_WS_MAC)
04140         if (f->testAttribute(Qt::WA_WState_Created)) {
04141             extern WindowPtr qt_mac_window_for(const QWidget *w); //qwidget_mac.cpp
04142             extern HIViewRef qt_mac_hiview_for(const QWidget *w); //qwidget_mac.cpp
04143             SetKeyboardFocus(qt_mac_window_for(f), qt_mac_hiview_for(f), 1);
04144         }
04145 #endif
04146 
04147 #if defined(Q_WS_WIN)
04148         if (f->testAttribute(Qt::WA_WState_Created)) {
04149             if (!(f->window()->windowType() == Qt::Popup))
04150                 SetFocus(f->internalWinId());
04151         } else {
04152 #endif
04153 #ifndef QT_NO_ACCESSIBILITY
04154             QAccessible::updateAccessibility(f, 0, QAccessible::Focus);
04155 #endif
04156 #if defined(Q_WS_WIN)
04157         }
04158 #endif
04159     }
04160 }
04161 
04185 void QWidget::clearFocus()
04186 {
04187     QWidget *w = this;
04188     while (w && w->d_func()->focus_child == this) {
04189         w->d_func()->focus_child = 0;
04190         w = w->isWindow() ? 0 : w->parentWidget();
04191     }
04192     if (hasFocus()) {
04193         QApplicationPrivate::setFocusWidget(0, Qt::OtherFocusReason);
04194 #if defined(Q_WS_WIN)
04195         if (!(windowType() == Qt::Popup) && GetFocus() == internalWinId())
04196             SetFocus(0);
04197         else {
04198 #endif
04199 #ifndef QT_NO_ACCESSIBILITY
04200             QAccessible::updateAccessibility(this, 0, QAccessible::Focus);
04201 #endif
04202 #if defined(Q_WS_WIN)
04203         }
04204 #endif
04205     }
04206 }
04207 
04208 
04251 bool QWidget::focusNextPrevChild(bool next)
04252 {
04253     QWidget* p = parentWidget();
04254     bool isSubWindow = (windowType() == Qt::SubWindow);
04255     if (!isWindow() && !isSubWindow && p)
04256         return p->focusNextPrevChild(next);
04257 
04258     QWidget *w = QApplicationPrivate::focusNextPrevChild_helper(this, next);
04259     if (!w) return false;
04260 
04261     w->setFocus(next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
04262     return true;
04263 }
04264 
04274 QWidget *QWidget::focusWidget() const
04275 {
04276     return const_cast<QWidget *>(d_func()->focus_child);
04277 }
04278 
04282 QWidget *QWidget::nextInFocusChain() const
04283 {
04284     return const_cast<QWidget *>(d_func()->focus_next);
04285 }
04286 
04299 bool QWidget::isActiveWindow() const
04300 {
04301     QWidget *tlw = window();
04302     if(tlw == qApp->activeWindow() || (isVisible() && (tlw->windowType() == Qt::Popup)))
04303         return true;
04304 #ifdef Q_WS_MAC
04305     { //check process
04306         Boolean compare;
04307         ProcessSerialNumber current, front;
04308         GetCurrentProcess(&current);
04309         GetFrontProcess(&front);
04310         if(SameProcess(&current, &front, &compare) == noErr && !compare)
04311             return false;
04312     }
04313     extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
04314     if(qt_mac_is_macdrawer(tlw) &&
04315        tlw->parentWidget() && tlw->parentWidget()->isActiveWindow())
04316         return true;
04317 #endif
04318     if(style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, this)) {
04319         if(((tlw->windowType() == Qt::Dialog) || (tlw->windowType() == Qt::Tool)) &&
04320            !tlw->isModal() &&
04321            (!tlw->parentWidget() || tlw->parentWidget()->isActiveWindow()))
04322            return true;
04323         QWidget *w = qApp->activeWindow();
04324         while(w && ((tlw->windowType() == Qt::Dialog) || (tlw->windowType() == Qt::Tool)) &&
04325               !w->isModal() && w->parentWidget()) {
04326             w = w->parentWidget()->window();
04327             if(w == tlw)
04328                 return true;
04329         }
04330     }
04331 #if defined(Q_WS_WIN32)
04332     HWND active = GetActiveWindow();
04333     return active == tlw->internalWinId() || ::IsChild(active, tlw->internalWinId());
04334 #else
04335     return false;
04336 #endif
04337 }
04338 
04367 void QWidget::setTabOrder(QWidget* first, QWidget *second)
04368 {
04369     if (!first || !second || first->focusPolicy() == Qt::NoFocus || second->focusPolicy() == Qt::NoFocus)
04370         return;
04371 
04372     QWidget *fp = first->focusProxy();
04373     if (fp) {
04374         // If first is redirected, set first to the last child of first
04375         // that can take keyboard focus so that second is inserted after
04376         // that last child, and the focus order within first is (more
04377         // likely to be) preserved.
04378         QList<QWidget *> l = qFindChildren<QWidget *>(first);
04379         for (int i = l.size()-1; i >= 0; --i) {
04380             QWidget * next = l.at(i);
04381             if (next->window() == fp->window()) {
04382                 fp = next;
04383                 if (fp->focusPolicy() != Qt::NoFocus)
04384                     break;
04385             }
04386         }
04387         first = fp;
04388     }
04389 
04390 
04391     if (QWidget *sp = second->focusProxy())
04392         second = sp;
04393 
04394 //    QWidget *fp = first->d_func()->focus_prev;
04395     QWidget *fn = first->d_func()->focus_next;
04396 
04397     if (fn == second)
04398         return;
04399 
04400     QWidget *sp = second->d_func()->focus_prev;
04401     QWidget *sn = second->d_func()->focus_next;
04402 
04403     fn->d_func()->focus_prev = second;
04404     first->d_func()->focus_next = second;
04405 
04406     second->d_func()->focus_next = fn;
04407     second->d_func()->focus_prev = first;
04408 
04409     sp->d_func()->focus_next = sn;
04410     sn->d_func()->focus_prev = sp;
04411 
04412 
04413     Q_ASSERT(first->d_func()->focus_next->d_func()->focus_prev == first);
04414     Q_ASSERT(first->d_func()->focus_prev->d_func()->focus_next == first);
04415 
04416     Q_ASSERT(second->d_func()->focus_next->d_func()->focus_prev == second);
04417     Q_ASSERT(second->d_func()->focus_prev->d_func()->focus_next == second);
04418 }
04419 
04432 void QWidgetPrivate::reparentFocusWidgets(QWidget * oldtlw)
04433 {
04434     Q_Q(QWidget);
04435     if (oldtlw == q->window())
04436         return; // nothing to do
04437 
04438     if(focus_child)
04439         focus_child->clearFocus();
04440 
04441     // separate the focus chain into new (children of myself) and old (the rest)
04442     QWidget *firstOld = 0;
04443     //QWidget *firstNew = q; //invariant
04444     QWidget *o = 0; // last in the old list
04445     QWidget *n = q; // last in the new list
04446 
04447     bool prevWasNew = true;
04448     QWidget *w = focus_next;
04449 
04450     //Note: for efficiency, we do not maintain the list invariant inside the loop
04451     //we append items to the relevant list, and we optimize by not changing pointers
04452     //when subsequent items are going into the same list.
04453     while (w  != q) {
04454         bool currentIsNew =  q->isAncestorOf(w);
04455         if (currentIsNew) {
04456             if (!prevWasNew) {
04457                 //prev was old -- append to new list
04458                 n->d_func()->focus_next = w;
04459                 w->d_func()->focus_prev = n;
04460             }
04461             n = w;
04462         } else {
04463             if (prevWasNew) {
04464                 //prev was new -- append to old list, if there is one
04465                 if (o) {
04466                     o->d_func()->focus_next = w;
04467                     w->d_func()->focus_prev = o;
04468                 } else {
04469                     // "create" the old list
04470                     firstOld = w;
04471                 }
04472             }
04473             o = w;
04474         }
04475         w = w->d_func()->focus_next;
04476         prevWasNew = currentIsNew;
04477     }
04478 
04479     //repair the old list:
04480     if (firstOld) {
04481         o->d_func()->focus_next = firstOld;
04482         firstOld->d_func()->focus_prev = o;
04483     }
04484 
04485     if (!q->isWindow()) {
04486         QWidget *topLevel = q->window();
04487         //insert new chain into toplevel's chain
04488 
04489         QWidget *prev = topLevel->d_func()->focus_prev;
04490 
04491         topLevel->d_func()->focus_prev = n;
04492         prev->d_func()->focus_next = q;
04493 
04494         focus_prev = prev;
04495         n->d_func()->focus_next = topLevel;
04496     } else {
04497         //repair the new list
04498             n->d_func()->focus_next = q;
04499             focus_prev = n;
04500     }
04501 
04502 }
04503 
04511 int QWidgetPrivate::pointToRect(const QPoint &p, const QRect &r)
04512 {
04513     int dx = 0;
04514     int dy = 0;
04515     if (p.x() < r.left())
04516         dx = r.left() - p.x();
04517     else if (p.x() > r.right())
04518         dx = p.x() - r.right();
04519     if (p.y() < r.top())
04520         dy = r.top() - p.y();
04521     else if (p.y() > r.bottom())
04522         dy = p.y() - r.bottom();
04523     return dx + dy;
04524 }
04525 
04530 QSize QWidget::frameSize() const
04531 {
04532     Q_D(const QWidget);
04533     if (isWindow() && !(windowType() == Qt::Popup)) {
04534         QRect fs = d->frameStrut();
04535         return QSize(data->crect.width() + fs.left() + fs.right(),
04536                       data->crect.height() + fs.top() + fs.bottom());
04537     }
04538     return data->crect.size();
04539 }
04540 
04548 void QWidget::move(const QPoint &p)
04549 {
04550     Q_D(QWidget);
04551     setAttribute(Qt::WA_Moved);
04552     if (testAttribute(Qt::WA_WState_Created)) {
04553         d->setGeometry_sys(p.x() + geometry().x() - QWidget::x(),
04554                        p.y() + geometry().y() - QWidget::y(),
04555                        width(), height(), true);
04556 #ifdef QT_EXPERIMENTAL_REGIONS
04557         d->setDirtyOpaqueRegion();
04558 #endif
04559     } else {
04560         if (isWindow())
04561             d->topData()->posFromMove = true;
04562         data->crect.moveTopLeft(p); // no frame yet
04563         setAttribute(Qt::WA_PendingMoveEvent);
04564     }
04565 }
04566 
04573 void QWidget::resize(const QSize &s)
04574 {
04575     Q_D(QWidget);
04576     setAttribute(Qt::WA_Resized);
04577     if (testAttribute(Qt::WA_WState_Created)) {
04578         d->setGeometry_sys(geometry().x(), geometry().y(), s.width(), s.height(), false);
04579 #ifdef QT_EXPERIMENTAL_REGIONS
04580         d->setDirtyOpaqueRegion();
04581 #endif
04582     } else {
04583         data->crect.setSize(s);
04584         setAttribute(Qt::WA_PendingResizeEvent);
04585     }
04586 }
04587 
04588 void QWidget::setGeometry(const QRect &r)
04589 {
04590     Q_D(QWidget);
04591     setAttribute(Qt::WA_Resized);
04592     setAttribute(Qt::WA_Moved);
04593     if (testAttribute(Qt::WA_WState_Created)) {
04594         d->setGeometry_sys(r.x(), r.y(), r.width(), r.height(), true);
04595 #ifdef QT_EXPERIMENTAL_REGIONS
04596         d->setDirtyOpaqueRegion();
04597 #endif
04598     } else {
04599         if (isWindow())
04600             d->topData()->posFromMove = false;
04601         data->crect = r;
04602         setAttribute(Qt::WA_PendingMoveEvent);
04603         setAttribute(Qt::WA_PendingResizeEvent);
04604     }
04605 }
04606 
04628 QByteArray QWidget::saveGeometry() const
04629 {
04630     QByteArray array;
04631     QDataStream stream(&array, QIODevice::WriteOnly);
04632     stream.setVersion(QDataStream::Qt_4_0);
04633     const quint32 magicNumber = 0x1D9D0CB;
04634     quint16 majorVersion = 1;
04635     quint16 minorVersion = 0;
04636     stream << magicNumber
04637            << majorVersion
04638            << minorVersion
04639            << frameGeometry()
04640            << normalGeometry()
04641            << qint32(QApplication::desktop()->screenNumber(this))
04642            << quint8(windowState() & Qt::WindowMaximized)
04643            << quint8(windowState() & Qt::WindowFullScreen);
04644     return array;
04645 }
04646 
04670 bool QWidget::restoreGeometry(const QByteArray &geometry)
04671 {
04672     if (geometry.size() < 4)
04673         return false;
04674     QDataStream stream(geometry);
04675     stream.setVersion(QDataStream::Qt_4_0);
04676 
04677     const quint32 magicNumber = 0x1D9D0CB;
04678     quint32 storedMagicNumber;
04679     stream >> storedMagicNumber;
04680     if (storedMagicNumber != magicNumber)
04681         return false;
04682 
04683     const quint16 currentMajorVersion = 1;
04684     quint16 majorVersion = 0;
04685     quint16 minorVersion = 0;
04686 
04687     stream >> majorVersion >> minorVersion;
04688 
04689     if (majorVersion != currentMajorVersion)
04690         return false;
04691     // (Allow all minor versions.)
04692 
04693     QRect restoredFrameGeometry;
04694     QRect restoredNormalGeometry;
04695     qint32 restoredScreenNumber;
04696     quint8 maximized;
04697     quint8 fullScreen;
04698 
04699     stream >> restoredFrameGeometry
04700            >> restoredNormalGeometry
04701            >> restoredScreenNumber
04702            >> maximized
04703            >> fullScreen;
04704 
04705     const int frameHeight = 20;
04706     if (!restoredFrameGeometry.isValid())
04707         restoredFrameGeometry = QRect(QPoint(0,0), sizeHint());
04708 
04709     if (!restoredNormalGeometry.isValid())
04710         restoredNormalGeometry = QRect(QPoint(0, frameHeight), sizeHint());
04711 
04712     const QDesktopWidget * const desktop = QApplication::desktop();
04713     if (restoredScreenNumber >= desktop->numScreens())
04714         restoredScreenNumber = desktop->primaryScreen();
04715 
04716     const QRect availableGeometry = desktop->availableGeometry(restoredScreenNumber);
04717 
04718     // Modify the restored geometry if we are about to restore to coordinates
04719     // that would make the window "lost". This happens if:
04720     // - The restored geometry is completely oustside the available geometry
04721     // - The title bar is outside the available geometry.
04722     // - (Mac only) The window is higher than the available geometry. It must
04723     //   be possible to bring the size grip on screen by moving the window.
04724 #ifdef Q_WS_MAC
04725     restoredFrameGeometry.setHeight(qMin(restoredFrameGeometry.height(), availableGeometry.height()));
04726     restoredNormalGeometry.setHeight(qMin(restoredNormalGeometry.height(), availableGeometry.height() - frameHeight));
04727 #endif
04728 
04729     if (!restoredFrameGeometry.intersects(availableGeometry)) {
04730         restoredFrameGeometry.moveBottom(qMin(restoredFrameGeometry.bottom(), availableGeometry.bottom()));
04731         restoredFrameGeometry.moveLeft(qMax(restoredFrameGeometry.left(), availableGeometry.left()));
04732         restoredFrameGeometry.moveRight(qMin(restoredFrameGeometry.right(), availableGeometry.right()));
04733     }
04734     restoredFrameGeometry.moveTop(qMax(restoredFrameGeometry.top(), availableGeometry.top()));
04735 
04736     if (!restoredNormalGeometry.intersects(availableGeometry)) {
04737         restoredNormalGeometry.moveBottom(qMin(restoredNormalGeometry.bottom(), availableGeometry.bottom()));
04738         restoredNormalGeometry.moveLeft(qMax(restoredNormalGeometry.left(), availableGeometry.left()));
04739         restoredNormalGeometry.moveRight(qMin(restoredNormalGeometry.right(), availableGeometry.right()));
04740     }
04741     restoredNormalGeometry.moveTop(qMax(restoredNormalGeometry.top(), availableGeometry.top() + frameHeight));
04742 
04743     if (maximized || fullScreen) {
04744         setGeometry(restoredNormalGeometry);
04745         if (maximized)
04746             setWindowState(windowState() | Qt::WindowMaximized);
04747         if (fullScreen)
04748             setWindowState(windowState() | Qt::WindowFullScreen);
04749     } else {
04750         move(restoredFrameGeometry.topLeft());
04751         resize(restoredNormalGeometry.size());
04752     }
04753     return true;
04754 }
04755 
04772 void QWidget::setContentsMargins(int left, int top, int right, int bottom)
04773 {
04774     Q_D(QWidget);
04775     if (left == d->leftmargin && top == d->topmargin
04776          && right == d->rightmargin && bottom == d->bottommargin)
04777         return;
04778     d->leftmargin = left;
04779     d->topmargin = top;
04780     d->rightmargin = right;
04781     d->bottommargin = bottom;
04782 
04783     if (QLayout *l=d->layout)
04784         l->update(); //force activate; will do updateGeometry
04785     else
04786         updateGeometry();
04787 
04788     if (isVisible()) {
04789         update();
04790         QResizeEvent e(data->crect.size(), data->crect.size());
04791         QApplication::sendEvent(this, &e);
04792     } else {
04793         setAttribute(Qt::WA_PendingResizeEvent, true);
04794     }
04795 }
04796 
04802 void QWidget::getContentsMargins(int *left, int *top, int *right, int *bottom) const
04803 {
04804     Q_D(const QWidget);
04805     if (left)
04806         *left = d->leftmargin;
04807     if (top)
04808         *top = d->topmargin;
04809     if (right)
04810         *right = d->rightmargin;
04811     if (bottom)
04812         *bottom = d->bottommargin;
04813 }
04814 
04820 QRect QWidget::contentsRect() const
04821 {
04822     Q_D(const QWidget);
04823     return QRect(QPoint(d->leftmargin, d->topmargin),
04824                  QPoint(data->crect.width() - 1 - d->rightmargin,
04825                         data->crect.height() - 1 - d->bottommargin));
04826 
04827 }
04828 
04829 
04830 
04861 Qt::ContextMenuPolicy QWidget::contextMenuPolicy() const
04862 {
04863     return (Qt::ContextMenuPolicy)data->context_menu_policy;
04864 }
04865 
04866 void QWidget::setContextMenuPolicy(Qt::ContextMenuPolicy policy)
04867 {
04868     data->context_menu_policy = (uint) policy;
04869 }
04870 
04890 Qt::FocusPolicy QWidget::focusPolicy() const
04891 {
04892     return (Qt::FocusPolicy)data->focus_policy;
04893 }
04894 
04895 void QWidget::setFocusPolicy(Qt::FocusPolicy policy)
04896 {
04897     data->focus_policy = (uint) policy;
04898 }
04899 
04930 void QWidget::setUpdatesEnabled(bool enable)
04931 {
04932     Q_D(QWidget);
04933     setAttribute(Qt::WA_ForceUpdatesDisabled, !enable);
04934     d->setUpdatesEnabled_helper(enable);
04935 }
04936 
04952 void QWidgetPrivate::show_recursive()
04953 {
04954     Q_Q(QWidget);
04955     // polish if necessary
04956 
04957     if (!q->testAttribute(Qt::WA_WState_Created))
04958         createRecursively();
04959     q->ensurePolished();
04960 
04961 #ifdef QT3_SUPPORT
04962     if(sendChildEvents)
04963         QApplication::sendPostedEvents(q, QEvent::ChildInserted);
04964 #endif
04965     if (!q->isWindow() && q->parentWidget()->d_func()->layout && !q->parentWidget()->data->in_show)
04966         q->parentWidget()->d_func()->layout->activate();
04967     // activate our layout before we and our children become visible
04968     if (layout)
04969         layout->activate();
04970 
04971     show_helper();
04972 }
04973 
04974 void QWidgetPrivate::show_helper()
04975 {
04976     Q_Q(QWidget);
04977     data.in_show = true; // qws optimization
04978     // make sure we receive pending move and resize events
04979     if (q->testAttribute(Qt::WA_PendingMoveEvent)) {
04980         QMoveEvent e(data.crect.topLeft(), data.crect.topLeft());
04981         QApplication::sendEvent(q, &e);
04982         q->setAttribute(Qt::WA_PendingMoveEvent, false);
04983     }
04984     if (q->testAttribute(Qt::WA_PendingResizeEvent)) {
04985         QResizeEvent e(data.crect.size(), QSize());
04986         QApplication::sendEvent(q, &e);
04987         q->setAttribute(Qt::WA_PendingResizeEvent, false);
04988     }
04989 
04990     // become visible before showing all children
04991     q->setAttribute(Qt::WA_WState_Visible);
04992 
04993     // finally show all children recursively
04994     showChildren(false);
04995 
04996 #ifdef QT3_SUPPORT
04997     if (q->parentWidget() && sendChildEvents)
04998         QApplication::sendPostedEvents(q->parentWidget(),
04999                                         QEvent::ChildInserted);
05000 #endif
05001 
05002 
05003     // popup handling: new popups and tools need to be raised, and
05004     // existing popups must be closed. Also propagate the current
05005     // windows's KeyboardFocusChange status.
05006     if (q->isWindow()) {
05007         if ((q->windowType() == Qt::Tool) || (q->windowType() == Qt::Popup) || q->windowType() == Qt::ToolTip) {
05008             q->raise();
05009             if (q->parentWidget() && q->parentWidget()->window()->testAttribute(Qt::WA_KeyboardFocusChange))
05010                 q->setAttribute(Qt::WA_KeyboardFocusChange);
05011         } else {
05012             while (QApplication::activePopupWidget()) {
05013                 if (!QApplication::activePopupWidget()->close())
05014                     break;
05015             }
05016         }
05017     }
05018 
05019     // On Windows, show the popup now so that our own focus handling
05020     // stores the correct old focus widget even if it's stolen in the
05021     // showevent
05022 #if defined(Q_WS_WIN)
05023     if ((q->windowType() == Qt::Popup))
05024         qApp->d_func()->openPopup(q);
05025 #endif
05026 
05027     // send the show event before showing the window
05028     QShowEvent showEvent;
05029     QApplication::sendEvent(q, &showEvent);
05030 
05031     if (q->isModal())
05032         // QApplicationPrivate::enterModal *before* show, otherwise the initial
05033         // stacking might be wrong
05034         QApplicationPrivate::enterModal(q);
05035 
05036 
05037     show_sys();
05038 
05039 #if !defined(Q_WS_WIN)
05040     if ((q->windowType() == Qt::Popup))
05041         qApp->d_func()->openPopup(q);
05042 #endif
05043 
05044 #ifndef QT_NO_ACCESSIBILITY
05045     QAccessible::updateAccessibility(q, 0, QAccessible::ObjectShow);
05046 #endif
05047 
05048     data.in_show = false;  // reset qws optimization
05049 }
05050 
05061 void QWidgetPrivate::hide_helper()
05062 {
05063     Q_Q(QWidget);
05064     if ((q->windowType() == Qt::Popup))
05065         qApp->d_func()->closePopup(q);
05066 
05067     // Move test modal here.  Otherwise, a modal dialog could get
05068     // destroyed and we lose all access to its parent because we haven't
05069     // left modality.  (Eg. modal Progress Dialog)
05070     if (q->isModal())
05071         QApplicationPrivate::leaveModal(q);
05072 
05073 #if defined(Q_WS_WIN)
05074     if (q->isWindow() && !(q->windowType() == Qt::Popup) && q->parentWidget()
05075         && !q->parentWidget()->isHidden() && q->isActiveWindow())
05076         q->parentWidget()->activateWindow();        // Activate parent
05077 #endif
05078 
05079     q->setAttribute(Qt::WA_Mapped, false);
05080     hide_sys();
05081 
05082     bool wasVisible = q->testAttribute(Qt::WA_WState_Visible);
05083 
05084     if (wasVisible) {
05085         q->setAttribute(Qt::WA_WState_Visible, false);
05086 
05087     }
05088 
05089     QHideEvent hideEvent;
05090     QApplication::sendEvent(q, &hideEvent);
05091     hideChildren(false);
05092 
05093     // next bit tries to move the focus if the focus widget is now
05094     // hidden.
05095     if (wasVisible) {
05096         QWidget *fw = QApplication::focusWidget();
05097         while (fw &&  !fw->isWindow()) {
05098             if (fw == q) {
05099                 q->focusNextPrevChild(true);
05100                 break;
05101             }
05102             fw = fw->parentWidget();
05103         }
05104     }
05105 
05106 
05107 #ifndef QT_NO_ACCESSIBILITY
05108     if (wasVisible)
05109         QAccessible::updateAccessibility(q, 0, QAccessible::ObjectHide);
05110 #endif
05111 }
05112 
05134 void QWidget::setVisible(bool visible)
05135 {
05136     if (visible) { // show
05137         if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
05138             return;
05139 
05140         Q_D(QWidget);
05141 
05142         // Designer uses a trick to make grabWidget work without showing
05143         if (!isWindow() && parentWidget() && parentWidget()->isVisible()
05144             && !parentWidget()->testAttribute(Qt::WA_WState_Created))
05145             parentWidget()->window()->d_func()->createRecursively();
05146 
05147         //we have to at least create toplevels before applyX11SpecificCommandLineArguments
05148         //but not children of non-visible parents
05149         QWidget *pw = parentWidget();
05150         if (!testAttribute(Qt::WA_WState_Created)
05151             && (isWindow() || pw->testAttribute(Qt::WA_WState_Created))) {
05152             create();
05153         }
05154 
05155 #if defined(Q_WS_X11)
05156         if (windowType() == Qt::Window)
05157             QApplicationPrivate::applyX11SpecificCommandLineArguments(this);
05158 #elif defined(Q_WS_QWS)
05159         if (windowType() == Qt::Window)
05160             QApplicationPrivate::applyQWSSpecificCommandLineArguments(this);
05161 #endif
05162 
05163         bool wasResized = testAttribute(Qt::WA_Resized);
05164         Qt::WindowStates initialWindowState = windowState();
05165 
05166         // polish if necessary
05167         ensurePolished();
05168 
05169         // remember that show was called explicitly
05170         setAttribute(Qt::WA_WState_ExplicitShowHide);
05171         // whether we need to inform the parent widget immediately
05172         bool needUpdateGeometry = !isWindow() && testAttribute(Qt::WA_WState_Hidden);
05173         // we are no longer hidden
05174         setAttribute(Qt::WA_WState_Hidden, false);
05175 
05176         if (needUpdateGeometry)
05177             updateGeometry();
05178 
05179 #ifdef QT3_SUPPORT
05180         QApplication::sendPostedEvents(this, QEvent::ChildInserted);
05181 #endif
05182         // activate our layout before we and our children become visible
05183         if (d->layout)
05184             d->layout->activate();
05185 
05186         if (!isWindow()) {
05187             QWidget *parent = parentWidget();
05188             while (parent && parent->isVisible() && parent->d_func()->layout  && !parent->data->in_show) {
05189                 parent->d_func()->layout->activate();
05190                 if (parent->isWindow())
05191                     break;
05192                 parent = parent->parentWidget();
05193             }
05194 #ifdef QT_EXPERIMENTAL_REGIONS
05195             if (parent && !d->getOpaqueRegion().isEmpty())
05196                 parent->d_func()->setDirtyOpaqueRegion();
05197 #endif
05198 
05199         }
05200 
05201         // adjust size if necessary
05202         if (!wasResized
05203             && (isWindow() || !parentWidget()->d_func()->layout))  {
05204             if (isWindow()) {
05205                 adjustSize();
05206                 if (windowState() != initialWindowState)
05207                     setWindowState(initialWindowState);
05208             } else {
05209                 adjustSize();
05210             }
05211             setAttribute(Qt::WA_Resized, false);
05212         }
05213 
05214         setAttribute(Qt::WA_KeyboardFocusChange, false);
05215 
05216         if (isWindow() || parentWidget()->isVisible())
05217             d->show_helper();
05218 
05219         QEvent showToParentEvent(QEvent::ShowToParent);
05220         QApplication::sendEvent(this, &showToParentEvent);
05221     } else { // hide
05222         if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden))
05223             return;
05224 
05225         Q_D(QWidget);
05226         setAttribute(Qt::WA_WState_Hidden);
05227         setAttribute(Qt::WA_WState_ExplicitShowHide);
05228         if (testAttribute(Qt::WA_WState_Created))
05229             d->hide_helper();
05230 
05231         // invalidate layout similar to updateGeometry()
05232         if (!isWindow() && parentWidget()) {
05233             if (parentWidget()->d_func()->layout)
05234                 parentWidget()->d_func()->layout->update();
05235             else if (parentWidget()->isVisible())
05236                 QApplication::postEvent(parentWidget(), new QEvent(QEvent::LayoutRequest));
05237 #ifdef QT_EXPERIMENTAL_REGIONS
05238             if (!d->getOpaqueRegion().isEmpty())
05239                 parentWidget()->d_func()->setDirtyOpaqueRegion();
05240 #endif
05241         }
05242 
05243         QEvent hideToParentEvent(QEvent::HideToParent);
05244         QApplication::sendEvent(this, &hideToParentEvent);
05245     }
05246 }
05247 
05259 void QWidgetPrivate::_q_showIfNotHidden()
05260 {
05261     Q_Q(QWidget);
05262     if ( !(q->isHidden() && q->testAttribute(Qt::WA_WState_ExplicitShowHide)) )
05263         q->setVisible(true);
05264 }
05265 
05266 void QWidgetPrivate::showChildren(bool spontaneous)
05267 {
05268     QList<QObject*> childList = children;
05269     for (int i = 0; i < childList.size(); ++i) {
05270         QWidget *widget = qobject_cast<QWidget*>(childList.at(i));
05271         if (!widget
05272             || widget->isWindow()
05273             || widget->testAttribute(Qt::WA_WState_Hidden))
05274             continue;
05275         if (spontaneous) {
05276             widget-&