~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/qt3support/widgets/q3mainwindow.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the Qt 3 compatibility classes of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "q3mainwindow.h"
 
30
#ifndef QT_NO_MAINWINDOW
 
31
 
 
32
#include "qapplication.h"
 
33
#include "qbitmap.h"
 
34
#include "qcursor.h"
 
35
#include "qdatetime.h"
 
36
#include "q3dockarea.h"
 
37
#include "qevent.h"
 
38
#include "qlayout.h"
 
39
#include "qmap.h"
 
40
#include "qmenubar.h"
 
41
#include "qpainter.h"
 
42
#include "q3popupmenu.h"
 
43
#include "q3scrollview.h"
 
44
#include "qstatusbar.h"
 
45
#include "qstringlist.h"
 
46
#include "qstyle.h"
 
47
#include "qstyleoption.h"
 
48
#include "qtimer.h"
 
49
#include "q3toolbar.h"
 
50
#include "qtooltip.h"
 
51
#include "qwhatsthis.h"
 
52
#ifdef Q_WS_MAC
 
53
#  include <private/qt_mac_p.h>
 
54
#endif
 
55
 
 
56
class QHideDock;
 
57
 
 
58
#include <private/q3mainwindow_p.h>
 
59
 
 
60
/* Q3MainWindowLayout, respects widthForHeight layouts (like the left
 
61
  and right docks are)
 
62
*/
 
63
 
 
64
class Q3MainWindowLayout : public QLayout
 
65
{
 
66
    Q_OBJECT
 
67
 
 
68
public:
 
69
    Q3MainWindowLayout(Q3MainWindow *mw, QLayout* parent = 0);
 
70
    ~Q3MainWindowLayout() {}
 
71
 
 
72
    void addItem(QLayoutItem *);
 
73
    void setLeftDock(Q3DockArea *l);
 
74
    void setRightDock(Q3DockArea *r);
 
75
    void setCentralWidget(QWidget *w);
 
76
    bool hasHeightForWidth() const { return false; }
 
77
    QSize sizeHint() const;
 
78
    QSize minimumSize() const;
 
79
    QLayoutItem *itemAt(int) const { return 0; } //###
 
80
    QLayoutItem *takeAt(int) { return 0; } //###
 
81
    int count() const { return 0; } //###
 
82
 
 
83
protected:
 
84
    void setGeometry(const QRect &r) {
 
85
        QLayout::setGeometry(r);
 
86
        layoutItems(r);
 
87
    }
 
88
 
 
89
private:
 
90
    int layoutItems(const QRect&, bool testonly = false);
 
91
    int extraPixels() const;
 
92
 
 
93
    Q3DockArea *left, *right;
 
94
    QWidget *central;
 
95
    Q3MainWindow *mainWindow;
 
96
 
 
97
};
 
98
 
 
99
QSize Q3MainWindowLayout::sizeHint() const
 
100
{
 
101
    int w = 0;
 
102
    int h = 0;
 
103
 
 
104
    if (left) {
 
105
        w += left->sizeHint().width();
 
106
        h = qMax(h, left->sizeHint().height());
 
107
    }
 
108
    if (right) {
 
109
        w += right->sizeHint().width();
 
110
        h = qMax(h, right->sizeHint().height());
 
111
    }
 
112
    if (central) {
 
113
        w += central->sizeHint().width();
 
114
        int diff = extraPixels();
 
115
        h = qMax(h, central->sizeHint().height() + diff);
 
116
    }
 
117
    return QSize(w, h);
 
118
}
 
119
 
 
120
QSize Q3MainWindowLayout::minimumSize() const
 
121
{
 
122
    int w = 0;
 
123
    int h = 0;
 
124
 
 
125
    if (left) {
 
126
        QSize ms = left->minimumSizeHint().expandedTo(left->minimumSize());
 
127
        w += ms.width();
 
128
        h = qMax(h, ms.height());
 
129
    }
 
130
    if (right) {
 
131
        QSize ms = right->minimumSizeHint().expandedTo(right->minimumSize());
 
132
        w += ms.width();
 
133
        h = qMax(h, ms.height());
 
134
    }
 
135
    if (central) {
 
136
        QSize min = central->minimumSize().isNull() ?
 
137
                    central->minimumSizeHint() : central->minimumSize();
 
138
        w += min.width();
 
139
        int diff = extraPixels();
 
140
        h = qMax(h, min.height() + diff);
 
141
    }
 
142
    return QSize(w, h);
 
143
}
 
144
 
 
145
Q3MainWindowLayout::Q3MainWindowLayout(Q3MainWindow *mw, QLayout* parent)
 
146
    : QLayout(parent), left(0), right(0), central(0)
 
147
{
 
148
    mainWindow = mw;
 
149
}
 
150
 
 
151
void Q3MainWindowLayout::setLeftDock(Q3DockArea *l)
 
152
{
 
153
    left = l;
 
154
}
 
155
 
 
156
void Q3MainWindowLayout::setRightDock(Q3DockArea *r)
 
157
{
 
158
    right = r;
 
159
}
 
160
 
 
161
void Q3MainWindowLayout::setCentralWidget(QWidget *w)
 
162
{
 
163
    central = w;
 
164
}
 
165
 
 
166
int Q3MainWindowLayout::layoutItems(const QRect &r, bool testonly)
 
167
{
 
168
    if (!left && !central && !right)
 
169
        return 0;
 
170
 
 
171
    int wl = 0, wr = 0;
 
172
    if (left)
 
173
        wl = ((Q3DockAreaLayout*)left->QWidget::layout())->widthForHeight(r.height());
 
174
    if (right)
 
175
        wr = ((Q3DockAreaLayout*)right->QWidget::layout())->widthForHeight(r.height());
 
176
    int w = r.width() - wr - wl;
 
177
    if (w < 0)
 
178
        w = 0;
 
179
 
 
180
    int diff = extraPixels();
 
181
    if (!testonly) {
 
182
        QRect g(geometry());
 
183
        if (left)
 
184
            left->setGeometry(QRect(g.x(), g.y() + diff, wl, r.height() - diff));
 
185
        if (right)
 
186
            right->setGeometry(QRect(g.x() + g.width() - wr, g.y() + diff, wr, r.height() - diff));
 
187
        if (central)
 
188
            central->setGeometry(g.x() + wl, g.y() + diff, w, r.height() - diff);
 
189
    }
 
190
 
 
191
    w = wl + wr;
 
192
    if (central)
 
193
        w += central->minimumSize().width();
 
194
    return w;
 
195
}
 
196
 
 
197
int Q3MainWindowLayout::extraPixels() const
 
198
{
 
199
    if (mainWindow->d_func()->topDock->isEmpty() &&
 
200
         !(mainWindow->d_func()->leftDock->isEmpty() &&
 
201
           mainWindow->d_func()->rightDock->isEmpty())) {
 
202
        return 2;
 
203
    } else {
 
204
        return 0;
 
205
    }
 
206
}
 
207
 
 
208
void Q3MainWindowLayout::addItem(QLayoutItem * /* item */)
 
209
{
 
210
}
 
211
 
 
212
/*
 
213
  QHideToolTip and QHideDock - minimized dock
 
214
*/
 
215
 
 
216
#if 0
 
217
class QHideToolTip : public QToolTip
 
218
{
 
219
public:
 
220
    QHideToolTip(QWidget *parent) : QToolTip(parent) {}
 
221
 
 
222
    void maybeTip(const QPoint &pos);
 
223
};
 
224
#endif
 
225
 
 
226
 
 
227
class QHideDock : public QWidget
 
228
{
 
229
    Q_OBJECT
 
230
 
 
231
public:
 
232
    QHideDock(Q3MainWindow *parent) : QWidget(parent, "qt_hide_dock") {
 
233
        hide();
 
234
        setFixedHeight(style()->pixelMetric(QStyle::PM_DockWidgetHandleExtent, 0, this) + 3);
 
235
        pressedHandle = -1;
 
236
        pressed = false;
 
237
        setMouseTracking(true);
 
238
        win = parent;
 
239
#if 0
 
240
        tip = new QHideToolTip(this);
 
241
#endif
 
242
    }
 
243
    ~QHideDock()
 
244
    {
 
245
#if 0
 
246
        delete tip;
 
247
#endif
 
248
    }
 
249
 
 
250
protected:
 
251
    void paintEvent(QPaintEvent *e) {
 
252
        QObjectList childs = children();
 
253
        if (childs.isEmpty())
 
254
            return;
 
255
        QPainter p(this);
 
256
        p.setClipRegion(e->rect());
 
257
        p.fillRect(e->rect(), palette().brush(QPalette::Background));
 
258
        int x = 0;
 
259
        for (int i = 0; i < childs.size(); ++i) {
 
260
            QObject *o = childs.at(i);
 
261
            Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
 
262
            if (!dw || !dw->isVisible())
 
263
                continue;
 
264
            QStyleOptionQ3DockWindow opt;
 
265
            opt.rect.setRect(x, 0, 30, 10);
 
266
            opt.palette = palette();
 
267
            opt.docked = dw->area();
 
268
            opt.closeEnabled = dw->isCloseEnabled();
 
269
            opt.state = QStyle::State_None;
 
270
            if (i == pressedHandle)
 
271
                opt.state |= QStyle::State_On;
 
272
 
 
273
            style()->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &opt, &p, this);
 
274
            x += 30;
 
275
        }
 
276
    }
 
277
 
 
278
    void mousePressEvent(QMouseEvent *e) {
 
279
        pressed = true;
 
280
        QObjectList childs = children();
 
281
        if (childs.isEmpty())
 
282
            return;
 
283
        mouseMoveEvent(e);
 
284
        pressedHandle = -1;
 
285
 
 
286
        if (e->button() == Qt::RightButton && win->isDockMenuEnabled()) {
 
287
            // ### TODO: HideDock menu
 
288
        } else {
 
289
            mouseMoveEvent(e);
 
290
        }
 
291
    }
 
292
 
 
293
    void mouseMoveEvent(QMouseEvent *e) {
 
294
        QObjectList childs = children();
 
295
        if (childs.isEmpty())
 
296
            return;
 
297
        if (!pressed)
 
298
            return;
 
299
        int x = 0;
 
300
        if (e->y() >= 0 && e->y() <= height()) {
 
301
            for (int i = 0; i < childs.size(); ++i) {
 
302
                QObject *o = childs.at(i);
 
303
                Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
 
304
                if (!dw || !dw->isVisible())
 
305
                    continue;
 
306
                if (e->x() >= x && e->x() <= x + 30) {
 
307
                    int old = pressedHandle;
 
308
                    pressedHandle = i;
 
309
                    if (pressedHandle != old)
 
310
                        repaint();
 
311
                    return;
 
312
                }
 
313
                x += 30;
 
314
            }
 
315
        }
 
316
        int old = pressedHandle;
 
317
        pressedHandle = -1;
 
318
        if (old != -1)
 
319
            repaint();
 
320
    }
 
321
 
 
322
    void mouseReleaseEvent(QMouseEvent *e) {
 
323
        pressed = false;
 
324
        if (pressedHandle == -1)
 
325
            return;
 
326
        QObjectList childs = children();
 
327
        if (childs.isEmpty())
 
328
            return;
 
329
        if (e->button() == Qt::LeftButton) {
 
330
            if (e->y() >= 0 && e->y() <= height()) {
 
331
                QObject *o = childs.at(pressedHandle);
 
332
                Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
 
333
                if (dw) {
 
334
                    dw->show();
 
335
                    dw->dock();
 
336
                }
 
337
            }
 
338
        }
 
339
        pressedHandle = -1;
 
340
        repaint();
 
341
    }
 
342
 
 
343
    bool eventFilter(QObject *o, QEvent *e) {
 
344
        if (o == this || !o->isWidgetType())
 
345
            return QWidget::eventFilter(o, e);
 
346
        if (e->type() == QEvent::HideToParent ||
 
347
             e->type() == QEvent::ShowToParent)
 
348
            updateState();
 
349
        return QWidget::eventFilter(o, e);
 
350
    }
 
351
 
 
352
    void updateState() {
 
353
        bool visible = true;
 
354
        QObjectList childs = children();
 
355
        if (childs.isEmpty())
 
356
            return;
 
357
        for (int i = 0; i < childs.size(); ++i) {
 
358
            QObject *o = childs.at(i);
 
359
            Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
 
360
            if (!dw)
 
361
                continue;
 
362
            if (dw->isHidden()) {
 
363
                visible = false;
 
364
                continue;
 
365
            }
 
366
            if (!dw->isVisible())
 
367
                continue;
 
368
            visible = true;
 
369
            break;
 
370
        }
 
371
 
 
372
        if (visible)
 
373
            show();
 
374
        else
 
375
            hide();
 
376
        win->triggerLayout(false);
 
377
        update();
 
378
    }
 
379
 
 
380
    void childEvent(QChildEvent *e) {
 
381
        QWidget::childEvent(e);
 
382
        if (e->type() == QEvent::ChildInserted)
 
383
            e->child()->installEventFilter(this);
 
384
        else
 
385
            e->child()->removeEventFilter(this);
 
386
        updateState();
 
387
    }
 
388
 
 
389
private:
 
390
    Q3MainWindow *win;
 
391
    int pressedHandle;
 
392
    bool pressed;
 
393
#if 0
 
394
    QHideToolTip *tip;
 
395
    friend class QHideToolTip;
 
396
#endif
 
397
};
 
398
 
 
399
#if 0
 
400
void QHideToolTip::maybeTip(const QPoint &pos)
 
401
{
 
402
    if (!parentWidget())
 
403
        return;
 
404
    QHideDock *dock = (QHideDock*)parentWidget();
 
405
 
 
406
    QObjectList dchilds = dock->children();
 
407
    if (dchilds.isEmpty())
 
408
        return;
 
409
    int x = 0;
 
410
    for (int i = 0; i < dchilds.size(); ++i) {
 
411
        QObject *o = dchilds.at(i);
 
412
        Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
 
413
        if (!dw || !dw->isVisible())
 
414
            continue;
 
415
        if (pos.x() >= x && pos.x() <= x + 30) {
 
416
            Q3DockWindow *dw = (Q3DockWindow*)o;
 
417
            if (!dw->windowTitle().isEmpty())
 
418
                tip(QRect(x, 0, 30, dock->height()), dw->windowTitle());
 
419
            return;
 
420
        }
 
421
        x += 30;
 
422
    }
 
423
}
 
424
#endif
 
425
 
 
426
/*!
 
427
    \class Q3MainWindow
 
428
    \brief The Q3MainWindow class provides a main application window,
 
429
    with a menu bar, dock windows (e.g. for toolbars), and a status
 
430
    bar.
 
431
 
 
432
    \compat
 
433
 
 
434
    Main windows are most often used to provide menus, toolbars and a
 
435
    status bar around a large central widget, such as a text edit,
 
436
    drawing canvas or QWorkspace (for MDI applications). Q3MainWindow
 
437
    is usually subclassed since this makes it easier to encapsulate
 
438
    the central widget, menus and toolbars as well as the window's
 
439
    state. Subclassing makes it possible to create the slots that are
 
440
    called when the user clicks menu items or toolbar buttons.
 
441
 
 
442
    We'll briefly review adding menu items and
 
443
    toolbar buttons then describe the facilities of Q3MainWindow
 
444
    itself.
 
445
 
 
446
    \code
 
447
        Q3MainWindow *mw = new Q3MainWindow;
 
448
        QTextEdit *edit = new QTextEdit(mw, "editor");
 
449
        edit->setFocus();
 
450
        mw->setWindowTitle("Main Window");
 
451
        mw->setCentralWidget(edit);
 
452
        mw->show();
 
453
    \endcode
 
454
 
 
455
    Q3MainWindows may be created in their own right as shown above.
 
456
    The central widget is set with setCentralWidget(). Popup menus can
 
457
    be added to the default menu bar, widgets can be added to the
 
458
    status bar, toolbars and dock windows can be added to any of the
 
459
    dock areas.
 
460
 
 
461
    The main window will take care of the dock areas, and the geometry
 
462
    of the central widget, but all other aspects of the central widget
 
463
    are left to you. Q3MainWindow automatically detects the creation of
 
464
    a menu bar or status bar if you specify the Q3MainWindow as parent,
 
465
    or you can use the provided menuBar() and statusBar() functions.
 
466
    The functions menuBar() and statusBar() create a suitable widget
 
467
    if one doesn't exist, and update the window's layout to make
 
468
    space.
 
469
 
 
470
    New dock windows and toolbars can be added to a Q3MainWindow using
 
471
    addDockWindow(). Qt::Dock windows can be moved using moveDockWindow()
 
472
    and removed with removeDockWindow(). Q3MainWindow allows default
 
473
    dock window (toolbar) docking in all its dock areas (\c Top, \c
 
474
    Left, \c Right, \c Bottom). You can use setDockEnabled() to
 
475
    enable and disable docking areas for dock windows. When adding or
 
476
    moving dock windows you can specify their 'edge' (dock area). The
 
477
    currently available edges are: \c Top, \c Left, \c Right, \c
 
478
    Bottom, \c Minimized (effectively a 'hidden' dock area) and \c
 
479
    TornOff (floating). See \l Qt::Dock for an explanation of these
 
480
    areas. Note that the *ToolBar functions are included for backward
 
481
    compatibility; all new code should use the *DockWindow functions.
 
482
    QToolbar is a subclass of Q3DockWindow so all functions that work
 
483
    with dock windows work on toolbars in the same way.
 
484
 
 
485
    \target dwm
 
486
    If the user clicks the close button, then the dock window is
 
487
    hidden. A dock window can be hidden or unhidden by the user by
 
488
    right clicking a dock area and clicking the name of the relevant
 
489
    dock window on the pop up dock window menu. This menu lists the
 
490
    names of every dock window; visible dock windows have a tick
 
491
    beside their names. The dock window menu is created automatically
 
492
    as required by createDockWindowMenu(). Since it may not always be
 
493
    appropriate for a dock window to appear on this menu the
 
494
    setAppropriate() function is used to inform the main window
 
495
    whether or not the dock window menu should include a particular
 
496
    dock window. Double clicking a dock window handle (usually on the
 
497
    left-hand side of the dock window) undocks (floats) the dock
 
498
    window. Double clicking a floating dock window's title bar will
 
499
    dock the floating dock window. (See also
 
500
    \l{Q3MainWindow::DockWindows}.)
 
501
 
 
502
    Some functions change the appearance of a Q3MainWindow globally:
 
503
    \list
 
504
    \i Q3DockWindow::setHorizontalStretchable() and
 
505
    Q3DockWindow::setVerticalStretchable() are used to make specific dock
 
506
    windows or toolbars stretchable.
 
507
    \i setUsesBigPixmaps() is used to set whether tool buttons should
 
508
    draw small or large pixmaps (see QIcon for more information).
 
509
    \i setUsesTextLabel() is used to set whether tool buttons
 
510
    should display a textual label in addition to pixmaps
 
511
    (see QToolButton for more information).
 
512
    \endlist
 
513
 
 
514
    The user can drag dock windows into any enabled docking area. Qt::Dock
 
515
    windows can also be dragged \e within a docking area, for example
 
516
    to rearrange the order of some toolbars. Qt::Dock windows can also be
 
517
    dragged outside any docking area (undocked or 'floated'). Being
 
518
    able to drag dock windows can be enabled (the default) and
 
519
    disabled using setDockWindowsMovable().
 
520
 
 
521
    The \c Minimized edge is a hidden dock area. If this dock area is
 
522
    enabled the user can hide (minimize) a dock window or show (restore)
 
523
    a minimized dock window by clicking the dock window handle. If the
 
524
    user hovers the mouse cursor over one of the handles, the caption of
 
525
    the dock window is displayed in a tool tip (see
 
526
    Q3DockWindow::windowTitle() or Q3ToolBar::label()), so if you enable the
 
527
    \c Minimized dock area, it is best to specify a meaningful caption
 
528
    or label for each dock window. To minimize a dock window
 
529
    programmatically use moveDockWindow() with an edge of \c Minimized.
 
530
 
 
531
    Qt::Dock windows are moved transparently by default, i.e. during the
 
532
    drag an outline rectangle is drawn on the screen representing the
 
533
    position of the dock window as it moves. If you want the dock
 
534
    window to be shown normally whilst it is moved use
 
535
    setOpaqueMoving().
 
536
 
 
537
    The location of a dock window, i.e. its dock area and position
 
538
    within the dock area, can be determined by calling getLocation().
 
539
    Movable dock windows can be lined up to minimize wasted space with
 
540
    lineUpDockWindows(). Pointers to the dock areas are available from
 
541
    topDock(), leftDock(), rightDock() and bottomDock(). A customize
 
542
    menu item is added to the pop up dock window menu if
 
543
    isCustomizable() returns true; it returns false by default.
 
544
    Reimplement isCustomizable() and customize() if you want to offer
 
545
    this extra menu item, for example, to allow the user to change
 
546
    settings relating to the main window and its toolbars and dock
 
547
    windows.
 
548
 
 
549
    The main window's menu bar is fixed (at the top) by default. If
 
550
    you want a movable menu bar, create a QMenuBar as a stretchable
 
551
    widget inside its own movable dock window and restrict this dock
 
552
    window to only live within the \c Top or \c Bottom dock:
 
553
 
 
554
    \code
 
555
    Q3ToolBar *tb = new Q3ToolBar(this);
 
556
    addDockWindow(tb, tr("Menubar"), Top, false);
 
557
    QMenuBar *mb = new QMenuBar(tb);
 
558
    mb->setFrameStyle(QFrame::NoFrame);
 
559
    tb->setStretchableWidget(mb);
 
560
    setDockEnabled(tb, Left, false);
 
561
    setDockEnabled(tb, Right, false);
 
562
    \endcode
 
563
 
 
564
    An application with multiple dock windows can choose to save the
 
565
    current dock window layout in order to restore it later, e.g. in
 
566
    the next session. You can do this by using the streaming operators
 
567
    for Q3MainWindow.
 
568
 
 
569
    To save the layout and positions of all the dock windows do this:
 
570
 
 
571
    \code
 
572
    QFile file(filename);
 
573
    if (file.open(IO_WriteOnly)) {
 
574
        QTextStream stream(&file);
 
575
        stream << *mainWindow;
 
576
        file.close();
 
577
    }
 
578
    \endcode
 
579
 
 
580
    To restore the dock window positions and sizes (normally when the
 
581
    application is next started), do the following:
 
582
 
 
583
    \code
 
584
    QFile file(filename);
 
585
    if (file.open(IO_ReadOnly)) {
 
586
        QTextStream stream(&file);
 
587
        stream >> *mainWindow;
 
588
        file.close();
 
589
    }
 
590
    \endcode
 
591
 
 
592
    The QSettings class can be used in conjunction with the streaming
 
593
    operators to store the application's settings.
 
594
 
 
595
    Q3MainWindow's management of dock windows and toolbars is done
 
596
    transparently behind-the-scenes by Q3DockArea.
 
597
 
 
598
    For multi-document interfaces (MDI), use a QWorkspace as the
 
599
    central widget.
 
600
 
 
601
    Adding dock windows, e.g. toolbars, to Q3MainWindow's dock areas is
 
602
    straightforward. If the supplied dock areas are not sufficient for
 
603
    your application we suggest that you create a QWidget subclass and
 
604
    add your own dock areas (see \l Q3DockArea) to the subclass since
 
605
    Q3MainWindow provides functionality specific to the standard dock
 
606
    areas it provides.
 
607
 
 
608
    \sa Q3ToolBar Q3DockWindow QStatusBar QAction QMenuBar Q3PopupMenu QDialog
 
609
*/
 
610
 
 
611
/*!
 
612
    \enum Q3MainWindow::DockWindows
 
613
 
 
614
    Right-clicking a dock area will pop-up the dock window menu
 
615
    (createDockWindowMenu() is called automatically). When called in
 
616
    code you can specify what items should appear on the menu with
 
617
    this enum.
 
618
 
 
619
    \value OnlyToolBars The menu will list all the toolbars, but not
 
620
    any other dock windows.
 
621
 
 
622
    \value NoToolBars The menu will list dock windows but not
 
623
    toolbars.
 
624
 
 
625
    \value AllDockWindows The menu will list all toolbars and other
 
626
    dock windows. (This is the default.)
 
627
*/
 
628
 
 
629
/*!
 
630
    \fn void Q3MainWindow::addToolBar(Q3DockWindow *dockWindow,
 
631
    Qt::Dock position, bool newLine);
 
632
 
 
633
    Adds a new toolbar to the \a dockWindow. The toolbar is placed in
 
634
    the given \a position. If \a newLine is true the toolbar is put on
 
635
    a new line.
 
636
*/
 
637
 
 
638
/*!
 
639
    \fn void Q3MainWindow::addToolBar(Q3DockWindow *dockWindow, const
 
640
    QString &label, Qt::Dock position, bool newLine)
 
641
    \overload
 
642
 
 
643
    The toolbar has the caption \a label and is placed in the given \a
 
644
    position.
 
645
*/
 
646
 
 
647
/*!
 
648
    \fn void Q3MainWindow::moveToolBar(Q3DockWindow *dockWindow, Qt::Dock position);
 
649
 
 
650
    Moves the given \a dockWindow into the given \a position.
 
651
*/
 
652
 
 
653
/*!
 
654
    \fn void Q3MainWindow::moveToolBar(Q3DockWindow *dockWindow,
 
655
    Qt::Dock position, bool nl, int index, int extraOffset)
 
656
    \overload
 
657
 
 
658
    The \a dockWindow is made the \a{index}-th item in the toolbar,
 
659
    moved over by \a extraOffset. If \a nl is true, the dock window is
 
660
    put on a new line.
 
661
*/
 
662
 
 
663
/*!
 
664
    \fn void Q3MainWindow::removeToolBar(Q3DockWindow *dockWindow);
 
665
 
 
666
    Removes the toolbar from the given \a dockWindow.
 
667
*/
 
668
 
 
669
/*!
 
670
    \fn void Q3MainWindow::lineUpToolBars(bool keepNewLines);
 
671
 
 
672
    Lines up the toolbars. Line breaks are preserved if \a
 
673
    keepNewLines is true.
 
674
*/
 
675
 
 
676
/*!
 
677
    \fn void Q3MainWindow::toolBarPositionChanged(Q3ToolBar *toolbar);
 
678
 
 
679
    This signal is emitted when a \a toolbar is moved.
 
680
*/
 
681
 
 
682
/*!
 
683
    \fn bool Q3MainWindow::toolBarsMovable() const
 
684
*/
 
685
 
 
686
/*!
 
687
    \fn void Q3MainWindow::setToolBarsMovable(bool b)
 
688
    If \a b is true the tool bars can be moved.
 
689
*/
 
690
 
 
691
/*!
 
692
    Constructs an empty main window. The \a parent, \a name and widget
 
693
    flags \a f, are passed on to the QWidget constructor.
 
694
 
 
695
    By default, the widget flags are set to \c Qt::WType_TopLevel rather
 
696
    than 0 as they are with QWidget. If you don't want your
 
697
    Q3MainWindow to be a top level widget then you will need to set \a
 
698
    f to 0.
 
699
*/
 
700
 
 
701
Q3MainWindow::Q3MainWindow(QWidget * parent, const char * name, Qt::WFlags f)
 
702
    : QWidget(*new Q3MainWindowPrivate, parent, f)
 
703
{
 
704
    Q_D(Q3MainWindow);
 
705
    setObjectName(name);
 
706
    setAttribute(Qt::WA_PaintOnScreen); // disable double buffering
 
707
#ifdef Q_WS_MAC
 
708
    d->opaque = true;
 
709
#else
 
710
    d->opaque = false;
 
711
#endif
 
712
    installEventFilter(this);
 
713
    d->topDock = new Q3DockArea(Qt::Horizontal, Q3DockArea::Normal, this, "qt_top_dock");
 
714
    d->topDock->installEventFilter(this);
 
715
    d->bottomDock = new Q3DockArea(Qt::Horizontal, Q3DockArea::Reverse, this, "qt_bottom_dock");
 
716
    d->bottomDock->installEventFilter(this);
 
717
    d->leftDock = new Q3DockArea(Qt::Vertical, Q3DockArea::Normal, this, "qt_left_dock");
 
718
    d->leftDock->installEventFilter(this);
 
719
    d->rightDock = new Q3DockArea(Qt::Vertical, Q3DockArea::Reverse, this, "qt_right_dock");
 
720
    d->rightDock->installEventFilter(this);
 
721
    d->hideDock = new QHideDock(this);
 
722
}
 
723
 
 
724
 
 
725
/*!
 
726
    Destroys the object and frees any allocated resources.
 
727
*/
 
728
 
 
729
Q3MainWindow::~Q3MainWindow()
 
730
{
 
731
    delete layout();
 
732
}
 
733
 
 
734
#ifndef QT_NO_MENUBAR
 
735
/*!
 
736
    Sets this main window to use the menu bar \a newMenuBar.
 
737
 
 
738
    The existing menu bar (if any) is deleted along with its contents.
 
739
 
 
740
    \sa menuBar()
 
741
*/
 
742
 
 
743
void Q3MainWindow::setMenuBar(QMenuBar * newMenuBar)
 
744
{
 
745
    Q_D(Q3MainWindow);
 
746
    if (!newMenuBar)
 
747
        return;
 
748
    if (d->mb)
 
749
        delete d->mb;
 
750
    d->mb = newMenuBar;
 
751
    d->mb->installEventFilter(this);
 
752
    triggerLayout();
 
753
}
 
754
 
 
755
 
 
756
/*!
 
757
    Returns the menu bar for this window.
 
758
 
 
759
    If there isn't one, then menuBar() creates an empty menu bar.
 
760
 
 
761
    \sa statusBar()
 
762
*/
 
763
 
 
764
QMenuBar * Q3MainWindow::menuBar() const
 
765
{
 
766
    Q_D(const Q3MainWindow);
 
767
    if (d->mb)
 
768
        return d->mb;
 
769
 
 
770
    QObjectList l = queryList("QMenuBar", 0, false, false);
 
771
    QMenuBar * b;
 
772
    if (l.size()) {
 
773
        b = static_cast<QMenuBar *>(l.at(0));
 
774
    } else {
 
775
        b = new QMenuBar((Q3MainWindow *)this);
 
776
        b->setObjectName("automatic menu bar");
 
777
        b->show();
 
778
    }
 
779
    d->mb = b;
 
780
    d->mb->installEventFilter(const_cast<Q3MainWindow *>(this));
 
781
    ((Q3MainWindow *)this)->triggerLayout();
 
782
    return b;
 
783
}
 
784
#endif // QT_NO_MENUBAR
 
785
 
 
786
/*!
 
787
    Sets this main window to use the status bar \a newStatusBar.
 
788
 
 
789
    The existing status bar (if any) is deleted along with its
 
790
    contents.
 
791
 
 
792
    Note that \a newStatusBar \e must be a child of this main window,
 
793
    and that it is not automatically displayed. If you call this
 
794
    function after show(), you will probably also need to call
 
795
    newStatusBar->show().
 
796
 
 
797
    \sa setMenuBar() statusBar()
 
798
*/
 
799
 
 
800
void Q3MainWindow::setStatusBar(QStatusBar * newStatusBar)
 
801
{
 
802
    Q_D(Q3MainWindow);
 
803
    if (!newStatusBar || newStatusBar == d->sb)
 
804
        return;
 
805
    if (d->sb)
 
806
        delete d->sb;
 
807
    d->sb = newStatusBar;
 
808
#if 0
 
809
    // ### this code can cause unnecessary creation of a tool tip group
 
810
    connect(toolTipGroup(), SIGNAL(showTip(QString)),
 
811
             d->sb, SLOT(showMessage(QString)));
 
812
    connect(toolTipGroup(), SIGNAL(removeTip()),
 
813
             d->sb, SLOT(clearMessage()));
 
814
#endif
 
815
    d->sb->installEventFilter(this);
 
816
    triggerLayout();
 
817
}
 
818
 
 
819
 
 
820
/*!
 
821
    Returns this main window's status bar. If there isn't one,
 
822
    statusBar() creates an empty status bar, and if necessary a tool
 
823
    tip group too.
 
824
 
 
825
    \sa menuBar()
 
826
*/
 
827
 
 
828
QStatusBar * Q3MainWindow::statusBar() const
 
829
{
 
830
    Q_D(const Q3MainWindow);
 
831
    if (d->sb)
 
832
        return d->sb;
 
833
 
 
834
    QObjectList l = queryList("QStatusBar", 0, false, false);
 
835
    QStatusBar * s;
 
836
    if (l.size()) {
 
837
        s = (QStatusBar *)l.at(0);
 
838
    } else {
 
839
        s = new QStatusBar((Q3MainWindow *)this, "automatic status bar");
 
840
        s->show();
 
841
    }
 
842
    ((Q3MainWindow *)this)->setStatusBar(s);
 
843
    ((Q3MainWindow *)this)->triggerLayout(true);
 
844
    return s;
 
845
}
 
846
 
 
847
 
 
848
#if 0
 
849
/*!
 
850
    Sets this main window to use the tool tip group \a
 
851
    newToolTipGroup.
 
852
 
 
853
    The existing tool tip group (if any) is deleted along with its
 
854
    contents. All the tool tips connected to it lose the ability to
 
855
    display the group texts.
 
856
 
 
857
    \sa menuBar()
 
858
*/
 
859
 
 
860
void Q3MainWindow::setToolTipGroup(QToolTipGroup * newToolTipGroup)
 
861
{
 
862
    Q_D(Q3MainWindow);
 
863
    if (!newToolTipGroup || newToolTipGroup == d->ttg)
 
864
        return;
 
865
    if (d->ttg)
 
866
        delete d->ttg;
 
867
    d->ttg = newToolTipGroup;
 
868
 
 
869
    connect(toolTipGroup(), SIGNAL(showTip(QString)),
 
870
            statusBar(), SLOT(showMessage(QString)));
 
871
    connect(toolTipGroup(), SIGNAL(removeTip()),
 
872
            statusBar(), SLOT(clearMessage()));
 
873
}
 
874
 
 
875
 
 
876
/*!
 
877
    Returns this main window's tool tip group. If there isn't one,
 
878
    toolTipGroup() creates an empty tool tip group.
 
879
 
 
880
    \sa menuBar() statusBar()
 
881
*/
 
882
QToolTipGroup * Q3MainWindow::toolTipGroup() const
 
883
{
 
884
    Q_D(const Q3MainWindow);
 
885
    if (d->ttg)
 
886
        return d->ttg;
 
887
 
 
888
    QToolTipGroup * t = new QToolTipGroup((Q3MainWindow*)this,
 
889
                                           "automatic tool tip group");
 
890
    ((Q3MainWindowPrivate*)d)->ttg = t;
 
891
    return t;
 
892
}
 
893
#endif
 
894
 
 
895
 
 
896
/*!
 
897
    If \a enable is true then users can dock windows in the \a dock
 
898
    area. If \a enable is false users cannot dock windows in the \a
 
899
    dock dock area.
 
900
 
 
901
    Users can dock (drag) dock windows into any enabled dock area.
 
902
*/
 
903
 
 
904
void Q3MainWindow::setDockEnabled(Qt::Dock dock, bool enable)
 
905
{
 
906
    d_func()->docks.insert(dock, enable);
 
907
}
 
908
 
 
909
 
 
910
/*!
 
911
    Returns true if the \a dock dock area is enabled, i.e. it can
 
912
    accept user dragged dock windows; otherwise returns false.
 
913
 
 
914
    \sa setDockEnabled()
 
915
*/
 
916
 
 
917
bool Q3MainWindow::isDockEnabled(Qt::Dock dock) const
 
918
{
 
919
    return d_func()->docks[dock];
 
920
}
 
921
 
 
922
/*!
 
923
    \overload
 
924
 
 
925
    Returns true if dock area \a area is enabled, i.e. it can accept
 
926
    user dragged dock windows; otherwise returns false.
 
927
 
 
928
    \sa setDockEnabled()
 
929
*/
 
930
 
 
931
bool Q3MainWindow::isDockEnabled(Q3DockArea *area) const
 
932
{
 
933
    Q_D(const Q3MainWindow);
 
934
    if (area == d->leftDock)
 
935
        return d->docks[Qt::DockLeft];
 
936
    if (area == d->rightDock)
 
937
        return d->docks[Qt::DockRight];
 
938
    if (area == d->topDock)
 
939
        return d->docks[Qt::DockTop];
 
940
    if (area == d->bottomDock)
 
941
        return d->docks[Qt::DockBottom];
 
942
    return false;
 
943
}
 
944
 
 
945
/*!
 
946
    \overload
 
947
 
 
948
    If \a enable is true then users can dock the \a dw dock window in
 
949
    the \a dock area. If \a enable is false users cannot dock the \a
 
950
    dw dock window in the \a dock area.
 
951
 
 
952
    In general users can dock (drag) dock windows into any enabled
 
953
    dock area. Using this function particular dock areas can be
 
954
    enabled (or disabled) as docking points for particular dock
 
955
    windows.
 
956
*/
 
957
 
 
958
 
 
959
void Q3MainWindow::setDockEnabled(Q3DockWindow *dw, Qt::Dock dock, bool enable)
 
960
{
 
961
    Q_D(Q3MainWindow);
 
962
    if (d->dockWindows.contains(dw)) {
 
963
        d->dockWindows.append(dw);
 
964
        connect(dw, SIGNAL(placeChanged(Q3DockWindow::Place)),
 
965
                 this, SLOT(slotPlaceChanged()));
 
966
    }
 
967
    QString s;
 
968
    s.sprintf("%p_%d", (void*)dw, (int)dock);
 
969
    if (enable)
 
970
        d->disabledDocks.removeAll(s);
 
971
    else if (!d->disabledDocks.contains(s))
 
972
        d->disabledDocks << s;
 
973
    switch (dock) {
 
974
        case Qt::DockTop:
 
975
            topDock()->setAcceptDockWindow(dw, enable);
 
976
            break;
 
977
        case Qt::DockLeft:
 
978
            leftDock()->setAcceptDockWindow(dw, enable);
 
979
            break;
 
980
        case Qt::DockRight:
 
981
            rightDock()->setAcceptDockWindow(dw, enable);
 
982
            break;
 
983
        case Qt::DockBottom:
 
984
            bottomDock()->setAcceptDockWindow(dw, enable);
 
985
            break;
 
986
        default:
 
987
            break;
 
988
    }
 
989
}
 
990
 
 
991
/*!
 
992
    \overload
 
993
 
 
994
    Returns true if dock area \a area is enabled for the dock window
 
995
    \a dw; otherwise returns false.
 
996
 
 
997
    \sa setDockEnabled()
 
998
*/
 
999
 
 
1000
bool Q3MainWindow::isDockEnabled(Q3DockWindow *dw, Q3DockArea *area) const
 
1001
{
 
1002
    Q_D(const Q3MainWindow);
 
1003
    if (!isDockEnabled(area))
 
1004
        return false;
 
1005
    Qt::Dock dock;
 
1006
    if (area == d->leftDock)
 
1007
        dock = Qt::DockLeft;
 
1008
    else if (area == d->rightDock)
 
1009
        dock = Qt::DockRight;
 
1010
    else if (area == d->topDock)
 
1011
        dock = Qt::DockTop;
 
1012
    else if (area == d->bottomDock)
 
1013
        dock = Qt::DockBottom;
 
1014
    else
 
1015
        return false;
 
1016
    return isDockEnabled(dw, dock);
 
1017
}
 
1018
 
 
1019
/*!
 
1020
    \overload
 
1021
 
 
1022
    Returns true if dock area \a dock is enabled for the dock window
 
1023
    \a tb; otherwise returns false.
 
1024
 
 
1025
    \sa setDockEnabled()
 
1026
*/
 
1027
 
 
1028
bool Q3MainWindow::isDockEnabled(Q3DockWindow *tb, Qt::Dock dock) const
 
1029
{
 
1030
    if (!isDockEnabled(dock))
 
1031
        return false;
 
1032
    QString s;
 
1033
    s.sprintf("%p_%d", (void*)tb, (int)dock);
 
1034
    return !d_func()->disabledDocks.contains(s);
 
1035
}
 
1036
 
 
1037
 
 
1038
 
 
1039
/*!
 
1040
    Adds \a dockWindow to the \a edge dock area.
 
1041
 
 
1042
    If \a newLine is false (the default) then the \a dockWindow is
 
1043
    added at the end of the \a edge. For vertical edges the end is at
 
1044
    the bottom, for horizontal edges (including \c Minimized) the end
 
1045
    is at the right. If \a newLine is true a new line of dock windows
 
1046
    is started with \a dockWindow as the first (left-most and
 
1047
    top-most) dock window.
 
1048
 
 
1049
    If \a dockWindow is managed by another main window, it is first
 
1050
    removed from that window.
 
1051
*/
 
1052
 
 
1053
void Q3MainWindow::addDockWindow(Q3DockWindow *dockWindow,
 
1054
                              Qt::Dock edge, bool newLine)
 
1055
{
 
1056
    Q_D(Q3MainWindow);
 
1057
#ifdef Q_WS_MAC
 
1058
    extern WindowPtr qt_mac_window_for(const QWidget*); //qwidget_mac.cpp
 
1059
    if(isWindow() && edge == Qt::DockTop)
 
1060
        ChangeWindowAttributes(qt_mac_window_for(this), kWindowToolbarButtonAttribute, 0);
 
1061
#endif
 
1062
    moveDockWindow(dockWindow, edge);
 
1063
    dockWindow->setNewLine(newLine);
 
1064
    if (!d->dockWindows.contains(dockWindow)) {
 
1065
        d->dockWindows.append(dockWindow);
 
1066
        connect(dockWindow, SIGNAL(placeChanged(Q3DockWindow::Place)),
 
1067
                 this, SLOT(slotPlaceChanged()));
 
1068
        dockWindow->installEventFilter(this);
 
1069
    }
 
1070
    dockWindow->setOpaqueMoving(d->opaque);
 
1071
}
 
1072
 
 
1073
 
 
1074
/*!
 
1075
    \overload
 
1076
 
 
1077
    Adds \a dockWindow to the dock area with label \a label.
 
1078
 
 
1079
    If \a newLine is false (the default) the \a dockWindow is added at
 
1080
    the end of the \a edge. For vertical edges the end is at the
 
1081
    bottom, for horizontal edges (including \c Minimized) the end is
 
1082
    at the right. If \a newLine is true a new line of dock windows is
 
1083
    started with \a dockWindow as the first (left-most and top-most)
 
1084
    dock window.
 
1085
 
 
1086
    If \a dockWindow is managed by another main window, it is first
 
1087
    removed from that window.
 
1088
*/
 
1089
 
 
1090
void Q3MainWindow::addDockWindow(Q3DockWindow * dockWindow, const QString &label,
 
1091
                              Qt::Dock edge, bool newLine)
 
1092
{
 
1093
    addDockWindow(dockWindow, edge, newLine);
 
1094
#ifndef QT_NO_TOOLBAR
 
1095
    Q3ToolBar *tb = qobject_cast<Q3ToolBar*>(dockWindow);
 
1096
    if (tb)
 
1097
        tb->setLabel(label);
 
1098
#endif
 
1099
}
 
1100
 
 
1101
/*!
 
1102
    Moves \a dockWindow to the end of the \a edge.
 
1103
 
 
1104
    For vertical edges the end is at the bottom, for horizontal edges
 
1105
    (including \c Minimized) the end is at the right.
 
1106
 
 
1107
    If \a dockWindow is managed by another main window, it is first
 
1108
    removed from that window.
 
1109
*/
 
1110
 
 
1111
void Q3MainWindow::moveDockWindow(Q3DockWindow * dockWindow, Qt::Dock edge)
 
1112
{
 
1113
    Q_D(Q3MainWindow);
 
1114
    Qt::Orientation oo = dockWindow->orientation();
 
1115
    switch (edge) {
 
1116
    case Qt::DockTop:
 
1117
        if (dockWindow->area() != d->topDock)
 
1118
            dockWindow->removeFromDock(false);
 
1119
        d->topDock->moveDockWindow(dockWindow);
 
1120
        emit dockWindowPositionChanged(dockWindow);
 
1121
        break;
 
1122
    case Qt::DockBottom:
 
1123
        if (dockWindow->area() != d->bottomDock)
 
1124
            dockWindow->removeFromDock(false);
 
1125
        d->bottomDock->moveDockWindow(dockWindow);
 
1126
        emit dockWindowPositionChanged(dockWindow);
 
1127
        break;
 
1128
    case Qt::DockRight:
 
1129
        if (dockWindow->area() != d->rightDock)
 
1130
            dockWindow->removeFromDock(false);
 
1131
        d->rightDock->moveDockWindow(dockWindow);
 
1132
        emit dockWindowPositionChanged(dockWindow);
 
1133
        break;
 
1134
    case Qt::DockLeft:
 
1135
        if (dockWindow->area() != d->leftDock)
 
1136
            dockWindow->removeFromDock(false);
 
1137
        d->leftDock->moveDockWindow(dockWindow);
 
1138
        emit dockWindowPositionChanged(dockWindow);
 
1139
        break;
 
1140
    case Qt::DockTornOff:
 
1141
        dockWindow->undock();
 
1142
        break;
 
1143
    case Qt::DockMinimized:
 
1144
        dockWindow->undock(d->hideDock);
 
1145
        break;
 
1146
    case Qt::DockUnmanaged:
 
1147
        break;
 
1148
    }
 
1149
 
 
1150
    if (oo != dockWindow->orientation())
 
1151
        dockWindow->setOrientation(dockWindow->orientation());
 
1152
}
 
1153
 
 
1154
/*!
 
1155
    \overload
 
1156
 
 
1157
    Moves \a dockWindow to position \a index within the \a edge dock
 
1158
    area.
 
1159
 
 
1160
    Any dock windows with positions \a index or higher have their
 
1161
    position number incremented and any of these on the same line are
 
1162
    moved right (down for vertical dock areas) to make room.
 
1163
 
 
1164
    If \a nl is true, a new dock window line is created below the line
 
1165
    in which the moved dock window appears and the moved dock window,
 
1166
    with any others with higher positions on the same line, is moved
 
1167
    to this new line.
 
1168
 
 
1169
    The \a extraOffset is the space to put between the left side of
 
1170
    the dock area (top side for vertical dock areas) and the dock
 
1171
    window. (This is mostly used for restoring dock windows to the
 
1172
    positions the user has dragged them to.)
 
1173
 
 
1174
    If \a dockWindow is managed by another main window, it is first
 
1175
    removed from that window.
 
1176
*/
 
1177
 
 
1178
void Q3MainWindow::moveDockWindow(Q3DockWindow * dockWindow, Qt::Dock edge, bool nl, int index, int extraOffset)
 
1179
{
 
1180
    Q_D(Q3MainWindow);
 
1181
    Qt::Orientation oo = dockWindow->orientation();
 
1182
 
 
1183
    dockWindow->setNewLine(nl);
 
1184
    dockWindow->setOffset(extraOffset);
 
1185
    switch (edge) {
 
1186
    case Qt::DockTop:
 
1187
        if (dockWindow->area() != d->topDock)
 
1188
            dockWindow->removeFromDock(false);
 
1189
        d->topDock->moveDockWindow(dockWindow, index);
 
1190
        break;
 
1191
    case Qt::DockBottom:
 
1192
        if (dockWindow->area() != d->bottomDock)
 
1193
            dockWindow->removeFromDock(false);
 
1194
        d->bottomDock->moveDockWindow(dockWindow, index);
 
1195
        break;
 
1196
    case Qt::DockRight:
 
1197
        if (dockWindow->area() != d->rightDock)
 
1198
            dockWindow->removeFromDock(false);
 
1199
        d->rightDock->moveDockWindow(dockWindow, index);
 
1200
        break;
 
1201
    case Qt::DockLeft:
 
1202
        if (dockWindow->area() != d->leftDock)
 
1203
            dockWindow->removeFromDock(false);
 
1204
        d->leftDock->moveDockWindow(dockWindow, index);
 
1205
        break;
 
1206
    case Qt::DockTornOff:
 
1207
        dockWindow->undock();
 
1208
        break;
 
1209
    case Qt::DockMinimized:
 
1210
        dockWindow->undock(d->hideDock);
 
1211
        break;
 
1212
    case Qt::DockUnmanaged:
 
1213
        break;
 
1214
    }
 
1215
 
 
1216
    if (oo != dockWindow->orientation())
 
1217
        dockWindow->setOrientation(dockWindow->orientation());
 
1218
}
 
1219
 
 
1220
/*!
 
1221
    Removes \a dockWindow from the main window's docking area,
 
1222
    provided \a dockWindow is non-null and managed by this main
 
1223
    window.
 
1224
*/
 
1225
 
 
1226
void Q3MainWindow::removeDockWindow(Q3DockWindow * dockWindow)
 
1227
{
 
1228
    Q_D(Q3MainWindow);
 
1229
 
 
1230
#ifdef Q_WS_MAC
 
1231
    extern WindowPtr qt_mac_window_for(const QWidget*); //qwidget_mac.cpp
 
1232
    if(isWindow() && dockWindow->area() == topDock() && !dockWindows(Qt::DockTop).count())
 
1233
        ChangeWindowAttributes(qt_mac_window_for(this), 0, kWindowToolbarButtonAttribute);
 
1234
#endif
 
1235
 
 
1236
    dockWindow->hide();
 
1237
    d->dockWindows.removeAll(dockWindow);
 
1238
    disconnect(dockWindow, SIGNAL(placeChanged(Q3DockWindow::Place)),
 
1239
                this, SLOT(slotPlaceChanged()));
 
1240
    dockWindow->removeEventFilter(this);
 
1241
}
 
1242
 
 
1243
/*!
 
1244
    Sets up the geometry management of the window. It is called
 
1245
    automatically when needed, so you shouldn't need to call it.
 
1246
*/
 
1247
 
 
1248
void Q3MainWindow::setUpLayout()
 
1249
{
 
1250
    Q_D(Q3MainWindow);
 
1251
#ifndef QT_NO_MENUBAR
 
1252
    if (!d->mb) {
 
1253
        // slightly evil hack here.  reconsider this
 
1254
        QObjectList l = queryList("QMenuBar", 0, false, false);
 
1255
        if (l.size())
 
1256
            d->mb = menuBar();
 
1257
    }
 
1258
#endif
 
1259
    if (!d->sb) {
 
1260
        // as above.
 
1261
        QObjectList l = queryList("QStatusBar", 0, false, false);
 
1262
        if (l.size())
 
1263
            d->sb = statusBar();
 
1264
    }
 
1265
 
 
1266
    if (!d->tll) {
 
1267
        d->tll = new QBoxLayout(this, QBoxLayout::Down);
 
1268
        d->tll->setResizeMode(minimumSize().isNull() ? QLayout::Minimum : QLayout::FreeResize);
 
1269
    } else {
 
1270
        d->tll->setMenuBar(0);
 
1271
        QLayoutItem *item;
 
1272
        while ((item = d->tll->takeAt(0)))
 
1273
            delete item;
 
1274
    }
 
1275
 
 
1276
#ifndef QT_NO_MENUBAR
 
1277
    if (d->mb && d->mb->isVisibleTo(this)) {
 
1278
        d->tll->setMenuBar(d->mb);
 
1279
        if (style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this))
 
1280
            d->tll->addSpacing(d->movable ? 1 : 2);
 
1281
    }
 
1282
#endif
 
1283
 
 
1284
    d->tll->addWidget(d->hideDock);
 
1285
    if(d->topDock->parentWidget() == this)
 
1286
        d->tll->addWidget(d->topDock);
 
1287
 
 
1288
    Q3MainWindowLayout *mwl = new Q3MainWindowLayout(this, d->tll);
 
1289
    d->tll->setStretchFactor(mwl, 1);
 
1290
 
 
1291
    if(d->leftDock->parentWidget() == this)
 
1292
        mwl->setLeftDock(d->leftDock);
 
1293
    if (centralWidget())
 
1294
        mwl->setCentralWidget(centralWidget());
 
1295
    if(d->rightDock->parentWidget() == this)
 
1296
        mwl->setRightDock(d->rightDock);
 
1297
    d->mwl = mwl;
 
1298
 
 
1299
    if(d->bottomDock->parentWidget() == this)
 
1300
        d->tll->addWidget(d->bottomDock);
 
1301
 
 
1302
    if (d->sb && d->sb->parentWidget() == this) {
 
1303
        d->tll->addWidget(d->sb, 0);
 
1304
        // make the sb stay on top of tool bars if there isn't enough space
 
1305
        d->sb->raise();
 
1306
    }
 
1307
}
 
1308
 
 
1309
/*! \reimp */
 
1310
void Q3MainWindow::setVisible(bool visible)
 
1311
{
 
1312
    Q_D(Q3MainWindow);
 
1313
    if (visible) {
 
1314
        if (!d->tll)
 
1315
            setUpLayout();
 
1316
 
 
1317
        // show all floating dock windows not explicitly hidden
 
1318
        if (!isVisible()) {
 
1319
            for (int i = 0; i < d->dockWindows.size(); ++i) {
 
1320
                Q3DockWindow *dw = d->dockWindows.at(i);
 
1321
                if (dw->isWindow() && !dw->isVisible() && !dw->testAttribute(Qt::WA_WState_Hidden)) {
 
1322
                    reinterpret_cast<Q3MainWindow *>(dw)->setAttribute(Qt::WA_WState_Hidden);
 
1323
                    dw->show();
 
1324
                }
 
1325
            }
 
1326
        }
 
1327
    } else if (isVisible()) {
 
1328
        for (int i = 0; i < d->dockWindows.size(); ++i) {
 
1329
            Q3DockWindow *dw = d->dockWindows.at(i);
 
1330
            if (dw->isWindow() && dw->isVisible()) {
 
1331
                dw->hide(); // implicit hide, so clear forcehide
 
1332
                reinterpret_cast<Q3MainWindow *>(dw)->setAttribute(Qt::WA_WState_Hidden, false);
 
1333
            }
 
1334
        }
 
1335
    }
 
1336
    QWidget::setVisible(visible);
 
1337
}
 
1338
 
 
1339
 
 
1340
/*!  \reimp */
 
1341
QSize Q3MainWindow::sizeHint() const
 
1342
{
 
1343
    Q3MainWindow* that = (Q3MainWindow*) this;
 
1344
    // Workaround: because d->tll get's deleted in
 
1345
    // totalSizeHint->polish->sendPostedEvents->childEvent->triggerLayout
 
1346
    // [eg. canvas example on Qt/Embedded]
 
1347
    QApplication::sendPostedEvents(that, QEvent::ChildInserted);
 
1348
    if (!that->d_func()->tll)
 
1349
        that->setUpLayout();
 
1350
    return that->d_func()->tll->totalSizeHint();
 
1351
}
 
1352
 
 
1353
/*!  \reimp */
 
1354
QSize Q3MainWindow::minimumSizeHint() const
 
1355
{
 
1356
    Q_D(const Q3MainWindow);
 
1357
    if (!d->tll) {
 
1358
        Q3MainWindow* that = (Q3MainWindow*) this;
 
1359
        that->setUpLayout();
 
1360
    }
 
1361
    return d->tll->totalMinimumSize();
 
1362
}
 
1363
 
 
1364
/*!
 
1365
    Sets the central widget for this main window to \a w.
 
1366
 
 
1367
    The central widget is surrounded by the left, top, right and
 
1368
    bottom dock areas. The menu bar is above the top dock area.
 
1369
 
 
1370
    \sa centralWidget()
 
1371
*/
 
1372
 
 
1373
void Q3MainWindow::setCentralWidget(QWidget * w)
 
1374
{
 
1375
    Q_D(Q3MainWindow);
 
1376
    if (d->mc)
 
1377
        d->mc->removeEventFilter(this);
 
1378
    d->mc = w;
 
1379
    if (d->mc)
 
1380
        d->mc->installEventFilter(this);
 
1381
    triggerLayout();
 
1382
}
 
1383
 
 
1384
 
 
1385
/*!
 
1386
    Returns a pointer to the main window's central widget.
 
1387
 
 
1388
    The central widget is surrounded by the left, top, right and
 
1389
    bottom dock areas. The menu bar is above the top dock area.
 
1390
 
 
1391
    \sa setCentralWidget()
 
1392
*/
 
1393
 
 
1394
QWidget * Q3MainWindow::centralWidget() const
 
1395
{
 
1396
    return d_func()->mc;
 
1397
}
 
1398
 
 
1399
 
 
1400
/*! \reimp */
 
1401
 
 
1402
void Q3MainWindow::paintEvent(QPaintEvent *)
 
1403
{
 
1404
    Q_D(Q3MainWindow);
 
1405
    if (d->mb &&
 
1406
        style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this)) {
 
1407
        QPainter p(this);
 
1408
        int y = d->mb->height() + 1;
 
1409
        QStyleOption opt(0, QStyleOption::SO_Default);
 
1410
        opt.rect.setRect(0, y, width(), 1);
 
1411
        opt.palette = palette();
 
1412
        opt.state = QStyle::State_Sunken;
 
1413
        style()->drawPrimitive(QStyle::PE_Q3Separator, &opt, &p, this);
 
1414
    }
 
1415
}
 
1416
 
 
1417
 
 
1418
bool Q3MainWindow::dockMainWindow(QObject *dock) const
 
1419
{
 
1420
    while (dock) {
 
1421
        if (dock->parent() &&
 
1422
            dock->parent() == const_cast<Q3MainWindow*>(this))
 
1423
            return true;
 
1424
        if (qobject_cast<Q3MainWindow*>(dock->parent()))
 
1425
            return false;
 
1426
        dock = dock->parent();
 
1427
    }
 
1428
    return false;
 
1429
}
 
1430
 
 
1431
/*!
 
1432
    \reimp
 
1433
*/
 
1434
 
 
1435
bool Q3MainWindow::eventFilter(QObject* o, QEvent *e)
 
1436
{
 
1437
    Q_D(Q3MainWindow);
 
1438
    if (e->type() == QEvent::Show && o == this) {
 
1439
        if (!d->tll)
 
1440
            setUpLayout();
 
1441
        d->tll->activate();
 
1442
    } else if (e->type() == QEvent::ContextMenu && d->dockMenu &&
 
1443
                (qobject_cast<Q3DockArea*>(o) && dockMainWindow(o) || o == d->hideDock || o == d->mb)) {
 
1444
        if (showDockMenu(((QMouseEvent*)e)->globalPos())) {
 
1445
            ((QContextMenuEvent*)e)->accept();
 
1446
            return true;
 
1447
        }
 
1448
    }
 
1449
 
 
1450
    return QWidget::eventFilter(o, e);
 
1451
}
 
1452
 
 
1453
 
 
1454
/*!
 
1455
    Monitors events, received in \a e, to ensure the layout is updated.
 
1456
*/
 
1457
void Q3MainWindow::childEvent(QChildEvent* e)
 
1458
{
 
1459
    Q_D(Q3MainWindow);
 
1460
    if (e->type() == QEvent::ChildRemoved) {
 
1461
        if (e->child() == 0 ||
 
1462
             !e->child()->isWidgetType() ||
 
1463
             ((QWidget*)e->child())->isWindow()) {
 
1464
            // nothing
 
1465
        } else if (e->child() == d->sb) {
 
1466
            d->sb = 0;
 
1467
            triggerLayout();
 
1468
        } else if (e->child() == d->mb) {
 
1469
            d->mb = 0;
 
1470
            triggerLayout();
 
1471
        } else if (e->child() == d->mc) {
 
1472
            d->mc = 0;
 
1473
            d->mwl->setCentralWidget(0);
 
1474
            triggerLayout();
 
1475
        } else if (qobject_cast<Q3DockWindow*>(e->child())) {
 
1476
            removeDockWindow((Q3DockWindow *)(e->child()));
 
1477
            d->appropriate.remove((Q3DockWindow*)e->child());
 
1478
            triggerLayout();
 
1479
        }
 
1480
    } else if (e->type() == QEvent::ChildInserted && !d->sb) {
 
1481
        d->sb = qobject_cast<QStatusBar*>(e->child());
 
1482
        if (d->sb) {
 
1483
            if (d->tll) {
 
1484
                if (!d->tll->findWidget(d->sb))
 
1485
                    d->tll->addWidget(d->sb);
 
1486
            } else {
 
1487
                triggerLayout();
 
1488
            }
 
1489
        }
 
1490
    }
 
1491
}
 
1492
 
 
1493
/*!
 
1494
    \reimp
 
1495
*/
 
1496
 
 
1497
bool Q3MainWindow::event(QEvent * e)
 
1498
{
 
1499
    Q_D(Q3MainWindow);
 
1500
    if (e->type() == QEvent::StatusTip) {
 
1501
        if (d->sb) {
 
1502
            d->sb->showMessage(static_cast<QStatusTipEvent*>(e)->tip());
 
1503
            return true;
 
1504
        }
 
1505
    }
 
1506
    if (e->type() == QEvent::ToolBarChange) {
 
1507
        // Keep compatibility with the Qt 3 main window, use the real main window
 
1508
        // or reimplement if you want proper handling.
 
1509
        int deltaH = 0;
 
1510
        Q3DockArea *area = topDock();
 
1511
        if (area->width() >= area->height()) {
 
1512
            deltaH = area->sizeHint().height();
 
1513
            if (!area->isVisible()) {
 
1514
                area->show();
 
1515
            } else {
 
1516
                area->hide();
 
1517
                deltaH = -deltaH;
 
1518
            }
 
1519
        }
 
1520
 
 
1521
        if (deltaH) {
 
1522
            QApplication::sendPostedEvents(this, QEvent::LayoutRequest);
 
1523
            resize(width(), height() + deltaH);
 
1524
        }
 
1525
        return true;
 
1526
    }
 
1527
    if (e->type() == QEvent::ChildRemoved && ((QChildEvent*)e)->child() == d->mc) {
 
1528
        d->mc->removeEventFilter(this);
 
1529
        d->mc = 0;
 
1530
        d->mwl->setCentralWidget(0);
 
1531
    }
 
1532
 
 
1533
    return QWidget::event(e);
 
1534
}
 
1535
 
 
1536
 
 
1537
/*!
 
1538
    \property Q3MainWindow::usesBigPixmaps
 
1539
    \brief whether big pixmaps are enabled
 
1540
 
 
1541
    If false (the default), the tool buttons will use small pixmaps;
 
1542
    otherwise big pixmaps will be used.
 
1543
 
 
1544
    Tool buttons and other widgets that wish to respond to this
 
1545
    setting are responsible for reading the correct state on startup,
 
1546
    and for connecting to the main window's widget's
 
1547
    pixmapSizeChanged() signal.
 
1548
*/
 
1549
 
 
1550
bool Q3MainWindow::usesBigPixmaps() const
 
1551
{
 
1552
    return d_func()->ubp;
 
1553
}
 
1554
 
 
1555
void Q3MainWindow::setUsesBigPixmaps(bool enable)
 
1556
{
 
1557
    Q_D(Q3MainWindow);
 
1558
    if (enable == (bool)d->ubp)
 
1559
        return;
 
1560
 
 
1561
    d->ubp = enable;
 
1562
    emit pixmapSizeChanged(enable);
 
1563
 
 
1564
    QObjectList l = queryList("QLayout");
 
1565
    for (int i = 0; i < l.size(); ++i)
 
1566
            static_cast<QLayout *>(l.at(i))->activate();
 
1567
}
 
1568
 
 
1569
/*!
 
1570
    \property Q3MainWindow::usesTextLabel
 
1571
    \brief whether text labels for toolbar buttons are enabled
 
1572
 
 
1573
    If disabled (the default), the tool buttons will not use text
 
1574
    labels. If enabled, text labels will be used.
 
1575
 
 
1576
    Tool buttons and other widgets that wish to respond to this
 
1577
    setting are responsible for reading the correct state on startup,
 
1578
    and for connecting to the main window's widget's
 
1579
    usesTextLabelChanged() signal.
 
1580
 
 
1581
    \sa QToolButton::setUsesTextLabel()
 
1582
*/
 
1583
 
 
1584
bool Q3MainWindow::usesTextLabel() const
 
1585
{
 
1586
    return d_func()->utl;
 
1587
}
 
1588
 
 
1589
 
 
1590
void Q3MainWindow::setUsesTextLabel(bool enable)
 
1591
{
 
1592
    Q_D(Q3MainWindow);
 
1593
    if (enable == (bool)d->utl)
 
1594
        return;
 
1595
 
 
1596
    d->utl = enable;
 
1597
    emit usesTextLabelChanged(enable);
 
1598
 
 
1599
    QObjectList l = queryList("QLayout");
 
1600
    for (int i = 0; i < l.size(); ++i)
 
1601
            static_cast<QLayout *>(l.at(i))->activate();
 
1602
}
 
1603
 
 
1604
 
 
1605
/*!
 
1606
    \fn void Q3MainWindow::pixmapSizeChanged(bool b)
 
1607
 
 
1608
    This signal is emitted whenever the setUsesBigPixmaps() is called
 
1609
    with a value different to the current setting. The new value is
 
1610
    passed in \a b. All widgets that should respond to such changes,
 
1611
    e.g. toolbar buttons, must connect to this signal.
 
1612
*/
 
1613
 
 
1614
/*!
 
1615
    \fn void Q3MainWindow::usesTextLabelChanged(bool b)
 
1616
 
 
1617
    This signal is emitted whenever the setUsesTextLabel() is called
 
1618
    with a value different to the current setting. The new value is
 
1619
    passed in \a b. All widgets that should respond to such changes,
 
1620
    e.g. toolbar buttons, must connect to this signal.
 
1621
*/
 
1622
 
 
1623
/*!
 
1624
    \fn void Q3MainWindow::dockWindowPositionChanged(Q3DockWindow *dockWindow)
 
1625
 
 
1626
    This signal is emitted when the \a dockWindow has changed its
 
1627
    position. A change in position occurs when a dock window is moved
 
1628
    within its dock area or moved to another dock area (including the
 
1629
    \c Minimized and \c TearOff dock areas).
 
1630
 
 
1631
    \sa getLocation()
 
1632
*/
 
1633
 
 
1634
void Q3MainWindow::setRightJustification(bool enable)
 
1635
{
 
1636
    Q_D(Q3MainWindow);
 
1637
    if (enable == (bool)d->justify)
 
1638
        return;
 
1639
    d->justify = enable;
 
1640
    triggerLayout(true);
 
1641
}
 
1642
 
 
1643
 
 
1644
/*!
 
1645
    \property Q3MainWindow::rightJustification
 
1646
    \brief whether the main window right-justifies its dock windows
 
1647
 
 
1648
    If disabled (the default), stretchable dock windows are expanded,
 
1649
    and non-stretchable dock windows are given the minimum space they
 
1650
    need. Since most dock windows are not stretchable, this usually
 
1651
    results in an unjustified right edge (or unjustified bottom edge
 
1652
    for a vertical dock area). If enabled, the main window will
 
1653
    right-justify its dock windows.
 
1654
 
 
1655
    \sa Q3DockWindow::setVerticalStretchable(), Q3DockWindow::setHorizontalStretchable()
 
1656
*/
 
1657
 
 
1658
bool Q3MainWindow::rightJustification() const
 
1659
{
 
1660
    return d_func()->justify;
 
1661
}
 
1662
 
 
1663
/*! \internal
 
1664
 */
 
1665
 
 
1666
void Q3MainWindow::triggerLayout(bool deleteLayout)
 
1667
{
 
1668
    Q_D(Q3MainWindow);
 
1669
    if (deleteLayout || !d->tll)
 
1670
        setUpLayout();
 
1671
    QApplication::postEvent(this, new QEvent(QEvent::LayoutHint));
 
1672
}
 
1673
 
 
1674
/*!
 
1675
    Enters 'What's This?' mode and returns immediately.
 
1676
 
 
1677
    This is the same as QWhatsThis::enterWhatsThisMode(), but
 
1678
    implemented as a main window object's slot. This way it can easily
 
1679
    be used for popup menus, for example:
 
1680
 
 
1681
    \code
 
1682
    Q3PopupMenu * help = new Q3PopupMenu(this);
 
1683
    help->insertItem("What's &This", this , SLOT(enterWhatsThis()), Qt::SHIFT+Qt::Key_F1);
 
1684
    \endcode
 
1685
 
 
1686
    \sa Q3WhatsThis::enterWhatsThisMode()
 
1687
*/
 
1688
void Q3MainWindow::whatsThis()
 
1689
{
 
1690
#ifndef QT_NO_WHATSTHIS
 
1691
    QWhatsThis::enterWhatsThisMode();
 
1692
#endif
 
1693
}
 
1694
 
 
1695
/*!
 
1696
    Finds the location of the dock window \a dw.
 
1697
 
 
1698
    If the \a dw dock window is found in the main window the function
 
1699
    returns true and populates the \a dock variable with the dw's dock
 
1700
    area and the \a index with the dw's position within the dock area.
 
1701
    It also sets \a nl to true if the \a dw begins a new line
 
1702
    (otherwise false), and \a extraOffset with the dock window's offset.
 
1703
 
 
1704
    If the \a dw dock window is not found then the function returns
 
1705
    false and the state of \a dock, \a index, \a nl and \a extraOffset
 
1706
    is undefined.
 
1707
 
 
1708
    If you want to save and restore dock window positions then use
 
1709
    operator>>() and operator<<().
 
1710
*/
 
1711
 
 
1712
bool Q3MainWindow::getLocation(Q3DockWindow *dw, Qt::Dock &dock, int &index, bool &nl, int &extraOffset) const
 
1713
{
 
1714
    Q_D(const Q3MainWindow);
 
1715
    dock = Qt::DockTornOff;
 
1716
    if (d->topDock->hasDockWindow(dw, &index))
 
1717
        dock = Qt::DockTop;
 
1718
    else if (d->bottomDock->hasDockWindow(dw, &index))
 
1719
        dock = Qt::DockBottom;
 
1720
    else if (d->leftDock->hasDockWindow(dw, &index))
 
1721
        dock = Qt::DockLeft;
 
1722
    else if (d->rightDock->hasDockWindow(dw, &index))
 
1723
        dock = Qt::DockRight;
 
1724
    else if (dw->parentWidget() == d->hideDock) {
 
1725
        index = 0;
 
1726
        dock = Qt::DockMinimized;
 
1727
    } else {
 
1728
        index = 0;
 
1729
    }
 
1730
    nl = dw->newLine();
 
1731
    extraOffset = dw->offset();
 
1732
    return true;
 
1733
}
 
1734
 
 
1735
#ifndef QT_NO_TOOLBAR
 
1736
/*!
 
1737
    Returns a list of all the toolbars which are in the \a dock dock
 
1738
    area, regardless of their state.
 
1739
 
 
1740
    For example, the \c TornOff dock area may contain closed toolbars
 
1741
    but these are returned along with the visible toolbars.
 
1742
 
 
1743
    \sa dockWindows()
 
1744
*/
 
1745
 
 
1746
QList<Q3ToolBar *> Q3MainWindow::toolBars(Qt::Dock dock) const
 
1747
{
 
1748
    QList<Q3DockWindow *> lst = dockWindows(dock);
 
1749
    QList<Q3ToolBar *> tbl;
 
1750
    for (int i = 0; i < lst.size(); ++i) {
 
1751
        Q3ToolBar *tb = qobject_cast<Q3ToolBar *>(lst.at(i));
 
1752
        if (tb)
 
1753
            tbl.append(tb);
 
1754
    }
 
1755
    return tbl;
 
1756
}
 
1757
#endif
 
1758
 
 
1759
/*!
 
1760
    Returns a list of all the dock windows which are in the \a dock
 
1761
    dock area, regardless of their state.
 
1762
 
 
1763
    For example, the \c Qt::DockTornOff dock area may contain closed dock
 
1764
    windows but these are returned along with the visible dock
 
1765
    windows.
 
1766
*/
 
1767
 
 
1768
QList<Q3DockWindow *> Q3MainWindow::dockWindows(Qt::Dock dock) const
 
1769
{
 
1770
    Q_D(const Q3MainWindow);
 
1771
    QList<Q3DockWindow *> lst;
 
1772
    switch (dock) {
 
1773
    case Qt::DockTop:
 
1774
        return d->topDock->dockWindowList();
 
1775
    case Qt::DockBottom:
 
1776
        return d->bottomDock->dockWindowList();
 
1777
    case Qt::DockLeft:
 
1778
        return d->leftDock->dockWindowList();
 
1779
    case Qt::DockRight:
 
1780
        return d->rightDock->dockWindowList();
 
1781
    case Qt::DockTornOff: {
 
1782
        for (int i = 0; i < d->dockWindows.size(); ++i) {
 
1783
            Q3DockWindow *w = d->dockWindows.at(i);
 
1784
            if (!w->area() && w->place() == Q3DockWindow::OutsideDock)
 
1785
                lst.append(w);
 
1786
        }
 
1787
    }
 
1788
    return lst;
 
1789
    case Qt::DockMinimized: {
 
1790
        QObjectList childs = d->hideDock->children();
 
1791
        for (int i = 0; i < childs.size(); ++i) {
 
1792
            Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(childs.at(i));
 
1793
            if (dw)
 
1794
                lst.append(dw);
 
1795
        }
 
1796
    }
 
1797
    return lst;
 
1798
    default:
 
1799
        break;
 
1800
    }
 
1801
    return lst;
 
1802
}
 
1803
 
 
1804
/*!
 
1805
    \overload
 
1806
 
 
1807
    Returns the list of dock windows which belong to this main window,
 
1808
    regardless of which dock area they are in or what their state is,
 
1809
    (e.g. irrespective of whether they are visible or not).
 
1810
*/
 
1811
 
 
1812
QList<Q3DockWindow *> Q3MainWindow::dockWindows() const
 
1813
{
 
1814
    return d_func()->dockWindows;
 
1815
}
 
1816
 
 
1817
void Q3MainWindow::setDockWindowsMovable(bool enable)
 
1818
{
 
1819
    Q_D(Q3MainWindow);
 
1820
    d->movable = enable;
 
1821
    QObjectList l = queryList("Q3DockWindow");
 
1822
    for (int i = 0; i < l.size(); ++i)
 
1823
        static_cast<Q3DockWindow*>(l.at(i))->setMovingEnabled(enable);
 
1824
}
 
1825
 
 
1826
/*!
 
1827
    \property Q3MainWindow::dockWindowsMovable
 
1828
    \brief whether the dock windows are movable
 
1829
 
 
1830
    If true (the default), the user will be able to move movable dock
 
1831
    windows from one Q3MainWindow dock area to another, including the
 
1832
    \c TearOff area (i.e. where the dock window floats freely as a
 
1833
    window in its own right), and the \c Minimized area (where only
 
1834
    the dock window's handle is shown below the menu bar). Movable
 
1835
    dock windows can also be moved within Q3MainWindow dock areas, i.e.
 
1836
    to rearrange them within a dock area.
 
1837
 
 
1838
    If false the user will not be able to move any dock windows.
 
1839
 
 
1840
    By default dock windows are moved transparently (i.e. only an
 
1841
    outline rectangle is shown during the drag), but this setting can
 
1842
    be changed with setOpaqueMoving().
 
1843
 
 
1844
    \sa setDockEnabled(), setOpaqueMoving()
 
1845
*/
 
1846
 
 
1847
bool Q3MainWindow::dockWindowsMovable() const
 
1848
{
 
1849
    return d_func()->movable;
 
1850
}
 
1851
 
 
1852
void Q3MainWindow::setOpaqueMoving(bool b)
 
1853
{
 
1854
    Q_D(Q3MainWindow);
 
1855
    d->opaque = b;
 
1856
    QObjectList l = queryList("Q3DockWindow");
 
1857
    for (int i = 0; i < l.size(); ++i)
 
1858
        static_cast<Q3DockWindow*>(l.at(i))->setOpaqueMoving(b);
 
1859
}
 
1860
 
 
1861
/*!
 
1862
    \property Q3MainWindow::opaqueMoving
 
1863
    \brief whether dock windows are moved opaquely
 
1864
 
 
1865
    If true the dock windows of the main window are shown opaquely
 
1866
    (i.e. it shows the toolbar as it looks when docked) whilst it is
 
1867
    being moved. If false (the default) they are shown transparently,
 
1868
    (i.e. as an outline rectangle).
 
1869
 
 
1870
    \warning Opaque moving of toolbars and dockwindows is known to
 
1871
    have several problems. We recommend avoiding the use of this
 
1872
    feature for the time being. We intend fixing the problems in a
 
1873
    future release.
 
1874
*/
 
1875
 
 
1876
bool Q3MainWindow::opaqueMoving() const
 
1877
{
 
1878
    return d_func()->opaque;
 
1879
}
 
1880
 
 
1881
/*!
 
1882
    This function will line up dock windows within the visible dock
 
1883
    areas (\c Top, \c Left, \c Right and \c Bottom) as compactly as
 
1884
    possible.
 
1885
 
 
1886
    If \a keepNewLines is true, all dock windows stay on their
 
1887
    original lines. If \a keepNewLines is false then newlines may be
 
1888
    removed to achieve the most compact layout possible.
 
1889
 
 
1890
    The method only works if dockWindowsMovable() returns true.
 
1891
*/
 
1892
 
 
1893
void Q3MainWindow::lineUpDockWindows(bool keepNewLines)
 
1894
{
 
1895
    Q_D(const Q3MainWindow);
 
1896
    if (!dockWindowsMovable())
 
1897
        return;
 
1898
    d->topDock->lineUp(keepNewLines);
 
1899
    d->leftDock->lineUp(keepNewLines);
 
1900
    d->rightDock->lineUp(keepNewLines);
 
1901
    d->bottomDock->lineUp(keepNewLines);
 
1902
}
 
1903
 
 
1904
/*!
 
1905
    Returns true, if the dock window menu is enabled; otherwise
 
1906
    returns false.
 
1907
 
 
1908
    The menu lists the (appropriate()) dock windows (which may be
 
1909
    shown or hidden), and has a "Line Up Dock Windows" menu item. It
 
1910
    will also have a "Customize" menu item if isCustomizable() returns
 
1911
    true.
 
1912
 
 
1913
    \sa setDockEnabled(), lineUpDockWindows() appropriate()
 
1914
    setAppropriate()
 
1915
*/
 
1916
 
 
1917
bool Q3MainWindow::isDockMenuEnabled() const
 
1918
{
 
1919
    return d_func()->dockMenu;
 
1920
}
 
1921
 
 
1922
/*!
 
1923
    If \a b is true, then right clicking on a dock window or dock area
 
1924
    will pop up the dock window menu. If \a b is false, right clicking
 
1925
    a dock window or dock area will not pop up the menu.
 
1926
 
 
1927
    The menu lists the (appropriate()) dock windows (which may be
 
1928
    shown or hidden), and has a "Line Up Dock Windows" item. It will
 
1929
    also have a "Customize" menu item if isCustomizable() returns
 
1930
    true.
 
1931
 
 
1932
    \sa lineUpDockWindows(), isDockMenuEnabled()
 
1933
*/
 
1934
 
 
1935
void Q3MainWindow::setDockMenuEnabled(bool b)
 
1936
{
 
1937
    d_func()->dockMenu = b;
 
1938
}
 
1939
 
 
1940
/*!
 
1941
    Creates the dock window menu which contains all toolbars (if \a
 
1942
    dockWindows is \c OnlyToolBars), all dock windows (if \a
 
1943
    dockWindows is \c NoToolBars) or all toolbars and dock windows (if
 
1944
    \a dockWindows is \c AllDockWindows - the default).
 
1945
 
 
1946
    This function is called internally when necessary, e.g. when the
 
1947
    user right clicks a dock area (providing isDockMenuEnabled()
 
1948
    returns true). You can reimplement this function if you wish to
 
1949
    customize the behavior.
 
1950
 
 
1951
    The menu items representing the toolbars and dock windows are
 
1952
    checkable. The visible dock windows are checked and the hidden
 
1953
    dock windows are unchecked. The user can click a menu item to
 
1954
    change its state (show or hide the dock window).
 
1955
 
 
1956
    The list and the state are always kept up-to-date.
 
1957
 
 
1958
    Toolbars and dock windows which are not appropriate in the current
 
1959
    context (see setAppropriate()) are not listed in the menu.
 
1960
 
 
1961
    The menu also has a menu item for lining up the dock windows.
 
1962
 
 
1963
    If isCustomizable() returns true, a Customize menu item is added
 
1964
    to the menu, which if clicked will call customize(). The
 
1965
    isCustomizable() function we provide returns false and customize()
 
1966
    does nothing, so they must be reimplemented in a subclass to be
 
1967
    useful.
 
1968
*/
 
1969
 
 
1970
Q3PopupMenu *Q3MainWindow::createDockWindowMenu(DockWindows dockWindows) const
 
1971
{
 
1972
    QObjectList l = queryList("Q3DockWindow");
 
1973
    if (l.isEmpty())
 
1974
        return 0;
 
1975
 
 
1976
    Q3PopupMenu *menu = new Q3PopupMenu((Q3MainWindow*)this);
 
1977
    menu->setObjectName("qt_customize_menu");
 
1978
    menu->setCheckable(true);
 
1979
 
 
1980
    bool empty = true;
 
1981
    if (!l.isEmpty()) {
 
1982
        if (dockWindows == AllDockWindows || dockWindows == NoToolBars) {
 
1983
            for (int i = 0; i < l.size(); ++i) {
 
1984
                Q3DockWindow *dw = (Q3DockWindow*)l.at(i);
 
1985
                if (!appropriate(dw) || qobject_cast<Q3ToolBar*>(dw) || !dockMainWindow(dw))
 
1986
                    continue;
 
1987
                QString label = dw->windowTitle();
 
1988
                if (!label.isEmpty()) {
 
1989
                    QAction *act = menu->addAction(label);
 
1990
                    act->setChecked(dw->isVisible());
 
1991
                    QObject::connect(act, SIGNAL(triggered()), dw, SLOT(toggleVisible()));
 
1992
                    empty = false;
 
1993
                }
 
1994
            }
 
1995
        }
 
1996
        if (!empty) {
 
1997
            menu->addSeparator();
 
1998
            empty = true;
 
1999
        }
 
2000
#ifndef QT_NO_TOOLBAR
 
2001
        if (dockWindows == AllDockWindows || dockWindows == OnlyToolBars) {
 
2002
            for (int i = 0; i < l.size(); ++i) {
 
2003
                Q3ToolBar *tb = qobject_cast<Q3ToolBar*>(l.at(i));
 
2004
                if (!tb || !appropriate(tb) || !dockMainWindow(tb))
 
2005
                    continue;
 
2006
                QString label = tb->label();
 
2007
                if (!label.isEmpty()) {
 
2008
                    QAction *act = menu->addAction(label);
 
2009
                    act->setCheckable(true);
 
2010
                    act->setChecked(tb->isVisible());
 
2011
                    QObject::connect(act, SIGNAL(triggered()), tb, SLOT(toggleVisible()));
 
2012
                    empty = false;
 
2013
                }
 
2014
            }
 
2015
        }
 
2016
#endif
 
2017
    }
 
2018
    if (!empty) {
 
2019
        menu->addSeparator();
 
2020
        empty = true;
 
2021
    }
 
2022
 
 
2023
    if (dockWindowsMovable())
 
2024
        menu->addAction(tr("Line up"), this, SLOT(doLineUp()));
 
2025
    if (isCustomizable())
 
2026
        menu->addAction(tr("Customize..."), this, SLOT(customize()));
 
2027
    return menu;
 
2028
}
 
2029
 
 
2030
/*!
 
2031
    Shows the dock menu at the position \a globalPos. The menu lists
 
2032
    the dock windows so that they can be shown (or hidden), lined up,
 
2033
    and possibly customized. Returns true if the menu is shown;
 
2034
    otherwise returns false.
 
2035
 
 
2036
    If you want a custom menu, reimplement this function. You can
 
2037
    create the menu from scratch or call createDockWindowMenu() and
 
2038
    modify the result.
 
2039
 
 
2040
    The default implementation uses the dock window menu which gets
 
2041
    created by createDockWindowMenu(). You can reimplement
 
2042
    createDockWindowMenu() if you want to use your own specialized
 
2043
    popup menu.
 
2044
*/
 
2045
 
 
2046
bool Q3MainWindow::showDockMenu(const QPoint &globalPos)
 
2047
{
 
2048
    Q_D(Q3MainWindow);
 
2049
    if (!d->dockMenu)
 
2050
        return false;
 
2051
 
 
2052
    if(Q3PopupMenu *ret = createDockWindowMenu()) {
 
2053
        ret->exec(globalPos);
 
2054
        delete ret;
 
2055
        return true;
 
2056
    }
 
2057
    return false;
 
2058
}
 
2059
 
 
2060
void Q3MainWindow::slotPlaceChanged()
 
2061
{
 
2062
    QObject* obj = (QObject*)sender();
 
2063
    Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(obj);
 
2064
    if (dw)
 
2065
        emit dockWindowPositionChanged(dw);
 
2066
#ifndef QT_NO_TOOLBAR
 
2067
    Q3ToolBar *tb = qobject_cast<Q3ToolBar*>(obj);
 
2068
    if (tb)
 
2069
        emit toolBarPositionChanged(tb);
 
2070
#endif
 
2071
}
 
2072
 
 
2073
/*!
 
2074
    \internal
 
2075
    For internal use of Q3DockWindow only.
 
2076
 */
 
2077
 
 
2078
Q3DockArea *Q3MainWindow::dockingArea(const QPoint &p)
 
2079
{
 
2080
    Q_D(Q3MainWindow);
 
2081
    int mh = d->mb ? d->mb->height() : 0;
 
2082
    int sh = d->sb ? d->sb->height() : 0;
 
2083
    if (p.x() >= -5 && p.x() <= 100 && p.y() > mh && p.y() - height() - sh)
 
2084
        return d->leftDock;
 
2085
    if (p.x() >= width() - 100 && p.x() <= width() + 5 && p.y() > mh && p.y() - height() - sh)
 
2086
        return d->rightDock;
 
2087
    if (p.y() >= -5 && p.y() < mh + 100 && p.x() >= 0 && p.x() <= width())
 
2088
        return d->topDock;
 
2089
    if (p.y() >= height() - sh - 100 && p.y() <= height() + 5 && p.x() >= 0 && p.x() <= width())
 
2090
        return d->bottomDock;
 
2091
    return 0;
 
2092
}
 
2093
 
 
2094
/*!
 
2095
    Returns true if \a dw is a dock window known to the main window;
 
2096
    otherwise returns false.
 
2097
*/
 
2098
 
 
2099
bool Q3MainWindow::hasDockWindow(Q3DockWindow *dw)
 
2100
{
 
2101
    return d_func()->dockWindows.contains(dw);
 
2102
}
 
2103
 
 
2104
/*!
 
2105
    Returns the \c Left dock area
 
2106
 
 
2107
    \sa rightDock() topDock() bottomDock()
 
2108
*/
 
2109
 
 
2110
Q3DockArea *Q3MainWindow::leftDock() const
 
2111
{
 
2112
    return d_func()->leftDock;
 
2113
}
 
2114
 
 
2115
/*!
 
2116
    Returns the \c Right dock area
 
2117
 
 
2118
    \sa leftDock() topDock() bottomDock()
 
2119
*/
 
2120
 
 
2121
Q3DockArea *Q3MainWindow::rightDock() const
 
2122
{
 
2123
    return d_func()->rightDock;
 
2124
}
 
2125
 
 
2126
/*!
 
2127
    Returns the \c Top dock area
 
2128
 
 
2129
    \sa bottomDock() leftDock() rightDock()
 
2130
*/
 
2131
 
 
2132
Q3DockArea *Q3MainWindow::topDock() const
 
2133
{
 
2134
    return d_func()->topDock;
 
2135
}
 
2136
 
 
2137
/*!
 
2138
    Returns a pointer the \c Bottom dock area
 
2139
 
 
2140
    \sa topDock() leftDock() rightDock()
 
2141
*/
 
2142
 
 
2143
Q3DockArea *Q3MainWindow::bottomDock() const
 
2144
{
 
2145
    return d_func()->bottomDock;
 
2146
}
 
2147
 
 
2148
/*!
 
2149
    This function is called when the user clicks the Customize menu
 
2150
    item on the dock window menu.
 
2151
 
 
2152
    The customize menu item will only appear if isCustomizable()
 
2153
    returns true (it returns false by default).
 
2154
 
 
2155
    The function is intended, for example, to provide the user with a
 
2156
    means of telling the application that they wish to customize the
 
2157
    main window, dock windows or dock areas.
 
2158
 
 
2159
    The default implementation does nothing and the Customize menu
 
2160
    item is not shown on the right-click menu by default. If you want
 
2161
    the item to appear then reimplement isCustomizable() to return
 
2162
    true, and reimplement this function to do whatever you want.
 
2163
 
 
2164
    \sa isCustomizable()
 
2165
*/
 
2166
 
 
2167
void Q3MainWindow::customize()
 
2168
{
 
2169
}
 
2170
 
 
2171
/*!
 
2172
    Returns true if the dock area dock window menu includes the
 
2173
    Customize menu item (which calls customize() when clicked).
 
2174
    Returns false by default, i.e. the popup menu will not contain a
 
2175
    Customize menu item. You will need to reimplement this function
 
2176
    and set it to return true if you wish the user to be able to see
 
2177
    the dock window menu.
 
2178
 
 
2179
    \sa customize()
 
2180
*/
 
2181
 
 
2182
bool Q3MainWindow::isCustomizable() const
 
2183
{
 
2184
    return false;
 
2185
}
 
2186
 
 
2187
/*!
 
2188
    Returns true if it is appropriate to include a menu item for the
 
2189
    \a dw dock window in the dock window menu; otherwise returns
 
2190
    false.
 
2191
 
 
2192
    The user is able to change the state (show or hide) a dock window
 
2193
    that has a menu item by clicking the item.
 
2194
 
 
2195
    Call setAppropriate() to indicate whether or not a particular dock
 
2196
    window should appear on the popup menu.
 
2197
 
 
2198
    \sa setAppropriate()
 
2199
*/
 
2200
 
 
2201
bool Q3MainWindow::appropriate(Q3DockWindow *dw) const
 
2202
{
 
2203
    Q_D(const Q3MainWindow);
 
2204
    QMap<Q3DockWindow*, bool>::ConstIterator it = d->appropriate.find(dw);
 
2205
    if (it == d->appropriate.end())
 
2206
        return true;
 
2207
    return *it;
 
2208
}
 
2209
 
 
2210
/*!
 
2211
    Use this function to control whether or not the \a dw dock
 
2212
    window's caption should appear as a menu item on the dock window
 
2213
    menu that lists the dock windows.
 
2214
 
 
2215
    If \a a is true then the \a dw will appear as a menu item on the
 
2216
    dock window menu. The user is able to change the state (show or
 
2217
    hide) a dock window that has a menu item by clicking the item;
 
2218
    depending on the state of your application, this may or may not be
 
2219
    appropriate. If \a a is false the \a dw will not appear on the
 
2220
    popup menu.
 
2221
 
 
2222
    \sa showDockMenu() isCustomizable() customize()
 
2223
*/
 
2224
 
 
2225
void Q3MainWindow::setAppropriate(Q3DockWindow *dw, bool a)
 
2226
{
 
2227
    d_func()->appropriate.insert(dw, a);
 
2228
}
 
2229
 
 
2230
#ifndef QT_NO_TEXTSTREAM
 
2231
static void saveDockArea(QTextStream &ts, Q3DockArea *a)
 
2232
{
 
2233
    QList<Q3DockWindow *> l = a->dockWindowList();
 
2234
    for (int i = 0; i < l.size(); ++i) {
 
2235
        Q3DockWindow *dw = l.at(i);
 
2236
        ts << QString(dw->windowTitle());
 
2237
        ts << ",";
 
2238
    }
 
2239
    ts << endl;
 
2240
    ts << *a;
 
2241
}
 
2242
 
 
2243
/*!
 
2244
    \relates Q3MainWindow
 
2245
 
 
2246
    Writes the layout (sizes and positions) of the dock windows in the
 
2247
    dock areas of the Q3MainWindow \a mainWindow, including \c
 
2248
    Minimized and \c TornOff dock windows, to the text stream \a ts.
 
2249
 
 
2250
    This can be used, for example, in conjunction with QSettings to
 
2251
    save the user's layout when the \a mainWindow receives a
 
2252
    close event.
 
2253
 
 
2254
    \sa QWidget::closeEvent()
 
2255
*/
 
2256
 
 
2257
QTextStream &operator<<(QTextStream &ts, const Q3MainWindow &mainWindow)
 
2258
{
 
2259
    QList<Q3DockWindow *> l = mainWindow.dockWindows(Qt::DockMinimized);
 
2260
    for (int i = 0; i < l.size(); ++i) {
 
2261
        Q3DockWindow *dw = l.at(i);
 
2262
        ts << dw->windowTitle();
 
2263
        ts << ",";
 
2264
    }
 
2265
    ts << endl;
 
2266
 
 
2267
    l = mainWindow.dockWindows(Qt::DockTornOff);
 
2268
    for (int i = 0; i < l.size(); ++i) {
 
2269
        Q3DockWindow *dw = l.at(i);
 
2270
        ts << dw->windowTitle();
 
2271
        ts << ",";
 
2272
    }
 
2273
    ts << endl;
 
2274
    for (int i = 0; i < l.size(); ++i) {
 
2275
        Q3DockWindow *dw = l.at(i);
 
2276
        ts << "[" << dw->windowTitle() << ","
 
2277
           << (int)dw->geometry().x() << ","
 
2278
           << (int)dw->geometry().y() << ","
 
2279
           << (int)dw->geometry().width() << ","
 
2280
           << (int)dw->geometry().height() << ","
 
2281
           << (int)dw->isVisible() << "]";
 
2282
    }
 
2283
    ts << endl;
 
2284
 
 
2285
    saveDockArea(ts, mainWindow.topDock());
 
2286
    saveDockArea(ts, mainWindow.bottomDock());
 
2287
    saveDockArea(ts, mainWindow.rightDock());
 
2288
    saveDockArea(ts, mainWindow.leftDock());
 
2289
    return ts;
 
2290
}
 
2291
 
 
2292
static void loadDockArea(const QStringList &names, Q3DockArea *a, Qt::Dock dl, QList<Q3DockWindow *> &l, Q3MainWindow *mw, QTextStream &ts)
 
2293
{
 
2294
    for (QStringList::ConstIterator it = names.begin(); it != names.end(); ++it) {
 
2295
        for (int i = 0; i < l.size(); ++i) {
 
2296
            Q3DockWindow *dw = l.at(i);
 
2297
            if (dw->windowTitle() == *it) {
 
2298
                mw->addDockWindow(dw, dl);
 
2299
                break;
 
2300
            }
 
2301
        }
 
2302
    }
 
2303
    if (a) {
 
2304
        ts >> *a;
 
2305
    } else if (dl == Qt::DockTornOff) {
 
2306
        QString s = ts.readLine();
 
2307
        enum State { Pre, Name, X, Y, Width, Height, Visible, Post };
 
2308
        int state = Pre;
 
2309
        QString name, x, y, w, h, visible;
 
2310
        QChar c;
 
2311
        for (int i = 0; i < (int)s.length(); ++i) {
 
2312
            c = s[i];
 
2313
            if (state == Pre && c == '[') {
 
2314
                state++;
 
2315
                continue;
 
2316
            }
 
2317
            if (c == ',' &&
 
2318
                 (state == Name || state == X || state == Y || state == Width || state == Height)) {
 
2319
                state++;
 
2320
                continue;
 
2321
            }
 
2322
            if (state == Visible && c == ']') {
 
2323
                for (int i = 0; i < l.size(); ++i) {
 
2324
                    Q3DockWindow *dw = l.at(i);
 
2325
                    if (QString(dw->windowTitle()) == name) {
 
2326
                        if (!qobject_cast<Q3ToolBar*>(dw))
 
2327
                            dw->setGeometry(x.toInt(), y.toInt(), w.toInt(), h.toInt());
 
2328
                        else
 
2329
                            dw->setGeometry(x.toInt(), y.toInt(), dw->width(), dw->height());
 
2330
                        if (!(bool)visible.toInt())
 
2331
                            dw->hide();
 
2332
                        else
 
2333
                            dw->show();
 
2334
                        break;
 
2335
                    }
 
2336
                }
 
2337
 
 
2338
                name = x = y = w = h = visible = "";
 
2339
 
 
2340
                state = Pre;
 
2341
                continue;
 
2342
            }
 
2343
            if (state == Name)
 
2344
                name += c;
 
2345
            else if (state == X)
 
2346
                x += c;
 
2347
            else if (state == Y)
 
2348
                y += c;
 
2349
            else if (state == Width)
 
2350
                w += c;
 
2351
            else if (state == Height)
 
2352
                h += c;
 
2353
            else if (state == Visible)
 
2354
                visible += c;
 
2355
        }
 
2356
    }
 
2357
}
 
2358
 
 
2359
/*!
 
2360
    \relates Q3MainWindow
 
2361
 
 
2362
    Reads the layout (sizes and positions) of the dock windows in the
 
2363
    dock areas of the Q3MainWindow \a mainWindow from the text stream,
 
2364
    \a ts, including \c Minimized and \c TornOff dock windows.
 
2365
    Restores the dock windows and dock areas to these sizes and
 
2366
    positions. The layout information must be in the format produced
 
2367
    by operator<<().
 
2368
 
 
2369
    This can be used, for example, in conjunction with QSettings to
 
2370
    restore the user's layout.
 
2371
*/
 
2372
 
 
2373
QTextStream &operator>>(QTextStream &ts, Q3MainWindow &mainWindow)
 
2374
{
 
2375
    QList<Q3DockWindow *> l = mainWindow.dockWindows();
 
2376
 
 
2377
    QString s = ts.readLine();
 
2378
    QStringList names = s.split(',');
 
2379
    loadDockArea(names, 0, Qt::DockMinimized, l, &mainWindow, ts);
 
2380
 
 
2381
    s = ts.readLine();
 
2382
    names = s.split(',');
 
2383
    loadDockArea(names, 0, Qt::DockTornOff, l, &mainWindow, ts);
 
2384
 
 
2385
    int i = 0;
 
2386
    Q3DockArea *areas[] = { mainWindow.topDock(), mainWindow.bottomDock(), mainWindow.rightDock(), mainWindow.leftDock() };
 
2387
    for (int dl = (int)Qt::DockTop; dl != (int)Qt::DockMinimized; ++dl, ++i) {
 
2388
        s = ts.readLine();
 
2389
        names = s.split(',');
 
2390
        loadDockArea(names, areas[i], (Qt::Dock)dl, l, &mainWindow, ts);
 
2391
    }
 
2392
    return ts;
 
2393
}
 
2394
#endif
 
2395
 
 
2396
#include "q3mainwindow.moc"
 
2397
 
 
2398
#endif