00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "qworkspace.h"
00025 #ifndef QT_NO_WORKSPACE
00026 #include "qapplication.h"
00027 #include "qbitmap.h"
00028 #include "qcursor.h"
00029 #include "qdatetime.h"
00030 #include "qdesktopwidget.h"
00031 #include "qevent.h"
00032 #include "qhash.h"
00033 #include "qicon.h"
00034 #include "qimage.h"
00035 #include "qlabel.h"
00036 #include "qlayout.h"
00037 #include "qmenubar.h"
00038 #include "qmenu.h"
00039 #include "qpainter.h"
00040 #include "qpointer.h"
00041 #include "qscrollbar.h"
00042 #include "qstyle.h"
00043 #include "qstyleoption.h"
00044 #include "qtoolbutton.h"
00045 #include "qtooltip.h"
00046 #include "qdebug.h"
00047 #include <private/qwidget_p.h>
00048 #include <private/qwidgetresizehandler_p.h>
00049 #include <private/qlayoutengine_p.h>
00050
00051 class QWorkspaceTitleBarPrivate;
00052 class QWorkspaceTitleBar : public QWidget
00053 {
00054 Q_OBJECT
00055 Q_DECLARE_PRIVATE(QWorkspaceTitleBar)
00056 Q_PROPERTY(bool autoRaise READ autoRaise WRITE setAutoRaise)
00057 Q_PROPERTY(bool movable READ isMovable WRITE setMovable)
00058
00059 public:
00060 QWorkspaceTitleBar (QWidget *w, QWidget *parent, Qt::WindowFlags f = 0);
00061 ~QWorkspaceTitleBar();
00062
00063 bool isActive() const;
00064 bool usesActiveColor() const;
00065
00066 bool isMovable() const;
00067 void setMovable(bool);
00068
00069 bool autoRaise() const;
00070 void setAutoRaise(bool);
00071
00072 QWidget *window() const;
00073 bool isTool() const;
00074
00075 QSize sizeHint() const;
00076 QStyleOptionTitleBar getStyleOption() const;
00077
00078 public slots:
00079 void setActive(bool);
00080
00081 signals:
00082 void doActivate();
00083 void doNormal();
00084 void doClose();
00085 void doMaximize();
00086 void doMinimize();
00087 void doShade();
00088 void showOperationMenu();
00089 void popupOperationMenu(const QPoint&);
00090 void doubleClicked();
00091
00092 protected:
00093 bool event(QEvent *);
00094 void contextMenuEvent(QContextMenuEvent *);
00095 void mousePressEvent(QMouseEvent *);
00096 void mouseDoubleClickEvent(QMouseEvent *);
00097 void mouseReleaseEvent(QMouseEvent *);
00098 void mouseMoveEvent(QMouseEvent *);
00099 void enterEvent(QEvent *e);
00100 void leaveEvent(QEvent *e);
00101 void paintEvent(QPaintEvent *p);
00102
00103 private:
00104 Q_DISABLE_COPY(QWorkspaceTitleBar)
00105 };
00106
00107
00108 class QWorkspaceTitleBarPrivate : public QWidgetPrivate
00109 {
00110 Q_DECLARE_PUBLIC(QWorkspaceTitleBar)
00111 public:
00112 QWorkspaceTitleBarPrivate()
00113 :
00114 lastControl(QStyle::SC_None),
00115 #ifndef QT_NO_TOOLTIP
00116 toolTip(0),
00117 #endif
00118 act(0), window(0), movable(1), pressed(0), autoraise(0), moving(0)
00119 {
00120 }
00121
00122 Qt::WindowFlags flags;
00123 QStyle::SubControl buttonDown;
00124 QStyle::SubControl lastControl;
00125 QPoint moveOffset;
00126 #ifndef QT_NO_TOOLTIP
00127 QToolTip *toolTip;
00128 #endif
00129 bool act :1;
00130 QPointer<QWidget> window;
00131 bool movable :1;
00132 bool pressed :1;
00133 bool autoraise :1;
00134 bool moving : 1;
00135
00136 int titleBarState() const;
00137 QStyleOptionTitleBar getStyleOption() const;
00138 void readColors();
00139 };
00140
00141 inline int QWorkspaceTitleBarPrivate::titleBarState() const
00142 {
00143 Q_Q(const QWorkspaceTitleBar);
00144 uint state = window ? window->windowState() : static_cast<Qt::WindowStates>(Qt::WindowNoState);
00145 state |= uint((act && q->isActiveWindow()) ? QStyle::State_Active : QStyle::State_None);
00146 return (int)state;
00147 }
00148
00149 QStyleOptionTitleBar QWorkspaceTitleBarPrivate::getStyleOption() const
00150 {
00151 Q_Q(const QWorkspaceTitleBar);
00152 QStyleOptionTitleBar opt;
00153 opt.init(q);
00154
00155 if (window && (flags & Qt::WindowTitleHint)) {
00156 opt.text = window->windowTitle();
00157 QIcon icon = window->windowIcon();
00158 QSize s = icon.actualSize(QSize(64, 64));
00159 opt.icon = icon.pixmap(s);
00160 }
00161 opt.subControls = QStyle::SC_All;
00162 opt.activeSubControls = QStyle::SC_None;
00163 opt.titleBarState = titleBarState();
00164 opt.titleBarFlags = flags;
00165 opt.state &= ~QStyle::State_MouseOver;
00166 return opt;
00167 }
00168
00169 QWorkspaceTitleBar::QWorkspaceTitleBar(QWidget *w, QWidget *parent, Qt::WindowFlags f)
00170 : QWidget(*new QWorkspaceTitleBarPrivate, parent, Qt::FramelessWindowHint)
00171 {
00172 Q_D(QWorkspaceTitleBar);
00173 if (f == 0 && w)
00174 f = w->windowFlags();
00175 d->flags = f;
00176 d->window = w;
00177 d->buttonDown = QStyle::SC_None;
00178 d->act = 0;
00179 if (w) {
00180 if (w->maximumSize() != QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX))
00181 d->flags &= ~Qt::WindowMaximizeButtonHint;
00182 setWindowTitle(w->windowTitle());
00183 }
00184
00185 d->readColors();
00186 setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
00187 setMouseTracking(true);
00188 setAutoRaise(style()->styleHint(QStyle::SH_TitleBar_AutoRaise, 0, this));
00189 }
00190
00191 QWorkspaceTitleBar::~QWorkspaceTitleBar()
00192 {
00193 }
00194
00195 QStyleOptionTitleBar QWorkspaceTitleBar::getStyleOption() const
00196 {
00197 return d_func()->getStyleOption();
00198 }
00199
00200 #ifdef Q_WS_WIN
00201 static inline QRgb colorref2qrgb(COLORREF col)
00202 {
00203 return qRgb(GetRValue(col),GetGValue(col),GetBValue(col));
00204 }
00205 #endif
00206
00207 void QWorkspaceTitleBarPrivate::readColors()
00208 {
00209 Q_Q(QWorkspaceTitleBar);
00210 QPalette pal = q->palette();
00211
00212 bool colorsInitialized = false;
00213
00214 #ifdef Q_WS_WIN // ask system properties on windows
00215 #ifndef SPI_GETGRADIENTCAPTIONS
00216 #define SPI_GETGRADIENTCAPTIONS 0x1008
00217 #endif
00218 #ifndef COLOR_GRADIENTACTIVECAPTION
00219 #define COLOR_GRADIENTACTIVECAPTION 27
00220 #endif
00221 #ifndef COLOR_GRADIENTINACTIVECAPTION
00222 #define COLOR_GRADIENTINACTIVECAPTION 28
00223 #endif
00224 if (QApplication::desktopSettingsAware()) {
00225 pal.setColor(QPalette::Active, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_ACTIVECAPTION)));
00226 pal.setColor(QPalette::Inactive, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION)));
00227 pal.setColor(QPalette::Active, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT)));
00228 pal.setColor(QPalette::Inactive, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT)));
00229 if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) {
00230 colorsInitialized = true;
00231 BOOL gradient;
00232 QT_WA({
00233 SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
00234 } , {
00235 SystemParametersInfoA(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
00236 });
00237 if (gradient) {
00238 pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)));
00239 pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)));
00240 } else {
00241 pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight));
00242 pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight));
00243 }
00244 }
00245 }
00246 #endif // Q_WS_WIN
00247 if (!colorsInitialized) {
00248 pal.setColor(QPalette::Active, QPalette::Highlight,
00249 pal.color(QPalette::Active, QPalette::Highlight));
00250 pal.setColor(QPalette::Active, QPalette::Base,
00251 pal.color(QPalette::Active, QPalette::Highlight));
00252 pal.setColor(QPalette::Inactive, QPalette::Highlight,
00253 pal.color(QPalette::Inactive, QPalette::Dark));
00254 pal.setColor(QPalette::Inactive, QPalette::Base,
00255 pal.color(QPalette::Inactive, QPalette::Dark));
00256 pal.setColor(QPalette::Inactive, QPalette::HighlightedText,
00257 pal.color(QPalette::Inactive, QPalette::Window));
00258 }
00259
00260 q->setPalette(pal);
00261 q->setActive(act);
00262 }
00263
00264 void QWorkspaceTitleBar::mousePressEvent(QMouseEvent *e)
00265 {
00266 Q_D(QWorkspaceTitleBar);
00267 if (!d->act)
00268 emit doActivate();
00269 if (e->button() == Qt::LeftButton) {
00270 if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, 0)
00271 && !rect().adjusted(5, 5, -5, 0).contains(e->pos())) {
00272
00273 e->ignore();
00274 return;
00275 }
00276
00277 d->pressed = true;
00278 QStyleOptionTitleBar opt = d->getStyleOption();
00279 QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
00280 e->pos(), this);
00281 switch (ctrl) {
00282 case QStyle::SC_TitleBarSysMenu:
00283 if (d->flags & Qt::WindowSystemMenuHint) {
00284 d->buttonDown = QStyle::SC_None;
00285 static QTime *t = 0;
00286 static QWorkspaceTitleBar *tc = 0;
00287 if (!t)
00288 t = new QTime;
00289 if (tc != this || t->elapsed() > QApplication::doubleClickInterval()) {
00290 emit showOperationMenu();
00291 t->start();
00292 tc = this;
00293 } else {
00294 tc = 0;
00295 emit doClose();
00296 return;
00297 }
00298 }
00299 break;
00300
00301 case QStyle::SC_TitleBarShadeButton:
00302 case QStyle::SC_TitleBarUnshadeButton:
00303 if (d->flags & Qt::WindowShadeButtonHint)
00304 d->buttonDown = ctrl;
00305 break;
00306
00307 case QStyle::SC_TitleBarNormalButton:
00308 d->buttonDown = ctrl;
00309 break;
00310
00311 case QStyle::SC_TitleBarMinButton:
00312 if (d->flags & Qt::WindowMinimizeButtonHint)
00313 d->buttonDown = ctrl;
00314 break;
00315
00316 case QStyle::SC_TitleBarMaxButton:
00317 if (d->flags & Qt::WindowMaximizeButtonHint)
00318 d->buttonDown = ctrl;
00319 break;
00320
00321 case QStyle::SC_TitleBarCloseButton:
00322 if (d->flags & Qt::WindowSystemMenuHint)
00323 d->buttonDown = ctrl;
00324 break;
00325
00326 case QStyle::SC_TitleBarLabel:
00327 d->buttonDown = ctrl;
00328 d->moveOffset = mapToParent(e->pos());
00329 break;
00330
00331 default:
00332 break;
00333 }
00334 update();
00335 } else {
00336 d->pressed = false;
00337 }
00338 }
00339
00340 void QWorkspaceTitleBar::contextMenuEvent(QContextMenuEvent *e)
00341 {
00342 QStyleOptionTitleBar opt = d_func()->getStyleOption();
00343 QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt, e->pos(),
00344 this);
00345 if(ctrl == QStyle::SC_TitleBarLabel || ctrl == QStyle::SC_TitleBarSysMenu) {
00346 e->accept();
00347 emit popupOperationMenu(e->globalPos());
00348 } else {
00349 e->ignore();
00350 }
00351 }
00352
00353 void QWorkspaceTitleBar::mouseReleaseEvent(QMouseEvent *e)
00354 {
00355 Q_D(QWorkspaceTitleBar);
00356 if (!d->window) {
00357
00358 return;
00359 }
00360 if (e->button() == Qt::LeftButton && d->pressed) {
00361 if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, 0)
00362 && !rect().adjusted(5, 5, -5, 0).contains(e->pos())) {
00363
00364 e->ignore();
00365 d->buttonDown = QStyle::SC_None;
00366 d->pressed = false;
00367 return;
00368 }
00369 e->accept();
00370 QStyleOptionTitleBar opt = d->getStyleOption();
00371 QStyle::SubControl ctrl = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
00372 e->pos(), this);
00373
00374 if (d->pressed) {
00375 update();
00376 d->pressed = false;
00377 d->moving = false;
00378 }
00379 if (ctrl == d->buttonDown) {
00380 d->buttonDown = QStyle::SC_None;
00381 switch(ctrl) {
00382 case QStyle::SC_TitleBarShadeButton:
00383 case QStyle::SC_TitleBarUnshadeButton:
00384 if(d->flags & Qt::WindowShadeButtonHint)
00385 emit doShade();
00386 break;
00387
00388 case QStyle::SC_TitleBarNormalButton:
00389 if(d->flags & Qt::WindowMinMaxButtonsHint)
00390 emit doNormal();
00391 break;
00392
00393 case QStyle::SC_TitleBarMinButton:
00394 if(d->flags & Qt::WindowMinimizeButtonHint) {
00395 if (d->window && d->window->isMinimized())
00396 emit doNormal();
00397 else
00398 emit doMinimize();
00399 }
00400 break;
00401
00402 case QStyle::SC_TitleBarMaxButton:
00403 if(d->flags & Qt::WindowMaximizeButtonHint) {
00404 if(d->window && d->window->isMaximized())
00405 emit doNormal();
00406 else
00407 emit doMaximize();
00408 }
00409 break;
00410
00411 case QStyle::SC_TitleBarCloseButton:
00412 if(d->flags & Qt::WindowSystemMenuHint) {
00413 d->buttonDown = QStyle::SC_None;
00414 emit doClose();
00415 return;
00416 }
00417 break;
00418
00419 default:
00420 break;
00421 }
00422 }
00423 } else {
00424 e->ignore();
00425 }
00426 }
00427
00428 void QWorkspaceTitleBar::mouseMoveEvent(QMouseEvent *e)
00429 {
00430 Q_D(QWorkspaceTitleBar);
00431 e->ignore();
00432 if ((e->buttons() & Qt::LeftButton) && style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, 0)
00433 && !rect().adjusted(5, 5, -5, 0).contains(e->pos()) && !d->pressed) {
00434
00435 return;
00436 }
00437
00438 QStyleOptionTitleBar opt = d->getStyleOption();
00439 QStyle::SubControl under_mouse = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
00440 e->pos(), this);
00441 if(under_mouse != d->lastControl) {
00442 d->lastControl = under_mouse;
00443 update();
00444 }
00445
00446 switch (d->buttonDown) {
00447 case QStyle::SC_None:
00448 break;
00449 case QStyle::SC_TitleBarSysMenu:
00450 break;
00451 case QStyle::SC_TitleBarLabel:
00452 if (d->buttonDown == QStyle::SC_TitleBarLabel && d->movable && d->pressed) {
00453 if (d->moving || (d->moveOffset - mapToParent(e->pos())).manhattanLength() >= 4) {
00454 d->moving = true;
00455 QPoint p = mapFromGlobal(e->globalPos());
00456
00457 QWidget *parent = d->window ? d->window->parentWidget() : 0;
00458 if(parent && parent->inherits("QWorkspaceChild")) {
00459 QWidget *workspace = parent->parentWidget();
00460 p = workspace->mapFromGlobal(e->globalPos());
00461 if (!workspace->rect().contains(p)) {
00462 if (p.x() < 0)
00463 p.rx() = 0;
00464 if (p.y() < 0)
00465 p.ry() = 0;
00466 if (p.x() > workspace->width())
00467 p.rx() = workspace->width();
00468 if (p.y() > workspace->height())
00469 p.ry() = workspace->height();
00470 }
00471 }
00472
00473 QPoint pp = p - d->moveOffset;
00474 if (!parentWidget()->isMaximized())
00475 parentWidget()->move(pp);
00476 }
00477 }
00478 e->accept();
00479 break;
00480 default:
00481 break;
00482 }
00483 }
00484
00485 bool QWorkspaceTitleBar::isTool() const
00486 {
00487 Q_D(const QWorkspaceTitleBar);
00488 return (d->flags & Qt::WindowType_Mask) == Qt::Tool;
00489 }
00490
00491
00492 extern QString qt_setWindowTitle_helperHelper(const QString &, QWidget*);
00493
00494 void QWorkspaceTitleBar::paintEvent(QPaintEvent *)
00495 {
00496 Q_D(QWorkspaceTitleBar);
00497 QStyleOptionTitleBar opt = d->getStyleOption();
00498 opt.subControls = QStyle::SC_TitleBarLabel;
00499 opt.activeSubControls = d->buttonDown;
00500
00501 if (d->window && (d->flags & Qt::WindowTitleHint)) {
00502 QString title = qt_setWindowTitle_helperHelper(opt.text, d->window);
00503 int maxw = style()->subControlRect(QStyle::CC_TitleBar, &opt, QStyle::SC_TitleBarLabel,
00504 this).width();
00505 opt.text = fontMetrics().elidedText(title, Qt::ElideRight, maxw);
00506 }
00507
00508 if (d->flags & Qt::WindowSystemMenuHint) {
00509 opt.subControls |= QStyle::SC_TitleBarSysMenu | QStyle::SC_TitleBarCloseButton;
00510 if (d->window && (d->flags & Qt::WindowShadeButtonHint)) {
00511 if (d->window->isMinimized())
00512 opt.subControls |= QStyle::SC_TitleBarUnshadeButton;
00513 else
00514 opt.subControls |= QStyle::SC_TitleBarShadeButton;
00515 }
00516 if (d->window && (d->flags & Qt::WindowMinMaxButtonsHint)) {
00517 if(d->window && d->window->isMinimized())
00518 opt.subControls |= QStyle::SC_TitleBarNormalButton;
00519 else
00520 opt.subControls |= QStyle::SC_TitleBarMinButton;
00521 }
00522 if (d->window && (d->flags & Qt::WindowMaximizeButtonHint) && !d->window->isMaximized())
00523 opt.subControls |= QStyle::SC_TitleBarMaxButton;
00524 }
00525
00526 QStyle::SubControl under_mouse = QStyle::SC_None;
00527 under_mouse = style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt,
00528 mapFromGlobal(QCursor::pos()), this);
00529 if ((d->buttonDown == under_mouse) && d->pressed) {
00530 opt.state |= QStyle::State_Sunken;
00531 } else if( autoRaise() && under_mouse != QStyle::SC_None && !d->pressed) {
00532 opt.activeSubControls = under_mouse;
00533 opt.state |= QStyle::State_MouseOver;
00534 }
00535 opt.palette.setCurrentColorGroup(usesActiveColor() ? QPalette::Active : QPalette::Inactive);
00536
00537 QPainter p(this);
00538 style()->drawComplexControl(QStyle::CC_TitleBar, &opt, &p, this);
00539 }
00540
00541 void QWorkspaceTitleBar::mouseDoubleClickEvent(QMouseEvent *e)
00542 {
00543 Q_D(QWorkspaceTitleBar);
00544 if (e->button() != Qt::LeftButton) {
00545 e->ignore();
00546 return;
00547 }
00548 e->accept();
00549 QStyleOptionTitleBar opt = d->getStyleOption();
00550 switch (style()->hitTestComplexControl(QStyle::CC_TitleBar, &opt, e->pos(), this)) {
00551 case QStyle::SC_TitleBarLabel:
00552 emit doubleClicked();
00553 break;
00554
00555 case QStyle::SC_TitleBarSysMenu:
00556 if (d->flags & Qt::WindowSystemMenuHint)
00557 emit doClose();
00558 break;
00559
00560 default:
00561 break;
00562 }
00563 }
00564
00565 void QWorkspaceTitleBar::leaveEvent(QEvent *)
00566 {
00567 Q_D(QWorkspaceTitleBar);
00568 d->lastControl = QStyle::SC_None;
00569 if(autoRaise() && !d->pressed)
00570 update();
00571 }
00572
00573 void QWorkspaceTitleBar::enterEvent(QEvent *)
00574 {
00575 Q_D(QWorkspaceTitleBar);
00576 if(autoRaise() && !d->pressed)
00577 update();
00578 QEvent e(QEvent::Leave);
00579 QApplication::sendEvent(parentWidget(), &e);
00580 }
00581
00582 void QWorkspaceTitleBar::setActive(bool active)
00583 {
00584 Q_D(QWorkspaceTitleBar);
00585 if (d->act == active)
00586 return ;
00587
00588 d->act = active;
00589 update();
00590 }
00591
00592 bool QWorkspaceTitleBar::isActive() const
00593 {
00594 Q_D(const QWorkspaceTitleBar);
00595 return d->act;
00596 }
00597
00598 bool QWorkspaceTitleBar::usesActiveColor() const
00599 {
00600 return (isActive() && isActiveWindow()) ||
00601 (!window() && QWidget::window()->isActiveWindow());
00602 }
00603
00604 QWidget *QWorkspaceTitleBar::window() const
00605 {
00606 Q_D(const QWorkspaceTitleBar);
00607 return d->window;
00608 }
00609
00610 bool QWorkspaceTitleBar::event(QEvent *e)
00611 {
00612 Q_D(QWorkspaceTitleBar);
00613 if (e->type() == QEvent::ApplicationPaletteChange) {
00614 d->readColors();
00615 } else if (e->type() == QEvent::WindowActivate
00616 || e->type() == QEvent::WindowDeactivate) {
00617 if (d->act)
00618 update();
00619 }
00620 return QWidget::event(e);
00621 }
00622
00623 void QWorkspaceTitleBar::setMovable(bool b)
00624 {
00625 Q_D(QWorkspaceTitleBar);
00626 d->movable = b;
00627 }
00628
00629 bool QWorkspaceTitleBar::isMovable() const
00630 {
00631 Q_D(const QWorkspaceTitleBar);
00632 return d->movable;
00633 }
00634
00635 void QWorkspaceTitleBar::setAutoRaise(bool b)
00636 {
00637 Q_D(QWorkspaceTitleBar);
00638 d->autoraise = b;
00639 }
00640
00641 bool QWorkspaceTitleBar::autoRaise() const
00642 {
00643 Q_D(const QWorkspaceTitleBar);
00644 return d->autoraise;
00645 }
00646
00647 QSize QWorkspaceTitleBar::sizeHint() const
00648 {
00649 Q_D(const QWorkspaceTitleBar);
00650 ensurePolished();
00651 QStyleOptionTitleBar opt = d->getStyleOption();
00652 QRect menur = style()->subControlRect(QStyle::CC_TitleBar, &opt,
00653 QStyle::SC_TitleBarSysMenu, this);
00654 return QSize(menur.width(), style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt, this));
00655 }
00656
00722 class QWorkspaceChild : public QWidget
00723 {
00724 Q_OBJECT
00725
00726 friend class QWorkspacePrivate;
00727 friend class QWorkspace;
00728 friend class QWorkspaceTitleBar;
00729
00730 public:
00731 QWorkspaceChild(QWidget* window, QWorkspace* parent=0, Qt::WindowFlags flags = 0);
00732 ~QWorkspaceChild();
00733
00734 void setActive(bool);
00735 bool isActive() const;
00736
00737 void adjustToFullscreen();
00738
00739 QWidget* windowWidget() const;
00740 QWidget* iconWidget() const;
00741
00742 void doResize();
00743 void doMove();
00744
00745 QSize sizeHint() const;
00746 QSize minimumSizeHint() const;
00747
00748 QSize baseSize() const;
00749
00750 int frameWidth() const;
00751
00752 void show();
00753
00754 bool isWindowOrIconVisible() const;
00755
00756 signals:
00757 void showOperationMenu();
00758 void popupOperationMenu(const QPoint&);
00759
00760 public slots:
00761 void activate();
00762 void showMinimized();
00763 void showMaximized();
00764 void showNormal();
00765 void showShaded();
00766 void internalRaise();
00767 void titleBarDoubleClicked();
00768
00769 protected:
00770 void enterEvent(QEvent *);
00771 void leaveEvent(QEvent *);
00772 void childEvent(QChildEvent*);
00773 void resizeEvent(QResizeEvent *);
00774 void moveEvent(QMoveEvent *);
00775 bool eventFilter(QObject *, QEvent *);
00776
00777 void paintEvent(QPaintEvent *);
00778 void changeEvent(QEvent *);
00779
00780 private:
00781 void updateMask();
00782
00783 Q_DISABLE_COPY(QWorkspaceChild)
00784
00785 QWidget *childWidget;
00786 QWidgetResizeHandler *widgetResizeHandler;
00787 QWorkspaceTitleBar *titlebar;
00788 QPointer<QWorkspaceTitleBar> iconw;
00789 QSize windowSize;
00790 QSize shadeRestore;
00791 QSize shadeRestoreMin;
00792 bool act :1;
00793 bool shademode :1;
00794 };
00795
00796 int QWorkspaceChild::frameWidth() const
00797 {
00798 return contentsRect().left();
00799 }
00800
00801
00802
00803 class QWorkspacePrivate : public QWidgetPrivate {
00804 Q_DECLARE_PUBLIC(QWorkspace)
00805 public:
00806 QWorkspaceChild* active;
00807 QList<QWorkspaceChild *> windows;
00808 QList<QWorkspaceChild *> focus;
00809 QList<QWidget *> icons;
00810 QWorkspaceChild* maxWindow;
00811 QRect maxRestore;
00812 QPointer<QFrame> maxcontrols;
00813 QPointer<QMenuBar> maxmenubar;
00814 QHash<int, const char*> shortcutMap;
00815
00816 int px;
00817 int py;
00818 QWidget *becomeActive;
00819 QPointer<QLabel> maxtools;
00820 QString topTitle;
00821
00822 QMenu *popup, *toolPopup;
00823 enum WSActs { RestoreAct, MoveAct, ResizeAct, MinimizeAct, MaximizeAct, CloseAct, StaysOnTopAct, ShadeAct, NCountAct };
00824 QAction *actions[NCountAct];
00825
00826 QScrollBar *vbar, *hbar;
00827 QWidget *corner;
00828 int yoffset, xoffset;
00829 QBrush background;
00830
00831 void init();
00832 void insertIcon(QWidget* w);
00833 void removeIcon(QWidget* w);
00834 void place(QWidget*);
00835
00836 QWorkspaceChild* findChild(QWidget* w);
00837 void showMaximizeControls();
00838 void hideMaximizeControls();
00839 void activateWindow(QWidget* w, bool change_focus = true);
00840 void hideChild(QWorkspaceChild *c);
00841 void showWindow(QWidget* w);
00842 void maximizeWindow(QWidget* w);
00843 void minimizeWindow(QWidget* w);
00844 void normalizeWindow(QWidget* w);
00845
00846 QRect updateWorkspace();
00847
00848 private:
00849 void _q_normalizeActiveWindow();
00850 void _q_minimizeActiveWindow();
00851 void _q_showOperationMenu();
00852 void _q_popupOperationMenu(const QPoint&);
00853 void _q_operationMenuActivated(QAction *);
00854 void _q_scrollBarChanged();
00855 void _q_updateActions();
00856 bool inTitleChange;
00857 };
00858
00859 static bool isChildOf(QWidget * child, QWidget * parent)
00860 {
00861 if (!parent || !child)
00862 return false;
00863 QWidget * w = child;
00864 while(w && w != parent)
00865 w = w->parentWidget();
00866 return w != 0;
00867 }
00868
00872 QWorkspace::QWorkspace(QWidget *parent)
00873 : QWidget(*new QWorkspacePrivate, parent, 0)
00874 {
00875 Q_D(QWorkspace);
00876 d->init();
00877 }
00878
00879 #ifdef QT3_SUPPORT
00880
00884 QWorkspace::QWorkspace(QWidget *parent, const char *name)
00885 : QWidget(*new QWorkspacePrivate, parent, 0)
00886 {
00887 Q_D(QWorkspace);
00888 setObjectName(QString::fromAscii(name));
00889 d->init();
00890 }
00891 #endif // QT3_SUPPORT
00892
00896 void
00897 QWorkspacePrivate::init()
00898 {
00899 Q_Q(QWorkspace);
00900
00901 maxcontrols = 0;
00902 active = 0;
00903 maxWindow = 0;
00904 maxtools = 0;
00905 px = 0;
00906 py = 0;
00907 becomeActive = 0;
00908 popup = new QMenu(q);
00909 toolPopup = new QMenu(q);
00910 popup->setObjectName(QLatin1String("qt_internal_mdi_popup"));
00911 toolPopup->setObjectName(QLatin1String("qt_internal_mdi_tool_popup"));
00912
00913 actions[QWorkspacePrivate::RestoreAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarNormalButton)),
00914 QWorkspace::tr("&Restore"), q);
00915 actions[QWorkspacePrivate::MoveAct] = new QAction(QWorkspace::tr("&Move"), q);
00916 actions[QWorkspacePrivate::ResizeAct] = new QAction(QWorkspace::tr("&Size"), q);
00917 actions[QWorkspacePrivate::MinimizeAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarMinButton)),
00918 QWorkspace::tr("Mi&nimize"), q);
00919 actions[QWorkspacePrivate::MaximizeAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarMaxButton)),
00920 QWorkspace::tr("Ma&ximize"), q);
00921 actions[QWorkspacePrivate::CloseAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarCloseButton)),
00922 QWorkspace::tr("&Close")
00923 #ifndef QT_NO_SHORTCUT
00924 +QLatin1Char('\t')+(QString)QKeySequence(Qt::CTRL+Qt::Key_F4)
00925 #endif
00926 ,q);
00927 QObject::connect(actions[QWorkspacePrivate::CloseAct], SIGNAL(triggered()), q, SLOT(closeActiveWindow()));
00928 actions[QWorkspacePrivate::StaysOnTopAct] = new QAction(QWorkspace::tr("Stay on &Top"), q);
00929 actions[QWorkspacePrivate::StaysOnTopAct]->setChecked(true);
00930 actions[QWorkspacePrivate::ShadeAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarShadeButton)),
00931 QWorkspace::tr("Sh&ade"), q);
00932
00933 QObject::connect(popup, SIGNAL(aboutToShow()), q, SLOT(_q_updateActions()));
00934 QObject::connect(popup, SIGNAL(triggered(QAction*)), q, SLOT(_q_operationMenuActivated(QAction*)));
00935 popup->addAction(actions[QWorkspacePrivate::RestoreAct]);
00936 popup->addAction(actions[QWorkspacePrivate::MoveAct]);
00937 popup->addAction(actions[QWorkspacePrivate::ResizeAct]);
00938 popup->addAction(actions[QWorkspacePrivate::MinimizeAct]);
00939 popup->addAction(actions[QWorkspacePrivate::MaximizeAct]);
00940 popup->addSeparator();
00941 popup->addAction(actions[QWorkspacePrivate::CloseAct]);
00942
00943 QObject::connect(toolPopup, SIGNAL(aboutToShow()), q, SLOT(_q_updateActions()));
00944 QObject::connect(toolPopup, SIGNAL(triggered(QAction*)), q, SLOT(_q_operationMenuActivated(QAction*)));
00945 toolPopup->addAction(actions[QWorkspacePrivate::MoveAct]);
00946 toolPopup->addAction(actions[QWorkspacePrivate::ResizeAct]);
00947 toolPopup->addAction(actions[QWorkspacePrivate::StaysOnTopAct]);
00948 toolPopup->addSeparator();
00949 toolPopup->addAction(actions[QWorkspacePrivate::ShadeAct]);
00950 toolPopup->addAction(actions[QWorkspacePrivate::CloseAct]);
00951
00952 #ifndef QT_NO_SHORTCUT
00953
00954 QList <QKeySequence> shortcuts = QKeySequence::keyBindings(QKeySequence::NextChild);
00955 foreach (QKeySequence seq, shortcuts)
00956 shortcutMap.insert(q->grabShortcut(seq), "activateNextWindow");
00957
00958 shortcuts = QKeySequence::keyBindings(QKeySequence::PreviousChild);
00959 foreach (QKeySequence seq, shortcuts)
00960 shortcutMap.insert(q->grabShortcut(seq), "activatePreviousWindow");
00961
00962 shortcuts = QKeySequence::keyBindings(QKeySequence::Close);
00963 foreach (QKeySequence seq, shortcuts)
00964 shortcutMap.insert(q->grabShortcut(seq), "closeActiveWindow");
00965
00966 shortcutMap.insert(q->grabShortcut(QKeySequence("ALT+-")), "_q_showOperationMenu");
00967 #endif // QT_NO_SHORTCUT
00968
00969 q->setBackgroundRole(QPalette::Dark);
00970 q->setAutoFillBackground(true);
00971 q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
00972
00973 hbar = vbar = 0;
00974 corner = 0;
00975 xoffset = yoffset = 0;
00976
00977 q->window()->installEventFilter(q);
00978
00979 inTitleChange = false;
00980 updateWorkspace();
00981 }
00982
00987 QWorkspace::~QWorkspace()
00988 {
00989 }
00990
00992 QSize QWorkspace::sizeHint() const
00993 {
00994 QSize s(QApplication::desktop()->size());
00995 return QSize(s.width()*2/3, s.height()*2/3);
00996 }
00997
00998
00999 #ifdef QT3_SUPPORT
01000
01004 void QWorkspace::setPaletteBackgroundColor(const QColor & c)
01005 {
01006 setBackground(c);
01007 }
01008
01013 void QWorkspace::setPaletteBackgroundPixmap(const QPixmap & pm)
01014 {
01015 setBackground(pm);
01016 }
01017 #endif // QT3_SUPPORT
01018
01023 QBrush QWorkspace::background() const
01024 {
01025 Q_D(const QWorkspace);
01026 if (d->background.style() == Qt::NoBrush)
01027 return palette().dark();
01028 return d->background;
01029 }
01030
01031 void QWorkspace::setBackground(const QBrush &background)
01032 {
01033 Q_D(QWorkspace);
01034 d->background = background;
01035 setAttribute(Qt::WA_OpaquePaintEvent, background.style() == Qt::NoBrush);
01036 update();
01037 }
01038
01049 QWidget * QWorkspace::addWindow(QWidget *w, Qt::WindowFlags flags)
01050 {
01051 Q_D(QWorkspace);
01052 if (!w)
01053 return 0;
01054
01055 w->setAutoFillBackground(true);
01056
01057 QWidgetPrivate::adjustFlags(flags);
01058
01059 #if 0
01060 bool wasMaximized = w->isMaximized();
01061 bool wasMinimized = w->isMinimized();
01062 #endif
01063 bool hasSize = w->testAttribute(Qt::WA_Resized);
01064 int x = w->x();
01065 int y = w->y();
01066 bool hasPos = w->testAttribute(Qt::WA_Moved);
01067 QSize s = w->size().expandedTo(qSmartMinSize(w));
01068 if (!hasSize && w->sizeHint().isValid())
01069 w->adjustSize();
01070
01071 QWorkspaceChild* child = new QWorkspaceChild(w, this, flags);
01072 child->setObjectName(QLatin1String("qt_workspacechild"));
01073 child->installEventFilter(this);
01074
01075 connect(child, SIGNAL(popupOperationMenu(QPoint)),
01076 this, SLOT(_q_popupOperationMenu(QPoint)));
01077 connect(child, SIGNAL(showOperationMenu()),
01078 this, SLOT(_q_showOperationMenu()));
01079 d->windows.append(child);
01080 if (child->isVisibleTo(this))
01081 d->focus.append(child);
01082 child->internalRaise();
01083
01084 if (!hasPos)
01085 d->place(child);
01086 if (!hasSize)
01087 child->adjustSize();
01088 if (hasPos)
01089 child->move(x, y);
01090
01091 return child;
01092
01093 #if 0
01094 if (wasMaximized)
01095 w->showMaximized();
01096 else if (wasMinimized)
01097 w->showMinimized();
01098 else if (!hasBeenHidden)
01099 d->activateWindow(w);
01100
01101 d->updateWorkspace();
01102 return child;
01103 #endif
01104 }
01105
01107 void QWorkspace::childEvent(QChildEvent * e)
01108 {
01109 Q_D(QWorkspace);
01110 if (e->removed()) {
01111 if (d->windows.removeAll(static_cast<QWorkspaceChild*>(e->child()))) {
01112 d->focus.removeAll(static_cast<QWorkspaceChild*>(e->child()));
01113 if (d->maxWindow == e->child())
01114 d->maxWindow = 0;
01115 d->updateWorkspace();
01116 }
01117 }
01118 }
01119
01121 #ifndef QT_NO_WHEELEVENT
01122 void QWorkspace::wheelEvent(QWheelEvent *e)
01123 {
01124 Q_D(QWorkspace);
01125 if (!scrollBarsEnabled())
01126 return;
01127
01128
01129
01130
01131
01132 if (d->vbar && d->vbar->isVisible() && !(e->modifiers() & Qt::AltModifier))
01133 d->vbar->event(e);
01134 else if (d->hbar && d->hbar->isVisible())
01135 d->hbar->event(e);
01136 }
01137 #endif
01138
01139 void QWorkspacePrivate::activateWindow(QWidget* w, bool change_focus)
01140 {
01141 Q_Q(QWorkspace);
01142 if (!w) {
01143 active = 0;
01144 emit q->windowActivated(0);
01145 return;
01146 }
01147 if (!q->isVisible()) {
01148 becomeActive = w;
01149 return;
01150 }
01151
01152 if (active && active->windowWidget() == w) {
01153 if (!isChildOf(q->focusWidget(), w))
01154 active->setActive(true);
01155 return;
01156 }
01157
01158 active = 0;
01159
01160 QList<QWorkspaceChild *>::Iterator it(windows.begin());
01161 while (it != windows.end()) {
01162 QWorkspaceChild* c = *it;
01163 ++it;
01164 if (c->windowWidget() == w)
01165 active = c;
01166 else
01167 c->setActive(false);
01168 }
01169
01170 if (!active)
01171 return;
01172
01173
01174 active->setActive(true);
01175
01176 if (!active)
01177 return;
01178
01179 if (maxWindow && maxWindow != active && active->windowWidget() &&
01180 (active->windowWidget()->windowFlags() & Qt::WindowMaximizeButtonHint))
01181 active->showMaximized();
01182
01183 active->internalRaise();
01184
01185 if (change_focus) {
01186 int from = focus.indexOf(active);
01187 if (from >= 0)
01188 focus.move(from, focus.size() - 1);
01189 }
01190
01191 updateWorkspace();
01192 emit q->windowActivated(w);
01193 }
01194
01195
01202 QWidget* QWorkspace::activeWindow() const
01203 {
01204 Q_D(const QWorkspace);
01205 return d->active? d->active->windowWidget() : 0;
01206 }
01207
01213 void QWorkspace::setActiveWindow(QWidget *w)
01214 {
01215 Q_D(QWorkspace);
01216 d->activateWindow(w, true);
01217 if (w && w->isMinimized())
01218 w->setWindowState(w->windowState() & ~Qt::WindowMinimized);
01219 }
01220
01221 void QWorkspacePrivate::place(QWidget *w)
01222 {
01223 Q_Q(QWorkspace);
01224
01225 QList<QWidget *> widgets;
01226 for (QList<QWorkspaceChild *>::Iterator it(windows.begin()); it != windows.end(); ++it)
01227 if (*it != w)
01228 widgets.append(*it);
01229
01230 int overlap, minOverlap = 0;
01231 int possible;
01232
01233 QRect r1(0, 0, 0, 0);
01234 QRect r2(0, 0, 0, 0);
01235 QRect maxRect = q->rect();
01236 int x = maxRect.left(), y = maxRect.top();
01237 QPoint wpos(maxRect.left(), maxRect.top());
01238
01239 bool firstPass = true;
01240
01241 do {
01242 if (y + w->height() > maxRect.bottom()) {
01243 overlap = -1;
01244 } else if(x + w->width() > maxRect.right()) {
01245 overlap = -2;
01246 } else {
01247 overlap = 0;
01248
01249 r1.setRect(x, y, w->width(), w->height());
01250
01251 QWidget *l;
01252 QList<QWidget *>::Iterator it(widgets.begin());
01253 while (it != widgets.end()) {
01254 l = *it;
01255 ++it;
01256
01257 if (maxWindow == l)
01258 r2 = QStyle::visualRect(q->layoutDirection(), maxRect, maxRestore);
01259 else
01260 r2 = QStyle::visualRect(q->layoutDirection(), maxRect,
01261 QRect(l->x(), l->y(), l->width(), l->height()));
01262
01263 if (r2.intersects(r1)) {
01264 r2.setCoords(qMax(r1.left(), r2.left()),
01265 qMax(r1.top(), r2.top()),
01266 qMin(r1.right(), r2.right()),
01267 qMin(r1.bottom(), r2.bottom())
01268 );
01269
01270 overlap += (r2.right() - r2.left()) *
01271 (r2.bottom() - r2.top());
01272 }
01273 }
01274 }
01275
01276 if (overlap == 0) {
01277 wpos = QPoint(x, y);
01278 break;
01279 }
01280
01281 if (firstPass) {
01282 firstPass = false;
01283 minOverlap = overlap;
01284 } else if (overlap >= 0 && overlap < minOverlap) {
01285 minOverlap = overlap;
01286 wpos = QPoint(x, y);
01287 }
01288
01289 if (overlap > 0) {
01290 possible = maxRect.right();
01291 if (possible - w->width() > x) possible -= w->width();
01292
01293 QWidget *l;
01294 QList<QWidget *>::Iterator it(widgets.begin());
01295 while (it != widgets.end()) {
01296 l = *it;
01297 ++it;
01298 if (maxWindow == l)
01299 r2 = QStyle::visualRect(q->layoutDirection(), maxRect, maxRestore);
01300 else
01301 r2 = QStyle::visualRect(q->layoutDirection(), maxRect,
01302 QRect(l->x(), l->y(), l->width(), l->height()));
01303
01304 if((y < r2.bottom()) && (r2.top() < w->height() + y)) {
01305 if(r2.right() > x)
01306 possible = possible < r2.right() ?
01307 possible : r2.right();
01308
01309 if(r2.left() - w->width() > x)
01310 possible = possible < r2.left() - w->width() ?
01311 possible : r2.left() - w->width();
01312 }
01313 }
01314
01315 x = possible;
01316 } else if (overlap == -2) {
01317 x = maxRect.left();
01318 possible = maxRect.bottom();
01319
01320 if (possible - w->height() > y) possible -= w->height();
01321
01322 QWidget *l;
01323 QList<QWidget *>::Iterator it(widgets.begin());
01324 while (it != widgets.end()) {
01325 l = *it;
01326 ++it;
01327 if (maxWindow == l)
01328 r2 = QStyle::visualRect(q->layoutDirection(), maxRect, maxRestore);
01329 else
01330 r2 = QStyle::visualRect(q->layoutDirection(), maxRect,
01331 QRect(l->x(), l->y(), l->width(), l->height()));
01332
01333 if(r2.bottom() > y)
01334 possible = possible < r2.bottom() ?
01335 possible : r2.bottom();
01336
01337 if(r2.top() - w->height() > y)
01338 possible = possible < r2.top() - w->height() ?
01339 possible : r2.top() - w->height();
01340 }
01341
01342 y = possible;
01343 }
01344 }
01345 while(overlap != 0 && overlap != -1);
01346
01347 QRect resultRect = w->geometry();
01348 resultRect.moveTo(wpos);
01349 w->setGeometry(QStyle::visualRect(q->layoutDirection(), maxRect, resultRect));
01350 updateWorkspace();
01351 }
01352
01353
01354 void QWorkspacePrivate::insertIcon(QWidget* w)
01355 {
01356 Q_Q(QWorkspace);
01357 if (!w || icons.contains(w))
01358 return;
01359 icons.append(w);
01360 if (w->parentWidget() != q) {
01361 w->setParent(q, 0);
01362 w->move(0,0);
01363 }
01364 QRect cr = updateWorkspace();
01365 int x = 0;
01366 int y = cr.height() - w->height();
01367
01368 QList<QWidget *>::Iterator it(icons.begin());
01369 while (it != icons.end()) {
01370 QWidget* i = *it;
01371 ++it;
01372 if (x > 0 && x + i->width() > cr.width()){
01373 x = 0;
01374 y -= i->height();
01375 }
01376
01377 if (i != w &&
01378 i->geometry().intersects(QRect(x, y, w->width(), w->height())))
01379 x += i->width();
01380 }
01381 w->move(x, y);
01382
01383 if (q->isVisibleTo(q->parentWidget())) {
01384 w->show();
01385 w->lower();
01386 }
01387 updateWorkspace();
01388 }
01389
01390
01391 void QWorkspacePrivate::removeIcon(QWidget* w)
01392 {
01393 if (icons.removeAll(w))
01394 w->hide();
01395 }
01396
01397
01399 void QWorkspace::resizeEvent(QResizeEvent *)
01400 {
01401 Q_D(QWorkspace);
01402 if (d->maxWindow) {
01403 d->maxWindow->adjustToFullscreen();
01404 if (d->maxWindow->windowWidget())
01405 d->maxWindow->windowWidget()->overrideWindowState(Qt::WindowMaximized);
01406 }
01407 d->updateWorkspace();
01408 }
01409
01411 void QWorkspace::showEvent(QShowEvent *e)
01412 {
01413 Q_D(QWorkspace);
01414 if (d->maxWindow)
01415 d->showMaximizeControls();
01416 QWidget::showEvent(e);
01417 if (d->becomeActive) {
01418 d->activateWindow(d->becomeActive);
01419 d->becomeActive = 0;
01420 } else if (d->windows.count() > 0 && !d->active) {
01421 d->activateWindow(d->windows.first()->windowWidget());
01422 }
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432 d->updateWorkspace();
01433 }
01434
01436 void QWorkspace::hideEvent(QHideEvent *)
01437 {
01438 Q_D(QWorkspace);
01439 if (!isVisible())
01440 d->hideMaximizeControls();
01441 }
01442
01444 void QWorkspace::paintEvent(QPaintEvent *)
01445 {
01446 Q_D(QWorkspace);
01447
01448 if (d->background.style() != Qt::NoBrush) {
01449 QPainter p(this);
01450 p.fillRect(0, 0, width(), height(), d->background);
01451 }
01452 }
01453
01454 void QWorkspacePrivate::minimizeWindow(QWidget* w)
01455 {
01456 QWorkspaceChild* c = findChild(w);
01457
01458 if (!w || !(w->windowFlags() & Qt::WindowMinimizeButtonHint))
01459 return;
01460
01461 if (c) {
01462 bool wasMax = false;
01463 if (c == maxWindow) {
01464 wasMax = true;
01465 maxWindow = 0;
01466 hideMaximizeControls();
01467 for (QList<QWorkspaceChild *>::Iterator it(windows.begin()); it != windows.end(); ++it) {
01468 QWorkspaceChild* c = *it;
01469 if (c->titlebar)
01470 c->titlebar->setMovable(true);
01471 c->widgetResizeHandler->setActive(true);
01472 }
01473 }
01474 c->hide();
01475 if (wasMax)
01476 c->setGeometry(maxRestore);
01477 if (!focus.contains(c))
01478 focus.append(c);
01479 insertIcon(c->iconWidget());
01480
01481 if (!maxWindow)
01482 activateWindow(w);
01483
01484 updateWorkspace();
01485
01486 w->overrideWindowState(Qt::WindowMinimized);
01487 c->overrideWindowState(Qt::WindowMinimized);
01488 }
01489 }
01490
01491 void QWorkspacePrivate::normalizeWindow(QWidget* w)
01492 {
01493 Q_Q(QWorkspace);
01494 QWorkspaceChild* c = findChild(w);
01495 if (!w)
01496 return;
01497 if (c) {
01498 w->overrideWindowState(Qt::WindowNoState);
01499 hideMaximizeControls();
01500 if (!maxmenubar || q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q) || !maxWindow) {
01501 if (w->minimumSize() != w->maximumSize())
01502 c->widgetResizeHandler->setActive(true);
01503 if (c->titlebar)
01504 c->titlebar->setMovable(true);
01505 }
01506 w->overrideWindowState(Qt::WindowNoState);
01507 c->overrideWindowState(Qt::WindowNoState);
01508
01509 if (c == maxWindow) {
01510 c->setGeometry(maxRestore);
01511 maxWindow = 0;
01512 } else {
01513 if (c->iconw)
01514 removeIcon(c->iconw->parentWidget());
01515 c->show();
01516 }
01517
01518 hideMaximizeControls();
01519 for (QList<QWorkspaceChild *>::Iterator it(windows.begin()); it != windows.end(); ++it) {
01520 QWorkspaceChild* c = *it;
01521 if (c->titlebar)
01522 c->titlebar->setMovable(true);
01523 if (c->childWidget && c->childWidget->minimumSize() != c->childWidget->maximumSize())
01524 c->widgetResizeHandler->setActive(true);
01525 }
01526 activateWindow(w, true);
01527 updateWorkspace();
01528 }
01529 }
01530
01531 void QWorkspacePrivate::maximizeWindow(QWidget* w)
01532 {
01533 Q_Q(QWorkspace);
01534 QWorkspaceChild* c = findChild(w);
01535
01536 if (!w || !(w->windowFlags() & Qt::WindowMaximizeButtonHint))
01537 return;
01538
01539 if (!c || c == maxWindow)
01540 return;
01541
01542 bool updatesEnabled = q->updatesEnabled();
01543 q->setUpdatesEnabled(false);
01544
01545 if (c->iconw && icons.contains(c->iconw->parentWidget()))
01546 normalizeWindow(w);
01547 QRect r(c->geometry());
01548 QWorkspaceChild *oldMaxWindow = maxWindow;
01549 maxWindow = c;
01550
01551 showMaximizeControls();
01552
01553 c->adjustToFullscreen();
01554 c->show();
01555 c->internalRaise();
01556 if (oldMaxWindow != c) {
01557 if (oldMaxWindow) {
01558 oldMaxWindow->setGeometry(maxRestore);
01559 oldMaxWindow->overrideWindowState(Qt::WindowNoState);
01560 if(oldMaxWindow->windowWidget())
01561 oldMaxWindow->windowWidget()->overrideWindowState(Qt::WindowNoState);
01562 }
01563 maxRestore = r;
01564 }
01565
01566 activateWindow(w);
01567
01568 if(!maxmenubar || q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q)) {
01569 if (!active && becomeActive) {
01570 active = (QWorkspaceChild*)becomeActive->parentWidget();
01571 active->setActive(true);
01572 becomeActive = 0;
01573 emit q->windowActivated(active->windowWidget());
01574 }
01575 c->widgetResizeHandler->setActive(false);
01576 if (c->titlebar)
01577 c->titlebar->setMovable(false);
01578 }
01579 updateWorkspace();
01580
01581 w->overrideWindowState(Qt::WindowMaximized);
01582 c->overrideWindowState(Qt::WindowMaximized);
01583 q->setUpdatesEnabled(updatesEnabled);
01584 }
01585
01586 void QWorkspacePrivate::showWindow(QWidget* w)
01587 {
01588 if (w->isMinimized() && (w->windowFlags() & Qt::WindowMinimizeButtonHint))
01589 minimizeWindow(w);
01590 else if ((maxWindow || w->isMaximized()) && w->windowFlags() & Qt::WindowMaximizeButtonHint)
01591 maximizeWindow(w);
01592 else if (w->windowFlags() & Qt::WindowMaximizeButtonHint)
01593 normalizeWindow(w);
01594 else
01595 w->parentWidget()->show();
01596 if (maxWindow)
01597 maxWindow->internalRaise();
01598 updateWorkspace();
01599 }
01600
01601
01602 QWorkspaceChild* QWorkspacePrivate::findChild(QWidget* w)
01603 {
01604 QList<QWorkspaceChild *>::Iterator it(windows.begin());
01605 while (it != windows.end()) {
01606 QWorkspaceChild* c = *it;
01607 ++it;
01608 if (c->windowWidget() == w)
01609 return c;
01610 }
01611 return 0;
01612 }
01613
01621 QWidgetList QWorkspace::windowList(WindowOrder order) const
01622 {
01623 Q_D(const QWorkspace);
01624 QWidgetList windows;
01625 if (order == StackingOrder) {
01626 QObjectList cl = children();
01627 for (int i = 0; i < cl.size(); ++i) {
01628 QWorkspaceChild *c = qobject_cast<QWorkspaceChild*>(cl.at(i));
01629 if (c && c->isWindowOrIconVisible())
01630 windows.append(c->windowWidget());
01631 }
01632 } else {
01633 QList<QWorkspaceChild *>::ConstIterator it(d->windows.begin());
01634 while (it != d->windows.end()) {
01635 QWorkspaceChild* c = *it;
01636 ++it;
01637 if (c && c->isWindowOrIconVisible())
01638 windows.append(c->windowWidget());
01639 }
01640 }
01641 return windows;
01642 }
01643
01644
01646 bool QWorkspace::event(QEvent *e)
01647 {
01648 #ifndef QT_NO_SHORTCUT
01649 Q_D(QWorkspace);
01650 if (e->type() == QEvent::Shortcut) {
01651 QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
01652 const char *theSlot = d->shortcutMap.value(se->shortcutId(), 0);
01653 if (theSlot)
01654 QMetaObject::invokeMethod(this, theSlot);
01655 } else
01656 #endif
01657 if (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut){
01658 return true;
01659 }
01660 return QWidget::event(e);
01661 }
01662
01664 bool QWorkspace::eventFilter(QObject *o, QEvent * e)
01665 {
01666 Q_D(QWorkspace);
01667 static QTime* t = 0;
01668 static QWorkspace* tc = 0;
01669 if (o == d->maxtools) {
01670 switch (e->type()) {
01671 case QEvent::MouseButtonPress:
01672 {
01673 QMenuBar* b = (QMenuBar*)o->parent();
01674 if (!t)
01675 t = new QTime;
01676 if (tc != this || t->elapsed() > QApplication::doubleClickInterval()) {
01677 if (isRightToLeft()) {
01678 QPoint p = b->mapToGlobal(QPoint(b->x() + b->width(), b->y() + b->height()));
01679 p.rx() -= d->popup->sizeHint().width();
01680 d->_q_popupOperationMenu(p);
01681 } else {
01682 d->_q_popupOperationMenu(b->mapToGlobal(QPoint(b->x(), b->y() + b->height())));
01683 }
01684 t->start();
01685 tc = this;
01686 } else {
01687 tc = 0;
01688 closeActiveWindow();
01689 }
01690 return true;
01691 }
01692 default:
01693 break;
01694 }
01695 return QWidget::eventFilter(o, e);
01696 }
01697 switch (e->type()) {
01698 case QEvent::HideToParent:
01699 break;
01700 case QEvent::ShowToParent:
01701 if (QWorkspaceChild *c = qobject_cast<QWorkspaceChild*>(o))
01702 if (!d->focus.contains(c))
01703 d->focus.append(c);
01704 d->updateWorkspace();
01705 break;
01706 case QEvent::WindowTitleChange:
01707 if (!d->inTitleChange) {
01708 if (o == window())
01709 d->topTitle = window()->windowTitle();
01710 if (d->maxWindow && d->maxWindow->windowWidget() && d->topTitle.size()) {
01711 d->inTitleChange = true;
01712 window()->setWindowTitle(tr("%1 - [%2]")
01713 .arg(d->topTitle).arg(d->maxWindow->windowWidget()->windowTitle()));
01714 d->inTitleChange = false;
01715 }
01716 }
01717 break;
01718
01719 case QEvent::ModifiedChange:
01720 if (o == d->maxWindow)
01721 window()->setWindowModified(d->maxWindow->isWindowModified());
01722 break;
01723
01724 case QEvent::Close:
01725 if (o == window())
01726 {
01727 QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
01728 while (it != d->windows.end()) {
01729 QWorkspaceChild* c = *it;
01730 ++it;
01731 if (c->shademode)
01732 c->showShaded();
01733 }
01734 } else if (qobject_cast<QWorkspaceChild*>(o)) {
01735 d->popup->hide();
01736 }
01737 d->updateWorkspace();
01738 break;
01739 default:
01740 break;
01741 }
01742 return QWidget::eventFilter(o, e);
01743 }
01744
01745 static QMenuBar *findMenuBar(QWidget *w)
01746 {
01747
01748
01749
01750 QList<QObject *> children = w->children();
01751 for (int i = 0; i < children.count(); ++i) {
01752 QMenuBar *bar = qobject_cast<QMenuBar *>(children.at(i));
01753 if (bar)
01754 return bar;
01755 }
01756 return 0;
01757 }
01758
01759 void QWorkspacePrivate::showMaximizeControls()
01760 {
01761 Q_Q(QWorkspace);
01762 Q_ASSERT(maxWindow);
01763
01764
01765 if (!topTitle.size())
01766 topTitle = q->window()->windowTitle();
01767
01768 if (maxWindow->windowWidget()) {
01769 QString docTitle = maxWindow->windowWidget()->windowTitle();
01770 if (topTitle.size() && docTitle.size()) {
01771 inTitleChange = true;
01772 q->window()->setWindowTitle(QWorkspace::tr("%1 - [%2]").arg(topTitle).arg(docTitle));
01773 inTitleChange = false;
01774 }
01775 q->window()->setWindowModified(maxWindow->windowWidget()->isWindowModified());
01776 }
01777
01778 if (!q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q)) {
01779 QMenuBar* b = 0;
01780
01781
01782 QWidget* w = q->parentWidget();
01783 while (w) {
01784 b = findMenuBar(w);
01785 if (b)
01786 break;
01787 w = w->parentWidget();
01788 }
01789
01790
01791 if (!b)
01792 b = findMenuBar(q->window());
01793
01794 if (!b)
01795 return;
01796
01797 if (!maxcontrols) {
01798 maxmenubar = b;
01799 maxcontrols = new QFrame(q->window());
01800 maxcontrols->setObjectName(QLatin1String("qt_maxcontrols"));
01801 QHBoxLayout* l = new QHBoxLayout(maxcontrols);
01802 l->setMargin(maxcontrols->frameWidth());
01803 l->setSpacing(0);
01804 if (maxWindow->windowWidget() &&
01805 (maxWindow->windowWidget()->windowFlags() & Qt::WindowMinimizeButtonHint)) {
01806 QToolButton* iconB = new QToolButton(maxcontrols);
01807 iconB->setObjectName(QLatin1String("iconify"));
01808 #ifndef QT_NO_TOOLTIP
01809 iconB->setToolTip(QWorkspace::tr("Minimize"));
01810 #endif
01811 l->addWidget(iconB);
01812 iconB->setFocusPolicy(Qt::NoFocus);
01813 QPixmap pm = q->style()->standardPixmap(QStyle::SP_TitleBarMinButton);
01814 iconB->setIcon(pm);
01815 iconB->setIconSize(pm.size());
01816 QObject::connect(iconB, SIGNAL(clicked()),
01817 q, SLOT(_q_minimizeActiveWindow()));
01818 }
01819
01820 QToolButton* restoreB = new QToolButton(maxcontrols);
01821 restoreB->setObjectName(QLatin1String("restore"));
01822 #ifndef QT_NO_TOOLTIP
01823 restoreB->setToolTip(QWorkspace::tr("Restore Down"));
01824 #endif
01825 l->addWidget(restoreB);
01826 restoreB->setFocusPolicy(Qt::NoFocus);
01827 QPixmap pm = q->style()->standardPixmap(QStyle::SP_TitleBarNormalButton);
01828 restoreB->setIcon(pm);
01829 restoreB->setIconSize(pm.size());
01830 QObject::connect(restoreB, SIGNAL(clicked()),
01831 q, SLOT(_q_normalizeActiveWindow()));
01832
01833 l->addSpacing(2);
01834 QToolButton* closeB = new QToolButton(maxcontrols);
01835 closeB->setObjectName(QLatin1String("close"));
01836 #ifndef QT_NO_TOOLTIP
01837 closeB->setToolTip(QWorkspace::tr("Close"));
01838 #endif
01839 l->addWidget(closeB);
01840 closeB->setFocusPolicy(Qt::NoFocus);
01841 pm = q->style()->standardPixmap(QStyle::SP_TitleBarCloseButton);
01842 closeB->setIcon(pm);
01843 closeB->setIconSize(pm.size());
01844 QObject::connect(closeB, SIGNAL(clicked()),
01845 q, SLOT(closeActiveWindow()));
01846
01847 maxcontrols->setFixedSize(maxcontrols->minimumSizeHint());
01848 }
01849
01850 b->setCornerWidget(maxcontrols);
01851 if (b->isVisible())
01852 maxcontrols->show();
01853 if (!active && becomeActive) {
01854 active = (QWorkspaceChild*)becomeActive->parentWidget();
01855 active->setActive(true);
01856 becomeActive = 0;
01857 emit q->windowActivated(active->windowWidget());
01858 }
01859 if (active) {
01860 if (!maxtools) {
01861 maxtools = new QLabel(q->window());
01862 maxtools->setObjectName(QLatin1String("qt_maxtools"));
01863 maxtools->installEventFilter(q);
01864 }
01865 if (active->windowWidget() && !active->windowWidget()->windowIcon().isNull()) {
01866 QIcon icon = active->windowWidget()->windowIcon();
01867 int iconSize = maxcontrols->size().height();
01868 maxtools->setPixmap(icon.pixmap(QSize(iconSize, iconSize)));
01869 } else {
01870 QPixmap pm = q->style()->standardPixmap(QStyle::SP_TitleBarMenuButton);
01871 if (pm.isNull()) {
01872 pm = QPixmap(14,14);
01873 pm.fill(Qt::black);
01874 }
01875 maxtools->setPixmap(pm);
01876 }
01877 b->setCornerWidget(maxtools, Qt::TopLeftCorner);
01878 if (b->isVisible())
01879 maxtools->show();
01880 }
01881 }
01882 }
01883
01884
01885 void QWorkspacePrivate::hideMaximizeControls()
01886 {
01887 Q_Q(QWorkspace);
01888 if (maxmenubar && !q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q)) {
01889 if (maxmenubar) {
01890 maxmenubar->setCornerWidget(0, Qt::TopLeftCorner);
01891 maxmenubar->setCornerWidget(0, Qt::TopRightCorner);
01892 }
01893 maxcontrols->deleteLater();
01894 maxtools->deleteLater();
01895 }
01896
01897
01898 if (topTitle.size()) {
01899 inTitleChange = true;
01900 q->window()->setWindowTitle(topTitle);
01901 inTitleChange = false;
01902 }
01903 q->window()->setWindowModified(false);
01904 }
01905
01911 void QWorkspace::closeActiveWindow()
01912 {
01913 Q_D(QWorkspace);
01914 if (d->maxWindow && d->maxWindow->windowWidget())
01915 d->maxWindow->windowWidget()->close();
01916 else if (d->active && d->active->windowWidget())
01917 d->active->windowWidget()->close();
01918 d->updateWorkspace();
01919 }
01920
01929 void QWorkspace::closeAllWindows()
01930 {
01931 Q_D(QWorkspace);
01932 bool did_close = true;
01933 QList<QWorkspaceChild *>::const_iterator it = d->windows.constBegin();
01934 while (it != d->windows.constEnd() && did_close) {
01935 QWorkspaceChild *c = *it;
01936 ++it;
01937 if (c->windowWidget() && !c->windowWidget()->isHidden())
01938 did_close = c->windowWidget()->close();
01939 }
01940 }
01941
01942 void QWorkspacePrivate::_q_normalizeActiveWindow()
01943 {
01944 if (maxWindow)
01945 maxWindow->showNormal();
01946 else if (active)
01947 active->showNormal();
01948 }
01949
01950 void QWorkspacePrivate::_q_minimizeActiveWindow()
01951 {
01952 if (maxWindow)
01953 maxWindow->showMinimized();
01954 else if (active)
01955 active->showMinimized();
01956 }
01957
01958 void QWorkspacePrivate::_q_showOperationMenu()
01959 {
01960 Q_Q(QWorkspace);
01961 if (!active || !active->windowWidget())
01962 return;
01963 Q_ASSERT((active->windowWidget()->windowFlags() & Qt::WindowSystemMenuHint));
01964 QPoint p;
01965 QMenu *popup = (active->titlebar && active->titlebar->isTool()) ? toolPopup : this->popup;
01966 if (q->isRightToLeft()) {
01967 p = QPoint(active->windowWidget()->mapToGlobal(QPoint(active->windowWidget()->width(),0)));
01968 p.rx() -= popup->sizeHint().width();
01969 } else {
01970 p = QPoint(active->windowWidget()->mapToGlobal(QPoint(0,0)));
01971 }
01972 if (!active->isVisible()) {
01973 p = active->iconWidget()->mapToGlobal(QPoint(0,0));
01974 p.ry() -= popup->sizeHint().height();
01975 }
01976 _q_popupOperationMenu(p);
01977 }
01978
01979 void QWorkspacePrivate::_q_popupOperationMenu(const QPoint& p)
01980 {
01981 if (!active || !active->windowWidget() || !(active->windowWidget()->windowFlags() & Qt::WindowSystemMenuHint))
01982 return;
01983 if (active->titlebar && active->titlebar->isTool())
01984 toolPopup->popup(p);
01985 else
01986 popup->popup(p);
01987 }
01988
01989 void QWorkspacePrivate::_q_updateActions()
01990 {
01991 Q_Q(QWorkspace);
01992 for (int i = 1; i < NCountAct-1; i++) {
01993 bool enable = active != 0;
01994 actions[i]->setEnabled(enable);
01995 }
01996
01997 if (!active || !active->windowWidget())
01998 return;
01999
02000 QWidget *windowWidget = active->windowWidget();
02001 bool canResize = windowWidget->maximumSize() != windowWidget->minimumSize();
02002 actions[QWorkspacePrivate::ResizeAct]->setEnabled(canResize);
02003 actions[QWorkspacePrivate::MinimizeAct]->setEnabled((windowWidget->windowFlags() & Qt::WindowMinimizeButtonHint));
02004 actions[QWorkspacePrivate::MaximizeAct]->setEnabled((windowWidget->windowFlags() & Qt::WindowMaximizeButtonHint) && canResize);
02005
02006 if (active == maxWindow) {
02007 actions[QWorkspacePrivate::MoveAct]->setEnabled(false);
02008 actions[QWorkspacePrivate::ResizeAct]->setEnabled(false);
02009 actions[QWorkspacePrivate::MaximizeAct]->setEnabled(false);
02010 actions[QWorkspacePrivate::RestoreAct]->setEnabled(true);
02011 } else if (active->isVisible()){
02012 actions[QWorkspacePrivate::RestoreAct]->setEnabled(false);
02013 } else {
02014 actions[QWorkspacePrivate::MoveAct]->setEnabled(false);
02015 actions[QWorkspacePrivate::ResizeAct]->setEnabled(false);
02016 actions[QWorkspacePrivate::MinimizeAct]->setEnabled(false);
02017 actions[QWorkspacePrivate::RestoreAct]->setEnabled(true);
02018 }
02019 if (active->shademode) {
02020 actions[QWorkspacePrivate::ShadeAct]->setIcon(
02021 QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarUnshadeButton)));
02022 actions[QWorkspacePrivate::ShadeAct]->setText(QWorkspace::tr("&Unshade"));
02023 } else {
02024 actions[QWorkspacePrivate::ShadeAct]->setIcon(
02025 QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarShadeButton)));
02026 actions[QWorkspacePrivate::ShadeAct]->setText(QWorkspace::tr("Sh&ade"));
02027 }
02028 actions[QWorkspacePrivate::StaysOnTopAct]->setEnabled(!active->shademode && canResize);
02029 actions[QWorkspacePrivate::StaysOnTopAct]->setChecked(
02030 (active->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint));
02031 }
02032
02033 void QWorkspacePrivate::_q_operationMenuActivated(QAction *action)
02034 {
02035 if (!active)
02036 return;
02037 if(action == actions[QWorkspacePrivate::RestoreAct]) {
02038 active->showNormal();
02039 } else if(action == actions[QWorkspacePrivate::MoveAct]) {
02040 active->doMove();
02041 } else if(action == actions[QWorkspacePrivate::ResizeAct]) {
02042 if (active->shademode)
02043 active->showShaded();
02044 active->doResize();
02045 } else if(action == actions[QWorkspacePrivate::MinimizeAct]) {
02046 active->showMinimized();
02047 } else if(action == actions[QWorkspacePrivate::MaximizeAct]) {
02048 active->showMaximized();
02049 } else if(action == actions[QWorkspacePrivate::ShadeAct]) {
02050 active->showShaded();
02051 } else if(action == actions[QWorkspacePrivate::StaysOnTopAct]) {
02052 if(QWidget* w = active->windowWidget()) {
02053 if ((w->windowFlags() & Qt::WindowStaysOnTopHint)) {
02054 w->overrideWindowFlags(w->windowFlags() & ~Qt::WindowStaysOnTopHint);
02055 } else {
02056 w->overrideWindowFlags(w->windowFlags() | Qt::WindowStaysOnTopHint);
02057 w->parentWidget()->raise();
02058 }
02059 }
02060 }
02061 }
02062
02063
02064 void QWorkspacePrivate::hideChild(QWorkspaceChild *c)
02065 {
02066 Q_Q(QWorkspace);
02067
02068
02069
02070 focus.removeAll(c);
02071 QRect restore;
02072 if (maxWindow == c)
02073 restore = maxRestore;
02074 if (active == c) {
02075 q->setFocus();
02076 q->activatePreviousWindow();
02077 }
02078 if (active == c)
02079 activateWindow(0);
02080 if (maxWindow == c) {
02081 hideMaximizeControls();
02082 maxWindow = 0;
02083 }
02084 c->hide();
02085 if (!restore.isEmpty())
02086 c->setGeometry(restore);
02087
02088 }
02089
02096 void QWorkspace::activateNextWindow()
02097 {
02098 Q_D(QWorkspace);
02099
02100 if (d->focus.isEmpty())
02101 return;
02102 if (!d->active) {
02103 if (d->focus.first())
02104 d->activateWindow(d->focus.first()->windowWidget(), false);
02105 return;
02106 }
02107
02108 int a = d->focus.indexOf(d->active) + 1;
02109
02110 a = a % d->focus.count();
02111
02112 if (d->focus.at(a))
02113 d->activateWindow(d->focus.at(a)->windowWidget(), false);
02114 else
02115 d->activateWindow(0);
02116 }
02117
02124 void QWorkspace::activatePreviousWindow()
02125 {
02126 Q_D(QWorkspace);
02127
02128 if (d->focus.isEmpty())
02129 return;
02130 if (!d->active) {
02131 if (d->focus.last())
02132 d->activateWindow(d->focus.first()->windowWidget(), false);
02133 else
02134 d->activateWindow(0);
02135 return;
02136 }
02137
02138 int a = d->focus.indexOf(d->active) - 1;
02139 if (a < 0)
02140 a = d->focus.count()-1;
02141
02142 if (d->focus.at(a))
02143 d->activateWindow(d->focus.at(a)->windowWidget(), false);
02144 else
02145 d->activateWindow(0);
02146 }
02147
02148
02164 void QWorkspace::cascade()
02165 {
02166 Q_D(QWorkspace);
02167 blockSignals(true);
02168 if (d->maxWindow)
02169 d->maxWindow->showNormal();
02170
02171 if (d->vbar) {
02172 d->vbar->blockSignals(true);
02173 d->vbar->setValue(0);
02174 d->vbar->blockSignals(false);
02175 d->hbar->blockSignals(true);
02176 d->hbar->setValue(0);
02177 d->hbar->blockSignals(false);
02178 d->_q_scrollBarChanged();
02179 }
02180
02181 const int xoffset = 13;
02182 const int yoffset = 20;
02183
02184
02185 QList<QWorkspaceChild *> widgets;
02186 QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
02187 QWorkspaceChild* wc = 0;
02188
02189 for (it = d->focus.begin(); it != d->focus.end(); ++it) {
02190 wc = *it;
02191 if (wc->windowWidget()->isVisibleTo(this) && !(wc->titlebar && wc->titlebar->isTool()))
02192 widgets.append(wc);
02193 }
02194
02195 int x = 0;
02196 int y = 0;
02197
02198 it = widgets.begin();
02199 while (it != widgets.end()) {
02200 QWorkspaceChild *child = *it;
02201 ++it;
02202
02203 QSize prefSize = child->windowWidget()->sizeHint().expandedTo(qSmartMinSize(child->windowWidget()));
02204 if (!prefSize.isValid())
02205 prefSize = child->windowWidget()->size();
02206 prefSize = prefSize.expandedTo(qSmartMinSize(child->windowWidget()));
02207 if (prefSize.isValid())
02208 prefSize += QSize(child->baseSize().width(), child->baseSize().height());
02209
02210 int w = prefSize.width();
02211 int h = prefSize.height();
02212
02213 child->showNormal();
02214 if (y + h > height())
02215 y = 0;
02216 if (x + w > width())
02217 x = 0;
02218 child->setGeometry(x, y, w, h);
02219 x += xoffset;
02220 y += yoffset;
02221 child->internalRaise();
02222 }
02223 d->updateWorkspace();
02224 blockSignals(false);
02225 }
02226
02232 void QWorkspace::tile()
02233 {
02234 Q_D(QWorkspace);
02235 blockSignals(true);
02236 QWidget *oldActive = d->active ? d->active->windowWidget() : 0;
02237 if (d->maxWindow)
02238 d->maxWindow->showNormal();
02239
02240 if (d->vbar) {
02241 d->vbar->blockSignals(true);
02242 d->vbar->setValue(0);
02243 d->vbar->blockSignals(false);
02244 d->hbar->blockSignals(true);
02245 d->hbar->setValue(0);
02246 d->hbar->blockSignals(false);
02247 d->_q_scrollBarChanged();
02248 }
02249
02250 int rows = 1;
02251 int cols = 1;
02252 int n = 0;
02253 QWorkspaceChild* c;
02254
02255 QList<QWorkspaceChild *>::Iterator it(d->windows.begin());
02256 while (it != d->windows.end()) {
02257 c = *it;
02258 ++it;
02259 if (!c->windowWidget()->isHidden()
02260 && !(c->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)
02261 && !c->iconw)
02262 n++;
02263 }
02264
02265 while (rows * cols < n) {
02266 if (cols <= rows)
02267 cols++;
02268 else
02269 rows++;
02270 }
02271 int add = cols * rows - n;
02272 bool* used = new bool[cols*rows];
02273 for (int i = 0; i < rows*cols; i++)
02274 used[i] = false;
02275
02276 int row = 0;
02277 int col = 0;
02278 int w = width() / cols;
02279 int h = height() / rows;
02280
02281 it = d->windows.begin();
02282 while (it != d->windows.end()) {
02283 c = *it;
02284 ++it;
02285 if (c->iconw || c->windowWidget()->isHidden() || (c->titlebar && c->titlebar->isTool()))
02286 continue;
02287 if (!row && !col) {
02288 w -= c->baseSize().width();
02289 h -= c->baseSize().height();
02290 }
02291 if ((c->windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)) {
02292 QPoint p = c->pos();
02293 if (p.x()+c->width() < 0)
02294 p.setX(0);
02295 if (p.x() > width())
02296 p.setX(width() - c->width());
02297 if (p.y() + 10 < 0)
02298 p.setY(0);
02299 if (p.y() > height())
02300 p.setY(height() - c->height());
02301
02302 if (p != c->pos())
02303 c->QWidget::move(p);
02304 } else {
02305 c->showNormal();
02306 used[row*cols+col] = true;
02307 QSize sz(w, h);
02308 QSize bsize(c->baseSize());
02309 sz = sz.expandedTo(c->windowWidget()->minimumSize()).boundedTo(c->windowWidget()->maximumSize());
02310 sz += bsize;
02311
02312 if ( add ) {
02313 if (sz.height() == h + bsize.height())
02314 sz.rheight() *= 2;
02315 used[(row+1)*cols+col] = true;
02316 add--;
02317 }
02318
02319 c->setGeometry(col*w + col*bsize.width(), row*h + row*bsize.height(), sz.width(), sz.height());
02320
02321 while(row < rows && col < cols && used[row*cols+col]) {
02322 col++;
02323 if (col == cols) {
02324 col = 0;
02325 row++;
02326 }
02327 }
02328 }
02329 }
02330 delete [] used;
02331
02332 d->activateWindow(oldActive);
02333 d->updateWorkspace();
02334 blockSignals(false);
02335 }
02336
02342 void QWorkspace::arrangeIcons()
02343 {
02344 Q_D(QWorkspace);
02345
02346 QRect cr = d->updateWorkspace();
02347 int x = 0;
02348 int y = -1;
02349
02350 QList<QWidget *>::Iterator it(d->icons.begin());
02351 while (it != d->icons.end()) {
02352 QWidget* i = *it;
02353 if (y == -1)
02354 y = cr.height() - i->height();
02355 if (x > 0 && x + i->width() > cr.width()) {
02356 x = 0;
02357 y -= i->height();
02358 }
02359 i->move(x, y);
02360 x += i->width();
02361 ++it;
02362 }
02363 d->updateWorkspace();
02364 }
02365
02366
02367 QWorkspaceChild::QWorkspaceChild(QWidget* window, QWorkspace *parent, Qt::WindowFlags flags)
02368 : QWidget(parent,
02369 Qt::FramelessWindowHint | Qt::SubWindow)
02370 {
02371 setAttribute(Qt::WA_DeleteOnClose);
02372 setAttribute(Qt::WA_NoMousePropagation);
02373 setMouseTracking(true);
02374 act = false;
02375 iconw = 0;
02376 shademode = false;
02377 titlebar = 0;
02378 setAutoFillBackground(true);
02379
02380 setBackgroundRole(QPalette::Window);
02381 if (window) {
02382 if (flags)
02383 window->setParent(this, flags & ~Qt::WindowType_Mask);
02384 else
02385 window->setParent(this);
02386 }
02387
02388 if (window && (flags & (Qt::WindowTitleHint
02389 | Qt::WindowSystemMenuHint
02390 | Qt::WindowMinimizeButtonHint
02391 | Qt::WindowMaximizeButtonHint
02392 | Qt::WindowContextHelpButtonHint))) {
02393 titlebar = new QWorkspaceTitleBar(window, this, flags);
02394 connect(titlebar, SIGNAL(doActivate()),
02395 this, SLOT(activate()));
02396 connect(titlebar, SIGNAL(doClose()),
02397 window, SLOT(close()));
02398 connect(titlebar, SIGNAL(doMinimize()),
02399 this, SLOT(showMinimized()));
02400 connect(titlebar, SIGNAL(doNormal()),
02401 this, SLOT(showNormal()));
02402 connect(titlebar, SIGNAL(doMaximize()),
02403 this, SLOT(showMaximized()));
02404 connect(titlebar, SIGNAL(popupOperationMenu(QPoint)),
02405 this, SIGNAL(popupOperationMenu(QPoint)));
02406 connect(titlebar, SIGNAL(showOperationMenu()),
02407 this, SIGNAL(showOperationMenu()));
02408 connect(titlebar, SIGNAL(doShade()),
02409 this, SLOT(showShaded()));
02410 connect(titlebar, SIGNAL(doubleClicked()),
02411 this, SLOT(titleBarDoubleClicked()));
02412 }
02413
02414 setMinimumSize(128, 0);
02415 int fw = style()->pixelMetric(QStyle::PM_MDIFrameWidth, 0, this);
02416 setContentsMargins(fw, fw, fw, fw);
02417
02418 childWidget = window;
02419 if (!childWidget)
02420 return;
02421
02422 setWindowTitle(childWidget->windowTitle());
02423
02424 QPoint p;
02425 QSize s;
02426 QSize cs;
02427
02428 bool hasBeenResized = childWidget->testAttribute(Qt::WA_Resized);
02429
02430 if (!hasBeenResized)
02431 cs = childWidget->sizeHint().expandedTo(childWidget->minimumSizeHint()).expandedTo(childWidget->minimumSize()).boundedTo(childWidget->maximumSize());
02432 else
02433 cs = childWidget->size();
02434
02435 windowSize = cs;
02436
02437 int th = titlebar ? titlebar->sizeHint().height() : 0;
02438 if (titlebar) {
02439 if (!childWidget->windowIcon().isNull())
02440 titlebar->setWindowIcon(childWidget->windowIcon());
02441
02442 if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
02443 th -= contentsRect().y();
02444
02445 p = QPoint(contentsRect().x(),
02446 th + contentsRect().y());
02447 s = QSize(cs.width() + 2*frameWidth(),
02448 cs.height() + 2*frameWidth() + th);
02449 } else {
02450 p = QPoint(contentsRect().x(), contentsRect().y());
02451 s = QSize(cs.width() + 2*frameWidth(),
02452 cs.height() + 2*frameWidth());
02453 }
02454
02455 childWidget->move(p);
02456 resize(s);
02457
02458 childWidget->installEventFilter(this);
02459
02460 widgetResizeHandler = new QWidgetResizeHandler(this, window);
02461 widgetResizeHandler->setSizeProtection(!parent->scrollBarsEnabled());
02462 widgetResizeHandler->setFrameWidth(frameWidth());
02463 connect(widgetResizeHandler, SIGNAL(activate()),
02464 this, SLOT(activate()));
02465 if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
02466 widgetResizeHandler->setExtraHeight(th + contentsRect().y() - 2*frameWidth());
02467 else
02468 widgetResizeHandler->setExtraHeight(th + contentsRect().y() - frameWidth());
02469 if (childWidget->minimumSize() == childWidget->maximumSize())
02470 widgetResizeHandler->setActive(QWidgetResizeHandler::Resize, false);
02471 setBaseSize(baseSize());
02472 }
02473
02474 QWorkspaceChild::~QWorkspaceChild()
02475 {
02476 if (iconw)
02477 delete iconw->parentWidget();
02478
02479 QWorkspace *workspace = qobject_cast<QWorkspace*>(parentWidget());
02480 if (workspace) {
02481 workspace->d_func()->focus.removeAll(this);
02482 if (workspace->d_func()->active == this)
02483 workspace->activatePreviousWindow();
02484 if (workspace->d_func()->active == this)
02485 workspace->d_func()->activateWindow(0);
02486 if (workspace->d_func()->maxWindow == this) {
02487 workspace->d_func()->hideMaximizeControls();
02488 workspace->d_func()->maxWindow = 0;
02489 }
02490 }
02491 }
02492
02493 void QWorkspaceChild::moveEvent(QMoveEvent *)
02494 {
02495 ((QWorkspace*)parentWidget())->d_func()->updateWorkspace();
02496 }
02497
02498 void QWorkspaceChild::resizeEvent(QResizeEvent *)
02499 {
02500 bool wasMax = isMaximized();
02501 QRect r = contentsRect();
02502 QRect cr;
02503
02504 updateMask();
02505
02506 if (titlebar) {
02507 int th = titlebar->sizeHint().height();
02508 QRect tbrect(0, 0, width(), th);
02509 if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
02510 tbrect = QRect(r.x(), r.y(), r.width(), th);
02511 titlebar->setGeometry(tbrect);
02512
02513 if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
02514 th -= frameWidth();
02515 cr = QRect(r.x(), r.y() + th + (shademode ? (frameWidth() * 3) : 0),
02516 r.width(), r.height() - th);
02517 } else {
02518 cr = r;
02519 }
02520
02521 if (!childWidget)
02522 return;
02523
02524 bool doContentsResize = (windowSize == childWidget->size()
02525 || !(childWidget->testAttribute(Qt::WA_Resized) && childWidget->testAttribute(Qt::WA_PendingResizeEvent))
02526 ||childWidget->isMaximized());
02527
02528 windowSize = cr.size();
02529 childWidget->move(cr.topLeft());
02530 if (doContentsResize)
02531 childWidget->resize(cr.size());
02532 ((QWorkspace*)parentWidget())->d_func()->updateWorkspace();
02533
02534 if (wasMax) {
02535 overrideWindowState(Qt::WindowMaximized);
02536 childWidget->overrideWindowState(Qt::WindowMaximized);
02537 }
02538 }
02539
02540 QSize QWorkspaceChild::baseSize() const
02541 {
02542 int th = titlebar ? titlebar->sizeHint().height() : 0;
02543 if (style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar))
02544 th -= frameWidth();
02545 return QSize(2*frameWidth(), 2*frameWidth() + th);
02546 }
02547
02548 QSize QWorkspaceChild::sizeHint() const
02549 {
02550 if (!childWidget)
02551 return QWidget::sizeHint() + baseSize();
02552
02553 QSize prefSize = windowWidget()->sizeHint().expandedTo(windowWidget()->minimumSizeHint());
02554 prefSize = prefSize.expandedTo(windowWidget()->minimumSize()).boundedTo(windowWidget()->maximumSize());
02555 prefSize += baseSize();
02556
02557 return prefSize;
02558 }
02559
02560 QSize QWorkspaceChild::minimumSizeHint() const
02561 {
02562 if (!childWidget)
02563 return QWidget::minimumSizeHint() + baseSize();
02564 QSize s = childWidget->minimumSize();
02565 if (s.isEmpty())
02566 s = childWidget->minimumSizeHint();
02567 return s + baseSize();
02568 }
02569
02570 void QWorkspaceChild::activate()
02571 {
02572 ((QWorkspace*)parentWidget())->d_func()->activateWindow(windowWidget());
02573 }
02574
02575 bool QWorkspaceChild::eventFilter(QObject * o, QEvent * e)
02576 {
02577 if (!isActive()
02578 && (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::FocusIn)) {
02579 if (iconw) {
02580 ((QWorkspace*)parentWidget())->d_func()->normalizeWindow(windowWidget());
02581 if (iconw) {
02582 ((QWorkspace*)parentWidget())->d_func()->removeIcon(iconw->parentWidget());
02583 delete iconw->parentWidget();
02584 iconw = 0;
02585 }
02586 }
02587 activate();
02588 }
02589
02590
02591
02592 if (o != childWidget || childWidget == 0)
02593 return false;
02594
02595 switch (e->type()) {
02596 case QEvent::ShowToParent:
02597 if (((QWorkspace*)parentWidget())->d_func()->focus.indexOf(this) < 0)
02598 ((QWorkspace*)parentWidget())->d_func()->focus.append(this);
02599
02600 if (windowWidget() && (windowWidget()->windowFlags() & Qt::WindowStaysOnTopHint)) {
02601 internalRaise();
02602 show();
02603 }
02604 ((QWorkspace*)parentWidget())->d_func()->showWindow(windowWidget());
02605 break;
02606 case QEvent::WindowStateChange: {
02607 if (static_cast<QWindowStateChangeEvent*>(e)->isOverride())
02608 break;
02609 Qt::WindowStates state = windowWidget()->windowState();
02610
02611 if (state & Qt::WindowMinimized) {
02612 ((QWorkspace*)parentWidget())->d_func()->minimizeWindow(windowWidget());
02613 } else if (state & Qt::WindowMaximized) {
02614 if (windowWidget()->maximumSize().isValid() &&
02615 (windowWidget()->maximumWidth() < parentWidget()->width() ||
02616 windowWidget()->maximumHeight() < parentWidget()->height())) {
02617 windowWidget()->resize(windowWidget()->maximumSize());
02618 windowWidget()->overrideWindowState(Qt::WindowNoState);
02619 if (titlebar)
02620 titlebar->update();
02621 break;
02622 }
02623 if ((windowWidget()->windowFlags() & Qt::WindowMaximizeButtonHint))
02624 ((QWorkspace*)parentWidget())->d_func()->maximizeWindow(windowWidget());
02625 else
02626 ((QWorkspace*)parentWidget())->d_func()->normalizeWindow(windowWidget());
02627 } else {
02628 ((QWorkspace*)parentWidget())->d_func()->normalizeWindow(windowWidget());
02629 if (iconw) {
02630 ((QWorkspace*)parentWidget())->d_func()->removeIcon(iconw->parentWidget());
02631 delete iconw->parentWidget();
02632 }
02633 }
02634 } break;
02635 case QEvent::HideToParent:
02636 {
02637 QWidget * w = iconw;
02638 if (w && (w = w->parentWidget())) {
02639 ((QWorkspace*)parentWidget())->d_func()->removeIcon(w);
02640 delete w;
02641 }
02642 ((QWorkspace*)parentWidget())->d_func()->hideChild(this);
02643 } break;
02644 case QEvent::WindowIconChange:
02645 {
02646 QWorkspace* ws = (QWorkspace*)parentWidget();
02647 if (ws->d_func()->maxtools && ws->d_func()->maxWindow == this) {
02648 int iconSize = ws->d_func()->maxtools->size().height();
02649 ws->d_func()->maxtools->setPixmap(childWidget->windowIcon().pixmap(QSize(iconSize, iconSize)));
02650 }
02651 }
02652
02653 case QEvent::WindowTitleChange:
02654 setWindowTitle(windowWidget()->windowTitle());
02655 if (titlebar)
02656 titlebar->update();
02657 if (iconw)
02658 iconw->update();
02659 break;
02660 case QEvent::ModifiedChange:
02661 setWindowModified(windowWidget()->isWindowModified());
02662 if (titlebar)
02663 titlebar->update();
02664 if (iconw)
02665 iconw->update();
02666 break;
02667 case QEvent::Resize:
02668 {
02669 QResizeEvent* re = (QResizeEvent*)e;
02670 if (re->size() != windowSize && !shademode) {
02671 resize(re->size() + baseSize());
02672 childWidget->update();
02673 }
02674 }
02675 break;
02676
02677 case QEvent::WindowDeactivate:
02678 if (titlebar && titlebar->isActive()) {
02679 update();
02680 }
02681 break;
02682
02683 case QEvent::WindowActivate:
02684 if (titlebar && titlebar->isActive()) {
02685 update();
02686 }
02687 break;
02688
02689 default:
02690 break;
02691 }
02692
02693 return QWidget::eventFilter(o, e);
02694 }
02695
02696 void QWorkspaceChild::childEvent(QChildEvent* e)
02697 {
02698 if (e->type() == QEvent::ChildRemoved && e->child() == childWidget) {
02699 childWidget = 0;
02700 if (iconw) {
02701 ((QWorkspace*)parentWidget())->d_func()->removeIcon(iconw->parentWidget());
02702 delete iconw->parentWidget();
02703 }
02704 close();
02705 }
02706 }
02707
02708
02709 void QWorkspaceChild::doResize()
02710 {
02711 widgetResizeHandler->doResize();
02712 }
02713
02714 void QWorkspaceChild::doMove()
02715 {
02716 widgetResizeHandler->doMove();
02717 }
02718
02719 void QWorkspaceChild::enterEvent(QEvent *)
02720 {
02721 }
02722
02723 void QWorkspaceChild::leaveEvent(QEvent *)
02724 {
02725 #ifndef QT_NO_CURSOR
02726 if (!widgetResizeHandler->isButtonDown())
02727 setCursor(Qt::ArrowCursor);
02728 #endif
02729 }
02730
02731 void QWorkspaceChild::paintEvent(QPaintEvent *)
02732 {
02733 QPainter p(this);
02734 QStyleOptionFrame opt;
02735 opt.rect = rect();
02736 opt.palette = palette();
02737 opt.state = QStyle::State_None;
02738 opt.lineWidth = style()->pixelMetric(QStyle::PM_MDIFrameWidth, 0, this);
02739 opt.midLineWidth = 1;
02740
02741 if (titlebar && titlebar->isActive() && isActiveWindow())
02742 opt.state |= QStyle::State_Active;
02743
02744 style()->drawPrimitive(QStyle::PE_FrameWindow, &opt, &p, this);
02745 }
02746
02747 void QWorkspaceChild::changeEvent(QEvent *ev)
02748 {
02749 if(ev->type() == QEvent::StyleChange) {
02750 resizeEvent(0);
02751 if (iconw) {
02752 QFrame *frame = qobject_cast<QFrame*>(iconw->parentWidget());
02753 Q_ASSERT(frame);
02754 if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar)) {
02755 frame->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
02756 frame->resize(196+2*frame->frameWidth(), 20 + 2*frame->frameWidth());
02757 } else {
02758 frame->resize(196, 20);
02759 }
02760 }
02761 updateMask();
02762 }
02763 QWidget::changeEvent(ev);
02764 }
02765
02766 void QWorkspaceChild::setActive(bool b)
02767 {
02768 if (!childWidget)
02769 return;
02770
02771 bool hasFocus = isChildOf(window()->focusWidget(), this);
02772 if (act == b && (act == hasFocus))
02773 return;
02774
02775 act = b;
02776
02777 if (titlebar)
02778 titlebar->setActive(act);
02779 if (iconw)
02780 iconw->setActive(act);
02781 update();
02782
02783 QList<QWidget*> wl = qFindChildren<QWidget*>(childWidget);
02784 if (act) {
02785 for (int i = 0; i < wl.size(); ++i) {
02786 QWidget *w = wl.at(i);
02787 w->removeEventFilter(this);
02788 }
02789 if (!hasFocus) {
02790 QWidget *lastfocusw = childWidget->focusWidget();
02791 if (lastfocusw && lastfocusw->focusPolicy() != Qt::NoFocus) {
02792 lastfocusw->setFocus();
02793 } else if (childWidget->focusPolicy() != Qt::NoFocus) {
02794 childWidget->setFocus();
02795 } else {
02796
02797 for (int i = 0; i < wl.size(); ++i) {
02798 QWidget *w = wl.at(i);
02799 if(w->focusPolicy() != Qt::NoFocus) {
02800 w->setFocus();
02801 hasFocus = true;
02802 break;
02803 }
02804 }
02805 if (!hasFocus)
02806 setFocus();
02807 }
02808 }
02809 } else {
02810 for (int i = 0; i < wl.size(); ++i) {
02811 QWidget *w = wl.at(i);
02812 w->removeEventFilter(this);
02813 w->installEventFilter(this);
02814 }
02815 }
02816 }
02817
02818 bool QWorkspaceChild::isActive() const
02819 {
02820 return act;
02821 }
02822
02823 QWidget* QWorkspaceChild::windowWidget() const
02824 {
02825 return childWidget;
02826 }
02827
02828 bool QWorkspaceChild::isWindowOrIconVisible() const
02829 {
02830 return childWidget && (!isHidden() || (iconw && !iconw->isHidden()));
02831 }
02832
02833 void QWorkspaceChild::updateMask()
02834 {
02835 QStyleOptionTitleBar titleBarOptions;
02836 titleBarOptions.rect = rect();
02837 titleBarOptions.titleBarFlags = windowFlags();
02838 titleBarOptions.titleBarState = windowState();
02839
02840 QStyleHintReturnMask frameMask;
02841 if (style()->styleHint(QStyle::SH_WindowFrame_Mask, &titleBarOptions, this, &frameMask)) {
02842 setMask(frameMask.region);
02843 } else if (!mask().isEmpty()) {
02844 clearMask();
02845 }
02846
02847 if (iconw) {
02848 QFrame *frame = qobject_cast<QFrame *>(iconw->parentWidget());
02849 Q_ASSERT(frame);
02850
02851 titleBarOptions.rect = frame->rect();
02852 titleBarOptions.titleBarFlags = frame->windowFlags();
02853 titleBarOptions.titleBarState = frame->windowState() | Qt::WindowMinimized;
02854 if (style()->styleHint(QStyle::SH_WindowFrame_Mask, &titleBarOptions, frame, &frameMask)) {
02855 frame->setMask(frameMask.region);
02856 } else if (!frame->mask().isEmpty()) {
02857 frame->clearMask();
02858 }
02859 }
02860 }
02861
02862 QWidget* QWorkspaceChild::iconWidget() const
02863 {
02864 if (!iconw) {
02865 QWorkspaceChild* that = (QWorkspaceChild*) this;
02866
02867 QFrame* frame = new QFrame(that, Qt::Window);
02868 QVBoxLayout *vbox = new QVBoxLayout(frame);
02869 vbox->setMargin(0);
02870 QWorkspaceTitleBar *tb = new QWorkspaceTitleBar(windowWidget(), frame);
02871 vbox->addWidget(tb);
02872 tb->setObjectName(QLatin1String("_workspacechild_icon_"));
02873 QStyleOptionTitleBar opt = tb->getStyleOption();
02874 int th = style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt, tb);
02875 int iconSize = style()->pixelMetric(QStyle::PM_MDIMinimizedWidth, 0, this);
02876 if (!style()->styleHint(QStyle::SH_TitleBar_NoBorder, 0, titlebar)) {
02877 frame->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
02878 frame->resize(iconSize+2*frame->frameWidth(), th+2*frame->frameWidth());
02879 } else {
02880 frame->resize(iconSize, th);
02881 }
02882
02883 that->iconw = tb;
02884 that->updateMask();
02885 iconw->setActive(isActive());
02886
02887 connect(iconw, SIGNAL(doActivate()),
02888 this, SLOT(activate()));
02889 connect(iconw, SIGNAL(doClose()),
02890 windowWidget(), SLOT(close()));
02891 connect(iconw, SIGNAL(doNormal()),
02892 this, SLOT(showNormal()));
02893 connect(iconw, SIGNAL(doMaximize()),
02894 this, SLOT(showMaximized()));
02895 connect(