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 "q3mainwindow.h"
00025 #ifndef QT_NO_MAINWINDOW
00026
00027 #include "qapplication.h"
00028 #include "qbitmap.h"
00029 #include "qcursor.h"
00030 #include "qdatetime.h"
00031 #include "q3dockarea.h"
00032 #include "qevent.h"
00033 #include "qlayout.h"
00034 #include "qmap.h"
00035 #include "qmenubar.h"
00036 #include "qpainter.h"
00037 #include "q3popupmenu.h"
00038 #include "q3scrollview.h"
00039 #include "qstatusbar.h"
00040 #include "qstringlist.h"
00041 #include "qstyle.h"
00042 #include "qstyleoption.h"
00043 #include "qtimer.h"
00044 #include "q3toolbar.h"
00045 #include "qtooltip.h"
00046 #include "qwhatsthis.h"
00047 #ifdef Q_WS_MAC
00048 # include <private/qt_mac_p.h>
00049 #endif
00050
00051 class QHideDock;
00052
00053 #include <private/q3mainwindow_p.h>
00054
00055
00056
00057
00058
00059 class Q3MainWindowLayout : public QLayout
00060 {
00061 Q_OBJECT
00062
00063 public:
00064 Q3MainWindowLayout(Q3MainWindow *mw, QLayout* parent = 0);
00065 ~Q3MainWindowLayout() {}
00066
00067 void addItem(QLayoutItem *);
00068 void setLeftDock(Q3DockArea *l);
00069 void setRightDock(Q3DockArea *r);
00070 void setCentralWidget(QWidget *w);
00071 bool hasHeightForWidth() const { return false; }
00072 QSize sizeHint() const;
00073 QSize minimumSize() const;
00074 QLayoutItem *itemAt(int) const { return 0; }
00075 QLayoutItem *takeAt(int) { return 0; }
00076 int count() const { return 0; }
00077
00078 protected:
00079 void setGeometry(const QRect &r) {
00080 QLayout::setGeometry(r);
00081 layoutItems(r);
00082 }
00083
00084 private:
00085 int layoutItems(const QRect&, bool testonly = false);
00086 int extraPixels() const;
00087
00088 Q3DockArea *left, *right;
00089 QWidget *central;
00090 Q3MainWindow *mainWindow;
00091
00092 };
00093
00094 QSize Q3MainWindowLayout::sizeHint() const
00095 {
00096 int w = 0;
00097 int h = 0;
00098
00099 if (left) {
00100 w += left->sizeHint().width();
00101 h = qMax(h, left->sizeHint().height());
00102 }
00103 if (right) {
00104 w += right->sizeHint().width();
00105 h = qMax(h, right->sizeHint().height());
00106 }
00107 if (central) {
00108 w += central->sizeHint().width();
00109 int diff = extraPixels();
00110 h = qMax(h, central->sizeHint().height() + diff);
00111 }
00112 return QSize(w, h);
00113 }
00114
00115 QSize Q3MainWindowLayout::minimumSize() const
00116 {
00117 int w = 0;
00118 int h = 0;
00119
00120 if (left) {
00121 QSize ms = left->minimumSizeHint().expandedTo(left->minimumSize());
00122 w += ms.width();
00123 h = qMax(h, ms.height());
00124 }
00125 if (right) {
00126 QSize ms = right->minimumSizeHint().expandedTo(right->minimumSize());
00127 w += ms.width();
00128 h = qMax(h, ms.height());
00129 }
00130 if (central) {
00131 QSize min = central->minimumSize().isNull() ?
00132 central->minimumSizeHint() : central->minimumSize();
00133 w += min.width();
00134 int diff = extraPixels();
00135 h = qMax(h, min.height() + diff);
00136 }
00137 return QSize(w, h);
00138 }
00139
00140 Q3MainWindowLayout::Q3MainWindowLayout(Q3MainWindow *mw, QLayout* parent)
00141 : QLayout(parent), left(0), right(0), central(0)
00142 {
00143 mainWindow = mw;
00144 }
00145
00146 void Q3MainWindowLayout::setLeftDock(Q3DockArea *l)
00147 {
00148 left = l;
00149 }
00150
00151 void Q3MainWindowLayout::setRightDock(Q3DockArea *r)
00152 {
00153 right = r;
00154 }
00155
00156 void Q3MainWindowLayout::setCentralWidget(QWidget *w)
00157 {
00158 central = w;
00159 }
00160
00161 int Q3MainWindowLayout::layoutItems(const QRect &r, bool testonly)
00162 {
00163 if (!left && !central && !right)
00164 return 0;
00165
00166 int wl = 0, wr = 0;
00167 if (left)
00168 wl = ((Q3DockAreaLayout*)left->QWidget::layout())->widthForHeight(r.height());
00169 if (right)
00170 wr = ((Q3DockAreaLayout*)right->QWidget::layout())->widthForHeight(r.height());
00171 int w = r.width() - wr - wl;
00172 if (w < 0)
00173 w = 0;
00174
00175 int diff = extraPixels();
00176 if (!testonly) {
00177 QRect g(geometry());
00178 if (left)
00179 left->setGeometry(QRect(g.x(), g.y() + diff, wl, r.height() - diff));
00180 if (right)
00181 right->setGeometry(QRect(g.x() + g.width() - wr, g.y() + diff, wr, r.height() - diff));
00182 if (central)
00183 central->setGeometry(g.x() + wl, g.y() + diff, w, r.height() - diff);
00184 }
00185
00186 w = wl + wr;
00187 if (central)
00188 w += central->minimumSize().width();
00189 return w;
00190 }
00191
00192 int Q3MainWindowLayout::extraPixels() const
00193 {
00194 if (mainWindow->d_func()->topDock->isEmpty() &&
00195 !(mainWindow->d_func()->leftDock->isEmpty() &&
00196 mainWindow->d_func()->rightDock->isEmpty())) {
00197 return 2;
00198 } else {
00199 return 0;
00200 }
00201 }
00202
00203 void Q3MainWindowLayout::addItem(QLayoutItem * )
00204 {
00205 }
00206
00207
00208
00209
00210
00211 #if 0
00212 class QHideToolTip : public QToolTip
00213 {
00214 public:
00215 QHideToolTip(QWidget *parent) : QToolTip(parent) {}
00216
00217 void maybeTip(const QPoint &pos);
00218 };
00219 #endif
00220
00221
00222 class QHideDock : public QWidget
00223 {
00224 Q_OBJECT
00225
00226 public:
00227 QHideDock(Q3MainWindow *parent) : QWidget(parent, "qt_hide_dock") {
00228 hide();
00229 setFixedHeight(style()->pixelMetric(QStyle::PM_DockWidgetHandleExtent, 0, this) + 3);
00230 pressedHandle = -1;
00231 pressed = false;
00232 setMouseTracking(true);
00233 win = parent;
00234 #if 0
00235 tip = new QHideToolTip(this);
00236 #endif
00237 }
00238 ~QHideDock()
00239 {
00240 #if 0
00241 delete tip;
00242 #endif
00243 }
00244
00245 protected:
00246 void paintEvent(QPaintEvent *e) {
00247 QObjectList childList = children();
00248 if (childList.isEmpty())
00249 return;
00250 QPainter p(this);
00251 p.setClipRegion(e->rect());
00252 p.fillRect(e->rect(), palette().brush(QPalette::Window));
00253 int x = 0;
00254 for (int i = 0; i < childList.size(); ++i) {
00255 QObject *o = childList.at(i);
00256 Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
00257 if (!dw || !dw->isVisible())
00258 continue;
00259 QStyleOptionQ3DockWindow opt;
00260 opt.rect.setRect(x, 0, 30, 10);
00261 opt.palette = palette();
00262 opt.docked = dw->area();
00263 opt.closeEnabled = dw->isCloseEnabled();
00264 opt.state = QStyle::State_None;
00265 if (i == pressedHandle)
00266 opt.state |= QStyle::State_On;
00267
00268 style()->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &opt, &p, this);
00269 x += 30;
00270 }
00271 }
00272
00273 void mousePressEvent(QMouseEvent *e) {
00274 pressed = true;
00275 QObjectList childList = children();
00276 if (childList.isEmpty())
00277 return;
00278 mouseMoveEvent(e);
00279 pressedHandle = -1;
00280
00281 if (e->button() == Qt::RightButton && win->isDockMenuEnabled()) {
00282
00283 } else {
00284 mouseMoveEvent(e);
00285 }
00286 }
00287
00288 void mouseMoveEvent(QMouseEvent *e) {
00289 QObjectList childList = children();
00290 if (childList.isEmpty())
00291 return;
00292 if (!pressed)
00293 return;
00294 int x = 0;
00295 if (e->y() >= 0 && e->y() <= height()) {
00296 for (int i = 0; i < childList.size(); ++i) {
00297 QObject *o = childList.at(i);
00298 Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
00299 if (!dw || !dw->isVisible())
00300 continue;
00301 if (e->x() >= x && e->x() <= x + 30) {
00302 int old = pressedHandle;
00303 pressedHandle = i;
00304 if (pressedHandle != old)
00305 repaint();
00306 return;
00307 }
00308 x += 30;
00309 }
00310 }
00311 int old = pressedHandle;
00312 pressedHandle = -1;
00313 if (old != -1)
00314 repaint();
00315 }
00316
00317 void mouseReleaseEvent(QMouseEvent *e) {
00318 pressed = false;
00319 if (pressedHandle == -1)
00320 return;
00321 QObjectList childList = children();
00322 if (childList.isEmpty())
00323 return;
00324 if (e->button() == Qt::LeftButton) {
00325 if (e->y() >= 0 && e->y() <= height()) {
00326 QObject *o = childList.at(pressedHandle);
00327 Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
00328 if (dw) {
00329 dw->show();
00330 dw->dock();
00331 }
00332 }
00333 }
00334 pressedHandle = -1;
00335 repaint();
00336 }
00337
00338 bool eventFilter(QObject *o, QEvent *e) {
00339 if (o == this || !o->isWidgetType())
00340 return QWidget::eventFilter(o, e);
00341 if (e->type() == QEvent::HideToParent ||
00342 e->type() == QEvent::ShowToParent)
00343 updateState();
00344 return QWidget::eventFilter(o, e);
00345 }
00346
00347 void updateState() {
00348 bool visible = true;
00349 QObjectList childList = children();
00350 if (childList.isEmpty())
00351 return;
00352 for (int i = 0; i < childList.size(); ++i) {
00353 QObject *o = childList.at(i);
00354 Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
00355 if (!dw)
00356 continue;
00357 if (dw->isHidden()) {
00358 visible = false;
00359 continue;
00360 }
00361 if (!dw->isVisible())
00362 continue;
00363 visible = true;
00364 break;
00365 }
00366
00367 if (visible)
00368 show();
00369 else
00370 hide();
00371 win->triggerLayout(false);
00372 update();
00373 }
00374
00375 void childEvent(QChildEvent *e) {
00376 QWidget::childEvent(e);
00377 if (e->type() == QEvent::ChildInserted)
00378 e->child()->installEventFilter(this);
00379 else
00380 e->child()->removeEventFilter(this);
00381 updateState();
00382 }
00383
00384 private:
00385 Q3MainWindow *win;
00386 int pressedHandle;
00387 bool pressed;
00388 #if 0
00389 QHideToolTip *tip;
00390 friend class QHideToolTip;
00391 #endif
00392 };
00393
00394 #if 0
00395 void QHideToolTip::maybeTip(const QPoint &pos)
00396 {
00397 if (!parentWidget())
00398 return;
00399 QHideDock *dock = (QHideDock*)parentWidget();
00400
00401 QObjectList dchilds = dock->children();
00402 if (dchilds.isEmpty())
00403 return;
00404 int x = 0;
00405 for (int i = 0; i < dchilds.size(); ++i) {
00406 QObject *o = dchilds.at(i);
00407 Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
00408 if (!dw || !dw->isVisible())
00409 continue;
00410 if (pos.x() >= x && pos.x() <= x + 30) {
00411 Q3DockWindow *dw = (Q3DockWindow*)o;
00412 if (!dw->windowTitle().isEmpty())
00413 tip(QRect(x, 0, 30, dock->height()), dw->windowTitle());
00414 return;
00415 }
00416 x += 30;
00417 }
00418 }
00419 #endif
00420
00699 Q3MainWindow::Q3MainWindow(QWidget * parent, const char * name, Qt::WindowFlags f)
00700 : QWidget(*new Q3MainWindowPrivate, parent, f)
00701 {
00702 Q_D(Q3MainWindow);
00703 setObjectName(name);
00704 #ifdef Q_WS_MAC
00705 d->opaque = true;
00706 #else
00707 d->opaque = false;
00708 #endif
00709 installEventFilter(this);
00710 d->topDock = new Q3DockArea(Qt::Horizontal, Q3DockArea::Normal, this, "qt_top_dock");
00711 d->topDock->installEventFilter(this);
00712 d->bottomDock = new Q3DockArea(Qt::Horizontal, Q3DockArea::Reverse, this, "qt_bottom_dock");
00713 d->bottomDock->installEventFilter(this);
00714 d->leftDock = new Q3DockArea(Qt::Vertical, Q3DockArea::Normal, this, "qt_left_dock");
00715 d->leftDock->installEventFilter(this);
00716 d->rightDock = new Q3DockArea(Qt::Vertical, Q3DockArea::Reverse, this, "qt_right_dock");
00717 d->rightDock->installEventFilter(this);
00718 d->hideDock = new QHideDock(this);
00719 }
00720
00721
00726 Q3MainWindow::~Q3MainWindow()
00727 {
00728 delete layout();
00729 }
00730
00731 #ifndef QT_NO_MENUBAR
00732
00740 void Q3MainWindow::setMenuBar(QMenuBar * newMenuBar)
00741 {
00742 Q_D(Q3MainWindow);
00743 if (!newMenuBar)
00744 return;
00745 if (d->mb)
00746 delete d->mb;
00747 d->mb = newMenuBar;
00748 d->mb->installEventFilter(this);
00749 triggerLayout();
00750 }
00751
00752
00761 QMenuBar * Q3MainWindow::menuBar() const
00762 {
00763 Q_D(const Q3MainWindow);
00764 if (d->mb)
00765 return d->mb;
00766
00767 QObjectList l = queryList("QMenuBar", 0, false, false);
00768 QMenuBar * b;
00769 if (l.size()) {
00770 b = static_cast<QMenuBar *>(l.at(0));
00771 } else {
00772 b = new QMenuBar((Q3MainWindow *)this);
00773 b->setObjectName("automatic menu bar");
00774 b->show();
00775 }
00776 d->mb = b;
00777 d->mb->installEventFilter(const_cast<Q3MainWindow *>(this));
00778 ((Q3MainWindow *)this)->triggerLayout();
00779 return b;
00780 }
00781 #endif // QT_NO_MENUBAR
00782
00797 void Q3MainWindow::setStatusBar(QStatusBar * newStatusBar)
00798 {
00799 Q_D(Q3MainWindow);
00800 if (!newStatusBar || newStatusBar == d->sb)
00801 return;
00802 if (d->sb)
00803 delete d->sb;
00804 d->sb = newStatusBar;
00805 #if 0
00806
00807 connect(toolTipGroup(), SIGNAL(showTip(QString)),
00808 d->sb, SLOT(showMessage(QString)));
00809 connect(toolTipGroup(), SIGNAL(removeTip()),
00810 d->sb, SLOT(clearMessage()));
00811 #endif
00812 d->sb->installEventFilter(this);
00813 triggerLayout();
00814 }
00815
00816
00825 QStatusBar * Q3MainWindow::statusBar() const
00826 {
00827 Q_D(const Q3MainWindow);
00828 if (d->sb)
00829 return d->sb;
00830
00831 QObjectList l = queryList("QStatusBar", 0, false, false);
00832 QStatusBar * s;
00833 if (l.size()) {
00834 s = (QStatusBar *)l.at(0);
00835 } else {
00836 s = new QStatusBar((Q3MainWindow *)this, "automatic status bar");
00837 s->show();
00838 }
00839 ((Q3MainWindow *)this)->setStatusBar(s);
00840 ((Q3MainWindow *)this)->triggerLayout(true);
00841 return s;
00842 }
00843
00844
00845 #if 0
00846
00857 void Q3MainWindow::setToolTipGroup(QToolTipGroup * newToolTipGroup)
00858 {
00859 Q_D(Q3MainWindow);
00860 if (!newToolTipGroup || newToolTipGroup == d->ttg)
00861 return;
00862 if (d->ttg)
00863 delete d->ttg;
00864 d->ttg = newToolTipGroup;
00865
00866 connect(toolTipGroup(), SIGNAL(showTip(QString)),
00867 statusBar(), SLOT(showMessage(QString)));
00868 connect(toolTipGroup(), SIGNAL(removeTip()),
00869 statusBar(), SLOT(clearMessage()));
00870 }
00871
00872
00879 QToolTipGroup * Q3MainWindow::toolTipGroup() const
00880 {
00881 Q_D(const Q3MainWindow);
00882 if (d->ttg)
00883 return d->ttg;
00884
00885 QToolTipGroup * t = new QToolTipGroup((Q3MainWindow*)this,
00886 "automatic tool tip group");
00887 ((Q3MainWindowPrivate*)d)->ttg = t;
00888 return t;
00889 }
00890 #endif
00891
00892
00901 void Q3MainWindow::setDockEnabled(Qt::Dock dock, bool enable)
00902 {
00903 d_func()->docks.insert(dock, enable);
00904 }
00905
00906
00914 bool Q3MainWindow::isDockEnabled(Qt::Dock dock) const
00915 {
00916 return d_func()->docks[dock];
00917 }
00918
00928 bool Q3MainWindow::isDockEnabled(Q3DockArea *area) const
00929 {
00930 Q_D(const Q3MainWindow);
00931 if (area == d->leftDock)
00932 return d->docks[Qt::DockLeft];
00933 if (area == d->rightDock)
00934 return d->docks[Qt::DockRight];
00935 if (area == d->topDock)
00936 return d->docks[Qt::DockTop];
00937 if (area == d->bottomDock)
00938 return d->docks[Qt::DockBottom];
00939 return false;
00940 }
00941
00956 void Q3MainWindow::setDockEnabled(Q3DockWindow *dw, Qt::Dock dock, bool enable)
00957 {
00958 Q_D(Q3MainWindow);
00959 if (d->dockWindows.contains(dw)) {
00960 d->dockWindows.append(dw);
00961 connect(dw, SIGNAL(placeChanged(Q3DockWindow::Place)),
00962 this, SLOT(slotPlaceChanged()));
00963 }
00964 QString s;
00965 s.sprintf("%p_%d", (void*)dw, (int)dock);
00966 if (enable)
00967 d->disabledDocks.removeAll(s);
00968 else if (!d->disabledDocks.contains(s))
00969 d->disabledDocks << s;
00970 switch (dock) {
00971 case Qt::DockTop:
00972 topDock()->setAcceptDockWindow(dw, enable);
00973 break;
00974 case Qt::DockLeft:
00975 leftDock()->setAcceptDockWindow(dw, enable);
00976 break;
00977 case Qt::DockRight:
00978 rightDock()->setAcceptDockWindow(dw, enable);
00979 break;
00980 case Qt::DockBottom:
00981 bottomDock()->setAcceptDockWindow(dw, enable);
00982 break;
00983 default:
00984 break;
00985 }
00986 }
00987
00997 bool Q3MainWindow::isDockEnabled(Q3DockWindow *dw, Q3DockArea *area) const
00998 {
00999 Q_D(const Q3MainWindow);
01000 if (!isDockEnabled(area))
01001 return false;
01002 Qt::Dock dock;
01003 if (area == d->leftDock)
01004 dock = Qt::DockLeft;
01005 else if (area == d->rightDock)
01006 dock = Qt::DockRight;
01007 else if (area == d->topDock)
01008 dock = Qt::DockTop;
01009 else if (area == d->bottomDock)
01010 dock = Qt::DockBottom;
01011 else
01012 return false;
01013 return isDockEnabled(dw, dock);
01014 }
01015
01025 bool Q3MainWindow::isDockEnabled(Q3DockWindow *tb, Qt::Dock dock) const
01026 {
01027 if (!isDockEnabled(dock))
01028 return false;
01029 QString s;
01030 s.sprintf("%p_%d", (void*)tb, (int)dock);
01031 return !d_func()->disabledDocks.contains(s);
01032 }
01033
01034
01035
01050 void Q3MainWindow::addDockWindow(Q3DockWindow *dockWindow,
01051 Qt::Dock edge, bool newLine)
01052 {
01053 Q_D(Q3MainWindow);
01054 #ifdef Q_WS_MAC
01055 extern WindowPtr qt_mac_window_for(const QWidget*);
01056 if(isWindow() && edge == Qt::DockTop) {
01057 d->createWinId();
01058 ChangeWindowAttributes(qt_mac_window_for(this), kWindowToolbarButtonAttribute, 0);
01059 }
01060 #endif
01061 moveDockWindow(dockWindow, edge);
01062 dockWindow->setNewLine(newLine);
01063 if (!d->dockWindows.contains(dockWindow)) {
01064 d->dockWindows.append(dockWindow);
01065 connect(dockWindow, SIGNAL(placeChanged(Q3DockWindow::Place)),
01066 this, SLOT(slotPlaceChanged()));
01067 dockWindow->installEventFilter(this);
01068 }
01069 dockWindow->setOpaqueMoving(d->opaque);
01070 }
01071
01072
01089 void Q3MainWindow::addDockWindow(Q3DockWindow * dockWindow, const QString &label,
01090 Qt::Dock edge, bool newLine)
01091 {
01092 addDockWindow(dockWindow, edge, newLine);
01093 #ifndef QT_NO_TOOLBAR
01094 Q3ToolBar *tb = qobject_cast<Q3ToolBar*>(dockWindow);
01095 if (tb)
01096 tb->setLabel(label);
01097 #endif
01098 }
01099
01110 void Q3MainWindow::moveDockWindow(Q3DockWindow * dockWindow, Qt::Dock edge)
01111 {
01112 Q_D(Q3MainWindow);
01113 Qt::Orientation oo = dockWindow->orientation();
01114 switch (edge) {
01115 case Qt::DockTop:
01116 if (dockWindow->area() != d->topDock)
01117 dockWindow->removeFromDock(false);
01118 d->topDock->moveDockWindow(dockWindow);
01119 emit dockWindowPositionChanged(dockWindow);
01120 break;
01121 case Qt::DockBottom:
01122 if (dockWindow->area() != d->bottomDock)
01123 dockWindow->removeFromDock(false);
01124 d->bottomDock->moveDockWindow(dockWindow);
01125 emit dockWindowPositionChanged(dockWindow);
01126 break;
01127 case Qt::DockRight:
01128 if (dockWindow->area() != d->rightDock)
01129 dockWindow->removeFromDock(false);
01130 d->rightDock->moveDockWindow(dockWindow);
01131 emit dockWindowPositionChanged(dockWindow);
01132 break;
01133 case Qt::DockLeft:
01134 if (dockWindow->area() != d->leftDock)
01135 dockWindow->removeFromDock(false);
01136 d->leftDock->moveDockWindow(dockWindow);
01137 emit dockWindowPositionChanged(dockWindow);
01138 break;
01139 case Qt::DockTornOff:
01140 dockWindow->undock();
01141 break;
01142 case Qt::DockMinimized:
01143 dockWindow->undock(d->hideDock);
01144 break;
01145 case Qt::DockUnmanaged:
01146 break;
01147 }
01148
01149 if (oo != dockWindow->orientation())
01150 dockWindow->setOrientation(dockWindow->orientation());
01151 }
01152
01177 void Q3MainWindow::moveDockWindow(Q3DockWindow * dockWindow, Qt::Dock edge, bool nl, int index, int extraOffset)
01178 {
01179 Q_D(Q3MainWindow);
01180 Qt::Orientation oo = dockWindow->orientation();
01181
01182 dockWindow->setNewLine(nl);
01183 dockWindow->setOffset(extraOffset);
01184 switch (edge) {
01185 case Qt::DockTop:
01186 if (dockWindow->area() != d->topDock)
01187 dockWindow->removeFromDock(false);
01188 d->topDock->moveDockWindow(dockWindow, index);
01189 break;
01190 case Qt::DockBottom:
01191 if (dockWindow->area() != d->bottomDock)
01192 dockWindow->removeFromDock(false);
01193 d->bottomDock->moveDockWindow(dockWindow, index);
01194 break;
01195 case Qt::DockRight:
01196 if (dockWindow->area() != d->rightDock)
01197 dockWindow->removeFromDock(false);
01198 d->rightDock->moveDockWindow(dockWindow, index);
01199 break;
01200 case Qt::DockLeft:
01201 if (dockWindow->area() != d->leftDock)
01202 dockWindow->removeFromDock(false);
01203 d->leftDock->moveDockWindow(dockWindow, index);
01204 break;
01205 case Qt::DockTornOff:
01206 dockWindow->undock();
01207 break;
01208 case Qt::DockMinimized:
01209 dockWindow->undock(d->hideDock);
01210 break;
01211 case Qt::DockUnmanaged:
01212 break;
01213 }
01214
01215 if (oo != dockWindow->orientation())
01216 dockWindow->setOrientation(dockWindow->orientation());
01217 }
01218
01225 void Q3MainWindow::removeDockWindow(Q3DockWindow * dockWindow)
01226 {
01227 Q_D(Q3MainWindow);
01228
01229 #ifdef Q_WS_MAC
01230 extern WindowPtr qt_mac_window_for(const QWidget*);
01231 if(isWindow() && dockWindow->area() == topDock() && !dockWindows(Qt::DockTop).count())
01232 ChangeWindowAttributes(qt_mac_window_for(this), 0, kWindowToolbarButtonAttribute);
01233 #endif
01234
01235 dockWindow->hide();
01236 d->dockWindows.removeAll(dockWindow);
01237 disconnect(dockWindow, SIGNAL(placeChanged(Q3DockWindow::Place)),
01238 this, SLOT(slotPlaceChanged()));
01239 dockWindow->removeEventFilter(this);
01240 }
01241
01247 void Q3MainWindow::setUpLayout()
01248 {
01249 Q_D(Q3MainWindow);
01250 #ifndef QT_NO_MENUBAR
01251 if (!d->mb) {
01252
01253 QObjectList l = queryList("QMenuBar", 0, false, false);
01254 if (l.size())
01255 d->mb = menuBar();
01256 }
01257 #endif
01258 if (!d->sb) {
01259
01260 QObjectList l = queryList("QStatusBar", 0, false, false);
01261 if (l.size())
01262 d->sb = statusBar();
01263 }
01264
01265 if (!d->tll) {
01266 d->tll = new QBoxLayout(this, QBoxLayout::Down);
01267 d->tll->setResizeMode(minimumSize().isNull() ? QLayout::Minimum : QLayout::FreeResize);
01268 } else {
01269 d->tll->setMenuBar(0);
01270 QLayoutItem *item;
01271 while ((item = d->tll->takeAt(0)))
01272 delete item;
01273 }
01274
01275 #ifndef QT_NO_MENUBAR
01276 if (d->mb && d->mb->isVisibleTo(this)) {
01277 d->tll->setMenuBar(d->mb);
01278 if (style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this))
01279 d->tll->addSpacing(d->movable ? 1 : 2);
01280 }
01281 #endif
01282
01283 d->tll->addWidget(d->hideDock);
01284 if(d->topDock->parentWidget() == this)
01285 d->tll->addWidget(d->topDock);
01286
01287 Q3MainWindowLayout *mwl = new Q3MainWindowLayout(this, d->tll);
01288 d->tll->setStretchFactor(mwl, 1);
01289
01290 if(d->leftDock->parentWidget() == this)
01291 mwl->setLeftDock(d->leftDock);
01292 if (centralWidget())
01293 mwl->setCentralWidget(centralWidget());
01294 if(d->rightDock->parentWidget() == this)
01295 mwl->setRightDock(d->rightDock);
01296 d->mwl = mwl;
01297
01298 if(d->bottomDock->parentWidget() == this)
01299 d->tll->addWidget(d->bottomDock);
01300
01301 if (d->sb && d->sb->parentWidget() == this) {
01302 d->tll->addWidget(d->sb, 0);
01303
01304 d->sb->raise();
01305 }
01306 }
01307
01309 void Q3MainWindow::setVisible(bool visible)
01310 {
01311 Q_D(Q3MainWindow);
01312 if (visible) {
01313 if (!d->tll)
01314 setUpLayout();
01315
01316
01317 if (!isVisible()) {
01318 for (int i = 0; i < d->dockWindows.size(); ++i) {
01319 Q3DockWindow *dw = d->dockWindows.at(i);
01320 if (dw->isWindow() && !dw->isVisible() && !dw->testAttribute(Qt::WA_WState_Hidden)) {
01321 reinterpret_cast<Q3MainWindow *>(dw)->setAttribute(Qt::WA_WState_Hidden);
01322 dw->show();
01323 }
01324 }
01325 }
01326 } else if (isVisible()) {
01327 for (int i = 0; i < d->dockWindows.size(); ++i) {
01328 Q3DockWindow *dw = d->dockWindows.at(i);
01329 if (dw->isWindow() && dw->isVisible()) {
01330 dw->hide();
01331 reinterpret_cast<Q3MainWindow *>(dw)->setAttribute(Qt::WA_WState_Hidden, false);
01332 }
01333 }
01334 }
01335 QWidget::setVisible(visible);
01336 }
01337
01338
01340 QSize Q3MainWindow::sizeHint() const
01341 {
01342 Q3MainWindow* that = (Q3MainWindow*) this;
01343
01344
01345 QApplication::sendPostedEvents(that, QEvent::ChildInserted);
01346 if (!that->d_func()->tll)
01347 that->setUpLayout();
01348 return that->d_func()->tll->totalSizeHint();
01349 }
01350
01352 QSize Q3MainWindow::minimumSizeHint() const
01353 {
01354 Q_D(const Q3MainWindow);
01355 if (!d->tll) {
01356 Q3MainWindow* that = (Q3MainWindow*) this;
01357 that->setUpLayout();
01358 }
01359 return d->tll->totalMinimumSize();
01360 }
01361
01371 void Q3MainWindow::setCentralWidget(QWidget * w)
01372 {
01373 Q_D(Q3MainWindow);
01374 if (d->mc)
01375 d->mc->removeEventFilter(this);
01376 d->mc = w;
01377 if (d->mc)
01378 d->mc->installEventFilter(this);
01379 triggerLayout();
01380 }
01381
01382
01392 QWidget * Q3MainWindow::centralWidget() const
01393 {
01394 return d_func()->mc;
01395 }
01396
01397
01400 void Q3MainWindow::paintEvent(QPaintEvent *)
01401 {
01402 Q_D(Q3MainWindow);
01403 if (d->mb &&
01404 style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this)) {
01405 QPainter p(this);
01406 int y = d->mb->height() + 1;
01407 QStyleOption opt(0, QStyleOption::SO_Default);
01408 opt.rect.setRect(0, y, width(), 1);
01409 opt.palette = palette();
01410 opt.state = QStyle::State_Sunken;
01411 style()->drawPrimitive(QStyle::PE_Q3Separator, &opt, &p, this);
01412 }
01413 }
01414
01415
01416 bool Q3MainWindow::dockMainWindow(QObject *dock) const
01417 {
01418 while (dock) {
01419 if (dock->parent() &&
01420 dock->parent() == const_cast<Q3MainWindow*>(this))
01421 return true;
01422 if (qobject_cast<Q3MainWindow*>(dock->parent()))
01423 return false;
01424 dock = dock->parent();
01425 }
01426 return false;
01427 }
01428
01433 bool Q3MainWindow::eventFilter(QObject* o, QEvent *e)
01434 {
01435 Q_D(Q3MainWindow);
01436 if (e->type() == QEvent::Show && o == this) {
01437 if (!d->tll)
01438 setUpLayout();
01439 d->tll->activate();
01440 } else if (e->type() == QEvent::ContextMenu && d->dockMenu &&
01441 (qobject_cast<Q3DockArea*>(o) && dockMainWindow(o) || o == d->hideDock || o == d->mb)) {
01442 if (showDockMenu(((QMouseEvent*)e)->globalPos())) {
01443 ((QContextMenuEvent*)e)->accept();
01444 return true;
01445 }
01446 }
01447
01448 return QWidget::eventFilter(o, e);
01449 }
01450
01451
01455 void Q3MainWindow::childEvent(QChildEvent* e)
01456 {
01457 Q_D(Q3MainWindow);
01458 if (e->type() == QEvent::ChildRemoved) {
01459 if (e->child() == 0 ||
01460 !e->child()->isWidgetType() ||
01461 ((QWidget*)e->child())->isWindow()) {
01462
01463 } else if (e->child() == d->sb) {
01464 d->sb = 0;
01465 triggerLayout();
01466 } else if (e->child() == d->mb) {
01467 d->mb = 0;
01468 triggerLayout();
01469 } else if (e->child() == d->mc) {
01470 d->mc = 0;
01471 d->mwl->setCentralWidget(0);
01472 triggerLayout();
01473 } else if (qobject_cast<Q3DockWindow*>(e->child())) {
01474 removeDockWindow((Q3DockWindow *)(e->child()));
01475 d->appropriate.remove((Q3DockWindow*)e->child());
01476 triggerLayout();
01477 }
01478 } else if (e->type() == QEvent::ChildInserted && !d->sb) {
01479 d->sb = qobject_cast<QStatusBar*>(e->child());
01480 if (d->sb) {
01481 if (d->tll) {
01482 if (!d->tll->findWidget(d->sb))
01483 d->tll->addWidget(d->sb);
01484 } else {
01485 triggerLayout();
01486 }
01487 }
01488 }
01489 }
01490
01495 bool Q3MainWindow::event(QEvent * e)
01496 {
01497 Q_D(Q3MainWindow);
01498 #ifndef QT_NO_STATUSTIP
01499 if (e->type() == QEvent::StatusTip) {
01500 if (d->sb) {
01501 d->sb->showMessage(static_cast<QStatusTipEvent*>(e)->tip());
01502 return true;
01503 }
01504 }
01505 #endif
01506 if (e->type() == QEvent::ToolBarChange) {
01507
01508
01509 int deltaH = 0;
01510 Q3DockArea *area = topDock();
01511 if (area->width() >= area->height()) {
01512 deltaH = area->sizeHint().height();
01513 if (!area->isVisible()) {
01514 area->show();
01515 } else {
01516 area->hide();
01517 deltaH = -deltaH;
01518 }
01519 }
01520
01521 if (deltaH) {
01522 QApplication::sendPostedEvents(this, QEvent::LayoutRequest);
01523 resize(width(), height() + deltaH);
01524 }
01525 return true;
01526 }
01527 if (e->type() == QEvent::ChildRemoved && ((QChildEvent*)e)->child() == d->mc) {
01528 d->mc->removeEventFilter(this);
01529 d->mc = 0;
01530 d->mwl->setCentralWidget(0);
01531 }
01532
01533 if (e->type() == QEvent::MenubarUpdated) {
01534 QMenubarUpdatedEvent * const event = static_cast<QMenubarUpdatedEvent *>(e);
01535 if (event->menuBar() && event->menuBar()->parent() == this) {
01536 triggerLayout();
01537 update();
01538 }
01539 }
01540 return QWidget::event(e);
01541 }
01542
01543
01557 bool Q3MainWindow::usesBigPixmaps() const
01558 {
01559 return d_func()->ubp;
01560 }
01561
01562 void Q3MainWindow::setUsesBigPixmaps(bool enable)
01563 {
01564 Q_D(Q3MainWindow);
01565 if (enable == (bool)d->ubp)
01566 return;
01567
01568 d->ubp = enable;
01569 emit pixmapSizeChanged(enable);
01570
01571 QObjectList l = queryList("QLayout");
01572 for (int i = 0; i < l.size(); ++i)
01573 static_cast<QLayout *>(l.at(i))->activate();
01574 }
01575
01591 bool Q3MainWindow::usesTextLabel() const
01592 {
01593 return d_func()->utl;
01594 }
01595
01596
01597 void Q3MainWindow::setUsesTextLabel(bool enable)
01598 {
01599 Q_D(Q3MainWindow);
01600 if (enable == (bool)d->utl)
01601 return;
01602
01603 d->utl = enable;
01604 emit usesTextLabelChanged(enable);
01605
01606 QObjectList l = queryList("QLayout");
01607 for (int i = 0; i < l.size(); ++i)
01608 static_cast<QLayout *>(l.at(i))->activate();
01609 triggerLayout(false);
01610 }
01611
01612
01642 void Q3MainWindow::setRightJustification(bool enable)
01643 {
01644 Q_D(Q3MainWindow);
01645 if (enable == (bool)d->justify)
01646 return;
01647 d->justify = enable;
01648 triggerLayout(true);
01649 }
01650
01651
01666 bool Q3MainWindow::rightJustification() const
01667 {
01668 return d_func()->justify;
01669 }
01670
01674 void Q3MainWindow::triggerLayout(bool deleteLayout)
01675 {
01676 Q_D(Q3MainWindow);
01677 if (deleteLayout || !d->tll)
01678 setUpLayout();
01679 QApplication::postEvent(this, new QEvent(QEvent::LayoutHint));
01680 }
01681
01696 void Q3MainWindow::whatsThis()
01697 {
01698 #ifndef QT_NO_WHATSTHIS
01699 QWhatsThis::enterWhatsThisMode();
01700 #endif
01701 }
01702
01720 bool Q3MainWindow::getLocation(Q3DockWindow *dw, Qt::Dock &dock, int &index, bool &nl, int &extraOffset) const
01721 {
01722 Q_D(const Q3MainWindow);
01723 dock = Qt::DockTornOff;
01724 if (d->topDock->hasDockWindow(dw, &index))
01725 dock = Qt::DockTop;
01726 else if (d->bottomDock->hasDockWindow(dw, &index))
01727 dock = Qt::DockBottom;
01728 else if (d->leftDock->hasDockWindow(dw, &index))
01729 dock = Qt::DockLeft;
01730 else if (d->rightDock->hasDockWindow(dw, &index))
01731 dock = Qt::DockRight;
01732 else if (dw->parentWidget() == d->hideDock) {
01733 index = 0;
01734 dock = Qt::DockMinimized;
01735 } else {
01736 index = 0;
01737 }
01738 nl = dw->newLine();
01739 extraOffset = dw->offset();
01740 return true;
01741 }
01742
01743 #ifndef QT_NO_TOOLBAR
01744
01754 QList<Q3ToolBar *> Q3MainWindow::toolBars(Qt::Dock dock) const
01755 {
01756 QList<Q3DockWindow *> lst = dockWindows(dock);
01757 QList<Q3ToolBar *> tbl;
01758 for (int i = 0; i < lst.size(); ++i) {
01759 Q3ToolBar *tb = qobject_cast<Q3ToolBar *>(lst.at(i));
01760 if (tb)
01761 tbl.append(tb);
01762 }
01763 return tbl;
01764 }
01765 #endif
01766
01776 QList<Q3DockWindow *> Q3MainWindow::dockWindows(Qt::Dock dock) const
01777 {
01778 Q_D(const Q3MainWindow);
01779 QList<Q3DockWindow *> lst;
01780 switch (dock) {
01781 case Qt::DockTop:
01782 return d->topDock->dockWindowList();
01783 case Qt::DockBottom:
01784 return d->bottomDock->dockWindowList();
01785 case Qt::DockLeft:
01786 return d->leftDock->dockWindowList();
01787 case Qt::DockRight:
01788 return d->rightDock->dockWindowList();
01789 case Qt::DockTornOff: {
01790 for (int i = 0; i < d->dockWindows.size(); ++i) {
01791 Q3DockWindow *w = d->dockWindows.at(i);
01792 if (!w->area() && w->place() == Q3DockWindow::OutsideDock)
01793 lst.append(w);
01794 }
01795 }
01796 return lst;
01797 case Qt::DockMinimized: {
01798 QObjectList childList = d->hideDock->children();
01799 for (int i = 0; i < childList.size(); ++i) {
01800 Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(childList.at(i));
01801 if (dw)
01802 lst.append(dw);
01803 }
01804 }
01805 return lst;
01806 default:
01807 break;
01808 }
01809 return lst;
01810 }
01811
01820 QList<Q3DockWindow *> Q3MainWindow::dockWindows() const
01821 {
01822 return d_func()->dockWindows;
01823 }
01824
01825 void Q3MainWindow::setDockWindowsMovable(bool enable)
01826 {
01827 Q_D(Q3MainWindow);
01828 d->movable = enable;
01829 QObjectList l = queryList("Q3DockWindow");
01830 for (int i = 0; i < l.size(); ++i)
01831 static_cast<Q3DockWindow*>(l.at(i))->setMovingEnabled(enable);
01832 }
01833
01855 bool Q3MainWindow::dockWindowsMovable() const
01856 {
01857 return d_func()->movable;
01858 }
01859
01860 void Q3MainWindow::setOpaqueMoving(bool b)
01861 {
01862 Q_D(Q3MainWindow);
01863 d->opaque = b;
01864 QObjectList l = queryList("Q3DockWindow");
01865 for (int i = 0; i < l.size(); ++i)
01866 static_cast<Q3DockWindow*>(l.at(i))->setOpaqueMoving(b);
01867 }
01868
01884 bool Q3MainWindow::opaqueMoving() const
01885 {
01886 return d_func()->opaque;
01887 }
01888
01901 void Q3MainWindow::lineUpDockWindows(bool keepNewLines)
01902 {
01903 Q_D(const Q3MainWindow);
01904 if (!dockWindowsMovable())
01905 return;
01906 d->topDock->lineUp(keepNewLines);
01907 d->leftDock->lineUp(keepNewLines);
01908 d->rightDock->lineUp(keepNewLines);
01909 d->bottomDock->lineUp(keepNewLines);
01910 }
01911
01925 bool Q3MainWindow::isDockMenuEnabled() const
01926 {
01927 return d_func()->dockMenu;
01928 }
01929
01943 void Q3MainWindow::setDockMenuEnabled(bool b)
01944 {
01945 d_func()->dockMenu = b;
01946 }
01947
01978 Q3PopupMenu *Q3MainWindow::createDockWindowMenu(DockWindows dockWindows) const
01979 {
01980 Q_D(const Q3MainWindow);
01981 QObjectList l = queryList("Q3DockWindow");
01982 if (l.isEmpty())
01983 return 0;
01984
01985 Q3PopupMenu *menu = new Q3PopupMenu((Q3MainWindow*)this);
01986 menu->setObjectName("qt_customize_menu");
01987 d->dockWindowModes.replace( menu, dockWindows );
01988 menu->setCheckable(true);
01989 connect( menu, SIGNAL(aboutToShow()), this, SLOT(menuAboutToShow()) );
01990 return menu;
01991 }
01992
02000 void Q3MainWindow::menuAboutToShow()
02001 {
02002 Q_D(Q3MainWindow);
02003 Q3PopupMenu *menu = (Q3PopupMenu*)sender();
02004 menu->clear();
02005
02006 DockWindows dockWindows;
02007 {
02008 QMap<Q3PopupMenu*, DockWindows>::Iterator it = d->dockWindowModes.find( menu );
02009 if ( it == d->dockWindowModes.end() )
02010 return;
02011 dockWindows = (*it);
02012 }
02013
02014 QObjectList l = queryList("Q3DockWindow");
02015 bool empty = true;
02016 if (!l.isEmpty()) {
02017 if (dockWindows == AllDockWindows || dockWindows == NoToolBars) {
02018 for (int i = 0; i < l.size(); ++i) {
02019 Q3DockWindow *dw = (Q3DockWindow*)l.at(i);
02020 if (!appropriate(dw) || qobject_cast<Q3ToolBar*>(dw) || !dockMainWindow(dw))
02021 continue;
02022 QString label = dw->windowTitle();
02023 if (!label.isEmpty()) {
02024 QAction *act = menu->addAction(label);
02025 act->setChecked(dw->isVisible());
02026 QObject::connect(act, SIGNAL(triggered()), dw, SLOT(toggleVisible()));
02027 empty = false;
02028 }
02029 }
02030 }
02031 if (!empty) {
02032 menu->addSeparator();
02033 empty = true;
02034 }
02035 #ifndef QT_NO_TOOLBAR
02036 if (dockWindows == AllDockWindows || dockWindows == OnlyToolBars) {
02037 for (int i = 0; i < l.size(); ++i) {
02038 Q3ToolBar *tb = qobject_cast<Q3ToolBar*>(l.at(i));
02039 if (!tb || !appropriate(tb) || !dockMainWindow(tb))
02040 continue;
02041 QString label = tb->label();
02042 if (!label.isEmpty()) {
02043 QAction *act = menu->addAction(label);
02044 act->setCheckable(true);
02045 act->setChecked(tb->isVisible());
02046 QObject::connect(act, SIGNAL(triggered()), tb, SLOT(toggleVisible()));
02047 empty = false;
02048 }
02049 }
02050 }
02051 #endif
02052 }
02053 if (!empty) {
02054 menu->addSeparator();
02055 empty = true;
02056 }
02057
02058 if (dockWindowsMovable())
02059 menu->addAction(tr("Line up"), this, SLOT(doLineUp()));
02060 if (isCustomizable())
02061 menu->addAction(tr("Customize..."), this, SLOT(customize()));
02062 }
02063
02064
02081 bool Q3MainWindow::showDockMenu(const QPoint &globalPos)
02082 {
02083 Q_D(Q3MainWindow);
02084 if (!d->dockMenu)
02085 return false;
02086
02087 if(Q3PopupMenu *ret = createDockWindowMenu()) {
02088 ret->exec(globalPos);
02089 delete ret;
02090 return true;
02091 }
02092 return false;
02093 }
02094
02095 void Q3MainWindow::slotPlaceChanged()
02096 {
02097 QObject* obj = (QObject*)sender();
02098 Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(obj);
02099 if (dw)
02100 emit dockWindowPositionChanged(dw);
02101 #ifndef QT_NO_TOOLBAR
02102 Q3ToolBar *tb = qobject_cast<Q3ToolBar*>(obj);
02103 if (tb)
02104 emit toolBarPositionChanged(tb);
02105 #endif
02106 }
02107
02113 Q3DockArea *Q3MainWindow::dockingArea(const QPoint &p)
02114 {
02115 Q_D(Q3MainWindow);
02116 int mh = d->mb ? d->mb->height() : 0;
02117 int sh = d->sb ? d->sb->height() : 0;
02118 if (p.x() >= -5 && p.x() <= 100 && p.y() > mh && p.y() - height() - sh)
02119 return d->leftDock;
02120 if (p.x() >= width() - 100 && p.x() <= width() + 5 && p.y() > mh && p.y() - height() - sh)
02121 return d->rightDock;
02122 if (p.y() >= -5 && p.y() < mh + 100 && p.x() >= 0 && p.x() <= width())
02123 return d->topDock;
02124 if (p.y() >= height() - sh - 100 && p.y() <= height() + 5 && p.x() >= 0 && p.x() <= width())
02125 return d->bottomDock;
02126 return 0;
02127 }
02128
02134 bool Q3MainWindow::hasDockWindow(Q3DockWindow *dw)
02135 {
02136 return d_func()->dockWindows.contains(dw);
02137 }
02138
02145 Q3DockArea *Q3MainWindow::leftDock() const
02146 {
02147 return d_func()->leftDock;
02148 }
02149
02156 Q3DockArea *Q3MainWindow::rightDock() const
02157 {
02158 return d_func()->rightDock;
02159 }
02160
02167 Q3DockArea *Q3MainWindow::topDock() const
02168 {
02169 return d_func()->topDock;
02170 }
02171
02178 Q3DockArea *Q3MainWindow::bottomDock() const
02179 {
02180 return d_func()->bottomDock;
02181 }
02182
02202 void Q3MainWindow::customize()
02203 {
02204 }
02205
02217 bool Q3MainWindow::isCustomizable() const
02218 {
02219 return false;
02220 }
02221
02236 bool Q3MainWindow::appropriate(Q3DockWindow *dw) const
02237 {
02238 Q_D(const Q3MainWindow);
02239 QMap<Q3DockWindow*, bool>::ConstIterator it = d->appropriate.find(dw);
02240 if (it == d->appropriate.end())
02241 return true;
02242 return *it;
02243 }
02244
02260 void Q3MainWindow::setAppropriate(Q3DockWindow *dw, bool a)
02261 {
02262 d_func()->appropriate.insert(dw, a);
02263 }
02264
02265 #ifndef QT_NO_TEXTSTREAM
02266 static void saveDockArea(QTextStream &ts, Q3DockArea *a)
02267 {
02268 QList<Q3DockWindow *> l = a->dockWindowList();
02269 for (int i = 0; i < l.size(); ++i) {
02270 Q3DockWindow *dw = l.at(i);
02271 ts << QString(dw->windowTitle());
02272 ts << ",";
02273 }
02274 ts << endl;
02275 ts << *a;
02276 }
02277
02292 QTextStream &operator<<(QTextStream &ts, const Q3MainWindow &mainWindow)
02293 {
02294 QList<Q3DockWindow *> l = mainWindow.dockWindows(Qt::DockMinimized);
02295 for (int i = 0; i < l.size(); ++i) {
02296 Q3DockWindow *dw = l.at(i);
02297 ts << dw->windowTitle();
02298 ts << ",";
02299 }
02300 ts << endl;
02301
02302 l = mainWindow.dockWindows(Qt::DockTornOff);
02303 for (int i = 0; i < l.size(); ++i) {
02304 Q3DockWindow *dw = l.at(i);
02305 ts << dw->windowTitle();
02306 ts << ",";
02307 }
02308 ts << endl;
02309 for (int i = 0; i < l.size(); ++i) {
02310 Q3DockWindow *dw = l.at(i);
02311 ts << "[" << dw->windowTitle() << ","
02312 << (int)dw->geometry().x() << ","
02313 << (int)dw->geometry().y() << ","
02314 << (int)dw->geometry().width() << ","
02315 << (int)dw->geometry().height() << ","
02316 << (int)dw->isVisible() << "]";
02317 }
02318 ts << endl;
02319
02320 saveDockArea(ts, mainWindow.topDock());
02321 saveDockArea(ts, mainWindow.bottomDock());
02322 saveDockArea(ts, mainWindow.rightDock());
02323 saveDockArea(ts, mainWindow.leftDock());
02324 return ts;
02325 }
02326
02327 static void loadDockArea(const QStringList &names, Q3DockArea *a, Qt::Dock dl, QList<Q3DockWindow *> &l, Q3MainWindow *mw, QTextStream &ts)
02328 {
02329 for (QStringList::ConstIterator it = names.begin(); it != names.end(); ++it) {
02330 for (int i = 0; i < l.size(); ++i) {
02331 Q3DockWindow *dw = l.at(i);
02332 if (dw->windowTitle() == *it) {
02333 mw->addDockWindow(dw, dl);
02334 break;
02335 }
02336 }
02337 }
02338 if (a) {
02339 ts >> *a;
02340 } else if (dl == Qt::DockTornOff) {
02341 QString s = ts.readLine();
02342 enum State { Pre, Name, X, Y, Width, Height, Visible, Post };
02343 int state = Pre;
02344 QString name, x, y, w, h, visible;
02345 QChar c;
02346 for (int i = 0; i < (int)s.length(); ++i) {
02347 c = s[i];
02348 if (state == Pre && c == '[') {
02349 state++;
02350 continue;
02351 }
02352 if (c == ',' &&
02353 (state == Name || state == X || state == Y || state == Width || state == Height)) {
02354 state++;
02355 continue;
02356 }
02357 if (state == Visible && c == ']') {
02358 for (int i = 0; i < l.size(); ++i) {
02359 Q3DockWindow *dw = l.at(i);
02360 if (QString(dw->windowTitle()) == name) {
02361 if (!qobject_cast<Q3ToolBar*>(dw))
02362 dw->setGeometry(x.toInt(), y.toInt(), w.toInt(), h.toInt());
02363 else
02364 dw->setGeometry(x.toInt(), y.toInt(), dw->width(), dw->height());
02365 if (!(bool)visible.toInt())
02366 dw->hide();
02367 else
02368 dw->show();
02369 break;
02370 }
02371 }
02372
02373 name = x = y = w = h = visible = "";
02374
02375 state = Pre;
02376 continue;
02377 }
02378 if (state == Name)
02379 name += c;
02380 else if (state == X)
02381 x += c;
02382 else if (state == Y)
02383 y += c;
02384 else if (state == Width)
02385 w += c;
02386 else if (state == Height)
02387 h += c;
02388 else if (state == Visible)
02389 visible += c;
02390 }
02391 }
02392 }
02393
02408 QTextStream &operator>>(QTextStream &ts, Q3MainWindow &mainWindow)
02409 {
02410 QList<Q3DockWindow *> l = mainWindow.dockWindows();
02411
02412 QString s = ts.readLine();
02413 QStringList names = s.split(',');
02414 loadDockArea(names, 0, Qt::DockMinimized, l, &mainWindow, ts);
02415
02416 s = ts.readLine();
02417 names = s.split(',');
02418 loadDockArea(names, 0, Qt::DockTornOff, l, &mainWindow, ts);
02419
02420 int i = 0;
02421 Q3DockArea *areas[] = { mainWindow.topDock(), mainWindow.bottomDock(), mainWindow.rightDock(), mainWindow.leftDock() };
02422 for (int dl = (int)Qt::DockTop; dl != (int)Qt::DockMinimized; ++dl, ++i) {
02423 s = ts.readLine();
02424 names = s.split(',');
02425 loadDockArea(names, areas[i], (Qt::Dock)dl, l, &mainWindow, ts);
02426 }
02427 return ts;
02428 }
02429 #endif
02430
02431 #include "q3mainwindow.moc"
02432
02433 #endif