source: trunk/src/qt3support/widgets/q3mainwindow.cpp@ 616

Last change on this file since 616 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 71.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the Qt3Support module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "q3mainwindow.h"
43#ifndef QT_NO_MAINWINDOW
44
45#include "qapplication.h"
46#include "qbitmap.h"
47#include "qcursor.h"
48#include "qdatetime.h"
49#include "q3dockarea.h"
50#include "qevent.h"
51#include "qlayout.h"
52#include "qmap.h"
53#include "qmenubar.h"
54#include "qpainter.h"
55#include "q3popupmenu.h"
56#include "q3scrollview.h"
57#include "qstatusbar.h"
58#include "qstringlist.h"
59#include "qstyle.h"
60#include "qstyleoption.h"
61#include "qtimer.h"
62#include "q3toolbar.h"
63#include "qtooltip.h"
64#include "qwhatsthis.h"
65#ifdef Q_WS_MAC
66# include <private/qt_mac_p.h>
67#endif
68
69#include <private/q3mainwindow_p.h>
70
71QT_BEGIN_NAMESPACE
72
73class QHideDock;
74
75/* Q3MainWindowLayout, respects widthForHeight layouts (like the left
76 and right docks are)
77*/
78
79class Q3MainWindowLayout : public QLayout
80{
81 Q_OBJECT
82
83public:
84 Q3MainWindowLayout(Q3MainWindow *mw);
85 ~Q3MainWindowLayout() {}
86
87 void addItem(QLayoutItem *);
88 void setLeftDock(Q3DockArea *l);
89 void setRightDock(Q3DockArea *r);
90 void setCentralWidget(QWidget *w);
91 bool hasHeightForWidth() const { return false; }
92 QSize sizeHint() const;
93 QSize minimumSize() const;
94 QLayoutItem *itemAt(int) const { return 0; } //###
95 QLayoutItem *takeAt(int) { return 0; } //###
96 int count() const { return 0; } //###
97
98protected:
99 void setGeometry(const QRect &r) {
100 QLayout::setGeometry(r);
101 layoutItems(r);
102 }
103
104private:
105 int layoutItems(const QRect&, bool testonly = false);
106 int extraPixels() const;
107
108 Q3DockArea *left, *right;
109 QWidget *central;
110 Q3MainWindow *mainWindow;
111
112};
113
114QSize Q3MainWindowLayout::sizeHint() const
115{
116 int w = 0;
117 int h = 0;
118
119 if (left) {
120 w += left->sizeHint().width();
121 h = qMax(h, left->sizeHint().height());
122 }
123 if (right) {
124 w += right->sizeHint().width();
125 h = qMax(h, right->sizeHint().height());
126 }
127 if (central) {
128 w += central->sizeHint().width();
129 int diff = extraPixels();
130 h = qMax(h, central->sizeHint().height() + diff);
131 }
132 return QSize(w, h);
133}
134
135QSize Q3MainWindowLayout::minimumSize() const
136{
137 int w = 0;
138 int h = 0;
139
140 if (left) {
141 QSize ms = left->minimumSizeHint().expandedTo(left->minimumSize());
142 w += ms.width();
143 h = qMax(h, ms.height());
144 }
145 if (right) {
146 QSize ms = right->minimumSizeHint().expandedTo(right->minimumSize());
147 w += ms.width();
148 h = qMax(h, ms.height());
149 }
150 if (central) {
151 QSize min = central->minimumSize().isNull() ?
152 central->minimumSizeHint() : central->minimumSize();
153 w += min.width();
154 int diff = extraPixels();
155 h = qMax(h, min.height() + diff);
156 }
157 return QSize(w, h);
158}
159
160Q3MainWindowLayout::Q3MainWindowLayout(Q3MainWindow *mw)
161 : left(0), right(0), central(0)
162{
163 mainWindow = mw;
164}
165
166void Q3MainWindowLayout::setLeftDock(Q3DockArea *l)
167{
168 left = l;
169}
170
171void Q3MainWindowLayout::setRightDock(Q3DockArea *r)
172{
173 right = r;
174}
175
176void Q3MainWindowLayout::setCentralWidget(QWidget *w)
177{
178 central = w;
179}
180
181int Q3MainWindowLayout::layoutItems(const QRect &r, bool testonly)
182{
183 if (!left && !central && !right)
184 return 0;
185
186 int wl = 0, wr = 0;
187 if (left)
188 wl = ((Q3DockAreaLayout*)left->QWidget::layout())->widthForHeight(r.height());
189 if (right)
190 wr = ((Q3DockAreaLayout*)right->QWidget::layout())->widthForHeight(r.height());
191 int w = r.width() - wr - wl;
192 if (w < 0)
193 w = 0;
194
195 int diff = extraPixels();
196 if (!testonly) {
197 QRect g(geometry());
198 if (left)
199 left->setGeometry(QRect(g.x(), g.y() + diff, wl, r.height() - diff));
200 if (right)
201 right->setGeometry(QRect(g.x() + g.width() - wr, g.y() + diff, wr, r.height() - diff));
202 if (central)
203 central->setGeometry(g.x() + wl, g.y() + diff, w, r.height() - diff);
204 }
205
206 w = wl + wr;
207 if (central)
208 w += central->minimumSize().width();
209 return w;
210}
211
212int Q3MainWindowLayout::extraPixels() const
213{
214 if (mainWindow->d_func()->topDock->isEmpty() &&
215 !(mainWindow->d_func()->leftDock->isEmpty() &&
216 mainWindow->d_func()->rightDock->isEmpty())) {
217 return 2;
218 } else {
219 return 0;
220 }
221}
222
223void Q3MainWindowLayout::addItem(QLayoutItem * /* item */)
224{
225}
226
227/*
228 QHideToolTip and QHideDock - minimized dock
229*/
230
231#if 0
232class QHideToolTip : public QToolTip
233{
234public:
235 QHideToolTip(QWidget *parent) : QToolTip(parent) {}
236
237 void maybeTip(const QPoint &pos);
238};
239#endif
240
241
242class QHideDock : public QWidget
243{
244 Q_OBJECT
245
246public:
247 QHideDock(Q3MainWindow *parent) : QWidget(parent, "qt_hide_dock") {
248 hide();
249 setFixedHeight(style()->pixelMetric(QStyle::PM_DockWidgetHandleExtent, 0, this) + 3);
250 pressedHandle = -1;
251 pressed = false;
252 setMouseTracking(true);
253 win = parent;
254#if 0
255 tip = new QHideToolTip(this);
256#endif
257 }
258 ~QHideDock()
259 {
260#if 0
261 delete tip;
262#endif
263 }
264
265protected:
266 void paintEvent(QPaintEvent *e) {
267 QObjectList childList = children();
268 if (childList.isEmpty())
269 return;
270 QPainter p(this);
271 p.setClipRegion(e->rect());
272 p.fillRect(e->rect(), palette().brush(QPalette::Window));
273 int x = 0;
274 for (int i = 0; i < childList.size(); ++i) {
275 QObject *o = childList.at(i);
276 Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
277 if (!dw || !dw->isVisible())
278 continue;
279 QStyleOptionQ3DockWindow opt;
280 opt.rect.setRect(x, 0, 30, 10);
281 opt.palette = palette();
282 opt.docked = dw->area();
283 opt.closeEnabled = dw->isCloseEnabled();
284 opt.state = QStyle::State_None;
285 if (i == pressedHandle)
286 opt.state |= QStyle::State_On;
287
288 style()->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &opt, &p, this);
289 x += 30;
290 }
291 }
292
293 void mousePressEvent(QMouseEvent *e) {
294 pressed = true;
295 QObjectList childList = children();
296 if (childList.isEmpty())
297 return;
298 mouseMoveEvent(e);
299 pressedHandle = -1;
300
301 if (e->button() == Qt::RightButton && win->isDockMenuEnabled()) {
302 // ### TODO: HideDock menu
303 } else {
304 mouseMoveEvent(e);
305 }
306 }
307
308 void mouseMoveEvent(QMouseEvent *e) {
309 QObjectList childList = children();
310 if (childList.isEmpty())
311 return;
312 if (!pressed)
313 return;
314 int x = 0;
315 if (e->y() >= 0 && e->y() <= height()) {
316 for (int i = 0; i < childList.size(); ++i) {
317 QObject *o = childList.at(i);
318 Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
319 if (!dw || !dw->isVisible())
320 continue;
321 if (e->x() >= x && e->x() <= x + 30) {
322 int old = pressedHandle;
323 pressedHandle = i;
324 if (pressedHandle != old)
325 repaint();
326 return;
327 }
328 x += 30;
329 }
330 }
331 int old = pressedHandle;
332 pressedHandle = -1;
333 if (old != -1)
334 repaint();
335 }
336
337 void mouseReleaseEvent(QMouseEvent *e) {
338 pressed = false;
339 if (pressedHandle == -1)
340 return;
341 QObjectList childList = children();
342 if (childList.isEmpty())
343 return;
344 if (e->button() == Qt::LeftButton) {
345 if (e->y() >= 0 && e->y() <= height()) {
346 QObject *o = childList.at(pressedHandle);
347 Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
348 if (dw) {
349 dw->show();
350 dw->dock();
351 }
352 }
353 }
354 pressedHandle = -1;
355 repaint();
356 }
357
358 bool eventFilter(QObject *o, QEvent *e) {
359 if (o == this || !o->isWidgetType())
360 return QWidget::eventFilter(o, e);
361 if (e->type() == QEvent::HideToParent ||
362 e->type() == QEvent::ShowToParent)
363 updateState();
364 return QWidget::eventFilter(o, e);
365 }
366
367 void updateState() {
368 bool visible = true;
369 QObjectList childList = children();
370 if (childList.isEmpty())
371 return;
372 for (int i = 0; i < childList.size(); ++i) {
373 QObject *o = childList.at(i);
374 Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
375 if (!dw)
376 continue;
377 if (dw->isHidden()) {
378 visible = false;
379 continue;
380 }
381 if (!dw->isVisible())
382 continue;
383 visible = true;
384 break;
385 }
386
387 if (visible)
388 show();
389 else
390 hide();
391 win->triggerLayout(false);
392 update();
393 }
394
395 void childEvent(QChildEvent *e) {
396 QWidget::childEvent(e);
397 if (e->type() == QEvent::ChildInserted)
398 e->child()->installEventFilter(this);
399 else
400 e->child()->removeEventFilter(this);
401 updateState();
402 }
403
404private:
405 Q3MainWindow *win;
406 int pressedHandle;
407 bool pressed;
408#if 0
409 QHideToolTip *tip;
410 friend class QHideToolTip;
411#endif
412};
413
414#if 0
415void QHideToolTip::maybeTip(const QPoint &pos)
416{
417 if (!parentWidget())
418 return;
419 QHideDock *dock = (QHideDock*)parentWidget();
420
421 QObjectList dchilds = dock->children();
422 if (dchilds.isEmpty())
423 return;
424 int x = 0;
425 for (int i = 0; i < dchilds.size(); ++i) {
426 QObject *o = dchilds.at(i);
427 Q3DockWindow *dw = qobject_cast<Q3DockWindow*>(o);
428 if (!dw || !dw->isVisible())
429 continue;
430 if (pos.x() >= x && pos.x() <= x + 30) {
431 Q3DockWindow *dw = (Q3DockWindow*)o;
432 if (!dw->windowTitle().isEmpty())
433 tip(QRect(x, 0, 30, dock->height()), dw->windowTitle());
434 return;
435 }
436 x += 30;
437 }
438}
439#endif
440
441/*!
442 \class Q3MainWindow
443 \brief The Q3MainWindow class provides a main application window,
444 with a menu bar, dock windows (e.g. for toolbars), and a status
445 bar.
446
447 \compat
448
449 Main windows are most often used to provide menus, toolbars and a
450 status bar around a large central widget, such as a text edit,
451 drawing canvas or QWorkspace (for MDI applications). Q3MainWindow
452 is usually subclassed since this makes it easier to encapsulate
453 the central widget, menus and toolbars as well as the window's
454 state. Subclassing makes it possible to create the slots that are
455 called when the user clicks menu items or toolbar buttons.
456
457 We'll briefly review adding menu items and
458 toolbar buttons then describe the facilities of Q3MainWindow
459 itself.
460
461 \snippet doc/src/snippets/code/src_qt3support_widgets_q3mainwindow.cpp 0
462
463 Q3MainWindows may be created in their own right as shown above.
464 The central widget is set with setCentralWidget(). Popup menus can
465 be added to the default menu bar, widgets can be added to the
466 status bar, toolbars and dock windows can be added to any of the
467 dock areas.
468
469 The main window will take care of the dock areas, and the geometry
470 of the central widget, but all other aspects of the central widget
471 are left to you. Q3MainWindow automatically detects the creation of
472 a menu bar or status bar if you specify the Q3MainWindow as parent,
473 or you can use the provided menuBar() and statusBar() functions.
474 The functions menuBar() and statusBar() create a suitable widget
475 if one doesn't exist, and update the window's layout to make
476 space.
477
478 New dock windows and toolbars can be added to a Q3MainWindow using
479 addDockWindow(). Qt::Dock windows can be moved using moveDockWindow()
480 and removed with removeDockWindow(). Q3MainWindow allows default
481 dock window (toolbar) docking in all its dock areas (\c Top, \c
482 Left, \c Right, \c Bottom). You can use setDockEnabled() to
483 enable and disable docking areas for dock windows. When adding or
484 moving dock windows you can specify their 'edge' (dock area). The
485 currently available edges are: \c Top, \c Left, \c Right, \c
486 Bottom, \c Minimized (effectively a 'hidden' dock area) and \c
487 TornOff (floating). See \l Qt::Dock for an explanation of these
488 areas. Note that the *ToolBar functions are included for backward
489 compatibility; all new code should use the *DockWindow functions.
490 QToolbar is a subclass of Q3DockWindow so all functions that work
491 with dock windows work on toolbars in the same way.
492
493 \target dwm
494 If the user clicks the close button, then the dock window is
495 hidden. A dock window can be hidden or unhidden by the user by
496 right clicking a dock area and clicking the name of the relevant
497 dock window on the pop up dock window menu. This menu lists the
498 names of every dock window; visible dock windows have a tick
499 beside their names. The dock window menu is created automatically
500 as required by createDockWindowMenu(). Since it may not always be
501 appropriate for a dock window to appear on this menu the
502 setAppropriate() function is used to inform the main window
503 whether or not the dock window menu should include a particular
504 dock window. Double clicking a dock window handle (usually on the
505 left-hand side of the dock window) undocks (floats) the dock
506 window. Double clicking a floating dock window's title bar will
507 dock the floating dock window. (See also
508 \l{Q3MainWindow::DockWindows}.)
509
510 Some functions change the appearance of a Q3MainWindow globally:
511 \list
512 \i Q3DockWindow::setHorizontalStretchable() and
513 Q3DockWindow::setVerticalStretchable() are used to make specific dock
514 windows or toolbars stretchable.
515 \i setUsesBigPixmaps() is used to set whether tool buttons should
516 draw small or large pixmaps (see QIcon for more information).
517 \i setUsesTextLabel() is used to set whether tool buttons
518 should display a textual label in addition to pixmaps
519 (see QToolButton for more information).
520 \endlist
521
522 The user can drag dock windows into any enabled docking area. Qt::Dock
523 windows can also be dragged \e within a docking area, for example
524 to rearrange the order of some toolbars. Qt::Dock windows can also be
525 dragged outside any docking area (undocked or 'floated'). Being
526 able to drag dock windows can be enabled (the default) and
527 disabled using setDockWindowsMovable().
528
529 The \c Minimized edge is a hidden dock area. If this dock area is
530 enabled the user can hide (minimize) a dock window or show (restore)
531 a minimized dock window by clicking the dock window handle. If the
532 user hovers the mouse cursor over one of the handles, the caption of
533 the dock window is displayed in a tool tip (see
534 Q3DockWindow::windowTitle() or Q3ToolBar::label()), so if you enable the
535 \c Minimized dock area, it is best to specify a meaningful caption
536 or label for each dock window. To minimize a dock window
537 programmatically use moveDockWindow() with an edge of \c Minimized.
538
539 Qt::Dock windows are moved transparently by default, i.e. during the
540 drag an outline rectangle is drawn on the screen representing the
541 position of the dock window as it moves. If you want the dock
542 window to be shown normally whilst it is moved use
543 setOpaqueMoving().
544
545 The location of a dock window, i.e. its dock area and position
546 within the dock area, can be determined by calling getLocation().
547 Movable dock windows can be lined up to minimize wasted space with
548 lineUpDockWindows(). Pointers to the dock areas are available from
549 topDock(), leftDock(), rightDock() and bottomDock(). A customize
550 menu item is added to the pop up dock window menu if
551 isCustomizable() returns true; it returns false by default.
552 Reimplement isCustomizable() and customize() if you want to offer
553 this extra menu item, for example, to allow the user to change
554 settings relating to the main window and its toolbars and dock
555 windows.
556
557 The main window's menu bar is fixed (at the top) by default. If
558 you want a movable menu bar, create a QMenuBar as a stretchable
559 widget inside its own movable dock window and restrict this dock
560 window to only live within the \c Top or \c Bottom dock:
561
562 \snippet doc/src/snippets/code/src_qt3support_widgets_q3mainwindow.cpp 1
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 \snippet doc/src/snippets/code/src_qt3support_widgets_q3mainwindow.cpp 2
572
573 To restore the dock window positions and sizes (normally when the
574 application is next started), do the following:
575
576 \snippet doc/src/snippets/code/src_qt3support_widgets_q3mainwindow.cpp 3
577
578 The QSettings class can be used in conjunction with the streaming
579 operators to store the application's settings.
580
581 Q3MainWindow's management of dock windows and toolbars is done
582 transparently behind-the-scenes by Q3DockArea.
583
584 For multi-document interfaces (MDI), use a QWorkspace as the
585 central widget.
586
587 Adding dock windows, e.g. toolbars, to Q3MainWindow's dock areas is
588 straightforward. If the supplied dock areas are not sufficient for
589 your application we suggest that you create a QWidget subclass and
590 add your own dock areas (see \l Q3DockArea) to the subclass since
591 Q3MainWindow provides functionality specific to the standard dock
592 areas it provides.
593
594 \sa Q3ToolBar Q3DockWindow QStatusBar QAction QMenuBar Q3PopupMenu QDialog
595*/
596
597/*!
598 \enum Q3MainWindow::DockWindows
599
600 Right-clicking a dock area will pop-up the dock window menu
601 (createDockWindowMenu() is called automatically). When called in
602 code you can specify what items should appear on the menu with
603 this enum.
604
605 \value OnlyToolBars The menu will list all the toolbars, but not
606 any other dock windows.
607
608 \value NoToolBars The menu will list dock windows but not
609 toolbars.
610
611 \value AllDockWindows The menu will list all toolbars and other
612 dock windows. (This is the default.)
613*/
614
615/*!
616 \fn void Q3MainWindow::addToolBar(Q3DockWindow *dockWindow,
617 Qt::Dock position, bool newLine);
618
619 Adds a new toolbar to the \a dockWindow. The toolbar is placed in
620 the given \a position. If \a newLine is true the toolbar is put on
621 a new line.
622*/
623
624/*!
625 \fn void Q3MainWindow::addToolBar(Q3DockWindow *dockWindow, const
626 QString &label, Qt::Dock position, bool newLine)
627 \overload
628
629 The toolbar has the caption \a label and is placed in the given \a
630 position.
631*/
632
633/*!
634 \fn void Q3MainWindow::moveToolBar(Q3DockWindow *dockWindow, Qt::Dock position);
635
636 Moves the given \a dockWindow into the given \a position.
637*/
638
639/*!
640 \fn void Q3MainWindow::moveToolBar(Q3DockWindow *dockWindow,
641 Qt::Dock position, bool nl, int index, int extraOffset)
642 \overload
643
644 The \a dockWindow is made the \a{index}-th item in the toolbar,
645 moved over by \a extraOffset. If \a nl is true, the dock window is
646 put on a new line.
647*/
648
649/*!
650 \fn void Q3MainWindow::removeToolBar(Q3DockWindow *dockWindow);
651
652 Removes the toolbar from the given \a dockWindow.
653*/
654
655/*!
656 \fn void Q3MainWindow::lineUpToolBars(bool keepNewLines);
657
658 Lines up the toolbars. Line breaks are preserved if \a
659 keepNewLines is true.
660*/
661
662/*!
663 \fn void Q3MainWindow::toolBarPositionChanged(Q3ToolBar *toolbar);
664
665 This signal is emitted when a \a toolbar is moved.
666*/
667
668/*!
669 \fn bool Q3MainWindow::toolBarsMovable() const
670
671 Returns true if the window allows its toolbars to be moved; otherwise
672 returns false.
673*/
674
675/*!
676 \fn void Q3MainWindow::setToolBarsMovable(bool b)
677 If \a b is true the tool bars can be moved.
678*/
679
680/*!
681 Constructs an empty main window. The \a parent, \a name and widget
682 flags \a f, are passed on to the QWidget constructor.
683
684 By default, the widget flags are set to Qt::WType_TopLevel rather
685 than 0 as they are with QWidget. If you don't want your
686 Q3MainWindow to be a top level widget then you will need to set \a
687 f to 0.
688*/
689
690Q3MainWindow::Q3MainWindow(QWidget * parent, const char * name, Qt::WindowFlags f)
691 : QWidget(*new Q3MainWindowPrivate, parent, f)
692{
693 Q_D(Q3MainWindow);
694 setObjectName(QLatin1String(name));
695#ifdef Q_WS_MAC
696 d->opaque = true;
697#else
698 d->opaque = false;
699#endif
700 installEventFilter(this);
701 d->topDock = new Q3DockArea(Qt::Horizontal, Q3DockArea::Normal, this, "qt_top_dock");
702 d->topDock->installEventFilter(this);
703 d->bottomDock = new Q3DockArea(Qt::Horizontal, Q3DockArea::Reverse, this, "qt_bottom_dock");
704 d->bottomDock->installEventFilter(this);
705 d->leftDock = new Q3DockArea(Qt::Vertical, Q3DockArea::Normal, this, "qt_left_dock");
706 d->leftDock->installEventFilter(this);
707 d->rightDock = new Q3DockArea(Qt::Vertical, Q3DockArea::Reverse, this, "qt_right_dock");
708 d->rightDock->installEventFilter(this);
709 d->hideDock = new QHideDock(this);
710}
711
712
713/*!
714 Destroys the object and frees any allocated resources.
715*/
716
717Q3MainWindow::~Q3MainWindow()
718{
719 delete layout();
720}
721
722#ifndef QT_NO_MENUBAR
723/*!
724 Sets this main window to use the menu bar \a newMenuBar.
725
726 The existing menu bar (if any) is deleted along with its contents.
727
728 \sa menuBar()
729*/
730
731void Q3MainWindow::setMenuBar(QMenuBar * newMenuBar)
732{
733 Q_D(Q3MainWindow);
734 if (!newMenuBar)
735 return;
736 if (d->mb)
737 delete d->mb;
738 d->mb = newMenuBar;
739 d->mb->installEventFilter(this);
740 triggerLayout();
741}
742
743
744/*!
745 Returns the menu bar for this window.
746
747 If there isn't one, then menuBar() creates an empty menu bar.
748
749 \sa statusBar()
750*/
751
752QMenuBar * Q3MainWindow::menuBar() const
753{
754 Q_D(const Q3MainWindow);
755 if (d->mb)
756 return d->mb;
757
758 QObjectList l = queryList("QMenuBar", 0, false, false);
759 QMenuBar * b;
760 if (l.size()) {
761 b = static_cast<QMenuBar *>(l.at(0));
762 } else {
763 b = new QMenuBar((Q3MainWindow *)this);
764 b->setObjectName(QLatin1String("automatic menu bar"));
765 b->show();
766 }
767 d->mb = b;
768 d->mb->installEventFilter(const_cast<Q3MainWindow *>(this));
769 ((Q3MainWindow *)this)->triggerLayout();
770 return b;
771}
772#endif // QT_NO_MENUBAR
773
774/*!
775 Sets this main window to use the status bar \a newStatusBar.
776
777 The existing status bar (if any) is deleted along with its
778 contents.
779
780 Note that \a newStatusBar \e must be a child of this main window,
781 and that it is not automatically displayed. If you call this
782 function after show(), you will probably also need to call
783 newStatusBar->show().
784
785 \sa setMenuBar() statusBar()
786*/
787
788void Q3MainWindow::setStatusBar(QStatusBar * newStatusBar)
789{
790 Q_D(Q3MainWindow);
791 if (!newStatusBar || newStatusBar == d->sb)
792 return;
793 if (d->sb)
794 delete d->sb;
795 d->sb = newStatusBar;
796#if 0
797 // ### this code can cause unnecessary creation of a tool tip group
798 connect(toolTipGroup(), SIGNAL(showTip(QString)),
799 d->sb, SLOT(showMessage(QString)));
800 connect(toolTipGroup(), SIGNAL(removeTip()),
801 d->sb, SLOT(clearMessage()));
802#endif
803 d->sb->installEventFilter(this);
804 triggerLayout();
805}
806
807
808/*!
809 Returns this main window's status bar. If there isn't one,
810 statusBar() creates an empty status bar, and if necessary a tool
811 tip group too.
812
813 \sa menuBar()
814*/
815
816QStatusBar * Q3MainWindow::statusBar() const
817{
818 Q_D(const Q3MainWindow);
819 if (d->sb)
820 return d->sb;
821
822 QObjectList l = queryList("QStatusBar", 0, false, false);
823 QStatusBar * s;
824 if (l.size()) {
825 s = (QStatusBar *)l.at(0);
826 } else {
827 s = new QStatusBar((Q3MainWindow *)this, "automatic status bar");
828 s->show();
829 }
830 ((Q3MainWindow *)this)->setStatusBar(s);
831 ((Q3MainWindow *)this)->triggerLayout(true);
832 return s;
833}
834
835
836#if 0
837/*!
838 Sets this main window to use the tool tip group \a
839 newToolTipGroup.
840
841 The existing tool tip group (if any) is deleted along with its
842 contents. All the tool tips connected to it lose the ability to
843 display the group texts.
844
845 \sa menuBar()
846*/
847
848void Q3MainWindow::setToolTipGroup(QToolTipGroup * newToolTipGroup)
849{
850 Q_D(Q3MainWindow);
851 if (!newToolTipGroup || newToolTipGroup == d->ttg)
852 return;
853 if (d->ttg)
854 delete d->ttg;
855 d->ttg = newToolTipGroup;
856
857 connect(toolTipGroup(), SIGNAL(showTip(QString)),
858 statusBar(), SLOT(showMessage(QString)));
859 connect(toolTipGroup(), SIGNAL(removeTip()),
860 statusBar(), SLOT(clearMessage()));
861}
862
863
864/*!
865 Returns this main window's tool tip group. If there isn't one,
866 toolTipGroup() creates an empty tool tip group.
867
868 \sa menuBar() statusBar()
869*/
870QToolTipGroup * Q3MainWindow::toolTipGroup() const
871{
872 Q_D(const Q3MainWindow);
873 if (d->ttg)
874 return d->ttg;
875
876 QToolTipGroup * t = new QToolTipGroup((Q3MainWindow*)this,
877 "automatic tool tip group");
878 ((Q3MainWindowPrivate*)d)->ttg = t;
879 return t;
880}
881#endif
882
883
884/*!
885 If \a enable is true then users can dock windows in the \a dock
886 area. If \a enable is false users cannot dock windows in the \a
887 dock dock area.
888
889 Users can dock (drag) dock windows into any enabled dock area.
890*/
891
892void Q3MainWindow::setDockEnabled(Qt::Dock dock, bool enable)
893{
894 d_func()->docks.insert(dock, enable);
895}
896
897
898/*!
899 Returns true if the \a dock dock area is enabled, i.e. it can
900 accept user dragged dock windows; otherwise returns false.
901
902 \sa setDockEnabled()
903*/
904
905bool Q3MainWindow::isDockEnabled(Qt::Dock dock) const
906{
907 return d_func()->docks[dock];
908}
909
910/*!
911 \overload
912
913 Returns true if dock area \a area is enabled, i.e. it can accept
914 user dragged dock windows; otherwise returns false.
915
916 \sa setDockEnabled()
917*/
918
919bool Q3MainWindow::isDockEnabled(Q3DockArea *area) const
920{
921 Q_D(const Q3MainWindow);
922 if (area == d->leftDock)
923 return d->docks[Qt::DockLeft];
924 if (area == d->rightDock)
925 return d->docks[Qt::DockRight];
926 if (area == d->topDock)
927 return d->docks[Qt::DockTop];
928 if (area == d->bottomDock)
929 return d->docks[Qt::DockBottom];
930 return false;
931}
932
933/*!
934 \overload
935
936 If \a enable is true then users can dock the \a dw dock window in
937 the \a dock area. If \a enable is false users cannot dock the \a
938 dw dock window in the \a dock area.
939
940 In general users can dock (drag) dock windows into any enabled
941 dock area. Using this function particular dock areas can be
942 enabled (or disabled) as docking points for particular dock
943 windows.
944*/
945
946
947void Q3MainWindow::setDockEnabled(Q3DockWindow *dw, Qt::Dock dock, bool enable)
948{
949 Q_D(Q3MainWindow);
950 if (!d->dockWindows.contains(dw)) {
951 d->dockWindows.append(dw);
952 connect(dw, SIGNAL(placeChanged(Q3DockWindow::Place)),
953 this, SLOT(slotPlaceChanged()));
954 }
955 QString s;
956 s.sprintf("%p_%d", (void*)dw, (int)dock);
957 if (enable)
958 d->disabledDocks.removeAll(s);
959 else if (!d->disabledDocks.contains(s))
960 d->disabledDocks << s;
961 switch (dock) {
962 case Qt::DockTop:
963 topDock()->setAcceptDockWindow(dw, enable);
964 break;
965 case Qt::DockLeft:
966 leftDock()->setAcceptDockWindow(dw, enable);
967 break;
968 case Qt::DockRight:
969 rightDock()->setAcceptDockWindow(dw, enable);
970 break;
971 case Qt::DockBottom:
972 bottomDock()->setAcceptDockWindow(dw, enable);
973 break;
974 default:
975 break;
976 }
977}
978
979/*!
980 \overload
981
982 Returns true if dock area \a area is enabled for the dock window
983 \a dw; otherwise returns false.
984
985 \sa setDockEnabled()
986*/
987
988bool Q3MainWindow::isDockEnabled(Q3DockWindow *dw, Q3DockArea *area) const
989{
990 Q_D(const Q3MainWindow);
991 if (!isDockEnabled(area))
992 return false;
993 Qt::Dock dock;
994 if (area == d->leftDock)
995 dock = Qt::DockLeft;
996 else if (area == d->rightDock)
997 dock = Qt::DockRight;
998 else if (area == d->topDock)
999 dock = Qt::DockTop;
1000 else if (area == d->bottomDock)
1001 dock = Qt::DockBottom;
1002 else
1003 return false;
1004 return isDockEnabled(dw, dock);
1005}
1006
1007/*!
1008 \overload
1009
1010 Returns true if dock area \a dock is enabled for the dock window
1011 \a tb; otherwise returns false.
1012
1013 \sa setDockEnabled()
1014*/
1015
1016bool Q3MainWindow::isDockEnabled(Q3DockWindow *tb, Qt::Dock dock) const
1017{
1018 if (!isDockEnabled(dock))
1019 return false;
1020 QString s;
1021 s.sprintf("%p_%d", (void*)tb, (int)dock);
1022 return !d_func()->disabledDocks.contains(s);
1023}
1024
1025
1026
1027/*!
1028 Adds \a dockWindow to the \a edge dock area.
1029
1030 If \a newLine is false (the default) then the \a dockWindow is
1031 added at the end of the \a edge. For vertical edges the end is at
1032 the bottom, for horizontal edges (including \c Minimized) the end
1033 is at the right. If \a newLine is true a new line of dock windows
1034 is started with \a dockWindow as the first (left-most and
1035 top-most) dock window.
1036
1037 If \a dockWindow is managed by another main window, it is first
1038 removed from that window.
1039*/
1040
1041void Q3MainWindow::addDockWindow(Q3DockWindow *dockWindow,
1042 Qt::Dock edge, bool newLine)
1043{
1044 Q_D(Q3MainWindow);
1045#if defined (Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
1046 extern WindowPtr qt_mac_window_for(const QWidget*); //qwidget_mac.cpp
1047 if(isWindow() && edge == Qt::DockTop) {
1048 d->createWinId();
1049 ChangeWindowAttributes(qt_mac_window_for(this), kWindowToolbarButtonAttribute, 0);
1050 }
1051#endif
1052 moveDockWindow(dockWindow, edge);
1053 dockWindow->setNewLine(newLine);
1054 if (!d->dockWindows.contains(dockWindow)) {
1055 d->dockWindows.append(dockWindow);
1056 connect(dockWindow, SIGNAL(placeChanged(Q3DockWindow::Place)),
1057 this, SLOT(slotPlaceChanged()));
1058 dockWindow->installEventFilter(this);
1059 }
1060 dockWindow->setOpaqueMoving(d->opaque);
1061}
1062
1063
1064/*!
1065 \overload
1066
1067 Adds \a dockWindow to the dock area with label \a label.
1068
1069 If \a newLine is false (the default) the \a dockWindow is added at
1070 the end of the \a edge. For vertical edges the end is at the
1071 bottom, for horizontal edges (including \c Minimized) the end is
1072 at the right. If \a newLine is true a new line of dock windows is
1073 started with \a dockWindow as the first (left-most and top-most)
1074 dock window.
1075
1076 If \a dockWindow is managed by another main window, it is first
1077 removed from that window.
1078*/
1079
1080void Q3MainWindow::addDockWindow(Q3DockWindow * dockWindow, const QString &label,
1081 Qt::Dock edge, bool newLine)
1082{
1083 addDockWindow(dockWindow, edge, newLine);
1084#ifndef QT_NO_TOOLBAR
1085 Q3ToolBar *tb = qobject_cast<Q3ToolBar*>(dockWindow);
1086 if (tb)
1087 tb->setLabel(label);
1088#endif
1089}
1090
1091/*!
1092 Moves \a dockWindow to the end of the \a edge.
1093
1094 For vertical edges the end is at the bottom, for horizontal edges
1095 (including \c Minimized) the end is at the right.
1096
1097 If \a dockWindow is managed by another main window, it is first
1098 removed from that window.