src/gui/widgets/qworkspace.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qworkspace.h"
       
    43 #ifndef QT_NO_WORKSPACE
       
    44 #include "qapplication.h"
       
    45 #include "qbitmap.h"
       
    46 #include "qcursor.h"
       
    47 #include "qdatetime.h"
       
    48 #include "qdesktopwidget.h"
       
    49 #include "qevent.h"
       
    50 #include "qhash.h"
       
    51 #include "qicon.h"
       
    52 #include "qimage.h"
       
    53 #include "qlabel.h"
       
    54 #include "qlayout.h"
       
    55 #include "qmenubar.h"
       
    56 #include "qmenu.h"
       
    57 #include "qpainter.h"
       
    58 #include "qpointer.h"
       
    59 #include "qscrollbar.h"
       
    60 #include "qstyle.h"
       
    61 #include "qstyleoption.h"
       
    62 #include "qtooltip.h"
       
    63 #include "qdebug.h"
       
    64 #include <private/qwidget_p.h>
       
    65 #include <private/qwidgetresizehandler_p.h>
       
    66 #include <private/qlayoutengine_p.h>
       
    67 
       
    68 QT_BEGIN_NAMESPACE
       
    69 
       
    70 class QWorkspaceTitleBarPrivate;
       
    71 
       
    72 
       
    73 /**************************************************************
       
    74 * QMDIControl
       
    75 *
       
    76 * Used for displaying MDI controls in a maximized MDI window
       
    77 *
       
    78 */
       
    79 class QMDIControl : public QWidget
       
    80 {
       
    81     Q_OBJECT
       
    82 signals:
       
    83     void _q_minimize();
       
    84     void _q_restore();
       
    85     void _q_close();
       
    86 
       
    87 public:
       
    88     QMDIControl(QWidget *widget);
       
    89 
       
    90 private:
       
    91     QSize sizeHint() const;
       
    92     void paintEvent(QPaintEvent *event);
       
    93     void mousePressEvent(QMouseEvent *event);
       
    94     void mouseReleaseEvent(QMouseEvent *event);
       
    95     void mouseMoveEvent(QMouseEvent *event);
       
    96     void leaveEvent(QEvent *event);
       
    97     bool event(QEvent *event);
       
    98     void initStyleOption(QStyleOptionComplex *option) const;
       
    99     QStyle::SubControl activeControl; //control locked by pressing and holding the mouse
       
   100     QStyle::SubControl hoverControl; //previously active hover control, used for tracking repaints
       
   101 };
       
   102 
       
   103 bool QMDIControl::event(QEvent *event)
       
   104 {
       
   105     if (event->type() == QEvent::ToolTip) {
       
   106         QStyleOptionComplex opt;
       
   107         initStyleOption(&opt);
       
   108 #ifndef QT_NO_TOOLTIP
       
   109         QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
       
   110         QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_MdiControls, &opt,
       
   111                                                                  helpEvent->pos(), this);
       
   112         if (ctrl == QStyle::SC_MdiCloseButton)
       
   113             QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Close"), this);
       
   114         else if (ctrl == QStyle::SC_MdiMinButton)
       
   115             QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Minimize"), this);
       
   116         else if (ctrl == QStyle::SC_MdiNormalButton)
       
   117             QToolTip::showText(helpEvent->globalPos(), QWorkspace::tr("Restore Down"), this);
       
   118         else
       
   119             QToolTip::hideText();
       
   120 #endif // QT_NO_TOOLTIP
       
   121     }
       
   122     return QWidget::event(event);
       
   123 }
       
   124 
       
   125 void QMDIControl::initStyleOption(QStyleOptionComplex *option) const
       
   126 {
       
   127     option->initFrom(this);
       
   128     option->subControls = QStyle::SC_All;
       
   129     option->activeSubControls = QStyle::SC_None;
       
   130 }
       
   131 
       
   132 QMDIControl::QMDIControl(QWidget *widget)
       
   133     : QWidget(widget), activeControl(QStyle::SC_None),
       
   134       hoverControl(QStyle::SC_None)
       
   135 {
       
   136     setObjectName(QLatin1String("qt_maxcontrols"));
       
   137     setFocusPolicy(Qt::NoFocus);
       
   138     setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
       
   139     setMouseTracking(true);
       
   140 }
       
   141 
       
   142 QSize QMDIControl::sizeHint() const
       
   143 {
       
   144     ensurePolished();
       
   145     QStyleOptionComplex opt;
       
   146     initStyleOption(&opt);
       
   147     QSize size(48, 16);
       
   148     return style()->sizeFromContents(QStyle::CT_MdiControls, &opt, size, this);
       
   149 }
       
   150 
       
   151 void QMDIControl::mousePressEvent(QMouseEvent *event)
       
   152 {
       
   153     if (event->button() != Qt::LeftButton) {
       
   154         event->ignore();
       
   155         return;
       
   156     }
       
   157     QStyleOptionComplex opt;
       
   158     initStyleOption(&opt);
       
   159     QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_MdiControls, &opt,
       
   160                                                              event->pos(), this);
       
   161     activeControl = ctrl;
       
   162     update();
       
   163 }
       
   164 
       
   165 void QMDIControl::mouseReleaseEvent(QMouseEvent *event)
       
   166 {
       
   167     if (event->button() != Qt::LeftButton) {
       
   168         event->ignore();
       
   169         return;
       
   170     }
       
   171     QStyleOptionTitleBar opt;
       
   172     initStyleOption(&opt);
       
   173     QStyle::SubControl under_mouse = style()->hitTestComplexControl(QStyle::CC_MdiControls, &opt,
       
   174                                                                     event->pos(), this);
       
   175     if (under_mouse == activeControl) {
       
   176         switch (activeControl) {
       
   177         case QStyle::SC_MdiCloseButton:
       
   178             emit _q_close();
       
   179             break;
       
   180         case QStyle::SC_MdiNormalButton:
       
   181             emit _q_restore();
       
   182             break;
       
   183         case QStyle::SC_MdiMinButton:
       
   184             emit _q_minimize();
       
   185             break;
       
   186         default:
       
   187             break;
       
   188         }
       
   189     }
       
   190     activeControl = QStyle::SC_None;
       
   191     update();
       
   192 }
       
   193 
       
   194 void QMDIControl::leaveEvent(QEvent * /*event*/)
       
   195 {
       
   196     hoverControl = QStyle::SC_None;
       
   197     update();
       
   198 }
       
   199 
       
   200 void QMDIControl::mouseMoveEvent(QMouseEvent *event)
       
   201 {
       
   202     QStyleOptionTitleBar opt;
       
   203     initStyleOption(&opt);
       
   204     QStyle::SubControl under_mouse = style()->hitTestComplexControl(QStyle::CC_MdiControls, &opt,
       
   205                                                                     event->pos(), this);
       
   206     //test if hover state changes
       
   207     if (hoverControl != under_mouse) {
       
   208         hoverControl = under_mouse;
       
   209         update();
       
   210     }
       
   211 }
       
   212 
       
   213 void QMDIControl::paintEvent(QPaintEvent *)
       
   214 {
       
   215     QPainter p(this);
       
   216     QStyleOptionComplex opt;
       
   217     initStyleOption(&opt);
       
   218     if (activeControl == hoverControl) {
       
   219         opt.activeSubControls = activeControl;
       
   220         opt.state |= QStyle::State_Sunken;
       
   221     } else if (hoverControl != QStyle::SC_None && (activeControl == QStyle::SC_None)) {
       
   222         opt.activeSubControls = hoverControl;
       
   223         opt.state |= QStyle::State_MouseOver;
       
   224     }
       
   225     style()->drawComplexControl(QStyle::CC_MdiControls, &opt, &p, this);
       
   226 }
       
   227 
       
   228 class QWorkspaceTitleBar : public QWidget
       
   229 {
       
   230     Q_OBJECT
       
   231     Q_DECLARE_PRIVATE(QWorkspaceTitleBar)
       
   232     Q_PROPERTY(bool autoRaise READ autoRaise WRITE setAutoRaise)
       
   233     Q_PROPERTY(bool movable READ isMovable WRITE setMovable)
       
   234 
       
   235 public:
       
   236     QWorkspaceTitleBar (QWidget *w, QWidget *parent, Qt::WindowFlags f = 0);
       
   237     ~QWorkspaceTitleBar();
       
   238 
       
   239     bool isActive() const;
       
   240     bool usesActiveColor() const;
       
   241 
       
   242     bool isMovable() const;
       
   243     void setMovable(bool);
       
   244 
       
   245     bool autoRaise() const;
       
   246     void setAutoRaise(bool);
       
   247 
       
   248     QWidget *window() const;
       
   249     bool isTool() const;
       
   250 
       
   251     QSize sizeHint() const;
       
   252     void initStyleOption(QStyleOptionTitleBar *option) const;
       
   253 
       
   254 public slots:
       
   255     void setActive(bool);
       
   256 
       
   257 signals:
       
   258     void doActivate();
       
   259     void doNormal();
       
   260     void doClose();
       
   261     void doMaximize();
       
   262     void doMinimize();
       
   263     void doShade();
       
   264     void showOperationMenu();
       
   265     void popupOperationMenu(const QPoint&);
       
   266     void doubleClicked();
       
   267 
       
   268 protected:
       
   269     bool event(QEvent *);
       
   270 #ifndef QT_NO_CONTEXTMENU
       
   271     void contextMenuEvent(QContextMenuEvent *);
       
   272 #endif
       
   273     void mousePressEvent(QMouseEvent *);
       
   274     void mouseDoubleClickEvent(QMouseEvent *);
       
   275     void mouseReleaseEvent(QMouseEvent *);
       
   276     void mouseMoveEvent(QMouseEvent *);
       
   277     void enterEvent(QEvent *e);
       
   278     void leaveEvent(QEvent *e);
       
   279     void paintEvent(QPaintEvent *p);
       
   280 
       
   281 private:
       
   282     Q_DISABLE_COPY(QWorkspaceTitleBar)
       
   283 };
       
   284 
       
   285 
       
   286 class QWorkspaceTitleBarPrivate : public QWidgetPrivate
       
   287 {
       
   288     Q_DECLARE_PUBLIC(QWorkspaceTitleBar)
       
   289 public:
       
   290     QWorkspaceTitleBarPrivate()
       
   291         :
       
   292         lastControl(QStyle::SC_None),
       
   293 #ifndef QT_NO_TOOLTIP
       
   294         toolTip(0),
       
   295 #endif
       
   296         act(0), window(0), movable(1), pressed(0), autoraise(0), moving(0)
       
   297     {
       
   298     }
       
   299 
       
   300     Qt::WindowFlags flags;
       
   301     QStyle::SubControl buttonDown;
       
   302     QStyle::SubControl lastControl;
       
   303     QPoint moveOffset;
       
   304 #ifndef QT_NO_TOOLTIP
       
   305     QToolTip *toolTip;
       
   306 #endif
       
   307     bool act                    :1;
       
   308     QPointer<QWidget> window;
       
   309     bool movable            :1;
       
   310     bool pressed            :1;
       
   311     bool autoraise          :1;
       
   312     bool moving : 1;
       
   313 
       
   314     int titleBarState() const;
       
   315     void readColors();
       
   316 };
       
   317 
       
   318 inline int QWorkspaceTitleBarPrivate::titleBarState() const
       
   319 {
       
   320     Q_Q(const QWorkspaceTitleBar);
       
   321     uint state = window ? window->windowState() : static_cast<Qt::WindowStates>(Qt::WindowNoState);
       
   322     state |= uint((act && q->isActiveWindow()) ? QStyle::State_Active : QStyle::State_None);
       
   323     return (int)state;
       
   324 }
       
   325 
       
   326 void QWorkspaceTitleBar::initStyleOption(QStyleOptionTitleBar *option) const
       
   327 {
       
   328     Q_D(const QWorkspaceTitleBar);
       
   329     option->initFrom(this);
       
   330     //################
       
   331     if (d->window && (d->flags & Qt::WindowTitleHint)) {
       
   332         option->text = d->window->windowTitle();
       
   333         QIcon icon = d->window->windowIcon();
       
   334         QSize s = icon.actualSize(QSize(64, 64));
       
   335         option->icon = icon.pixmap(s);
       
   336     }
       
   337     option->subControls = QStyle::SC_All;
       
   338     option->activeSubControls = QStyle::SC_None;
       
   339     option->titleBarState = d->titleBarState();
       
   340     option->titleBarFlags = d->flags;
       
   341     option->state &= ~QStyle::State_MouseOver;
       
   342 }
       
   343 
       
   344 QWorkspaceTitleBar::QWorkspaceTitleBar(QWidget *w, QWidget *parent, Qt::WindowFlags f)
       
   345     : QWidget(*new QWorkspaceTitleBarPrivate, parent, Qt::FramelessWindowHint)
       
   346 {
       
   347     Q_D(QWorkspaceTitleBar);
       
   348     if (f == 0 && w)
       
   349         f = w->windowFlags();
       
   350     d->flags = f;
       
   351     d->window = w;
       
   352     d->buttonDown = QStyle::SC_None;
       
   353     d->act = 0;
       
   354     if (w) {
       
   355         if (w->maximumSize() != QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX))
       
   356             d->flags &= ~Qt::WindowMaximizeButtonHint;
       
   357         setWindowTitle(w->windowTitle());
       
   358     }
       
   359 
       
   360     d->readColors();
       
   361     setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
       
   362     setMouseTracking(true);
       
   363     setAutoRaise(style()->styleHint(QStyle::SH_TitleBar_AutoRaise, 0, this));
       
   364 }
       
   365 
       
   366 QWorkspaceTitleBar::~QWorkspaceTitleBar()
       
   367 {
       
   368 }
       
   369 
       
   370 
       
   371 #ifdef Q_WS_WIN
       
   372 static inline QRgb colorref2qrgb(COLORREF col)
       
   373 {
       
   374     return qRgb(GetRValue(col),GetGValue(col),GetBValue(col));
       
   375 }
       
   376 #endif
       
   377 
       
   378 void QWorkspaceTitleBarPrivate::readColors()
       
   379 {
       
   380     Q_Q(QWorkspaceTitleBar);
       
   381     QPalette pal = q->palette();
       
   382 
       
   383     bool colorsInitialized = false;
       
   384 
       
   385 #ifdef Q_WS_WIN // ask system properties on windows
       
   386 #ifndef SPI_GETGRADIENTCAPTIONS
       
   387 #define SPI_GETGRADIENTCAPTIONS 0x1008
       
   388 #endif
       
   389 #ifndef COLOR_GRADIENTACTIVECAPTION
       
   390 #define COLOR_GRADIENTACTIVECAPTION 27
       
   391 #endif
       
   392 #ifndef COLOR_GRADIENTINACTIVECAPTION
       
   393 #define COLOR_GRADIENTINACTIVECAPTION 28
       
   394 #endif
       
   395     if (QApplication::desktopSettingsAware()) {
       
   396         pal.setColor(QPalette::Active, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_ACTIVECAPTION)));
       
   397         pal.setColor(QPalette::Inactive, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION)));
       
   398         pal.setColor(QPalette::Active, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT)));
       
   399         pal.setColor(QPalette::Inactive, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT)));
       
   400 
       
   401         colorsInitialized = true;
       
   402         BOOL gradient = false;
       
   403         SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
       
   404 
       
   405         if (gradient) {
       
   406             pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)));
       
   407             pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)));
       
   408         } else {
       
   409             pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight));
       
   410             pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight));
       
   411         }
       
   412     }
       
   413 #endif // Q_WS_WIN
       
   414     if (!colorsInitialized) {
       
   415         pal.setColor(QPalette::Active, QPalette::Highlight,
       
   416                       pal.color(QPalette::Active, QPalette::Highlight));
       
   417         pal.setColor(QPalette::Active, QPalette::Base,
       
   418                       pal.color(QPalette::Active, QPalette::Highlight));
       
   419         pal.setColor(QPalette::Inactive, QPalette::Highlight,
       
   420                       pal.color(QPalette::Inactive, QPalette::Dark));
       
   421         pal.setColor(QPalette::Inactive, QPalette::Base,
       
   422                       pal.color(QPalette::Inactive, QPalette::Dark));
       
   423         pal.setColor(QPalette::Inactive, QPalette::HighlightedText,
       
   424                       pal.color(QPalette::Inactive, QPalette::Window));
       
   425     }
       
   426 
       
   427     q->setPalette(pal);
       
   428     q->setActive(act);
       
   429 }
       
   430 
       
   431 void QWorkspaceTitleBar::mousePressEvent(QMouseEvent *e)
       
   432 {
       
   433     Q_D(QWorkspaceTitleBar);
       
   434     if (!d->act)
       
   435         emit doActivate();
       
   436     if (e->button() == Qt::LeftButton) {
       
   437         if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, 0)
       
   438             && !rect().adjusted(5, 5, -5, 0).contains(e->pos())) {
       
   439             // propagate border events to the QWidgetResizeHandler
       
   440             e->ignore();
       
   441             return;
       
   442         }
       
   443 
       
   444         d->pressed = true;
       
   445         QStyleOptionTitleBar opt;
       
   446         initStyleOption(&opt);
       
   447         QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
       
   448                                                                  e->pos(), this);
       
   449         switch (ctrl) {
       
   450         case QStyle::SC_TitleBarSysMenu:
       
   451             if (d->flags & Qt::WindowSystemMenuHint) {
       
   452                 d->buttonDown = QStyle::SC_None;
       
   453                 static QTime *t = 0;
       
   454                 static QWorkspaceTitleBar *tc = 0;
       
   455                 if (!t)
       
   456                     t = new QTime;
       
   457                 if (tc != this || t->elapsed() > QApplication::doubleClickInterval()) {
       
   458                     emit showOperationMenu();
       
   459                     t->start();
       
   460                     tc = this;
       
   461                 } else {
       
   462                     tc = 0;
       
   463                     emit doClose();
       
   464                     return;
       
   465                 }
       
   466             }
       
   467             break;
       
   468 
       
   469         case QStyle::SC_TitleBarShadeButton:
       
   470         case QStyle::SC_TitleBarUnshadeButton:
       
   471             if (d->flags & Qt::WindowShadeButtonHint)
       
   472                 d->buttonDown = ctrl;
       
   473             break;
       
   474 
       
   475         case QStyle::SC_TitleBarNormalButton:
       
   476                 d->buttonDown = ctrl;
       
   477             break;
       
   478 
       
   479         case QStyle::SC_TitleBarMinButton:
       
   480             if (d->flags & Qt::WindowMinimizeButtonHint)
       
   481                 d->buttonDown = ctrl;
       
   482             break;
       
   483 
       
   484         case QStyle::SC_TitleBarMaxButton:
       
   485             if (d->flags & Qt::WindowMaximizeButtonHint)
       
   486                 d->buttonDown = ctrl;
       
   487             break;
       
   488 
       
   489         case QStyle::SC_TitleBarCloseButton:
       
   490             if (d->flags & Qt::WindowSystemMenuHint)
       
   491                 d->buttonDown = ctrl;
       
   492             break;
       
   493 
       
   494         case QStyle::SC_TitleBarLabel:
       
   495             d->buttonDown = ctrl;
       
   496             d->moveOffset = mapToParent(e->pos());
       
   497             break;
       
   498 
       
   499         default:
       
   500             break;
       
   501         }
       
   502         update();
       
   503     } else {
       
   504         d->pressed = false;
       
   505     }
       
   506 }
       
   507 
       
   508 #ifndef QT_NO_CONTEXTMENU
       
   509 void QWorkspaceTitleBar::contextMenuEvent(QContextMenuEvent *e)
       
   510 {
       
   511     QStyleOptionTitleBar opt;
       
   512     initStyleOption(&opt);
       
   513     QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt, e->pos(),
       
   514                                                              this);
       
   515     if(ctrl == QStyle::SC_TitleBarLabel || ctrl == QStyle::SC_TitleBarSysMenu) {
       
   516         e->accept();
       
   517         emit popupOperationMenu(e->globalPos());
       
   518     } else {
       
   519         e->ignore();
       
   520     }
       
   521 }
       
   522 #endif // QT_NO_CONTEXTMENU
       
   523 
       
   524 void QWorkspaceTitleBar::mouseReleaseEvent(QMouseEvent *e)
       
   525 {
       
   526     Q_D(QWorkspaceTitleBar);
       
   527     if (!d->window) {
       
   528         // could have been deleted as part of a double click event on the sysmenu
       
   529         return;
       
   530     }
       
   531     if (e->button() == Qt::LeftButton && d->pressed) {
       
   532         if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, 0)
       
   533             && !rect().adjusted(5, 5, -5, 0).contains(e->pos())) {
       
   534             // propagate border events to the QWidgetResizeHandler
       
   535             e->ignore();
       
   536             d->buttonDown = QStyle::SC_None;
       
   537             d->pressed = false;
       
   538             return;
       
   539         }
       
   540         e->accept();
       
   541         QStyleOptionTitleBar opt;
       
   542         initStyleOption(&opt);
       
   543         QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
       
   544                                                                  e->pos(), this);
       
   545 
       
   546         if (d->pressed) {
       
   547             update();
       
   548             d->pressed = false;
       
   549             d->moving = false;
       
   550         }
       
   551         if (ctrl == d->buttonDown) {
       
   552             d->buttonDown = QStyle::SC_None;
       
   553             switch(ctrl) {
       
   554             case QStyle::SC_TitleBarShadeButton:
       
   555             case QStyle::SC_TitleBarUnshadeButton:
       
   556                 if(d->flags & Qt::WindowShadeButtonHint)
       
   557                     emit doShade();
       
   558                 break;
       
   559 
       
   560             case QStyle::SC_TitleBarNormalButton:
       
   561                 if(d->flags & Qt::WindowMinMaxButtonsHint)
       
   562                     emit doNormal();
       
   563                 break;
       
   564 
       
   565             case QStyle::SC_TitleBarMinButton:
       
   566                 if(d->flags & Qt::WindowMinimizeButtonHint) {
       
   567                     if (d->window && d->window->isMinimized())
       
   568                         emit doNormal();
       
   569                     else
       
   570                         emit doMinimize();
       
   571                 }
       
   572                 break;
       
   573 
       
   574             case QStyle::SC_TitleBarMaxButton:
       
   575                 if(d->flags & Qt::WindowMaximizeButtonHint) {
       
   576                     if(d->window && d->window->isMaximized())
       
   577                         emit doNormal();
       
   578                     else
       
   579                         emit doMaximize();
       
   580                 }
       
   581                 break;
       
   582 
       
   583             case QStyle::SC_TitleBarCloseButton:
       
   584                 if(d->flags & Qt::WindowSystemMenuHint) {
       
   585                     d->buttonDown = QStyle::SC_None;
       
   586                     emit doClose();
       
   587                     return;
       
   588                 }
       
   589                 break;
       
   590 
       
   591             default:
       
   592                 break;
       
   593             }
       
   594         }
       
   595     } else {
       
   596         e->ignore();
       
   597     }
       
   598 }
       
   599 
       
   600 void QWorkspaceTitleBar::mouseMoveEvent(QMouseEvent *e)
       
   601 {
       
   602     Q_D(QWorkspaceTitleBar);
       
   603     e->ignore();
       
   604     if ((e->buttons() & Qt::LeftButton) && style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, 0)
       
   605         && !rect().adjusted(5, 5, -5, 0).contains(e->pos()) && !d->pressed) {
       
   606         // propagate border events to the QWidgetResizeHandler
       
   607         return;
       
   608     }
       
   609 
       
   610     QStyleOptionTitleBar opt;
       
   611     initStyleOption(&opt);
       
   612     QStyle::SubControl under_mouse = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
       
   613                                                                     e->pos(), this);
       
   614     if(under_mouse != d->lastControl) {
       
   615         d->lastControl = under_mouse;
       
   616         update();
       
   617     }
       
   618 
       
   619     switch (d->buttonDown) {
       
   620     case QStyle::SC_None:
       
   621         break;
       
   622     case QStyle::SC_TitleBarSysMenu:
       
   623         break;
       
   624     case QStyle::SC_TitleBarLabel:
       
   625         if (d->buttonDown == QStyle::SC_TitleBarLabel && d->movable && d->pressed) {
       
   626             if (d->moving || (d->moveOffset - mapToParent(e->pos())).manhattanLength() >= 4) {
       
   627                 d->moving = true;
       
   628                 QPoint p = mapFromGlobal(e->globalPos());
       
   629 
       
   630                 QWidget *parent = d->window ? d->window->parentWidget() : 0;
       
   631                 if(parent && parent->inherits("QWorkspaceChild")) {
       
   632                     QWidget *workspace = parent->parentWidget();
       
   633                     p = workspace->mapFromGlobal(e->globalPos());
       
   634                     if (!workspace->rect().contains(p)) {
       
   635                         if (p.x() < 0)
       
   636                             p.rx() = 0;
       
   637                         if (p.y() < 0)
       
   638                             p.ry() = 0;
       
   639                         if (p.x() > workspace->width())
       
   640                             p.rx() = workspace->width();
       
   641                         if (p.y() > workspace->height())
       
   642                             p.ry() = workspace->height();
       
   643                     }
       
   644                 }
       
   645 
       
   646                 QPoint pp = p - d->moveOffset;
       
   647                 if (!parentWidget()->isMaximized())
       
   648                     parentWidget()->move(pp);
       
   649             }
       
   650         }
       
   651         e->accept();
       
   652         break;
       
   653     default:
       
   654         break;
       
   655     }
       
   656 }
       
   657 
       
   658 bool QWorkspaceTitleBar::isTool() const
       
   659 {
       
   660     Q_D(const QWorkspaceTitleBar);
       
   661     return (d->flags & Qt::WindowType_Mask) == Qt::Tool;
       
   662 }
       
   663 
       
   664 // from qwidget.cpp
       
   665 extern QString qt_setWindowTitle_helperHelper(const QString &, const QWidget*);
       
   666 
       
   667 void QWorkspaceTitleBar::paintEvent(QPaintEvent *)
       
   668 {
       
   669     Q_D(QWorkspaceTitleBar);
       
   670     QStyleOptionTitleBar opt;
       
   671     initStyleOption(&opt);
       
   672     opt.subControls = QStyle::SC_TitleBarLabel;
       
   673     opt.activeSubControls = d->buttonDown;
       
   674 
       
   675     if (d->window && (d->flags & Qt::WindowTitleHint)) {
       
   676         QString title = qt_setWindowTitle_helperHelper(opt.text, d->window);
       
   677         int maxw = style()->subControlRect(QStyle::CC_TitleBar, &opt, QStyle::SC_TitleBarLabel,
       
   678                                        this).width();
       
   679         opt.text = fontMetrics().elidedText(title, Qt::ElideRight, maxw);
       
   680     }
       
   681 
       
   682     if (d->flags & Qt::WindowSystemMenuHint) {
       
   683         opt.subControls |= QStyle::SC_TitleBarSysMenu | QStyle::SC_TitleBarCloseButton;
       
   684         if (d->window && (d->flags & Qt::WindowShadeButtonHint)) {
       
   685             if (d->window->isMinimized())
       
   686                 opt.subControls |= QStyle::SC_TitleBarUnshadeButton;
       
   687             else
       
   688                 opt.subControls |= QStyle::SC_TitleBarShadeButton;
       
   689         }
       
   690         if (d->window && (d->flags & Qt::WindowMinMaxButtonsHint)) {
       
   691             if(d->window && d->window->isMinimized())
       
   692                 opt.subControls |= QStyle::SC_TitleBarNormalButton;
       
   693             else
       
   694                 opt.subControls |= QStyle::SC_TitleBarMinButton;
       
   695         }
       
   696         if (d->window && (d->flags & Qt::WindowMaximizeButtonHint) && !d->window->isMaximized())
       
   697             opt.subControls |= QStyle::SC_TitleBarMaxButton;
       
   698     }
       
   699 
       
   700     QStyle::SubControl under_mouse = QStyle::SC_None;
       
   701     under_mouse = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
       
   702                                                      mapFromGlobal(QCursor::pos()), this);
       
   703     if ((d->buttonDown == under_mouse) && d->pressed) {
       
   704         opt.state |= QStyle::State_Sunken;
       
   705     } else if( autoRaise() && under_mouse != QStyle::SC_None && !d->pressed) {
       
   706         opt.activeSubControls = under_mouse;
       
   707         opt.state |= QStyle::State_MouseOver;
       
   708     }
       
   709     opt.palette.setCurrentColorGroup(usesActiveColor() ? QPalette::Active : QPalette::Inactive);
       
   710 
       
   711     QPainter p(this);
       
   712     style()->drawComplexControl(QStyle::CC_TitleBar, &opt, &p, this);
       
   713 }
       
   714 
       
   715 void QWorkspaceTitleBar::mouseDoubleClickEvent(QMouseEvent *e)
       
   716 {
       
   717     Q_D(QWorkspaceTitleBar);
       
   718     if (e->button() != Qt::LeftButton) {
       
   719         e->ignore();
       
   720         return;
       
   721     }
       
   722     e->accept();
       
   723     QStyleOptionTitleBar opt;
       
   724     initStyleOption(&opt);
       
   725     switch (style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt, e->pos(), this)) {
       
   726     case QStyle::SC_TitleBarLabel:
       
   727         emit doubleClicked();
       
   728         break;
       
   729 
       
   730     case QStyle::SC_TitleBarSysMenu:
       
   731         if (d->flags & Qt::WindowSystemMenuHint)
       
   732             emit doClose();
       
   733         break;
       
   734 
       
   735     default:
       
   736         break;
       
   737     }
       
   738 }
       
   739 
       
   740 void QWorkspaceTitleBar::leaveEvent(QEvent *)
       
   741 {
       
   742     Q_D(QWorkspaceTitleBar);
       
   743     d->lastControl = QStyle::SC_None;
       
   744     if(autoRaise() && !d->pressed)
       
   745         update();
       
   746 }
       
   747 
       
   748 void QWorkspaceTitleBar::enterEvent(QEvent *)
       
   749 {
       
   750     Q_D(QWorkspaceTitleBar);
       
   751     if(autoRaise() && !d->pressed)
       
   752         update();
       
   753     QEvent e(QEvent::Leave);
       
   754     QApplication::sendEvent(parentWidget(), &e);
       
   755 }
       
   756 
       
   757 void QWorkspaceTitleBar::setActive(bool active)
       
   758 {
       
   759     Q_D(QWorkspaceTitleBar);
       
   760     if (d->act == active)
       
   761         return ;
       
   762 
       
   763     d->act = active;
       
   764     update();
       
   765 }
       
   766 
       
   767 bool QWorkspaceTitleBar::isActive() const
       
   768 {
       
   769     Q_D(const QWorkspaceTitleBar);
       
   770     return d->act;
       
   771 }
       
   772 
       
   773 bool QWorkspaceTitleBar::usesActiveColor() const
       
   774 {
       
   775     return (isActive() && isActiveWindow()) ||
       
   776         (!window() && QWidget::window()->isActiveWindow());
       
   777 }
       
   778 
       
   779 QWidget *QWorkspaceTitleBar::window() const
       
   780 {
       
   781     Q_D(const QWorkspaceTitleBar);
       
   782     return d->window;
       
   783 }
       
   784 
       
   785 bool QWorkspaceTitleBar::event(QEvent *e)
       
   786 {
       
   787     Q_D(QWorkspaceTitleBar);
       
   788     if (e->type() == QEvent::ApplicationPaletteChange) {
       
   789         d->readColors();
       
   790     } else if (e->type() == QEvent::WindowActivate
       
   791                || e->type() == QEvent::WindowDeactivate) {
       
   792         if (d->act)
       
   793             update();
       
   794     }
       
   795     return QWidget::event(e);
       
   796 }
       
   797 
       
   798 void QWorkspaceTitleBar::setMovable(bool b)
       
   799 {
       
   800     Q_D(QWorkspaceTitleBar);
       
   801     d->movable = b;
       
   802 }
       
   803 
       
   804 bool QWorkspaceTitleBar::isMovable() const
       
   805 {
       
   806     Q_D(const QWorkspaceTitleBar);
       
   807     return d->movable;
       
   808 }
       
   809 
       
   810 void QWorkspaceTitleBar::setAutoRaise(bool b)
       
   811 {
       
   812     Q_D(QWorkspaceTitleBar);
       
   813     d->autoraise = b;
       
   814 }
       
   815 
       
   816 bool QWorkspaceTitleBar::autoRaise() const
       
   817 {
       
   818     Q_D(const QWorkspaceTitleBar);
       
   819     return d->autoraise;
       
   820 }
       
   821 
       
   822 QSize QWorkspaceTitleBar::sizeHint() const
       
   823 {
       
   824     ensurePolished();
       
   825     QStyleOptionTitleBar opt;
       
   826     initStyleOption(&opt);
       
   827     QRect menur = style()->subControlRect(QStyle::CC_TitleBar, &opt,
       
   828                                           QStyle::SC_TitleBarSysMenu, this);
       
   829     return QSize(menur.width(), style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt, this));
       
   830 }
       
   831 
       
   832 /*!
       
   833     \class QWorkspace
       
   834     \obsolete
       
   835     \brief The QWorkspace widget provides a workspace window that can be
       
   836     used in an MDI application.
       
   837 
       
   838     This class is deprecated. Use QMdiArea instead.
       
   839 
       
   840     Multiple Document Interface (MDI) applications are typically
       
   841     composed of a main window containing a menu bar, a toolbar, and
       
   842     a central QWorkspace widget. The workspace itself is used to display
       
   843     a number of child windows, each of which is a widget.
       
   844 
       
   845     The workspace itself is an ordinary Qt widget. It has a standard
       
   846     constructor that takes a parent widget.
       
   847     Workspaces can be placed in any layout, but are typically given
       
   848     as the central widget in a QMainWindow:
       
   849 
       
   850     \snippet doc/src/snippets/code/src_gui_widgets_qworkspace.cpp 0
       
   851 
       
   852     Child windows (MDI windows) are standard Qt widgets that are
       
   853     inserted into the workspace with addWindow(). As with top-level
       
   854     widgets, you can call functions such as show(), hide(),
       
   855     showMaximized(), and setWindowTitle() on a child window to change
       
   856     its appearance within the workspace. You can also provide widget
       
   857     flags to determine the layout of the decoration or the behavior of
       
   858     the widget itself.
       
   859 
       
   860     To change or retrieve the geometry of a child window, you must
       
   861     operate on its parentWidget(). The parentWidget() provides
       
   862     access to the decorated frame that contains the child window
       
   863     widget. When a child window is maximised, its decorated frame
       
   864     is hidden. If the top-level widget contains a menu bar, it will display
       
   865     the maximised window's operations menu to the left of the menu
       
   866     entries, and the window's controls to the right.
       
   867 
       
   868     A child window becomes active when it gets the keyboard focus,
       
   869     or when setFocus() is called. The user can activate a window by moving
       
   870     focus in the usual ways, for example by clicking a window or by pressing
       
   871     Tab. The workspace emits a signal windowActivated() when the active
       
   872     window changes, and the function activeWindow() returns a pointer to the
       
   873     active child window, or 0 if no window is active.
       
   874 
       
   875     The convenience function windowList() returns a list of all child
       
   876     windows. This information could be used in a popup menu
       
   877     containing a list of windows, for example. This feature is also
       
   878     available as part of the \l{Window Menu} Solution.
       
   879 
       
   880     QWorkspace provides two built-in layout strategies for child
       
   881     windows: cascade() and tile(). Both are slots so you can easily
       
   882     connect menu entries to them.
       
   883 
       
   884     \table
       
   885     \row \o \inlineimage mdi-cascade.png
       
   886          \o \inlineimage mdi-tile.png
       
   887     \endtable
       
   888 
       
   889     If you want your users to be able to work with child windows
       
   890     larger than the visible workspace area, set the scrollBarsEnabled
       
   891     property to true.
       
   892 
       
   893     \sa QDockWidget, {MDI Example}
       
   894 */
       
   895 
       
   896 
       
   897 class QWorkspaceChild : public QWidget
       
   898 {
       
   899     Q_OBJECT
       
   900 
       
   901     friend class QWorkspacePrivate;
       
   902     friend class QWorkspace;
       
   903     friend class QWorkspaceTitleBar;
       
   904 
       
   905 public:
       
   906     QWorkspaceChild(QWidget* window, QWorkspace* parent=0, Qt::WindowFlags flags = 0);
       
   907     ~QWorkspaceChild();
       
   908 
       
   909     void setActive(bool);
       
   910     bool isActive() const;
       
   911 
       
   912     void adjustToFullscreen();
       
   913 
       
   914     QWidget* windowWidget() const;
       
   915     QWidget* iconWidget() const;
       
   916 
       
   917     void doResize();
       
   918     void doMove();
       
   919 
       
   920     QSize sizeHint() const;
       
   921     QSize minimumSizeHint() const;
       
   922 
       
   923     QSize baseSize() const;
       
   924 
       
   925     int frameWidth() const;
       
   926 
       
   927     void show();
       
   928 
       
   929     bool isWindowOrIconVisible() const;
       
   930 
       
   931 signals:
       
   932     void showOperationMenu();
       
   933     void popupOperationMenu(const QPoint&);
       
   934 
       
   935 public slots:
       
   936     void activate();
       
   937     void showMinimized();
       
   938     void showMaximized();
       
   939     void showNormal();
       
   940     void showShaded();
       
   941     void internalRaise();
       
   942     void titleBarDoubleClicked();
       
   943 
       
   944 protected:
       
   945     void enterEvent(QEvent *);
       
   946     void leaveEvent(QEvent *);
       
   947     void childEvent(QChildEvent*);
       
   948     void resizeEvent(QResizeEvent *);
       
   949     void moveEvent(QMoveEvent *);
       
   950     bool eventFilter(QObject *, QEvent *);
       
   951 
       
   952     void paintEvent(QPaintEvent *);
       
   953     void changeEvent(QEvent *);
       
   954 
       
   955 private:
       
   956     void updateMask();
       
   957 
       
   958     Q_DISABLE_COPY(QWorkspaceChild)
       
   959 
       
   960     QWidget *childWidget;
       
   961     QWidgetResizeHandler *widgetResizeHandler;
       
   962     QWorkspaceTitleBar *titlebar;
       
   963     QPointer<QWorkspaceTitleBar> iconw;
       
   964     QSize windowSize;
       
   965     QSize shadeRestore;
       
   966     QSize shadeRestoreMin;
       
   967     bool act                  :1;
       
   968     bool shademode            :1;
       
   969 };
       
   970 
       
   971 int QWorkspaceChild::frameWidth() const
       
   972 {
       
   973     return contentsRect().left();
       
   974 }
       
   975 
       
   976 
       
   977 
       
   978 class QWorkspacePrivate : public QWidgetPrivate {
       
   979     Q_DECLARE_PUBLIC(QWorkspace)
       
   980 public:
       
   981     QWorkspaceChild* active;
       
   982     QList<QWorkspaceChild *> windows;
       
   983     QList<QWorkspaceChild *> focus;
       
   984     QList<QWidget *> icons;
       
   985     QWorkspaceChild* maxWindow;
       
   986     QRect maxRestore;
       
   987     QPointer<QMDIControl> maxcontrols;
       
   988     QPointer<QMenuBar> maxmenubar;
       
   989     QHash<int, const char*> shortcutMap;
       
   990 
       
   991     int px;
       
   992     int py;
       
   993     QWidget *becomeActive;
       
   994     QPointer<QLabel> maxtools;
       
   995     QString topTitle;
       
   996 
       
   997     QMenu *popup, *toolPopup;
       
   998     enum WSActs { RestoreAct, MoveAct, ResizeAct, MinimizeAct, MaximizeAct, CloseAct, StaysOnTopAct, ShadeAct, NCountAct };
       
   999     QAction *actions[NCountAct];
       
  1000 
       
  1001     QScrollBar *vbar, *hbar;
       
  1002     QWidget *corner;
       
  1003     int yoffset, xoffset;
       
  1004     QBrush background;
       
  1005 
       
  1006     void init();
       
  1007     void insertIcon(QWidget* w);
       
  1008     void removeIcon(QWidget* w);
       
  1009     void place(QWidget*);
       
  1010 
       
  1011     QWorkspaceChild* findChild(QWidget* w);
       
  1012     void showMaximizeControls();
       
  1013     void hideMaximizeControls();
       
  1014     void activateWindow(QWidget* w, bool change_focus = true);
       
  1015     void hideChild(QWorkspaceChild *c);
       
  1016     void showWindow(QWidget* w);
       
  1017     void maximizeWindow(QWidget* w);
       
  1018     void minimizeWindow(QWidget* w);
       
  1019     void normalizeWindow(QWidget* w);
       
  1020 
       
  1021     QRect updateWorkspace();
       
  1022 
       
  1023 private:
       
  1024     void _q_normalizeActiveWindow();
       
  1025     void _q_minimizeActiveWindow();
       
  1026     void _q_showOperationMenu();
       
  1027     void _q_popupOperationMenu(const QPoint&);
       
  1028     void _q_operationMenuActivated(QAction *);
       
  1029     void _q_scrollBarChanged();
       
  1030     void _q_updateActions();
       
  1031     bool inTitleChange;
       
  1032 };
       
  1033 
       
  1034 static bool isChildOf(QWidget * child, QWidget * parent)
       
  1035 {
       
  1036     if (!parent || !child)
       
  1037         return false;
       
  1038     QWidget * w = child;
       
  1039     while(w && w != parent)
       
  1040         w = w->parentWidget();
       
  1041     return w != 0;
       
  1042 }
       
  1043 
       
  1044 /*!
       
  1045     Constructs a workspace with the given \a parent.
       
  1046 */
       
  1047 QWorkspace::QWorkspace(QWidget *parent)
       
  1048     : QWidget(*new QWorkspacePrivate, parent, 0)
       
  1049 {
       
  1050     Q_D(QWorkspace);
       
  1051     d->init();
       
  1052 }
       
  1053 
       
  1054 #ifdef QT3_SUPPORT
       
  1055 /*!
       
  1056     Use one of the constructors that doesn't take the \a name
       
  1057     argument and then use setObjectName() instead.
       
  1058 */
       
  1059 QWorkspace::QWorkspace(QWidget *parent, const char *name)
       
  1060     : QWidget(*new QWorkspacePrivate, parent, 0)
       
  1061 {
       
  1062     Q_D(QWorkspace);
       
  1063     setObjectName(QString::fromAscii(name));
       
  1064     d->init();
       
  1065 }
       
  1066 #endif // QT3_SUPPORT
       
  1067 
       
  1068 /*!
       
  1069     \internal
       
  1070 */
       
  1071 void
       
  1072 QWorkspacePrivate::init()
       
  1073 {
       
  1074     Q_Q(QWorkspace);
       
  1075 
       
  1076     maxcontrols = 0;
       
  1077     active = 0;
       
  1078     maxWindow = 0;
       
  1079     maxtools = 0;
       
  1080     px = 0;
       
  1081     py = 0;
       
  1082     becomeActive = 0;
       
  1083     popup = new QMenu(q);
       
  1084     toolPopup = new QMenu(q);
       
  1085     popup->setObjectName(QLatin1String("qt_internal_mdi_popup"));
       
  1086     toolPopup->setObjectName(QLatin1String("qt_internal_mdi_tool_popup"));
       
  1087 
       
  1088     actions[QWorkspacePrivate::RestoreAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarNormalButton, 0, q)),
       
  1089                                                          QWorkspace::tr("&Restore"), q);
       
  1090     actions[QWorkspacePrivate::MoveAct] = new QAction(QWorkspace::tr("&Move"), q);
       
  1091     actions[QWorkspacePrivate::ResizeAct] = new QAction(QWorkspace::tr("&Size"), q);
       
  1092     actions[QWorkspacePrivate::MinimizeAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarMinButton, 0, q)),
       
  1093                                                           QWorkspace::tr("Mi&nimize"), q);
       
  1094     actions[QWorkspacePrivate::MaximizeAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarMaxButton, 0, q)),
       
  1095                                                           QWorkspace::tr("Ma&ximize"), q);
       
  1096     actions[QWorkspacePrivate::CloseAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarCloseButton, 0, q)),
       
  1097                                                           QWorkspace::tr("&Close")
       
  1098 #ifndef QT_NO_SHORTCUT
       
  1099                                                           +QLatin1Char('\t')+(QString)QKeySequence(Qt::CTRL+Qt::Key_F4)
       
  1100 #endif
       
  1101                                                           ,q);
       
  1102     QObject::connect(actions[QWorkspacePrivate::CloseAct], SIGNAL(triggered()), q, SLOT(closeActiveWindow()));
       
  1103     actions[QWorkspacePrivate::StaysOnTopAct] = new QAction(QWorkspace::tr("Stay on &Top"), q);
       
  1104     actions[QWorkspacePrivate::StaysOnTopAct]->setChecked(true);
       
  1105     actions[QWorkspacePrivate::ShadeAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarShadeButton, 0, q)),
       
  1106                                                           QWorkspace::tr("Sh&ade"), q);
       
  1107 
       
  1108     QObject::connect(popup, SIGNAL(aboutToShow()), q, SLOT(_q_updateActions()));
       
  1109     QObject::connect(popup, SIGNAL(triggered(QAction*)), q, SLOT(_q_operationMenuActivated(QAction*)));
       
  1110     popup->addAction(actions[QWorkspacePrivate::RestoreAct]);
       
  1111     popup->addAction(actions[QWorkspacePrivate::MoveAct]);
       
  1112     popup->addAction(actions[QWorkspacePrivate::ResizeAct]);
       
  1113     popup->addAction(actions[QWorkspacePrivate::MinimizeAct]);
       
  1114     popup->addAction(actions[QWorkspacePrivate::MaximizeAct]);
       
  1115     popup->addSeparator();
       
  1116     popup->addAction(actions[QWorkspacePrivate::CloseAct]);
       
  1117 
       
  1118     QObject::connect(toolPopup, SIGNAL(aboutToShow()), q, SLOT(_q_updateActions()));
       
  1119     QObject::connect(toolPopup, SIGNAL(triggered(QAction*)), q, SLOT(_q_operationMenuActivated(QAction*)));
       
  1120     toolPopup->addAction(actions[QWorkspacePrivate::MoveAct]);
       
  1121     toolPopup->addAction(actions[QWorkspacePrivate::ResizeAct]);
       
  1122     toolPopup->addAction(actions[QWorkspacePrivate::StaysOnTopAct]);
       
  1123     toolPopup->addSeparator();
       
  1124     toolPopup->addAction(actions[QWorkspacePrivate::ShadeAct]);
       
  1125     toolPopup->addAction(actions[QWorkspacePrivate::CloseAct]);
       
  1126 
       
  1127 #ifndef QT_NO_SHORTCUT
       
  1128     // Set up shortcut bindings (id -> slot), most used first
       
  1129     QList <QKeySequence> shortcuts = QKeySequence::keyBindings(QKeySequence::NextChild);
       
  1130     foreach (const QKeySequence &seq, shortcuts)
       
  1131         shortcutMap.insert(q->grabShortcut(seq), "activateNextWindow");
       
  1132 
       
  1133     shortcuts = QKeySequence::keyBindings(QKeySequence::PreviousChild);
       
  1134     foreach (const QKeySequence &seq, shortcuts)
       
  1135         shortcutMap.insert(q->grabShortcut(seq), "activatePreviousWindow");
       
  1136 
       
  1137     shortcuts = QKeySequence::keyBindings(QKeySequence::Close);
       
  1138     foreach (const QKeySequence &seq, shortcuts)
       
  1139         shortcutMap.insert(q->grabShortcut(seq), "closeActiveWindow");
       
  1140 
       
  1141     shortcutMap.insert(q->grabShortcut(QKeySequence(QLatin1String("ALT+-"))), "_q_showOperationMenu");
       
  1142 #endif // QT_NO_SHORTCUT
       
  1143 
       
  1144     q->setBackgroundRole(QPalette::Dark);
       
  1145     q->setAutoFillBackground(true);
       
  1146     q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
       
  1147 
       
  1148     hbar = vbar = 0;
       
  1149     corner = 0;
       
  1150     xoffset = yoffset = 0;
       
  1151 
       
  1152     q->window()->installEventFilter(q);
       
  1153 
       
  1154     inTitleChange = false;
       
  1155     updateWorkspace();
       
  1156 }
       
  1157 
       
  1158 /*!
       
  1159     Destroys the workspace and frees any allocated resources.
       
  1160 */
       
  1161 
       
  1162 QWorkspace::~QWorkspace()
       
  1163 {
       
  1164 }
       
  1165 
       
  1166 /*! \reimp */
       
  1167 QSize QWorkspace::sizeHint() const
       
  1168 {
       
  1169     QSize s(QApplication::desktop()->size());
       
  1170     return QSize(s.width()*2/3, s.height()*2/3);
       
  1171 }
       
  1172 
       
  1173 
       
  1174 #ifdef QT3_SUPPORT
       
  1175 /*!
       
  1176     Sets the background color to \a c.
       
  1177     Use setBackground() instead.
       
  1178 */
       
  1179 void QWorkspace::setPaletteBackgroundColor(const QColor & c)
       
  1180 {
       
  1181     setBackground(c);
       
  1182 }
       
  1183 
       
  1184 /*!
       
  1185     Sets the background pixmap to \a pm.
       
  1186     Use setBackground() instead.
       
  1187 */
       
  1188 void QWorkspace::setPaletteBackgroundPixmap(const QPixmap & pm)
       
  1189 {
       
  1190     setBackground(pm);
       
  1191 }
       
  1192 #endif // QT3_SUPPORT
       
  1193 
       
  1194 /*!
       
  1195     \property QWorkspace::background
       
  1196     \brief the workspace's background
       
  1197 */
       
  1198 QBrush QWorkspace::background() const
       
  1199 {
       
  1200     Q_D(const QWorkspace);
       
  1201     if (d->background.style() == Qt::NoBrush)
       
  1202         return palette().dark();
       
  1203     return d->background;
       
  1204 }
       
  1205 
       
  1206 void QWorkspace::setBackground(const QBrush &background)
       
  1207 {
       
  1208     Q_D(QWorkspace);
       
  1209     d->background = background;
       
  1210     setAttribute(Qt::WA_OpaquePaintEvent, background.style() == Qt::NoBrush);
       
  1211     update();
       
  1212 }
       
  1213 
       
  1214 /*!
       
  1215     Adds widget \a w as new sub window to the workspace.  If \a flags
       
  1216     are non-zero, they will override the flags set on the widget.
       
  1217 
       
  1218     Returns the widget used for the window frame.
       
  1219 
       
  1220     To remove the widget \a w from the workspace, simply call
       
  1221     setParent() with the new parent (or 0 to make it a stand-alone
       
  1222     window).
       
  1223 */
       
  1224 QWidget * QWorkspace::addWindow(QWidget *w, Qt::WindowFlags flags)
       
  1225 {
       
  1226     Q_D(QWorkspace);
       
  1227     if (!w)
       
  1228         return 0;
       
  1229 
       
  1230     w->setAutoFillBackground(true);
       
  1231 
       
  1232     QWidgetPrivate::adjustFlags(flags);
       
  1233 
       
  1234 #if 0
       
  1235     bool wasMaximized = w->isMaximized();
       
  1236     bool wasMinimized = w->isMinimized();
       
  1237 #endif
       
  1238     bool hasSize = w->testAttribute(Qt::WA_Resized);
       
  1239     int x = w->x();
       
  1240     int y = w->y();
       
  1241     bool hasPos = w->testAttribute(Qt::WA_Moved);
       
  1242     QSize s = w->size().expandedTo(qSmartMinSize(w));
       
  1243     if (!hasSize && w->sizeHint().isValid())
       
  1244         w->adjustSize();
       
  1245 
       
  1246     QWorkspaceChild* child = new QWorkspaceChild(w, this, flags);
       
  1247     child->setObjectName(QLatin1String("qt_workspacechild"));
       
  1248     child->installEventFilter(this);
       
  1249 
       
  1250     connect(child, SIGNAL(popupOperationMenu(QPoint)),
       
  1251             this, SLOT(_q_popupOperationMenu(QPoint)));
       
  1252     connect(child, SIGNAL(showOperationMenu()),
       
  1253             this, SLOT(_q_showOperationMenu()));
       
  1254     d->windows.append(child);
       
  1255     if (child->isVisibleTo(this))
       
  1256         d->focus.append(child);
       
  1257     child->internalRaise();
       
  1258 
       
  1259     if (!hasPos)
       
  1260         d->place(child);
       
  1261     if (!hasSize)
       
  1262         child->adjustSize();
       
  1263     if (hasPos)
       
  1264         child->move(x, y);
       
  1265 
       
  1266     return child;
       
  1267 
       
  1268 #if 0
       
  1269     if (wasMaximized)
       
  1270         w->showMaximized();
       
  1271     else if (wasMinimized)
       
  1272         w->showMinimized();
       
  1273     else if (!hasBeenHidden)
       
  1274         d->activateWindow(w);
       
  1275 
       
  1276     d->updateWorkspace();
       
  1277     return child;
       
  1278 #endif
       
  1279 }
       
  1280 
       
  1281 /*! \reimp */
       
  1282 void QWorkspace::childEvent(QChildEvent * e)
       
  1283 {
       
  1284     Q_D(QWorkspace);
       
  1285     if (e->removed()) {
       
  1286         if (d->windows.removeAll(static_cast<QWorkspaceChild*>(e->child()))) {
       
  1287             d->focus.removeAll(static_cast<QWorkspaceChild*>(e->child()));
       
  1288             if (d->maxWindow == e->child())
       
  1289                 d->maxWindow = 0;
       
  1290             d->updateWorkspace();
       
  1291         }
       
  1292     }
       
  1293 }
       
  1294 
       
  1295 /*! \reimp */
       
  1296 #ifndef QT_NO_WHEELEVENT
       
  1297 void QWorkspace::wheelEvent(QWheelEvent *e)
       
  1298 {
       
  1299     Q_D(QWorkspace);
       
  1300     if (!scrollBarsEnabled())
       
  1301         return;
       
  1302     // the scroll bars are children of the workspace, so if we receive
       
  1303     // a wheel event we redirect to the scroll bars using a direct event
       
  1304     // call, /not/ using sendEvent() because if the scroll bar ignores the
       
  1305     // event QApplication::sendEvent() will propagate the event to the parent widget,
       
  1306     // which is us, who /just/ sent it.
       
  1307     if (d->vbar && d->vbar->isVisible() && !(e->modifiers() & Qt::AltModifier))
       
  1308         d->vbar->event(e);
       
  1309     else if (d->hbar && d->hbar->isVisible())
       
  1310         d->hbar->event(e);
       
  1311 }
       
  1312 #endif
       
  1313 
       
  1314 void QWorkspacePrivate::activateWindow(QWidget* w, bool change_focus)
       
  1315 {
       
  1316     Q_Q(QWorkspace);
       
  1317     if (!w) {
       
  1318         active = 0;
       
  1319         emit q->windowActivated(0);
       
  1320         return;
       
  1321     }
       
  1322     if (!q->isVisible()) {
       
  1323         becomeActive = w;
       
  1324         return;
       
  1325     }
       
  1326 
       
  1327     if (active && active->windowWidget() == w) {
       
  1328         if (!isChildOf(q->focusWidget(), w)) // child window does not have focus
       
  1329             active->setActive(true);
       
  1330         return;
       
  1331     }
       
  1332 
       
  1333     active = 0;
       
  1334     // First deactivate all other workspace clients
       
  1335     QList<QWorkspaceChild *>::Iterator it(windows.begin());
       
  1336     while (it != windows.end()) {
       
  1337         QWorkspaceChild* c = *it;
       
  1338         ++it;
       
  1339         if (c->windowWidget() == w)
       
  1340             active = c;
       
  1341         else
       
  1342             c->setActive(false);
       
  1343     }
       
  1344 
       
  1345     if (!active)
       
  1346         return;
       
  1347 
       
  1348     // Then activate the new one, so the focus is stored correctly
       
  1349     active->setActive(true);
       
  1350 
       
  1351     if (!active)
       
  1352         return;
       
  1353 
       
  1354     if (maxWindow && maxWindow != active && active->windowWidget() &&
       
  1355         (active->windowWidget()->windowFlags() & Qt::WindowMaximizeButtonHint))
       
  1356         active->showMaximized();
       
  1357 
       
  1358     active->internalRaise();
       
  1359 
       
  1360     if (change_focus) {
       
  1361         int from = focus.indexOf(active);
       
  1362         if (from >= 0)
       
  1363             focus.move(from, focus.size() - 1);
       
  1364     }
       
  1365 
       
  1366     updateWorkspace();
       
  1367     emit q->windowActivated(w);
       
  1368 }
       
  1369 
       
  1370 
       
  1371 /*!
       
  1372     Returns a pointer to the widget corresponding to the active child
       
  1373     window, or 0 if no window is active.
       
  1374 
       
  1375     \sa setActiveWindow()
       
  1376 */
       
  1377 QWidget* QWorkspace::activeWindow() const
       
  1378 {
       
  1379     Q_D(const QWorkspace);
       
  1380     return d->active? d->active->windowWidget() : 0;
       
  1381 }
       
  1382 
       
  1383 /*!
       
  1384     Makes the child window that contains \a w the active child window.
       
  1385 
       
  1386     \sa activeWindow()
       
  1387 */
       
  1388 void QWorkspace::setActiveWindow(QWidget *w)
       
  1389 {
       
  1390     Q_D(QWorkspace);
       
  1391     d->activateWindow(w, true);
       
  1392     if (w && w->isMinimized())
       
  1393         w->setWindowState(w->windowState() & ~Qt::WindowMinimized);
       
  1394 }
       
  1395 
       
  1396 void QWorkspacePrivate::place(QWidget *w)
       
  1397 {
       
  1398     Q_Q(QWorkspace);
       
  1399 
       
  1400     QList<QWidget *> widgets;
       
  1401     for (QList<QWorkspaceChild *>::Iterator it(windows.begin()); it != windows.end(); ++it)
       
  1402         if (*it != w)
       
  1403             widgets.append(*it);
       
  1404 
       
  1405     int overlap, minOverlap = 0;
       
  1406     int possible;
       
  1407 
       
  1408     QRect r1(0, 0, 0, 0);
       
  1409     QRect r2(0, 0, 0, 0);
       
  1410     QRect maxRect = q->rect();
       
  1411     int x = maxRect.left(), y = maxRect.top();
       
  1412     QPoint wpos(maxRect.left(), maxRect.top());
       
  1413 
       
  1414     bool firstPass = true;
       
  1415 
       
  1416     do {
       
  1417         if (y + w->height() > maxRect.bottom()) {
       
  1418             overlap = -1;
       
  1419         } else if(x + w->width() > maxRect.right()) {
       
  1420             overlap = -2;
       
  1421         } else {
       
  1422             overlap = 0;
       
  1423 
       
  1424             r1.setRect(x, y, w->width(), w->height());
       
  1425 
       
  1426             QWidget *l;
       
  1427             QList<QWidget *>::Iterator it(widgets.begin());
       
  1428             while (it != widgets.end()) {
       
  1429                 l = *it;
       
  1430                 ++it;
       
  1431 
       
  1432                 if (maxWindow == l)
       
  1433                     r2 = QStyle::visualRect(q->layoutDirection(), maxRect, maxRestore);
       
  1434                 else
       
  1435                     r2 = QStyle::visualRect(q->layoutDirection(), maxRect,
       
  1436                                             QRect(l->x(), l->y(), l->width(), l->height()));
       
  1437 
       
  1438                 if (r2.intersects(r1)) {
       
  1439                     r2.setCoords(qMax(r1.left(), r2.left()),
       
  1440                                  qMax(r1.top(), r2.top()),
       
  1441                                  qMin(r1.right(), r2.right()),
       
  1442                                  qMin(r1.bottom(), r2.bottom())
       
  1443                                 );
       
  1444 
       
  1445                     overlap += (r2.right() - r2.left()) *
       
  1446                                (r2.bottom() - r2.top());
       
  1447                 }
       
  1448             }
       
  1449         }
       
  1450 
       
  1451         if (overlap == 0) {
       
  1452             wpos = QPoint(x, y);
       
  1453             break;
       
  1454         }
       
  1455 
       
  1456         if (firstPass) {
       
  1457             firstPass = false;
       
  1458             minOverlap = overlap;
       
  1459         } else if (overlap >= 0 && overlap < minOverlap) {
       
  1460             minOverlap = overlap;
       
  1461             wpos = QPoint(x, y);
       
  1462         }
       
  1463 
       
  1464         if (overlap > 0) {
       
  1465             possible = maxRect.right();
       
  1466             if (possible - w->width() > x) possible -= w->width();
       
  1467 
       
  1468             QWidget *l;
       
  1469             QList<QWidget *>::Iterator it(widgets.begin());
       
  1470             while (it != widgets.end()) {
       
  1471                 l = *it;
       
  1472                 ++it;
       
  1473                 if (maxWindow == l)
       
  1474                     r2 = QStyle::visualRect(q->layoutDirection(), maxRect, maxRestore);
       
  1475                 else
       
  1476                     r2 = QStyle::visualRect(q->layoutDirection(), maxRect,
       
  1477                                             QRect(l->x(), l->y(), l->width(), l->height()));
       
  1478 
       
  1479                 if((y < r2.bottom()) && (r2.top() < w->height() + y)) {
       
  1480                     if(r2.right() > x)
       
  1481                         possible = possible < r2.right() ?
       
  1482                                    possible : r2.right();
       
  1483 
       
  1484                     if(r2.left() - w->width() > x)
       
  1485                         possible = possible < r2.left() - w->width() ?
       
  1486                                    possible : r2.left() - w->width();
       
  1487                 }
       
  1488             }
       
  1489 
       
  1490             x = possible;
       
  1491         } else if (overlap == -2) {
       
  1492             x = maxRect.left();
       
  1493             possible = maxRect.bottom();
       
  1494 
       
  1495             if (possible - w->height() > y) possible -= w->height();
       
  1496 
       
  1497             QWidget *l;
       
  1498             QList<QWidget *>::Iterator it(widgets.begin());
       
  1499             while (it != widgets.end()) {
       
  1500                 l = *it;
       
  1501                 ++it;
       
  1502                 if (maxWindow == l)
       
  1503                     r2 = QStyle::visualRect(q->layoutDirection(), maxRect, maxRestore);
       
  1504                 else
       
  1505                     r2 = QStyle::visualRect(q->layoutDirection(), maxRect,
       
  1506                                             QRect(l->x(), l->y(), l->width(), l->height()));
       
  1507 
       
  1508                 if(r2.bottom() > y)
       
  1509                     possible = possible < r2.bottom() ?
       
  1510                                possible : r2.bottom();
       
  1511 
       
  1512                 if(r2.top() - w->height() > y)
       
  1513                     possible = possible < r2.top() - w->height() ?
       
  1514                                possible : r2.top() - w->height();
       
  1515             }
       
  1516 
       
  1517             y = possible;
       
  1518         }
       
  1519     }
       
  1520     while(overlap != 0 && overlap != -1);
       
  1521 
       
  1522     QRect resultRect = w->geometry();
       
  1523     resultRect.moveTo(wpos);
       
  1524     w->setGeometry(QStyle::visualRect(q->layoutDirection(), maxRect, resultRect));
       
  1525     updateWorkspace();
       
  1526 }
       
  1527 
       
  1528 
       
  1529 void QWorkspacePrivate::insertIcon(QWidget* w)
       
  1530 {
       
  1531     Q_Q(QWorkspace);
       
  1532     if (!w || icons.contains(w))
       
  1533         return;
       
  1534     icons.append(w);
       
  1535     if (w->parentWidget() != q) {
       
  1536         w->setParent(q, 0);
       
  1537         w->move(0,0);
       
  1538     }
       
  1539     QRect cr = updateWorkspace();
       
  1540     int x = 0;
       
  1541     int y = cr.height() - w->height();
       
  1542 
       
  1543     QList<QWidget *>::Iterator it(icons.begin());
       
  1544     while (it != icons.end()) {
       
  1545         QWidget* i = *it;
       
  1546         ++it;
       
  1547         if (x > 0 && x + i->width() > cr.width()){
       
  1548             x = 0;
       
  1549             y -= i->height();
       
  1550         }
       
  1551 
       
  1552         if (i != w &&
       
  1553             i->geometry().intersects(QRect(x, y, w->width(), w->height())))
       
  1554             x += i->width();
       
  1555     }
       
  1556     w->move(x, y);
       
  1557 
       
  1558     if (q->isVisibleTo(q->parentWidget())) {
       
  1559         w->show();
       
  1560         w->lower();
       
  1561     }
       
  1562     updateWorkspace();
       
  1563 }
       
  1564 
       
  1565 
       
  1566 void QWorkspacePrivate::removeIcon(QWidget* w)
       
  1567 {
       
  1568     if (icons.removeAll(w))
       
  1569         w->hide();
       
  1570 }
       
  1571 
       
  1572 
       
  1573 /*! \reimp  */
       
  1574 void QWorkspace::resizeEvent(QResizeEvent *)
       
  1575 {
       
  1576     Q_D(QWorkspace);
       
  1577     if (d->maxWindow) {
       
  1578         d->maxWindow->adjustToFullscreen();
       
  1579         if (d->maxWindow->windowWidget())
       
  1580             d->maxWindow->windowWidget()->overrideWindowState(Qt::WindowMaximized);
       
  1581     }
       
  1582     d->updateWorkspace();
       
  1583 }
       
  1584 
       
  1585 /*! \reimp */
       
  1586 void QWorkspace::showEvent(QShowEvent *e)
       
  1587 {
       
  1588     Q_D(QWorkspace);
       
  1589     if (d->maxWindow)
       
  1590         d->showMaximizeControls();
       
  1591     QWidget::showEvent(e);
       
  1592     if (d->becomeActive) {
       
  1593         d->activateWindow(d->becomeActive);
       
  1594         d->becomeActive = 0;
       
  1595     } else if (d->windows.count() > 0 && !d->active) {
       
  1596         d->activateWindow(d->windows.first()->windowWidget());
       
  1597     }
       
  1598 
       
  1599 //     // force a frame repaint - this is a workaround for what seems to be a bug
       
  1600 //     // introduced when changing the QWidget::show() implementation. Might be
       
  1601 //     // a windows bug as well though.
       
  1602 //     for (int i = 0; i < d->windows.count(); ++i) {
       
  1603 //      QWorkspaceChild* c = d->windows.at(i);
       
  1604 //         c->update(c->rect());
       
  1605 //     }
       
  1606 
       
  1607     d->updateWorkspace();
       
  1608 }
       
  1609 
       
  1610 /*! \reimp */
       
  1611 void QWorkspace::hideEvent(QHideEvent *)
       
  1612 {
       
  1613     Q_D(QWorkspace);
       
  1614     if (!isVisible())
       
  1615         d->hideMaximizeControls();
       
  1616 }
       
  1617 
       
  1618 /*! \reimp */
       
  1619 void QWorkspace::paintEvent(QPaintEvent *)
       
  1620 {
       
  1621     Q_D(QWorkspace);
       
  1622 
       
  1623     if (d->background.style() != Qt::NoBrush) {
       
  1624         QPainter p(this);
       
  1625         p.fillRect(0, 0, width(), height(), d->background);
       
  1626     }
       
  1627 }
       
  1628 
       
  1629 void QWorkspacePrivate::minimizeWindow(QWidget* w)
       
  1630 {
       
  1631     QWorkspaceChild* c = findChild(w);
       
  1632 
       
  1633     if (!w || !(w->windowFlags() & Qt::WindowMinimizeButtonHint))
       
  1634         return;
       
  1635 
       
  1636     if (c) {
       
  1637         bool wasMax = false;
       
  1638         if (c == maxWindow) {
       
  1639             wasMax = true;
       
  1640             maxWindow = 0;
       
  1641             hideMaximizeControls();
       
  1642             for (QList<QWorkspaceChild *>::Iterator it(windows.begin()); it != windows.end(); ++it) {
       
  1643                 QWorkspaceChild* c = *it;
       
  1644                 if (c->titlebar)
       
  1645                     c->titlebar->setMovable(true);
       
  1646                 c->widgetResizeHandler->setActive(true);
       
  1647             }
       
  1648         }
       
  1649         c->hide();
       
  1650         if (wasMax)
       
  1651             c->setGeometry(maxRestore);
       
  1652         if (!focus.contains(c))
       
  1653             focus.append(c);
       
  1654         insertIcon(c->iconWidget());
       
  1655 
       
  1656         if (!maxWindow)
       
  1657             activateWindow(w);
       
  1658 
       
  1659         updateWorkspace();
       
  1660 
       
  1661         w->overrideWindowState(Qt::WindowMinimized);
       
  1662         c->overrideWindowState(Qt::WindowMinimized);
       
  1663     }
       
  1664 }
       
  1665 
       
  1666 void QWorkspacePrivate::normalizeWindow(QWidget* w)
       
  1667 {
       
  1668     Q_Q(QWorkspace);
       
  1669     QWorkspaceChild* c = findChild(w);
       
  1670     if (!w)
       
  1671         return;
       
  1672     if (c) {
       
  1673         w->overrideWindowState(Qt::WindowNoState);
       
  1674         hideMaximizeControls();
       
  1675         if (!maxmenubar || q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q) || !maxWindow) {
       
  1676             if (w->minimumSize() != w->maximumSize())
       
  1677                 c->widgetResizeHandler->setActive(true);
       
  1678             if (c->titlebar)
       
  1679                 c->titlebar->setMovable(true);
       
  1680         }
       
  1681         w->overrideWindowState(Qt::WindowNoState);
       
  1682         c->overrideWindowState(Qt::WindowNoState);
       
  1683 
       
  1684         if (c == maxWindow) {
       
  1685             c->setGeometry(maxRestore);
       
  1686             maxWindow = 0;
       
  1687         } else {
       
  1688             if (c->iconw)
       
  1689                 removeIcon(c->iconw->parentWidget());
       
  1690             c->show();
       
  1691         }
       
  1692 
       
  1693         hideMaximizeControls();
       
  1694         for (QList<QWorkspaceChild *>::Iterator it(windows.begin()); it != windows.end(); ++it) {
       
  1695             QWorkspaceChild* c = *it;
       
  1696             if (c->titlebar)
       
  1697                 c->titlebar->setMovable(true);
       
  1698             if (c->childWidget && c->childWidget->minimumSize() != c->childWidget->maximumSize())
       
  1699                 c->widgetResizeHandler->setActive(true);
       
  1700         }
       
  1701         activateWindow(w, true);
       
  1702         updateWorkspace();
       
  1703     }
       
  1704 }
       
  1705 
       
  1706 void QWorkspacePrivate::maximizeWindow(QWidget* w)
       
  1707 {
       
  1708     Q_Q(QWorkspace);
       
  1709     QWorkspaceChild* c = findChild(w);
       
  1710 
       
  1711     if (!w || !(w->windowFlags() & Qt::WindowMaximizeButtonHint))
       
  1712         return;
       
  1713 
       
  1714     if (!c || c == maxWindow)
       
  1715         return;
       
  1716 
       
  1717     bool updatesEnabled = q->updatesEnabled();
       
  1718     q->setUpdatesEnabled(false);
       
  1719 
       
  1720     if (c->iconw && icons.contains(c->iconw->parentWidget()))
       
  1721         normalizeWindow(w);
       
  1722     QRect r(c->geometry());
       
  1723     QWorkspaceChild *oldMaxWindow = maxWindow;
       
  1724     maxWindow = c;
       
  1725 
       
  1726     showMaximizeControls();
       
  1727 
       
  1728     c->adjustToFullscreen();
       
  1729     c->show();
       
  1730     c->internalRaise();
       
  1731     if (oldMaxWindow != c) {
       
  1732         if (oldMaxWindow) {
       
  1733             oldMaxWindow->setGeometry(maxRestore);
       
  1734             oldMaxWindow->overrideWindowState(Qt::WindowNoState);
       
  1735             if(oldMaxWindow->windowWidget())
       
  1736                 oldMaxWindow->windowWidget()->overrideWindowState(Qt::WindowNoState);
       
  1737         }
       
  1738         maxRestore = r;
       
  1739     }
       
  1740 
       
  1741     activateWindow(w);
       
  1742 
       
  1743     if(!maxmenubar || q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q)) {
       
  1744         if (!active && becomeActive) {
       
  1745             active = (QWorkspaceChild*)becomeActive->parentWidget();
       
  1746             active->setActive(true);
       
  1747             becomeActive = 0;
       
  1748             emit q->windowActivated(active->windowWidget());
       
  1749         }
       
  1750         c->widgetResizeHandler->setActive(false);
       
  1751         if (c->titlebar)
       
  1752             c->titlebar->setMovable(false);
       
  1753     }
       
  1754     updateWorkspace();
       
  1755 
       
  1756     w->overrideWindowState(Qt::WindowMaximized);
       
  1757     c->overrideWindowState(Qt::WindowMaximized);
       
  1758     q->setUpdatesEnabled(updatesEnabled);
       
  1759 }
       
  1760 
       
  1761 void QWorkspacePrivate::showWindow(QWidget* w)
       
  1762 {
       
  1763     if (w->isMinimized() && (w->windowFlags() & Qt::WindowMinimizeButtonHint))
       
  1764         minimizeWindow(w);
       
  1765     else if ((maxWindow || w->isMaximized()) && w->windowFlags() & Qt::WindowMaximizeButtonHint)
       
  1766         maximizeWindow(w);
       
  1767     else if (w->windowFlags() & Qt::WindowMaximizeButtonHint)
       
  1768         normalizeWindow(w);
       
  1769     else
       
  1770         w->parentWidget()->show();
       
  1771     if (maxWindow)
       
  1772         maxWindow->internalRaise();
       
  1773     updateWorkspace();
       
  1774 }
       
  1775 
       
  1776 
       
  1777 QWorkspaceChild* QWorkspacePrivate::findChild(QWidget* w)
       
  1778 {
       
  1779     QList<QWorkspaceChild *>::Iterator it(windows.begin());
       
  1780     while (it != windows.end()) {
       
  1781         QWorkspaceChild* c = *it;
       
  1782         ++it;
       
  1783         if (c->windowWidget() == w)
       
  1784             return c;
       
  1785     }
       
  1786     return 0;
       
  1787 }
       
  1788 
       
  1789 /*!
       
  1790     Returns a list of all visible or minimized child windows. If \a
       
  1791     order is CreationOrder (the default), the windows are listed in
       
  1792     the order in which they were inserted into the workspace. If \a
       
  1793     order is StackingOrder, the windows are listed in their stacking
       
  1794     order, with the topmost window as the last item in the list.
       
  1795 */
       
  1796 QWidgetList QWorkspace::windowList(WindowOrder order) const
       
  1797 {
       
  1798     Q_D(const QWorkspace);
       
  1799     QWidgetList windows;
       
  1800     if (order == StackingOrder) {
       
  1801         QObjectList cl = children();
       
  1802         for (int i = 0; i < cl.size(); ++i) {
       
  1803             QWorkspaceChild *c = qobject_cast<QWorkspaceChild*>(cl.at(i));
       
  1804             if (c && c->isWindowOrIconVisible())
       
  1805                 windows.append(c->windowWidget());
       
  1806         }
       
  1807     } else {
       
  1808         QList<QWorkspaceChild *>::ConstIterator it(d->windows.begin());
       
  1809         while (it != d->windows.end()) {
       
  1810             QWorkspaceChild* c = *it;
       
  1811             ++it;
       
  1812             if (c && c->isWindowOrIconVisible())
       
  1813                 windows.append(c->windowWidget());
       
  1814         }
       
  1815     }
       
  1816     return windows;
       
  1817 }
       
  1818 
       
  1819 
       
  1820 /*! \reimp */
       
  1821 bool QWorkspace::event(QEvent *e)
       
  1822 {
       
  1823 #ifndef QT_NO_SHORTCUT
       
  1824     Q_D(QWorkspace);
       
  1825     if (e->type() == QEvent::Shortcut) {
       
  1826         QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
       
  1827         const char *theSlot = d->shortcutMap.value(se->shortcutId(), 0);
       
  1828         if (theSlot)
       
  1829             QMetaObject::invokeMethod(this, theSlot);
       
  1830     } else
       
  1831 #endif
       
  1832     if (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut){
       
  1833         return true;
       
  1834     }
       
  1835     return QWidget::event(e);
       
  1836 }
       
  1837 
       
  1838 /*! \reimp */
       
  1839 bool QWorkspace::eventFilter(QObject *o, QEvent * e)
       
  1840 {
       
  1841     Q_D(QWorkspace);
       
  1842     static QTime* t = 0;
       
  1843     static QWorkspace* tc = 0;
       
  1844     if (o == d->maxtools) {
       
  1845         switch (e->type()) {
       
  1846         case QEvent::MouseButtonPress:
       
  1847             {
       
  1848                 QMenuBar* b = (QMenuBar*)o->parent();
       
  1849                 if (!t)
       
  1850                     t = new QTime;
       
  1851                 if (tc != this || t->elapsed() > QApplication::doubleClickInterval()) {
       
  1852                     if (isRightToLeft()) {
       
  1853                         QPoint p = b->mapToGlobal(QPoint(b->x() + b->width(), b->y() + b->height()));
       
  1854                         p.rx() -= d->popup->sizeHint().width();
       
  1855                         d->_q_popupOperationMenu(p);
       
  1856                     } else {
       
  1857                         d->_q_popupOperationMenu(b->mapToGlobal(QPoint(b->x(), b->y() + b->height())));
       
  1858                     }
       
  1859                     t->start();
       
  1860                     tc = this;
       
  1861                 } else {
       
  1862                     tc = 0;
       
  1863                     closeActiveWindow();
       
  1864                 }
       
  1865                 return true;
       
  1866             }
       
  1867         default:
       
  1868             break;
       
  1869         }
       
  1870         return QWidget::eventFilter(o, e);
       
  1871     }
       
  1872     switch (e->type()) {
       
  1873     case QEvent::HideToParent:
       
  1874         break;
       
  1875     case QEvent::ShowToParent:
       
  1876         if (QWorkspaceChild *c = qobject_cast<QWorkspaceChild*>(o))
       
  1877             if (!d->focus.contains(c))
       
  1878                 d->focus.append(c);
       
  1879         d->updateWorkspace();
       
  1880         break;
       
  1881     case QEvent::WindowTitleChange:
       
  1882         if (!d->inTitleChange) {
       
  1883             if (o == window())
       
  1884                 d->topTitle = window()->windowTitle();
       
  1885             if (d->maxWindow && d->maxWindow->windowWidget() && d->topTitle.size()) {
       
  1886                 d->inTitleChange = true;
       
  1887                 window()->setWindowTitle(tr("%1 - [%2]")
       
  1888                                          .arg(d->topTitle).arg(d->maxWindow->windowWidget()->windowTitle()));
       
  1889                 d->inTitleChange = false;
       
  1890             }
       
  1891         }
       
  1892         break;
       
  1893 
       
  1894     case QEvent::ModifiedChange:
       
  1895         if (o == d->maxWindow)
       
  1896             window()->setWindowModified(d->maxWindow->isWindowModified());
       
  1897         break;
       
  1898 
       
  1899     case QEvent::Close:
       
  1900         if (o == window())
       
  1901         {
       
  1902             QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
       
  1903             while (it != d->windows.end()) {
       
  1904                 QWorkspaceChild* c = *it;
       
  1905                 ++it;
       
  1906                 if (c->shademode)
       
  1907                     c->showShaded();
       
  1908             }
       
  1909         } else if (qobject_cast<QWorkspaceChild*>(o)) {
       
  1910             d->popup->hide();
       
  1911         }
       
  1912         d->updateWorkspace();
       
  1913         break;
       
  1914     default:
       
  1915         break;
       
  1916     }
       
  1917     return QWidget::eventFilter(o, e);
       
  1918 }
       
  1919 
       
  1920 static QMenuBar *findMenuBar(QWidget *w)
       
  1921 {
       
  1922     // don't search recursively to avoid finding a menu bar of a
       
  1923     // mainwindow that happens to be a workspace window (like
       
  1924     // a mainwindow in designer)
       
  1925     QList<QObject *> children = w->children();
       
  1926     for (int i = 0; i < children.count(); ++i) {
       
  1927         QMenuBar *bar = qobject_cast<QMenuBar *>(children.at(i));
       
  1928         if (bar)
       
  1929             return bar;
       
  1930     }
       
  1931     return 0;
       
  1932 }
       
  1933 
       
  1934 void QWorkspacePrivate::showMaximizeControls()
       
  1935 {
       
  1936     Q_Q(QWorkspace);
       
  1937     Q_ASSERT(maxWindow);
       
  1938 
       
  1939     // merge windowtitle and modified state
       
  1940     if (!topTitle.size())
       
  1941         topTitle = q->window()->windowTitle();
       
  1942 
       
  1943     if (maxWindow->windowWidget()) {
       
  1944         QString docTitle = maxWindow->windowWidget()->windowTitle();
       
  1945         if (topTitle.size() && docTitle.size()) {
       
  1946             inTitleChange = true;
       
  1947             q->window()->setWindowTitle(QWorkspace::tr("%1 - [%2]").arg(topTitle).arg(docTitle));
       
  1948             inTitleChange = false;
       
  1949         }
       
  1950         q->window()->setWindowModified(maxWindow->windowWidget()->isWindowModified());
       
  1951     }
       
  1952 
       
  1953     if (!q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q)) {
       
  1954         QMenuBar* b = 0;
       
  1955 
       
  1956         // Do a breadth-first search first on every parent,
       
  1957         QWidget* w = q->parentWidget();
       
  1958         while (w) {
       
  1959             b = findMenuBar(w);
       
  1960             if (b)
       
  1961                 break;
       
  1962             w = w->parentWidget();
       
  1963         }
       
  1964 
       
  1965         // last attempt.
       
  1966         if (!b)
       
  1967             b = findMenuBar(q->window());
       
  1968 
       
  1969         if (!b)
       
  1970             return;
       
  1971 
       
  1972         if (!maxcontrols) {
       
  1973             maxmenubar = b;
       
  1974             maxcontrols = new QMDIControl(b);
       
  1975             QObject::connect(maxcontrols, SIGNAL(_q_minimize()),
       
  1976                              q, SLOT(_q_minimizeActiveWindow()));
       
  1977             QObject::connect(maxcontrols, SIGNAL(_q_restore()),
       
  1978                              q, SLOT(_q_normalizeActiveWindow()));
       
  1979             QObject::connect(maxcontrols, SIGNAL(_q_close()),
       
  1980                              q, SLOT(closeActiveWindow()));
       
  1981         }
       
  1982 
       
  1983         b->setCornerWidget(maxcontrols);
       
  1984         if (b->isVisible())
       
  1985             maxcontrols->show();
       
  1986         if (!active && becomeActive) {
       
  1987             active = (QWorkspaceChild*)becomeActive->parentWidget();
       
  1988             active->setActive(true);
       
  1989             becomeActive = 0;
       
  1990             emit q->windowActivated(active->windowWidget());
       
  1991         }
       
  1992         if (active) {
       
  1993             if (!maxtools) {
       
  1994                 maxtools = new QLabel(q->window());
       
  1995                 maxtools->setObjectName(QLatin1String("qt_maxtools"));
       
  1996                 maxtools->installEventFilter(q);
       
  1997             }
       
  1998             if (active->windowWidget() && !active->windowWidget()->windowIcon().isNull()) {
       
  1999                 QIcon icon = active->windowWidget()->windowIcon();
       
  2000                 int iconSize = maxcontrols->size().height();
       
  2001                 maxtools->setPixmap(icon.pixmap(QSize(iconSize, iconSize)));
       
  2002             } else {
       
  2003                 QPixmap pm = q->style()->standardPixmap(QStyle::SP_TitleBarMenuButton, 0, q);
       
  2004                 if (pm.isNull()) {
       
  2005                     pm = QPixmap(14,14);
       
  2006                     pm.fill(Qt::black);
       
  2007                 }
       
  2008                 maxtools->setPixmap(pm);
       
  2009             }
       
  2010             b->setCornerWidget(maxtools, Qt::TopLeftCorner);
       
  2011             if (b->isVisible())
       
  2012                 maxtools->show();
       
  2013         }
       
  2014     }
       
  2015 }
       
  2016 
       
  2017 
       
  2018 void QWorkspacePrivate::hideMaximizeControls()
       
  2019 {
       
  2020     Q_Q(QWorkspace);
       
  2021     if (maxmenubar && !q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q)) {
       
  2022         if (maxmenubar) {
       
  2023             maxmenubar->setCornerWidget(0, Qt::TopLeftCorner);
       
  2024             maxmenubar->setCornerWidget(0, Qt::TopRightCorner);
       
  2025         }
       
  2026         if (maxcontrols) {
       
  2027             maxcontrols->deleteLater();
       
  2028             maxcontrols = 0;
       
  2029         }
       
  2030         if (maxtools) {
       
  2031             maxtools->deleteLater();
       
  2032             maxtools = 0;
       
  2033         }
       
  2034     }
       
  2035 
       
  2036     //unmerge the title bar/modification state
       
  2037     if (topTitle.size()) {
       
  2038         inTitleChange = true;
       
  2039         q->window()->setWindowTitle(topTitle);
       
  2040         inTitleChange = false;
       
  2041     }
       
  2042     q->window()->setWindowModified(false);
       
  2043 }
       
  2044 
       
  2045 /*!
       
  2046     Closes the child window that is currently active.
       
  2047 
       
  2048     \sa closeAllWindows()
       
  2049 */
       
  2050 void QWorkspace::closeActiveWindow()
       
  2051 {
       
  2052     Q_D(QWorkspace);
       
  2053     if (d->maxWindow && d->maxWindow->windowWidget())
       
  2054         d->maxWindow->windowWidget()->close();
       
  2055     else if (d->active && d->active->windowWidget())
       
  2056         d->active->windowWidget()->close();
       
  2057     d->updateWorkspace();
       
  2058 }
       
  2059 
       
  2060 /*!
       
  2061     Closes all child windows.
       
  2062 
       
  2063     If any child window fails to accept the close event, the remaining windows
       
  2064     will remain open.
       
  2065 
       
  2066     \sa closeActiveWindow()
       
  2067 */
       
  2068 void QWorkspace::closeAllWindows()
       
  2069 {
       
  2070     Q_D(QWorkspace);
       
  2071     bool did_close = true;
       
  2072     QList<QWorkspaceChild *>::const_iterator it = d->windows.constBegin();
       
  2073     while (it != d->windows.constEnd() && did_close) {
       
  2074         QWorkspaceChild *c = *it;
       
  2075         ++it;
       
  2076         if (c->windowWidget() && !c->windowWidget()->isHidden())
       
  2077             did_close = c->windowWidget()->close();
       
  2078     }
       
  2079 }
       
  2080 
       
  2081 void QWorkspacePrivate::_q_normalizeActiveWindow()
       
  2082 {
       
  2083     if (maxWindow)
       
  2084         maxWindow->showNormal();
       
  2085     else if (active)
       
  2086         active->showNormal();
       
  2087 }
       
  2088 
       
  2089 void QWorkspacePrivate::_q_minimizeActiveWindow()
       
  2090 {
       
  2091     if (maxWindow)
       
  2092         maxWindow->showMinimized();
       
  2093     else if (active)
       
  2094         active->showMinimized();
       
  2095 }
       
  2096 
       
  2097 void QWorkspacePrivate::_q_showOperationMenu()
       
  2098 {
       
  2099     Q_Q(QWorkspace);
       
  2100     if  (!active || !active->windowWidget())
       
  2101         return;
       
  2102     Q_ASSERT((active->windowWidget()->windowFlags() & Qt::WindowSystemMenuHint));
       
  2103     QPoint p;
       
  2104     QMenu *popup = (active->titlebar && active->titlebar->isTool()) ? toolPopup : this->popup;
       
  2105     if (q->isRightToLeft()) {
       
  2106         p = QPoint(active->windowWidget()->mapToGlobal(QPoint(active->windowWidget()->width(),0)));
       
  2107         p.rx() -= popup->sizeHint().width();
       
  2108     } else {
       
  2109         p = QPoint(active->windowWidget()->mapToGlobal(QPoint(0,0)));
       
  2110     }
       
  2111     if (!active->isVisible()) {
       
  2112         p = active->iconWidget()->mapToGlobal(QPoint(0,0));
       
  2113         p.ry() -= popup->sizeHint().height();
       
  2114     }
       
  2115     _q_popupOperationMenu(p);
       
  2116 }
       
  2117 
       
  2118 void QWorkspacePrivate::_q_popupOperationMenu(const QPoint&  p)
       
  2119 {
       
  2120     if (!active || !active->windowWidget() || !(active->windowWidget()->windowFlags() & Qt::WindowSystemMenuHint))
       
  2121         return;
       
  2122     if (active->titlebar && active->titlebar->isTool())
       
  2123         toolPopup->popup(p);
       
  2124     else
       
  2125         popup->popup(p);
       
  2126 }
       
  2127 
       
  2128 void QWorkspacePrivate::_q_updateActions()
       
  2129 {
       
  2130     Q_Q(QWorkspace);
       
  2131     for (int i = 1; i < NCountAct-1; i++) {
       
  2132         bool enable = active != 0;
       
  2133         actions[i]->setEnabled(enable);
       
  2134     }
       
  2135 
       
  2136     if (!active || !active->windowWidget())
       
  2137         return;
       
  2138 
       
  2139     QWidget *windowWidget = active->windowWidget();
       
  2140     bool canResize = windowWidget->maximumSize() != windowWidget->minimumSize();
       
  2141     actions[QWorkspacePrivate::ResizeAct]->setEnabled(canResize);
       
  2142     actions[QWorkspacePrivate::MinimizeAct]->setEnabled((windowWidget->windowFlags() & Qt::WindowMinimizeButtonHint));
       
  2143     actions[QWorkspacePrivate::MaximizeAct]->setEnabled((windowWidget->windowFlags() & Qt::WindowMaximizeButtonHint) && canResize);
       
  2144 
       
  2145     if (active == maxWindow) {
       
  2146         actions[QWorkspacePrivate::MoveAct]->setEnabled(false);
       
  2147         actions[QWorkspacePrivate::ResizeAct]->setEnabled(false);
       
  2148         actions[QWorkspacePrivate::MaximizeAct]->setEnabled(false);
       
  2149         actions[QWorkspacePrivate::RestoreAct]->setEnabled(true);
       
  2150     } else if (active->isVisible()){
       
  2151         actions[QWorkspacePrivate::RestoreAct]->setEnabled(false);
       
  2152     } else {
       
  2153         actions[QWorkspacePrivate::MoveAct]->setEnabled(false);
       
  2154         actions[QWorkspacePrivate::ResizeAct]->setEnabled(false);
       
  2155         actions[QWorkspacePrivate::MinimizeAct]->setEnabled(false);
       
  2156         actions[QWorkspacePrivate::RestoreAct]->setEnabled(true);
       
  2157     }
       
  2158     if (active->shademode) {
       
  2159         actions[QWorkspacePrivate::ShadeAct]->setIcon(
       
  2160             QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarUnshadeButton, 0, q)));
       
  2161         actions[QWorkspacePrivate::ShadeAct]->setText(QWorkspace::tr("&Unshade"));
       
  2162     } else {
       
  2163         actions[QWorkspacePrivate::ShadeAct]->setIcon(
       
  2164             QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarShadeButton, 0, q)));
       
  2165         actions[QWorkspacePrivate::ShadeAct]->setText(QWorkspace::tr("Sh&ade"));
       
  2166     }
       
  2167     actions[QWorkspacePrivate::StaysOnTopAct]->setEnabled(!active->shademode && canResize);
       
  2168     actions[QWorkspacePrivate::StaysOnTopAct]->setChecked(
       
  2169         (active->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint));
       
  2170 }
       
  2171 
       
  2172 void QWorkspacePrivate::_q_operationMenuActivated(QAction *action)
       
  2173 {
       
  2174     if (!active)
       
  2175         return;
       
  2176     if(action == actions[QWorkspacePrivate::RestoreAct]) {
       
  2177         active->showNormal();
       
  2178     } else if(action == actions[QWorkspacePrivate::MoveAct]) {
       
  2179         active->doMove();
       
  2180     } else if(action == actions[QWorkspacePrivate::ResizeAct]) {
       
  2181         if (active->shademode)
       
  2182             active->showShaded();
       
  2183         active->doResize();
       
  2184     } else if(action == actions[QWorkspacePrivate::MinimizeAct]) {
       
  2185         active->showMinimized();
       
  2186     } else if(action == actions[QWorkspacePrivate::MaximizeAct]) {
       
  2187         active->showMaximized();
       
  2188     } else if(action == actions[QWorkspacePrivate::ShadeAct]) {
       
  2189         active->showShaded();
       
  2190     } else if(action == actions[QWorkspacePrivate::StaysOnTopAct]) {
       
  2191         if(QWidget* w = active->windowWidget()) {
       
  2192             if ((w->windowFlags() & Qt::WindowStaysOnTopHint)) {
       
  2193                 w->overrideWindowFlags(w->windowFlags() & ~Qt::WindowStaysOnTopHint);
       
  2194             } else {
       
  2195                 w->overrideWindowFlags(w->windowFlags() | Qt::WindowStaysOnTopHint);
       
  2196                 w->parentWidget()->raise();
       
  2197             }
       
  2198         }
       
  2199     }
       
  2200 }
       
  2201 
       
  2202 
       
  2203 void QWorkspacePrivate::hideChild(QWorkspaceChild *c)
       
  2204 {
       
  2205     Q_Q(QWorkspace);
       
  2206 
       
  2207 //     bool updatesEnabled = q->updatesEnabled();
       
  2208 //     q->setUpdatesEnabled(false);
       
  2209     focus.removeAll(c);
       
  2210     QRect restore;
       
  2211     if (maxWindow == c)
       
  2212         restore = maxRestore;
       
  2213     if (active == c) {
       
  2214         q->setFocus();
       
  2215         q->activatePreviousWindow();
       
  2216     }
       
  2217     if (active == c)
       
  2218         activateWindow(0);
       
  2219     if (maxWindow == c) {
       
  2220         hideMaximizeControls();
       
  2221         maxWindow = 0;
       
  2222     }
       
  2223     c->hide();
       
  2224     if (!restore.isEmpty())
       
  2225         c->setGeometry(restore);
       
  2226 //     q->setUpdatesEnabled(updatesEnabled);
       
  2227 }
       
  2228 
       
  2229 /*!
       
  2230     Gives the input focus to the next window in the list of child
       
  2231     windows.
       
  2232 
       
  2233     \sa activatePreviousWindow()
       
  2234 */
       
  2235 void QWorkspace::activateNextWindow()
       
  2236 {
       
  2237     Q_D(QWorkspace);
       
  2238 
       
  2239     if (d->focus.isEmpty())
       
  2240         return;
       
  2241     if (!d->active) {
       
  2242         if (d->focus.first())
       
  2243             d->activateWindow(d->focus.first()->windowWidget(), false);
       
  2244         return;
       
  2245     }
       
  2246 
       
  2247     int a = d->focus.indexOf(d->active) + 1;
       
  2248 
       
  2249     a = a % d->focus.count();
       
  2250 
       
  2251     if (d->focus.at(a))
       
  2252         d->activateWindow(d->focus.at(a)->windowWidget(), false);
       
  2253     else
       
  2254         d->activateWindow(0);
       
  2255 }
       
  2256 
       
  2257 /*!
       
  2258     Gives the input focus to the previous window in the list of child
       
  2259     windows.
       
  2260 
       
  2261     \sa activateNextWindow()
       
  2262 */
       
  2263 void QWorkspace::activatePreviousWindow()
       
  2264 {
       
  2265     Q_D(QWorkspace);
       
  2266 
       
  2267     if (d->focus.isEmpty())
       
  2268         return;
       
  2269     if (!d->active) {
       
  2270         if (d->focus.last())
       
  2271             d->activateWindow(d->focus.first()->windowWidget(), false);
       
  2272         else
       
  2273             d->activateWindow(0);
       
  2274         return;
       
  2275     }
       
  2276 
       
  2277     int a = d->focus.indexOf(d->active) - 1;
       
  2278     if (a < 0)
       
  2279         a = d->focus.count()-1;
       
  2280 
       
  2281     if (d->focus.at(a))
       
  2282         d->activateWindow(d->focus.at(a)->windowWidget(), false);
       
  2283     else
       
  2284         d->activateWindow(0);
       
  2285 }
       
  2286 
       
  2287 
       
  2288 /*!
       
  2289     \fn void QWorkspace::windowActivated(QWidget* w)
       
  2290 
       
  2291     This signal is emitted when the child window \a w becomes active.
       
  2292     Note that \a w can be 0, and that more than one signal may be
       
  2293     emitted for a single activation event.
       
  2294 
       
  2295     \sa activeWindow(), windowList()
       
  2296 */
       
  2297 
       
  2298 /*!
       
  2299     Arranges all the child windows in a cascade pattern.
       
  2300 
       
  2301     \sa tile(), arrangeIcons()
       
  2302 */
       
  2303 void QWorkspace::cascade()
       
  2304 {
       
  2305     Q_D(QWorkspace);
       
  2306     blockSignals(true);
       
  2307     if  (d->maxWindow)
       
  2308         d->maxWindow->showNormal();
       
  2309 
       
  2310     if (d->vbar) {
       
  2311         d->vbar->blockSignals(true);
       
  2312         d->vbar->setValue(0);
       
  2313         d->vbar->blockSignals(false);
       
  2314         d->hbar->blockSignals(true);
       
  2315         d->hbar->setValue(0);
       
  2316         d->hbar->blockSignals(false);
       
  2317         d->_q_scrollBarChanged();
       
  2318     }
       
  2319 
       
  2320     const int xoffset = 13;
       
  2321     const int yoffset = 20;
       
  2322 
       
  2323     // make a list of all relevant mdi clients
       
  2324     QList<QWorkspaceChild *> widgets;
       
  2325     QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
       
  2326     QWorkspaceChild* wc = 0;
       
  2327 
       
  2328     for (it = d->focus.begin(); it != d->focus.end(); ++it) {
       
  2329         wc = *it;
       
  2330         if (wc->windowWidget()->isVisibleTo(this) && !(wc->titlebar && wc->titlebar->isTool()))
       
  2331             widgets.append(wc);
       
  2332     }
       
  2333 
       
  2334     int x = 0;
       
  2335     int y = 0;
       
  2336 
       
  2337     it = widgets.begin();
       
  2338     while (it != widgets.end()) {
       
  2339         QWorkspaceChild *child = *it;
       
  2340         ++it;
       
  2341 
       
  2342         QSize prefSize = child->windowWidget()->sizeHint().expandedTo(qSmartMinSize(child->windowWidget()));
       
  2343         if (!prefSize.isValid())
       
  2344             prefSize = child->windowWidget()->size();
       
  2345         prefSize = prefSize.expandedTo(qSmartMinSize(child->windowWidget()));
       
  2346         if (prefSize.isValid())
       
  2347             prefSize += QSize(child->baseSize().width(), child->baseSize().height());
       
  2348 
       
  2349         int w = prefSize.width();
       
  2350         int h = prefSize.height();
       
  2351 
       
  2352         child->showNormal();
       
  2353         if (y + h > height())
       
  2354             y = 0;
       
  2355         if (x + w > width())
       
  2356             x = 0;
       
  2357         child->setGeometry(x, y, w, h);
       
  2358         x += xoffset;
       
  2359         y += yoffset;
       
  2360         child->internalRaise();
       
  2361     }
       
  2362     d->updateWorkspace();
       
  2363     blockSignals(false);
       
  2364 }
       
  2365 
       
  2366 /*!
       
  2367     Arranges all child windows in a tile pattern.
       
  2368 
       
  2369     \sa cascade(), arrangeIcons()
       
  2370 */
       
  2371 void QWorkspace::tile()
       
  2372 {
       
  2373     Q_D(QWorkspace);
       
  2374     blockSignals(true);
       
  2375     QWidget *oldActive = d->active ? d->active->windowWidget() : 0;
       
  2376     if  (d->maxWindow)
       
  2377         d->maxWindow->showNormal();
       
  2378 
       
  2379     if (d->vbar) {
       
  2380         d->vbar->blockSignals(true);
       
  2381         d->vbar->setValue(0);
       
  2382         d->vbar->blockSignals(false);
       
  2383         d->hbar->blockSignals(true);
       
  2384         d->hbar->setValue(0);
       
  2385         d->hbar->blockSignals(false);
       
  2386         d->_q_scrollBarChanged();
       
  2387     }
       
  2388 
       
  2389     int rows = 1;
       
  2390     int cols = 1;
       
  2391     int n = 0;
       
  2392     QWorkspaceChild* c;
       
  2393 
       
  2394     QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
       
  2395     while (it != d->windows.end()) {
       
  2396         c = *it;
       
  2397         ++it;
       
  2398         if (!c->windowWidget()->isHidden()
       
  2399             && !(c->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)
       
  2400             && !c->iconw)
       
  2401             n++;
       
  2402     }
       
  2403 
       
  2404     while (rows * cols < n) {
       
  2405         if (cols <= rows)
       
  2406             cols++;
       
  2407         else
       
  2408             rows++;
       
  2409     }
       
  2410     int add = cols * rows - n;
       
  2411     bool* used = new bool[cols*rows];
       
  2412     for (int i = 0; i < rows*cols; i++)
       
  2413         used[i] = false;
       
  2414 
       
  2415     int row = 0;
       
  2416     int col = 0;
       
  2417     int w = width() / cols;
       
  2418     int h = height() / rows;
       
  2419 
       
  2420     it = d->windows.begin();
       
  2421     while (it != d->windows.end()) {
       
  2422         c = *it;
       
  2423         ++it;
       
  2424         if (c->iconw || c->windowWidget()->isHidden() || (c->titlebar && c->titlebar->isTool()))
       
  2425             continue;
       
  2426         if (!row && !col) {
       
  2427             w -= c->baseSize().width();
       
  2428             h -= c->baseSize().height();
       
  2429         }
       
  2430         if ((c->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)) {
       
  2431             QPoint p = c->pos();
       
  2432             if (p.x()+c->width() < 0)
       
  2433                 p.setX(0);
       
  2434             if (p.x() > width())
       
  2435                 p.setX(width() - c->width());
       
  2436             if (p.y() + 10 < 0)
       
  2437                 p.setY(0);
       
  2438             if (p.y() > height())
       
  2439                 p.setY(height() - c->height());
       
  2440 
       
  2441             if (p != c->pos())
       
  2442                 c->QWidget::move(p);
       
  2443         } else {
       
  2444             c->showNormal();
       
  2445             used[row*cols+col] = true;
       
  2446             QSize sz(w, h);
       
  2447             QSize bsize(c->baseSize());
       
  2448             sz = sz.expandedTo(c->windowWidget()->minimumSize()).boundedTo(c->windowWidget()->maximumSize());
       
  2449             sz += bsize;
       
  2450 
       
  2451             if ( add ) {
       
  2452                 if (sz.height() == h + bsize.height()) // no relevant constrains
       
  2453                     sz.rheight() *= 2;
       
  2454                 used[(row+1)*cols+col] = true;
       
  2455                 add--;
       
  2456             }
       
  2457 
       
  2458             c->setGeometry(col*w + col*bsize.width(), row*h + row*bsize.height(), sz.width(), sz.height());
       
  2459 
       
  2460             while(row < rows && col < cols && used[row*cols+col]) {
       
  2461                 col++;
       
  2462                 if (col == cols) {
       
  2463                     col = 0;
       
  2464                     row++;
       
  2465                 }
       
  2466             }
       
  2467         }
       
  2468     }
       
  2469     delete [] used;
       
  2470 
       
  2471     d->activateWindow(oldActive);
       
  2472     d->updateWorkspace();
       
  2473     blockSignals(false);
       
  2474 }
       
  2475 
       
  2476 /*!
       
  2477     Arranges all iconified windows at the bottom of the workspace.
       
  2478 
       
  2479     \sa cascade(), tile()
       
  2480 */
       
  2481 void QWorkspace::arrangeIcons()
       
  2482 {
       
  2483     Q_D(QWorkspace);
       
  2484 
       
  2485     QRect cr = d->updateWorkspace();
       
  2486     int x = 0;
       
  2487     int y = -1;
       
  2488 
       
  2489     QList<QWidget *>::Iterator it(d->icons.begin());
       
  2490     while (it != d->icons.end()) {
       
  2491         QWidget* i = *it;
       
  2492         if (y == -1)
       
  2493             y = cr.height() - i->height();
       
  2494         if (x > 0 && x + i->width() > cr.width()) {
       
  2495             x = 0;
       
  2496             y -= i->height();
       
  2497         }
       
  2498         i->move(x, y);
       
  2499         x += i->width();
       
  2500         ++it;
       
  2501     }
       
  2502     d->updateWorkspace();
       
  2503 }
       
  2504 
       
  2505 
       
  2506 QWorkspaceChild::QWorkspaceChild(QWidget* window, QWorkspace *parent, Qt::WindowFlags flags)
       
  2507     : QWidget(parent,
       
  2508              Qt::FramelessWindowHint | Qt::SubWindow)
       
  2509 {
       
  2510     setAttribute(Qt::WA_DeleteOnClose);
       
  2511     setAttribute(Qt::WA_NoMousePropagation);
       
  2512     setMouseTracking(true);
       
  2513     act = false;
       
  2514     iconw = 0;
       
  2515     shademode = false;
       
  2516     titlebar = 0;
       
  2517     setAutoFillBackground(true);
       
  2518 
       
  2519     setBackgroundRole(QPalette::Window);
       
  2520     if (window) {
       
  2521         flags |= (window->windowFlags() & Qt::MSWindowsOwnDC);
       
  2522         if (flags)
       
  2523             window->setParent(this, flags & ~Qt::WindowType_Mask);
       
  2524         else
       
  2525             window->setParent(this);
       
  2526     }
       
  2527 
       
  2528     if (window && (flags & (Qt::WindowTitleHint
       
  2529                             | Qt::WindowSystemMenuHint
       
  2530                             | Qt::WindowMinimizeButtonHint
       
  2531                             | Qt::WindowMaximizeButtonHint
       
  2532                             | Qt::WindowContextHelpButtonHint))) {
       
  2533         titlebar = new QWorkspaceTitleBar(window, this, flags);
       
  2534         connect(titlebar, SIGNAL(doActivate()),
       
  2535                  this, SLOT(activate()));
       
  2536         connect(titlebar, SIGNAL(doClose()),
       
  2537                  window, SLOT(close()));
       
  2538         connect(titlebar, SIGNAL(doMinimize()),
       
  2539                  this, SLOT(showMinimized()));
       
  2540         connect(titlebar, SIGNAL(doNormal()),
       
  2541                  this, SLOT(showNormal()));
       
  2542         connect(titlebar, SIGNAL(doMaximize()),
       
  2543                  this, SLOT(showMaximized()));
       
  2544         connect(titlebar, SIGNAL(popupOperationMenu(QPoint)),
       
  2545                  this, SIGNAL(popupOperationMenu(QPoint)));
       
  2546         connect(titlebar, SIGNAL(showOperationMenu()),
       
  2547                  this, SIGNAL(showOperationMenu()));
       
  2548         connect(titlebar, SIGNAL(doShade()),
       
  2549                  this, SLOT(showShaded()));
       
  2550         connect(titlebar, SIGNAL(doubleClicked()),
       
  2551                  this, SLOT(titleBarDoubleClicked()));
       
  2552     }
       
  2553 
       
  2554     setMinimumSize(128, 0);
       
  2555     int fw =  style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, this);
       
  2556     setContentsMargins(fw, fw, fw, fw);
       
  2557 
       
  2558     childWidget = window;
       
  2559     if (!childWidget)
       
  2560         return;
       
  2561 
       
  2562     setWindowTitle(childWidget->windowTitle());
       
  2563 
       
  2564     QPoint p;
       
  2565     QSize s;
       
  2566     QSize cs;
       
  2567 
       
  2568     bool hasBeenResized = childWidget->testAttribute(Qt::WA_Resized);
       
  2569 
       
  2570     if (!hasBeenResized)
       
  2571         cs = childWidget->sizeHint().expandedTo(childWidget->minimumSizeHint()).expandedTo(childWidget->minimumSize()).boundedTo(childWidget->maximumSize());
       
  2572     else
       
  2573         cs = childWidget->size();
       
  2574 
       
  2575     windowSize = cs;
       
  2576 
       
  2577     int th = titlebar ? titlebar->sizeHint().height() : 0;
       
  2578     if (titlebar) {
       
  2579         if (!childWidget->windowIcon().isNull())
       
  2580             titlebar->setWindowIcon(childWidget->windowIcon());
       
  2581 
       
  2582         if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
       
  2583             th -= contentsRect().y();
       
  2584 
       
  2585         p = QPoint(contentsRect().x(),
       
  2586                     th + contentsRect().y());
       
  2587         s = QSize(cs.width() + 2*frameWidth(),
       
  2588                    cs.height() + 2*frameWidth() + th);
       
  2589     } else {
       
  2590         p = QPoint(contentsRect().x(), contentsRect().y());
       
  2591         s = QSize(cs.width() + 2*frameWidth(),
       
  2592                    cs.height() + 2*frameWidth());
       
  2593     }
       
  2594 
       
  2595     childWidget->move(p);
       
  2596     resize(s);
       
  2597 
       
  2598     childWidget->installEventFilter(this);
       
  2599 
       
  2600     widgetResizeHandler = new QWidgetResizeHandler(this, window);
       
  2601     widgetResizeHandler->setSizeProtection(!parent->scrollBarsEnabled());
       
  2602     widgetResizeHandler->setFrameWidth(frameWidth());
       
  2603     connect(widgetResizeHandler, SIGNAL(activate()),
       
  2604              this, SLOT(activate()));
       
  2605     if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
       
  2606         widgetResizeHandler->setExtraHeight(th + contentsRect().y() - 2*frameWidth());
       
  2607     else
       
  2608         widgetResizeHandler->setExtraHeight(th + contentsRect().y() - frameWidth());
       
  2609     if (childWidget->minimumSize() == childWidget->maximumSize())
       
  2610         widgetResizeHandler->setActive(QWidgetResizeHandler::Resize, false);
       
  2611     setBaseSize(baseSize());
       
  2612 }
       
  2613 
       
  2614 QWorkspaceChild::~QWorkspaceChild()
       
  2615 {
       
  2616     QWorkspace *workspace = qobject_cast<QWorkspace*>(parentWidget());
       
  2617     if (iconw) {
       
  2618         if (workspace)
       
  2619             workspace->d_func()->removeIcon(iconw->parentWidget());
       
  2620         delete iconw->parentWidget();
       
  2621     }
       
  2622 
       
  2623     if (workspace) {
       
  2624         workspace->d_func()->focus.removeAll(this);
       
  2625         if (workspace->d_func()->active == this)
       
  2626             workspace->activatePreviousWindow();
       
  2627         if (workspace->d_func()->active == this)
       
  2628             workspace->d_func()->activateWindow(0);
       
  2629         if (workspace->d_func()->maxWindow == this) {
       
  2630             workspace->d_func()->hideMaximizeControls();
       
  2631             workspace->d_func()->maxWindow = 0;
       
  2632         }
       
  2633     }
       
  2634 }
       
  2635 
       
  2636 void QWorkspaceChild::moveEvent(QMoveEvent *)
       
  2637 {
       
  2638     ((QWorkspace*)parentWidget())->d_func()->updateWorkspace();
       
  2639 }
       
  2640 
       
  2641 void QWorkspaceChild::resizeEvent(QResizeEvent *)
       
  2642 {
       
  2643     bool wasMax = isMaximized();
       
  2644     QRect r = contentsRect();
       
  2645     QRect cr;
       
  2646 
       
  2647     updateMask();
       
  2648 
       
  2649     if (titlebar) {
       
  2650         int th = titlebar->sizeHint().height();
       
  2651         QRect tbrect(0, 0, width(), th);
       
  2652         if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
       
  2653             tbrect = QRect(r.x(), r.y(), r.width(), th);
       
  2654         titlebar->setGeometry(tbrect);
       
  2655 
       
  2656         if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
       
  2657             th -= frameWidth();
       
  2658         cr = QRect(r.x(), r.y() + th + (shademode ? (frameWidth() * 3) : 0),
       
  2659                     r.width(), r.height() - th);
       
  2660     } else {
       
  2661         cr = r;
       
  2662     }
       
  2663 
       
  2664     if (!childWidget)
       
  2665         return;
       
  2666 
       
  2667     bool doContentsResize = (windowSize == childWidget->size()
       
  2668                              || !(childWidget->testAttribute(Qt::WA_Resized) && childWidget->testAttribute(Qt::WA_PendingResizeEvent))
       
  2669                              ||childWidget->isMaximized());
       
  2670 
       
  2671     windowSize = cr.size();
       
  2672     childWidget->move(cr.topLeft());
       
  2673     if (doContentsResize)
       
  2674         childWidget->resize(cr.size());
       
  2675     ((QWorkspace*)parentWidget())->d_func()->updateWorkspace();
       
  2676 
       
  2677     if (wasMax) {
       
  2678         overrideWindowState(Qt::WindowMaximized);
       
  2679         childWidget->overrideWindowState(Qt::WindowMaximized);
       
  2680     }
       
  2681 }
       
  2682 
       
  2683 QSize QWorkspaceChild::baseSize() const
       
  2684 {
       
  2685     int th = titlebar ? titlebar->sizeHint().height() : 0;
       
  2686     if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
       
  2687         th -= frameWidth();
       
  2688     return QSize(2*frameWidth(), 2*frameWidth() + th);
       
  2689 }
       
  2690 
       
  2691 QSize QWorkspaceChild::sizeHint() const
       
  2692 {
       
  2693     if (!childWidget)
       
  2694         return QWidget::sizeHint() + baseSize();
       
  2695 
       
  2696     QSize prefSize = windowWidget()->sizeHint().expandedTo(windowWidget()->minimumSizeHint());
       
  2697     prefSize = prefSize.expandedTo(windowWidget()->minimumSize()).boundedTo(windowWidget()->maximumSize());
       
  2698     prefSize += baseSize();
       
  2699 
       
  2700     return prefSize;
       
  2701 }
       
  2702 
       
  2703 QSize QWorkspaceChild::minimumSizeHint() const
       
  2704 {
       
  2705     if (!childWidget)
       
  2706         return QWidget::minimumSizeHint() + baseSize();
       
  2707     QSize s = childWidget->minimumSize();
       
  2708     if (s.isEmpty())
       
  2709         s = childWidget->minimumSizeHint();
       
  2710     return s + baseSize();
       
  2711 }
       
  2712 
       
  2713 void QWorkspaceChild::activate()
       
  2714 {
       
  2715     ((QWorkspace*)parentWidget())->d_func()->activateWindow(windowWidget());
       
  2716 }
       
  2717 
       
  2718 bool QWorkspaceChild::eventFilter(QObject * o, QEvent * e)
       
  2719 {
       
  2720     if (!isActive()
       
  2721         && (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::FocusIn)) {
       
  2722         if (iconw) {
       
  2723             ((QWorkspace*)parentWidget())->d_func()->normalizeWindow(windowWidget());
       
  2724             if (iconw) {
       
  2725                 ((QWorkspace*)parentWidget())->d_func()->removeIcon(iconw->parentWidget());
       
  2726                 delete iconw->parentWidget();
       
  2727                 iconw = 0;
       
  2728             }
       
  2729         }
       
  2730         activate();
       
  2731     }
       
  2732 
       
  2733     // for all widgets except the window, that's the only thing we
       
  2734     // process, and if we have no childWidget we skip totally
       
  2735     if (o != childWidget || childWidget == 0)
       
  2736         return false;
       
  2737 
       
  2738     switch (e->type()) {
       
  2739     case QEvent::ShowToParent:
       
  2740         if (((QWorkspace*)parentWidget())->d_func()->focus.indexOf(this) < 0)
       
  2741             ((QWorkspace*)parentWidget())->d_func()->focus.append(this);
       
  2742 
       
  2743         if (windowWidget() && (windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)) {
       
  2744             internalRaise();
       
  2745             show();
       
  2746         }
       
  2747         ((QWorkspace*)parentWidget())->d_func()->showWindow(windowWidget());
       
  2748         break;
       
  2749     case QEvent::WindowStateChange: {
       
  2750         if (static_cast<QWindowStateChangeEvent*>(e)->isOverride())
       
  2751             break;
       
  2752         Qt::WindowStates state = windowWidget()->windowState();
       
  2753 
       
  2754         if (state & Qt::WindowMinimized) {
       
  2755             ((QWorkspace*)parentWidget())->d_func()->minimizeWindow(windowWidget());
       
  2756         } else if (state & Qt::WindowMaximized) {
       
  2757             if (windowWidget()->maximumSize().isValid() &&
       
  2758                 (windowWidget()->maximumWidth() < parentWidget()->width() ||
       
  2759                  windowWidget()->maximumHeight() < parentWidget()->height())) {
       
  2760                 windowWidget()->resize(windowWidget()->maximumSize());
       
  2761                 windowWidget()->overrideWindowState(Qt::WindowNoState);
       
  2762                 if (titlebar)
       
  2763                     titlebar->update();
       
  2764                 break;
       
  2765             }
       
  2766             if ((windowWidget()->windowFlags() & Qt::WindowMaximizeButtonHint))
       
  2767                 ((QWorkspace*)parentWidget())->d_func()->maximizeWindow(windowWidget());
       
  2768             else
       
  2769                 ((QWorkspace*)parentWidget())->d_func()->normalizeWindow(windowWidget());
       
  2770         } else {
       
  2771             ((QWorkspace*)parentWidget())->d_func()->normalizeWindow(windowWidget());
       
  2772             if (iconw) {
       
  2773                 ((QWorkspace*)parentWidget())->d_func()->removeIcon(iconw->parentWidget());
       
  2774                 delete iconw->parentWidget();
       
  2775             }
       
  2776         }
       
  2777     } break;
       
  2778     case QEvent::HideToParent:
       
  2779     {
       
  2780         QWidget * w = iconw;
       
  2781         if (w && (w = w->parentWidget())) {
       
  2782             ((QWorkspace*)parentWidget())->d_func()->removeIcon(w);
       
  2783             delete w;
       
  2784         }
       
  2785         ((QWorkspace*)parentWidget())->d_func()->hideChild(this);
       
  2786     } break;
       
  2787     case QEvent::WindowIconChange:
       
  2788         {
       
  2789             QWorkspace* ws = (QWorkspace*)parentWidget();
       
  2790             if (ws->d_func()->maxtools && ws->d_func()->maxWindow == this) {
       
  2791                 int iconSize = ws->d_func()->maxtools->size().height();
       
  2792                 ws->d_func()->maxtools->setPixmap(childWidget->windowIcon().pixmap(QSize(iconSize, iconSize)));
       
  2793             }
       
  2794         }
       
  2795         // fall through
       
  2796     case QEvent::WindowTitleChange:
       
  2797         setWindowTitle(windowWidget()->windowTitle());
       
  2798         if (titlebar)
       
  2799             titlebar->update();
       
  2800         if (iconw)
       
  2801             iconw->update();
       
  2802         break;
       
  2803     case QEvent::ModifiedChange:
       
  2804         setWindowModified(windowWidget()->isWindowModified());
       
  2805         if (titlebar)
       
  2806             titlebar->update();
       
  2807         if (iconw)
       
  2808             iconw->update();
       
  2809         break;
       
  2810     case QEvent::Resize:
       
  2811         {
       
  2812             QResizeEvent* re = (QResizeEvent*)e;
       
  2813             if (re->size() != windowSize && !shademode) {
       
  2814                 resize(re->size() + baseSize());
       
  2815                 childWidget->update(); //workaround
       
  2816             }
       
  2817         }
       
  2818         break;
       
  2819 
       
  2820     case QEvent::WindowDeactivate:
       
  2821         if (titlebar && titlebar->isActive()) {
       
  2822             update();
       
  2823         }
       
  2824         break;
       
  2825 
       
  2826     case QEvent::WindowActivate:
       
  2827         if (titlebar && titlebar->isActive()) {
       
  2828             update();
       
  2829         }
       
  2830         break;
       
  2831 
       
  2832     default:
       
  2833         break;
       
  2834     }
       
  2835 
       
  2836     return QWidget::eventFilter(o, e);
       
  2837 }
       
  2838 
       
  2839 void QWorkspaceChild::childEvent(QChildEvent* e)
       
  2840 {
       
  2841     if (e->type() == QEvent::ChildRemoved && e->child() == childWidget) {
       
  2842         childWidget = 0;
       
  2843         if (iconw) {
       
  2844             ((QWorkspace*)parentWidget())->d_func()->removeIcon(iconw->parentWidget());
       
  2845             delete iconw->parentWidget();
       
  2846         }
       
  2847         close();
       
  2848     }
       
  2849 }
       
  2850 
       
  2851 
       
  2852 void QWorkspaceChild::doResize()
       
  2853 {
       
  2854     widgetResizeHandler->doResize();
       
  2855 }
       
  2856 
       
  2857 void QWorkspaceChild::doMove()
       
  2858 {
       
  2859     widgetResizeHandler->doMove();
       
  2860 }
       
  2861 
       
  2862 void QWorkspaceChild::enterEvent(QEvent *)
       
  2863 {
       
  2864 }
       
  2865 
       
  2866 void QWorkspaceChild::leaveEvent(QEvent *)
       
  2867 {
       
  2868 #ifndef QT_NO_CURSOR
       
  2869     if (!widgetResizeHandler->isButtonDown())
       
  2870         setCursor(Qt::ArrowCursor);
       
  2871 #endif
       
  2872 }
       
  2873 
       
  2874 void QWorkspaceChild::paintEvent(QPaintEvent *)
       
  2875 {
       
  2876     QPainter p(this);
       
  2877     QStyleOptionFrame opt;
       
  2878     opt.rect = rect();
       
  2879     opt.palette = palette();
       
  2880     opt.state = QStyle::State_None;
       
  2881     opt.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, this);
       
  2882     opt.midLineWidth = 1;
       
  2883 
       
  2884     if (titlebar && titlebar->isActive() && isActiveWindow())
       
  2885         opt.state |= QStyle::State_Active;
       
  2886 
       
  2887     style()->drawPrimitive(QStyle::PE_FrameWindow, &opt, &p, this);
       
  2888 }
       
  2889 
       
  2890 void QWorkspaceChild::changeEvent(QEvent *ev)
       
  2891 {
       
  2892     if(ev->type() == QEvent::StyleChange) {
       
  2893         resizeEvent(0);
       
  2894         if (iconw) {
       
  2895             QFrame *frame = qobject_cast<QFrame*>(iconw->parentWidget());
       
  2896             Q_ASSERT(frame);
       
  2897             if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar)) {
       
  2898                 frame->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
       
  2899                 frame->resize(196+2*frame->frameWidth(), 20 + 2*frame->frameWidth());
       
  2900             } else {
       
  2901                 frame->resize(196, 20);
       
  2902             }
       
  2903         }
       
  2904         updateMask();
       
  2905     }
       
  2906     QWidget::changeEvent(ev);
       
  2907 }
       
  2908 
       
  2909 void QWorkspaceChild::setActive(bool b)
       
  2910 {
       
  2911     if (!childWidget)
       
  2912         return;
       
  2913 
       
  2914     bool hasFocus = isChildOf(window()->focusWidget(), this);
       
  2915     if (act == b && (act == hasFocus))
       
  2916         return;
       
  2917 
       
  2918     act = b;
       
  2919 
       
  2920     if (titlebar)
       
  2921         titlebar->setActive(act);
       
  2922     if (iconw)
       
  2923         iconw->setActive(act);
       
  2924     update();
       
  2925 
       
  2926     QList<QWidget*> wl = qFindChildren<QWidget*>(childWidget);
       
  2927     if (act) {
       
  2928         for (int i = 0; i < wl.size(); ++i) {
       
  2929             QWidget *w = wl.at(i);
       
  2930             w->removeEventFilter(this);
       
  2931         }
       
  2932         if (!hasFocus) {
       
  2933             QWidget *lastfocusw = childWidget->focusWidget();
       
  2934             if (lastfocusw && lastfocusw->focusPolicy() != Qt::NoFocus) {
       
  2935                 lastfocusw->setFocus();
       
  2936             } else if (childWidget->focusPolicy() != Qt::NoFocus) {
       
  2937                 childWidget->setFocus();
       
  2938             } else {
       
  2939                 // find something, anything, that accepts focus, and use that.
       
  2940                 for (int i = 0; i < wl.size(); ++i) {
       
  2941                     QWidget *w = wl.at(i);
       
  2942                     if(w->focusPolicy() != Qt::NoFocus) {
       
  2943                         w->setFocus();
       
  2944                         hasFocus = true;
       
  2945                         break;
       
  2946                     }
       
  2947                 }
       
  2948                 if (!hasFocus)
       
  2949                     setFocus();
       
  2950             }
       
  2951         }
       
  2952     } else {
       
  2953         for (int i = 0; i < wl.size(); ++i) {
       
  2954             QWidget *w = wl.at(i);
       
  2955             w->removeEventFilter(this);
       
  2956             w->installEventFilter(this);
       
  2957         }
       
  2958     }
       
  2959 }
       
  2960 
       
  2961 bool QWorkspaceChild::isActive() const
       
  2962 {
       
  2963     return act;
       
  2964 }
       
  2965 
       
  2966 QWidget* QWorkspaceChild::windowWidget() const
       
  2967 {
       
  2968     return childWidget;
       
  2969 }
       
  2970 
       
  2971 bool QWorkspaceChild::isWindowOrIconVisible() const
       
  2972 {
       
  2973     return childWidget && (!isHidden()  || (iconw && !iconw->isHidden()));
       
  2974 }
       
  2975 
       
  2976 void QWorkspaceChild::updateMask()
       
  2977 {
       
  2978     QStyleOptionTitleBar titleBarOptions;
       
  2979     titleBarOptions.rect = rect();
       
  2980     titleBarOptions.titleBarFlags = windowFlags();
       
  2981     titleBarOptions.titleBarState = windowState();
       
  2982 
       
  2983     QStyleHintReturnMask frameMask;
       
  2984     if (style()->styleHint(QStyle::SH_WindowFrame_Mask, &titleBarOptions, this, &frameMask)) {
       
  2985         setMask(frameMask.region);
       
  2986     } else if (!mask().isEmpty()) {
       
  2987         clearMask();
       
  2988     }
       
  2989 
       
  2990     if (iconw) {
       
  2991         QFrame *frame = qobject_cast<QFrame *>(iconw->parentWidget());
       
  2992         Q_ASSERT(frame);
       
  2993 
       
  2994         titleBarOptions.rect = frame->rect();
       
  2995         titleBarOptions.titleBarFlags = frame->windowFlags();
       
  2996         titleBarOptions.titleBarState = frame->windowState() | Qt::WindowMinimized;
       
  2997         if (style()->styleHint(QStyle::SH_WindowFrame_Mask, &titleBarOptions, frame, &frameMask)) {
       
  2998             frame->setMask(frameMask.region);
       
  2999         } else if (!frame->mask().isEmpty()) {
       
  3000             frame->clearMask();
       
  3001         }
       
  3002     }
       
  3003 }
       
  3004 
       
  3005 QWidget* QWorkspaceChild::iconWidget() const
       
  3006 {
       
  3007     if (!iconw) {
       
  3008         QWorkspaceChild* that = (QWorkspaceChild*) this;
       
  3009 
       
  3010         QFrame* frame = new QFrame(that, Qt::Window);
       
  3011         QVBoxLayout *vbox = new QVBoxLayout(frame);
       
  3012         vbox->setMargin(0);
       
  3013         QWorkspaceTitleBar *tb = new QWorkspaceTitleBar(windowWidget(), frame);
       
  3014         vbox->addWidget(tb);
       
  3015         tb->setObjectName(QLatin1String("_workspacechild_icon_"));
       
  3016         QStyleOptionTitleBar opt;
       
  3017         tb->initStyleOption(&opt);
       
  3018         int th = style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt, tb);
       
  3019         int iconSize = style()->pixelMetric(QStyle::PM_MdiSubWindowMinimizedWidth, 0, this);
       
  3020         if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar)) {
       
  3021             frame->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
       
  3022             frame->resize(iconSize+2*frame->frameWidth(), th+2*frame->frameWidth());
       
  3023         } else {
       
  3024             frame->resize(iconSize, th);
       
  3025         }
       
  3026 
       
  3027         that->iconw = tb;
       
  3028         that->updateMask();
       
  3029         iconw->setActive(isActive());
       
  3030 
       
  3031         connect(iconw, SIGNAL(doActivate()),
       
  3032                  this, SLOT(activate()));
       
  3033         connect(iconw, SIGNAL(doClose()),
       
  3034                  windowWidget(), SLOT(close()));
       
  3035         connect(iconw, SIGNAL(doNormal()),
       
  3036                  this, SLOT(showNormal()));
       
  3037         connect(iconw, SIGNAL(doMaximize()),
       
  3038                  this, SLOT(showMaximized()));
       
  3039         connect(iconw, SIGNAL(popupOperationMenu(QPoint)),
       
  3040                  this, SIGNAL(popupOperationMenu(QPoint)));
       
  3041         connect(iconw, SIGNAL(showOperationMenu()),
       
  3042                  this, SIGNAL(showOperationMenu()));
       
  3043         connect(iconw, SIGNAL(doubleClicked()),
       
  3044                  this, SLOT(titleBarDoubleClicked()));
       
  3045     }
       
  3046     if (windowWidget()) {
       
  3047         iconw->setWindowTitle(windowWidget()->windowTitle());
       
  3048     }
       
  3049     return iconw->parentWidget();
       
  3050 }
       
  3051 
       
  3052 void QWorkspaceChild::showMinimized()
       
  3053 {
       
  3054     windowWidget()->setWindowState(Qt::WindowMinimized | (windowWidget()->windowState() & ~Qt::WindowMaximized));
       
  3055 }
       
  3056 
       
  3057 void QWorkspaceChild::showMaximized()
       
  3058 {
       
  3059     windowWidget()->setWindowState(Qt::WindowMaximized | (windowWidget()->windowState() & ~Qt::WindowMinimized));
       
  3060 }
       
  3061 
       
  3062 void QWorkspaceChild::showNormal()
       
  3063 {
       
  3064     windowWidget()->setWindowState(windowWidget()->windowState() & ~(Qt::WindowMinimized|Qt::WindowMaximized));
       
  3065 }
       
  3066 
       
  3067 void QWorkspaceChild::showShaded()
       
  3068 {
       
  3069     if (!titlebar)
       
  3070         return;
       
  3071     ((QWorkspace*)parentWidget())->d_func()->activateWindow(windowWidget());
       
  3072     QWidget* w = windowWidget();
       
  3073     if (shademode) {
       
  3074         w->overrideWindowState(Qt::WindowNoState);
       
  3075         overrideWindowState(Qt::WindowNoState);
       
  3076 
       
  3077         shademode = false;
       
  3078         resize(shadeRestore.expandedTo(minimumSizeHint()));
       
  3079         setMinimumSize(shadeRestoreMin);
       
  3080         style()->polish(this);
       
  3081     } else {
       
  3082         shadeRestore = size();
       
  3083         shadeRestoreMin = minimumSize();
       
  3084         setMinimumHeight(0);
       
  3085         shademode = true;
       
  3086         w->overrideWindowState(Qt::WindowMinimized);
       
  3087         overrideWindowState(Qt::WindowMinimized);
       
  3088 
       
  3089         if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
       
  3090             resize(width(), titlebar->height());
       
  3091         else
       
  3092             resize(width(), titlebar->height() + 2*frameWidth() + 1);
       
  3093         style()->polish(this);
       
  3094     }
       
  3095     titlebar->update();
       
  3096 }
       
  3097 
       
  3098 void QWorkspaceChild::titleBarDoubleClicked()
       
  3099 {
       
  3100     if (!windowWidget())
       
  3101         return;
       
  3102     if (iconw)
       
  3103         showNormal();
       
  3104     else if (windowWidget()->windowFlags() & Qt::WindowShadeButtonHint)
       
  3105             showShaded();
       
  3106     else if (windowWidget()->windowFlags() & Qt::WindowMaximizeButtonHint)
       
  3107         showMaximized();
       
  3108 }
       
  3109 
       
  3110 void QWorkspaceChild::adjustToFullscreen()
       
  3111 {
       
  3112     if (!childWidget)
       
  3113         return;
       
  3114 
       
  3115     if(!((QWorkspace*)parentWidget())->d_func()->maxmenubar || style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, this)) {
       
  3116         setGeometry(parentWidget()->rect());
       
  3117     } else {
       
  3118         int fw =  style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, this);
       
  3119         bool noBorder = style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar);
       
  3120         int th = titlebar ? titlebar->sizeHint().height() : 0;
       
  3121         int w = parentWidget()->width() + 2*fw;
       
  3122         int h = parentWidget()->height() + (noBorder ? fw : 2*fw) + th;
       
  3123         w = qMax(w, childWidget->minimumWidth());
       
  3124         h = qMax(h, childWidget->minimumHeight());
       
  3125         setGeometry(-fw, (noBorder ? 0 : -fw) - th, w, h);
       
  3126     }
       
  3127     childWidget->overrideWindowState(Qt::WindowMaximized);
       
  3128     overrideWindowState(Qt::WindowMaximized);
       
  3129 }
       
  3130 
       
  3131 void QWorkspaceChild::internalRaise()
       
  3132 {
       
  3133 
       
  3134     QWidget *stackUnderWidget = 0;
       
  3135     if (!windowWidget() || (windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint) == 0) {
       
  3136 
       
  3137         QList<QWorkspaceChild *>::Iterator it(((QWorkspace*)parent())->d_func()->windows.begin());
       
  3138         while (it != ((QWorkspace*)parent())->d_func()->windows.end()) {
       
  3139             QWorkspaceChild* c = *it;
       
  3140             ++it;
       
  3141             if (c->windowWidget() &&
       
  3142                 !c->windowWidget()->isHidden() &&
       
  3143                 (c->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)) {
       
  3144                 if (stackUnderWidget)
       
  3145                     c->stackUnder(stackUnderWidget);
       
  3146                 else
       
  3147                     c->raise();
       
  3148                 stackUnderWidget = c;
       
  3149             }
       
  3150         }
       
  3151     }
       
  3152 
       
  3153     if (stackUnderWidget) {
       
  3154         if (iconw)
       
  3155             iconw->parentWidget()->stackUnder(stackUnderWidget);
       
  3156         stackUnder(stackUnderWidget);
       
  3157     } else {
       
  3158         if (iconw)
       
  3159             iconw->parentWidget()->raise();
       
  3160         raise();
       
  3161     }
       
  3162 
       
  3163 }
       
  3164 
       
  3165 void QWorkspaceChild::show()
       
  3166 {
       
  3167     if (childWidget && childWidget->isHidden())
       
  3168         childWidget->show();
       
  3169     QWidget::show();
       
  3170 }
       
  3171 
       
  3172 bool QWorkspace::scrollBarsEnabled() const
       
  3173 {
       
  3174     Q_D(const QWorkspace);
       
  3175     return d->vbar != 0;
       
  3176 }
       
  3177 
       
  3178 /*!
       
  3179     \property QWorkspace::scrollBarsEnabled
       
  3180     \brief whether the workspace provides scroll bars
       
  3181 
       
  3182     If this property is true, the workspace will provide scroll bars if any
       
  3183     of the child windows extend beyond the edges of the visible
       
  3184     workspace. The workspace area will automatically increase to
       
  3185     contain child windows if they are resized beyond the right or
       
  3186     bottom edges of the visible area.
       
  3187 
       
  3188     If this property is false (the default), resizing child windows
       
  3189     out of the visible area of the workspace is not permitted, although
       
  3190     it is still possible to position them partially outside the visible area.
       
  3191 */
       
  3192 void QWorkspace::setScrollBarsEnabled(bool enable)
       
  3193 {
       
  3194     Q_D(QWorkspace);
       
  3195     if ((d->vbar != 0) == enable)
       
  3196         return;
       
  3197 
       
  3198     d->xoffset = d->yoffset = 0;
       
  3199     if (enable) {
       
  3200         d->vbar = new QScrollBar(Qt::Vertical, this);
       
  3201         d->vbar->setObjectName(QLatin1String("vertical scrollbar"));
       
  3202         connect(d->vbar, SIGNAL(valueChanged(int)), this, SLOT(_q_scrollBarChanged()));
       
  3203         d->hbar = new QScrollBar(Qt::Horizontal, this);
       
  3204         d->hbar->setObjectName(QLatin1String("horizontal scrollbar"));
       
  3205         connect(d->hbar, SIGNAL(valueChanged(int)), this, SLOT(_q_scrollBarChanged()));
       
  3206         d->corner = new QWidget(this);
       
  3207         d->corner->setBackgroundRole(QPalette::Window);
       
  3208         d->corner->setObjectName(QLatin1String("qt_corner"));
       
  3209         d->updateWorkspace();
       
  3210     } else {
       
  3211         delete d->vbar;
       
  3212         delete d->hbar;
       
  3213         delete d->corner;
       
  3214         d->vbar = d->hbar = 0;
       
  3215         d->corner = 0;
       
  3216     }
       
  3217 
       
  3218     QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
       
  3219     while (it != d->windows.end()) {
       
  3220         QWorkspaceChild *child = *it;
       
  3221         ++it;
       
  3222         child->widgetResizeHandler->setSizeProtection(!enable);
       
  3223     }
       
  3224 }
       
  3225 
       
  3226 QRect QWorkspacePrivate::updateWorkspace()
       
  3227 {
       
  3228     Q_Q(QWorkspace);
       
  3229     QRect cr(q->rect());
       
  3230 
       
  3231     if (q->scrollBarsEnabled() && !maxWindow) {
       
  3232         corner->raise();
       
  3233         vbar->raise();
       
  3234         hbar->raise();
       
  3235         if (maxWindow)
       
  3236             maxWindow->internalRaise();
       
  3237 
       
  3238         QRect r(0, 0, 0, 0);
       
  3239         QList<QWorkspaceChild *>::Iterator it(windows.begin());
       
  3240         while (it != windows.end()) {
       
  3241             QWorkspaceChild *child = *it;
       
  3242             ++it;
       
  3243             if (!child->isHidden())
       
  3244                 r = r.unite(child->geometry());
       
  3245         }
       
  3246         vbar->blockSignals(true);
       
  3247         hbar->blockSignals(true);
       
  3248 
       
  3249         int hsbExt = hbar->sizeHint().height();
       
  3250         int vsbExt = vbar->sizeHint().width();
       
  3251 
       
  3252 
       
  3253         bool showv = yoffset || yoffset + r.bottom() - q->height() + 1 > 0 || yoffset + r.top() < 0;
       
  3254         bool showh = xoffset || xoffset + r.right() - q->width() + 1 > 0 || xoffset + r.left() < 0;
       
  3255 
       
  3256         if (showh && !showv)
       
  3257             showv = yoffset + r.bottom() - q->height() + hsbExt + 1 > 0;
       
  3258         if (showv && !showh)
       
  3259             showh = xoffset + r.right() - q->width() + vsbExt  + 1 > 0;
       
  3260 
       
  3261         if (!showh)
       
  3262             hsbExt = 0;
       
  3263         if (!showv)
       
  3264             vsbExt = 0;
       
  3265 
       
  3266         if (showv) {
       
  3267             vbar->setSingleStep(qMax(q->height() / 12, 30));
       
  3268             vbar->setPageStep(q->height() - hsbExt);
       
  3269             vbar->setMinimum(qMin(0, yoffset + qMin(0, r.top())));
       
  3270             vbar->setMaximum(qMax(0, yoffset + qMax(0, r.bottom() - q->height() + hsbExt + 1)));
       
  3271             vbar->setGeometry(q->width() - vsbExt, 0, vsbExt, q->height() - hsbExt);
       
  3272             vbar->setValue(yoffset);
       
  3273             vbar->show();
       
  3274         } else {
       
  3275             vbar->hide();
       
  3276         }
       
  3277 
       
  3278         if (showh) {
       
  3279             hbar->setSingleStep(qMax(q->width() / 12, 30));
       
  3280             hbar->setPageStep(q->width() - vsbExt);
       
  3281             hbar->setMinimum(qMin(0, xoffset + qMin(0, r.left())));
       
  3282             hbar->setMaximum(qMax(0, xoffset + qMax(0, r.right() - q->width() + vsbExt  + 1)));
       
  3283             hbar->setGeometry(0, q->height() - hsbExt, q->width() - vsbExt, hsbExt);
       
  3284             hbar->setValue(xoffset);
       
  3285             hbar->show();
       
  3286         } else {
       
  3287             hbar->hide();
       
  3288         }
       
  3289 
       
  3290         if (showh && showv) {
       
  3291             corner->setGeometry(q->width() - vsbExt, q->height() - hsbExt, vsbExt, hsbExt);
       
  3292             corner->show();
       
  3293         } else {
       
  3294             corner->hide();
       
  3295         }
       
  3296 
       
  3297         vbar->blockSignals(false);
       
  3298         hbar->blockSignals(false);
       
  3299 
       
  3300         cr.setRect(0, 0, q->width() - vsbExt, q->height() - hsbExt);
       
  3301     }
       
  3302 
       
  3303     QList<QWidget *>::Iterator ii(icons.begin());
       
  3304     while (ii != icons.end()) {
       
  3305         QWidget* w = *ii;
       
  3306         ++ii;
       
  3307         int x = w->x();
       
  3308         int y = w->y();
       
  3309         bool m = false;
       
  3310         if (x+w->width() > cr.width()) {
       
  3311             m = true;
       
  3312             x =  cr.width() - w->width();
       
  3313         }
       
  3314         if (y+w->height() >  cr.height()) {
       
  3315             y =  cr.height() - w->height();
       
  3316             m = true;
       
  3317         }
       
  3318         if (m) {
       
  3319             if (QWorkspaceChild *child = qobject_cast<QWorkspaceChild*>(w))
       
  3320                 child->move(x, y);
       
  3321             else
       
  3322                 w->move(x, y);
       
  3323         }
       
  3324     }
       
  3325 
       
  3326     return cr;
       
  3327 
       
  3328 }
       
  3329 
       
  3330 void QWorkspacePrivate::_q_scrollBarChanged()
       
  3331 {
       
  3332     int ver = yoffset - vbar->value();
       
  3333     int hor = xoffset - hbar->value();
       
  3334     yoffset = vbar->value();
       
  3335     xoffset = hbar->value();
       
  3336 
       
  3337     QList<QWorkspaceChild *>::Iterator it(windows.begin());
       
  3338     while (it != windows.end()) {
       
  3339         QWorkspaceChild *child = *it;
       
  3340         ++it;
       
  3341         // we do not use move() due to the reimplementation in QWorkspaceChild
       
  3342         child->setGeometry(child->x() + hor, child->y() + ver, child->width(), child->height());
       
  3343     }
       
  3344     updateWorkspace();
       
  3345 }
       
  3346 
       
  3347 /*!
       
  3348     \enum QWorkspace::WindowOrder
       
  3349 
       
  3350     Specifies the order in which child windows are returned from windowList().
       
  3351 
       
  3352     \value CreationOrder The windows are returned in the order of their creation
       
  3353     \value StackingOrder The windows are returned in the order of their stacking
       
  3354 */
       
  3355 
       
  3356 /*!\reimp */
       
  3357 void QWorkspace::changeEvent(QEvent *ev)
       
  3358 {
       
  3359     Q_D(QWorkspace);
       
  3360     if(ev->type() == QEvent::StyleChange) {
       
  3361         if (isVisible() && d->maxWindow && d->maxmenubar) {
       
  3362             if(style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, this)) {
       
  3363                 d->hideMaximizeControls(); //hide any visible maximized controls
       
  3364                 d->showMaximizeControls(); //updates the modification state as well
       
  3365             }
       
  3366         }
       
  3367     }
       
  3368     QWidget::changeEvent(ev);
       
  3369 }
       
  3370 
       
  3371 QT_END_NAMESPACE
       
  3372 
       
  3373 #include "moc_qworkspace.cpp"
       
  3374 
       
  3375 #include "qworkspace.moc"
       
  3376 
       
  3377 #endif // QT_NO_WORKSPACE