source: trunk/src/gui/widgets/qstatusbar.cpp@ 350

Last change on this file since 350 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 23.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qstatusbar.h"
43#ifndef QT_NO_STATUSBAR
44
45#include "qlist.h"
46#include "qdebug.h"
47#include "qevent.h"
48#include "qlayout.h"
49#include "qpainter.h"
50#include "qtimer.h"
51#include "qstyle.h"
52#include "qstyleoption.h"
53#include "qsizegrip.h"
54#include "qmainwindow.h"
55
56#include <private/qlayoutengine_p.h>
57#include <private/qwidget_p.h>
58
59QT_BEGIN_NAMESPACE
60
61class QStatusBarPrivate : public QWidgetPrivate
62{
63 Q_DECLARE_PUBLIC(QStatusBar)
64public:
65 QStatusBarPrivate() {}
66
67 struct SBItem {
68 SBItem(QWidget* widget, int stretch, bool permanent)
69 : s(stretch), w(widget), p(permanent) {}
70 int s;
71 QWidget * w;
72 bool p;
73 };
74
75 QList<SBItem *> items;
76 QString tempItem;
77
78 QBoxLayout * box;
79 QTimer * timer;
80
81#ifndef QT_NO_SIZEGRIP
82 QSizeGrip * resizer;
83 bool showSizeGrip;
84#endif
85
86 int savedStrut;
87
88#ifdef Q_WS_MAC
89 QPoint dragStart;
90#endif
91
92 int indexToLastNonPermanentWidget() const
93 {
94 int i = items.size() - 1;
95 for (; i >= 0; --i) {
96 SBItem *item = items.at(i);
97 if (!(item && item->p))
98 break;
99 }
100 return i;
101 }
102
103#ifndef QT_NO_SIZEGRIP
104 void tryToShowSizeGrip()
105 {
106 if (!showSizeGrip)
107 return;
108 showSizeGrip = false;
109 if (!resizer || resizer->isVisible())
110 return;
111 resizer->setAttribute(Qt::WA_WState_ExplicitShowHide, false);
112 QMetaObject::invokeMethod(resizer, "_q_showIfNotHidden", Qt::DirectConnection);
113 resizer->setAttribute(Qt::WA_WState_ExplicitShowHide, false);
114 }
115#endif
116
117 QRect messageRect() const;
118};
119
120
121QRect QStatusBarPrivate::messageRect() const
122{
123 Q_Q(const QStatusBar);
124 bool rtl = q->layoutDirection() == Qt::RightToLeft;
125
126 int left = 6;
127 int right = q->width() - 12;
128
129#ifndef QT_NO_SIZEGRIP
130 if (resizer && resizer->isVisible()) {
131 if (rtl)
132 left = resizer->x() + resizer->width();
133 else
134 right = resizer->x();
135 }
136#endif
137
138 for (int i=0; i<items.size(); ++i) {
139 QStatusBarPrivate::SBItem* item = items.at(i);
140 if (!item)
141 break;
142 if (item->p && item->w->isVisible()) {
143 if (item->p) {
144 if (rtl)
145 left = qMax(left, item->w->x() + item->w->width() + 2);
146 else
147 right = qMin(right, item->w->x()-1);
148 }
149 break;
150 }
151 }
152 return QRect(left, 0, right-left, q->height());
153}
154
155
156/*!
157 \class QStatusBar
158 \brief The QStatusBar class provides a horizontal bar suitable for
159 presenting status information.
160
161 \ingroup application
162 \ingroup helpsystem
163 \mainclass
164
165 Each status indicator falls into one of three categories:
166
167 \list
168 \o \e Temporary - briefly occupies most of the status bar. Used
169 to explain tool tip texts or menu entries, for example.
170 \o \e Normal - occupies part of the status bar and may be hidden
171 by temporary messages. Used to display the page and line
172 number in a word processor, for example.
173 \o \e Permanent - is never hidden. Used for important mode
174 indications, for example, some applications put a Caps Lock
175 indicator in the status bar.
176 \endlist
177
178 QStatusBar lets you display all three types of indicators.
179
180 Typically, a request for the status bar functionality occurs in
181 relation to a QMainWindow object. QMainWindow provides a main
182 application window, with a menu bar, tool bars, dock widgets \e
183 and a status bar around a large central widget. The status bar can
184 be retrieved using the QMainWindow::statusBar() function, and
185 replaced using the QMainWindow::setStatusBar() function.
186
187 Use the showMessage() slot to display a \e temporary message:
188
189 \snippet examples/mainwindows/dockwidgets/mainwindow.cpp 8
190
191 To remove a temporary message, use the clearMessage() slot, or set
192 a time limit when calling showMessage(). For example:
193
194 \snippet examples/mainwindows/dockwidgets/mainwindow.cpp 3
195
196 Use the currentMessage() function to retrieve the temporary
197 message currently shown. The QStatusBar class also provide the
198 messageChanged() signal which is emitted whenever the temporary
199 status message changes.
200
201 \target permanent message
202 \e Normal and \e Permanent messages are displayed by creating a
203 small widget (QLabel, QProgressBar or even QToolButton) and then
204 adding it to the status bar using the addWidget() or the
205 addPermanentWidget() function. Use the removeWidget() function to
206 remove such messages from the status bar.
207
208 \snippet doc/src/snippets/code/src_gui_widgets_qstatusbar.cpp 0
209
210 By default QStatusBar provides a QSizeGrip in the lower-right
211 corner. You can disable it using the setSizeGripEnabled()
212 function. Use the isSizeGripEnabled() function to determine the
213 current status of the size grip.
214
215 \image plastique-statusbar.png A status bar shown in the Plastique widget style
216
217 \sa QMainWindow, QStatusTipEvent, {fowler}{GUI Design Handbook:
218 Status Bar}, {Application Example}
219*/
220
221#ifdef QT3_SUPPORT
222/*!
223 Constructs a status bar with a size grip and the given \a parent
224 and object \a name.
225
226 Use the QStatusBar() constructor and the QObject::setObjectName()
227 function instead.
228
229 \oldcode
230 QStatusBar *myStatusBar = new QStatusBar(parent, name);
231 \newcode
232 QStatusBar *myStatusBar = new QStatusBar(parent);
233 myStatusBar->setObjectName(name);
234 \endcode
235*/
236QStatusBar::QStatusBar(QWidget * parent, const char *name)
237 : QWidget(*new QStatusBarPrivate, parent, 0)
238{
239 Q_D(QStatusBar);
240 setObjectName(QString::fromAscii(name));
241 d->box = 0;
242 d->timer = 0;
243
244#ifndef QT_NO_SIZEGRIP
245 d->resizer = 0;
246 d->showSizeGrip = false;
247 setSizeGripEnabled(true); // causes reformat()
248#else
249 reformat();
250#endif
251}
252
253
254/*!
255 \fn void QStatusBar::addWidget(QWidget * widget, int stretch, bool permanent)
256
257 Use addWidget() or addPermanentWidget() instead, depending on the
258 value of the \a permanent parameter.
259
260 \oldcode
261 QStatusBar *myStatusBar;
262 myStatusBar->addWidget(widget, stretch, permanent); // permanent == true
263 \newcode
264 QStatusBar *myStatusBar;
265 myStatusBar->addPermanentWidget(widget, stretch);
266 \endcode
267 */
268
269#endif
270
271/*!
272 Constructs a status bar with a size grip and the given \a parent.
273
274 \sa setSizeGripEnabled()
275*/
276QStatusBar::QStatusBar(QWidget * parent)
277 : QWidget(*new QStatusBarPrivate, parent, 0)
278{
279 Q_D(QStatusBar);
280 d->box = 0;
281 d->timer = 0;
282
283#ifndef QT_NO_SIZEGRIP
284 d->resizer = 0;
285 setSizeGripEnabled(true); // causes reformat()
286#else
287 reformat();
288#endif
289}
290
291/*!
292 Destroys this status bar and frees any allocated resources and
293 child widgets.
294*/
295QStatusBar::~QStatusBar()
296{
297 Q_D(QStatusBar);
298 while (!d->items.isEmpty())
299 delete d->items.takeFirst();
300}
301
302
303/*!
304 Adds the given \a widget to this status bar, reparenting the
305 widget if it isn't already a child of this QStatusBar object. The
306 \a stretch parameter is used to compute a suitable size for the
307 given \a widget as the status bar grows and shrinks. The default
308 stretch factor is 0, i.e giving the widget a minimum of space.
309
310 The widget is located to the far left of the first permanent
311 widget (see addPermanentWidget()) and may be obscured by temporary
312 messages.
313
314 \sa insertWidget(), removeWidget(), addPermanentWidget()
315*/
316
317void QStatusBar::addWidget(QWidget * widget, int stretch)
318{
319 if (!widget)
320 return;
321 insertWidget(d_func()->indexToLastNonPermanentWidget() + 1, widget, stretch);
322}
323
324/*!
325 \since 4.2
326
327 Inserts the given \a widget at the given \a index to this status bar,
328 reparenting the widget if it isn't already a child of this
329 QStatusBar object. If \a index is out of range, the widget is appended
330 (in which case it is the actual index of the widget that is returned).
331
332 The \a stretch parameter is used to compute a suitable size for
333 the given \a widget as the status bar grows and shrinks. The
334 default stretch factor is 0, i.e giving the widget a minimum of
335 space.
336
337 The widget is located to the far left of the first permanent
338 widget (see addPermanentWidget()) and may be obscured by temporary
339 messages.
340
341 \sa addWidget(), removeWidget(), addPermanentWidget()
342*/
343int QStatusBar::insertWidget(int index, QWidget *widget, int stretch)
344{
345 if (!widget)
346 return -1;
347
348 Q_D(QStatusBar);
349 QStatusBarPrivate::SBItem* item = new QStatusBarPrivate::SBItem(widget, stretch, false);
350
351 int idx = d->indexToLastNonPermanentWidget();
352 if (index < 0 || index > d->items.size() || (idx >= 0 && index > idx + 1)) {
353 qWarning("QStatusBar::insertWidget: Index out of range (%d), appending widget", index);
354 index = idx + 1;
355 }
356 d->items.insert(index, item);
357
358 if (!d->tempItem.isEmpty())
359 widget->hide();
360
361 reformat();
362 if (!widget->isHidden() || !widget->testAttribute(Qt::WA_WState_ExplicitShowHide))
363 widget->show();
364
365 return index;
366}
367
368/*!
369 Adds the given \a widget permanently to this status bar,
370 reparenting the widget if it isn't already a child of this
371 QStatusBar object. The \a stretch parameter is used to compute a
372 suitable size for the given \a widget as the status bar grows and
373 shrinks. The default stretch factor is 0, i.e giving the widget a
374 minimum of space.
375
376 Permanently means that the widget may not be obscured by temporary
377 messages. It is is located at the far right of the status bar.
378
379 \sa insertPermanentWidget(), removeWidget(), addWidget()
380*/
381
382void QStatusBar::addPermanentWidget(QWidget * widget, int stretch)
383{
384 if (!widget)
385 return;
386 insertPermanentWidget(d_func()->items.size(), widget, stretch);
387}
388
389
390/*!
391 \since 4.2
392
393 Inserts the given \a widget at the given \a index permanently to this status bar,
394 reparenting the widget if it isn't already a child of this
395 QStatusBar object. If \a index is out of range, the widget is appended
396 (in which case it is the actual index of the widget that is returned).
397
398 The \a stretch parameter is used to compute a
399 suitable size for the given \a widget as the status bar grows and
400 shrinks. The default stretch factor is 0, i.e giving the widget a
401 minimum of space.
402
403 Permanently means that the widget may not be obscured by temporary
404 messages. It is is located at the far right of the status bar.
405
406 \sa addPermanentWidget(), removeWidget(), addWidget()
407*/
408int QStatusBar::insertPermanentWidget(int index, QWidget *widget, int stretch)
409{
410 if (!widget)
411 return -1;
412
413 Q_D(QStatusBar);
414 QStatusBarPrivate::SBItem* item = new QStatusBarPrivate::SBItem(widget, stretch, true);
415
416 int idx = d->indexToLastNonPermanentWidget();
417 if (index < 0 || index > d->items.size() || (idx >= 0 && index <= idx)) {
418 qWarning("QStatusBar::insertPermanentWidget: Index out of range (%d), appending widget", index);
419 index = d->items.size();
420 }
421 d->items.insert(index, item);
422
423 reformat();
424 if (!widget->isHidden() || !widget->testAttribute(Qt::WA_WState_ExplicitShowHide))
425 widget->show();
426
427 return index;
428}
429
430/*!
431 Removes the specified \a widget from the status bar.
432
433 \note This function does not delete the widget but \e hides it.
434 To add the widget again, you must call both the addWidget() and
435 show() functions.
436
437 \sa addWidget(), addPermanentWidget(), clearMessage()
438*/
439
440void QStatusBar::removeWidget(QWidget *widget)
441{
442 if (!widget)
443 return;
444
445 Q_D(QStatusBar);
446 bool found = false;
447 QStatusBarPrivate::SBItem* item;
448 for (int i=0; i<d->items.size(); ++i) {
449 item = d->items.at(i);
450 if (!item)
451 break;
452 if (item->w == widget) {
453 d->items.removeAt(i);
454 item->w->hide();
455 delete item;
456 found = true;
457 break;
458 }
459 }
460
461 if (found)
462 reformat();
463#if defined(QT_DEBUG)
464 else
465 qDebug("QStatusBar::removeWidget(): Widget not found.");
466#endif
467}
468
469/*!
470 \property QStatusBar::sizeGripEnabled
471
472 \brief whether the QSizeGrip in the bottom-right corner of the
473 status bar is enabled
474
475 The size grip is enabled by default.
476*/
477
478bool QStatusBar::isSizeGripEnabled() const
479{
480#ifdef QT_NO_SIZEGRIP
481 return false;
482#else
483 Q_D(const QStatusBar);
484 return !!d->resizer;
485#endif
486}
487
488void QStatusBar::setSizeGripEnabled(bool enabled)
489{
490#ifdef QT_NO_SIZEGRIP
491 Q_UNUSED(enabled);
492#else
493 Q_D(QStatusBar);
494 if (!enabled != !d->resizer) {
495 if (enabled) {
496 d->resizer = new QSizeGrip(this);
497 d->resizer->hide();
498 d->resizer->installEventFilter(this);
499 d->showSizeGrip = true;
500 } else {
501 delete d->resizer;
502 d->resizer = 0;
503 d->showSizeGrip = false;
504 }
505 reformat();
506 if (d->resizer && isVisible())
507 d->tryToShowSizeGrip();
508 }
509#endif
510}
511
512
513/*!
514 Changes the status bar's appearance to account for item changes.
515
516 Special subclasses may need this function, but geometry management
517 will usually take care of any necessary rearrangements.
518*/
519void QStatusBar::reformat()
520{
521 Q_D(QStatusBar);
522 if (d->box)
523 delete d->box;
524
525 QBoxLayout *vbox;
526#ifndef QT_NO_SIZEGRIP
527 if (d->resizer) {
528 d->box = new QHBoxLayout(this);
529 d->box->setMargin(0);
530 vbox = new QVBoxLayout;
531 d->box->addLayout(vbox);
532 } else
533#endif
534 {
535 vbox = d->box = new QVBoxLayout(this);
536 d->box->setMargin(0);
537 }
538 vbox->addSpacing(3);
539 QBoxLayout* l = new QHBoxLayout;
540 vbox->addLayout(l);
541 l->addSpacing(2);
542 l->setSpacing(6);
543
544 int maxH = fontMetrics().height();
545
546 int i;
547 QStatusBarPrivate::SBItem* item;
548 for (i=0,item=0; i<d->items.size(); ++i) {
549 item = d->items.at(i);
550 if (!item || item->p)
551 break;
552 l->addWidget(item->w, item->s);
553 int itemH = qMin(qSmartMinSize(item->w).height(), item->w->maximumHeight());
554 maxH = qMax(maxH, itemH);
555 }
556
557 l->addStretch(0);
558
559 for (item=0; i<d->items.size(); ++i) {
560 item = d->items.at(i);
561 if (!item)
562 break;
563 l->addWidget(item->w, item->s);
564 int itemH = qMin(qSmartMinSize(item->w).height(), item->w->maximumHeight());
565 maxH = qMax(maxH, itemH);
566 }
567#ifndef QT_NO_SIZEGRIP
568 if (d->resizer) {
569 maxH = qMax(maxH, d->resizer->sizeHint().height());
570 d->box->addSpacing(1);
571 d->box->addWidget(d->resizer, 0, Qt::AlignBottom);
572 }
573#endif
574 l->addStrut(maxH);
575 d->savedStrut = maxH;
576 vbox->addSpacing(2);
577 d->box->activate();
578 repaint();
579}
580
581/*!
582
583 Hides the normal status indications and displays the given \a
584 message for the specified number of milli-seconds (\a{timeout}). If
585 \a{timeout} is 0 (default), the \a {message} remains displayed until
586 the clearMessage() slot is called or until the showMessage() slot is
587 called again to change the message.
588
589 Note that showMessage() is called to show temporary explanations of
590 tool tip texts, so passing a \a{timeout} of 0 is not sufficient to
591 display a \l{permanent message}{permanent message}.
592
593 \sa messageChanged(), currentMessage(), clearMessage()
594*/
595void QStatusBar::showMessage(const QString &message, int timeout)
596{
597 Q_D(QStatusBar);
598 if (d->tempItem == message)
599 return;
600
601 d->tempItem = message;
602
603 if (timeout > 0) {
604 if (!d->timer) {
605 d->timer = new QTimer(this);
606 connect(d->timer, SIGNAL(timeout()), this, SLOT(clearMessage()));
607 }
608 d->timer->start(timeout);
609 } else if (d->timer) {
610 delete d->timer;
611 d->timer = 0;
612 }
613
614 hideOrShow();
615}
616
617/*!
618 Removes any temporary message being shown.
619
620 \sa currentMessage(), showMessage(), removeWidget()
621*/
622
623void QStatusBar::clearMessage()
624{
625 Q_D(QStatusBar);
626 if (d->tempItem.isEmpty())
627 return;
628 if (d->timer) {
629 qDeleteInEventHandler(d->timer);
630 d->timer = 0;
631 }
632 d->tempItem.clear();
633 hideOrShow();
634}
635
636/*!
637 Returns the temporary message currently shown,
638 or an empty string if there is no such message.
639
640 \sa showMessage()
641*/
642QString QStatusBar::currentMessage() const
643{
644 Q_D(const QStatusBar);
645 return d->tempItem;
646}
647
648/*!
649 \fn void QStatusBar::message(const QString &message, int timeout)
650
651 Use the showMessage() function instead.
652*/
653
654/*!
655 \fn void QStatusBar::clear()
656
657 Use the clearMessage() function instead.
658*/
659
660/*!
661 \fn QStatusBar::messageChanged(const QString &message)
662
663 This signal is emitted whenever the temporary status message
664 changes. The new temporary message is passed in the \a message
665 parameter which is a null-string when the message has been
666 removed.
667
668 \sa showMessage(), clearMessage()
669*/
670
671/*!
672 Ensures that the right widgets are visible.
673
674 Used by the showMessage() and clearMessage() functions.
675*/
676void QStatusBar::hideOrShow()
677{
678 Q_D(QStatusBar);
679 bool haveMessage = !d->tempItem.isEmpty();
680
681 QStatusBarPrivate::SBItem* item = 0;
682 for (int i=0; i<d->items.size(); ++i) {
683 item = d->items.at(i);
684 if (!item || item->p)
685 break;
686 if (haveMessage && item->w->isVisible()) {
687 item->w->hide();
688 item->w->setAttribute(Qt::WA_WState_ExplicitShowHide, false);
689 } else if (!haveMessage && !item->w->testAttribute(Qt::WA_WState_ExplicitShowHide)) {
690 item->w->show();
691 }
692 }
693
694 emit messageChanged(d->tempItem);
695 repaint(d->messageRect());
696}
697
698/*!
699 \reimp
700 */
701void QStatusBar::showEvent(QShowEvent *)
702{
703#ifndef QT_NO_SIZEGRIP
704 Q_D(QStatusBar);
705 if (d->resizer && d->showSizeGrip)
706 d->tryToShowSizeGrip();
707#endif
708}
709
710/*!
711 \reimp
712 \fn void QStatusBar::paintEvent(QPaintEvent *event)
713
714 Shows the temporary message, if appropriate, in response to the
715 paint \a event.
716*/
717void QStatusBar::paintEvent(QPaintEvent *event)
718{
719 Q_D(QStatusBar);
720 bool haveMessage = !d->tempItem.isEmpty();
721
722 QPainter p(this);
723 QStyleOption opt;
724 opt.initFrom(this);
725 style()->drawPrimitive(QStyle::PE_PanelStatusBar, &opt, &p, this);
726
727 for (int i=0; i<d->items.size(); ++i) {
728 QStatusBarPrivate::SBItem* item = d->items.at(i);
729 if (item && item->w->isVisible() && (!haveMessage || item->p)) {
730 QRect ir = item->w->geometry().adjusted(-2, -1, 2, 1);
731 if (event->rect().contains(ir)) {
732 QStyleOption opt(0);
733 opt.rect = ir;
734 opt.palette = palette();
735 opt.state = QStyle::State_None;
736 style()->drawPrimitive(QStyle::PE_FrameStatusBarItem, &opt, &p, item->w);
737 }
738 }
739 }
740 if (haveMessage) {
741 p.setPen(palette().foreground().color());
742 p.drawText(d->messageRect(), Qt::AlignLeading | Qt::AlignVCenter | Qt::TextSingleLine, d->tempItem);
743 }
744}
745
746/*!
747 \reimp
748*/
749void QStatusBar::resizeEvent(QResizeEvent * e)
750{
751 QWidget::resizeEvent(e);
752}
753
754/*!
755 \reimp
756*/
757
758bool QStatusBar::event(QEvent *e)
759{
760 Q_D(QStatusBar);
761
762 if (e->type() == QEvent::LayoutRequest
763#ifdef QT3_SUPPORT
764 || e->type() == QEvent::LayoutHint
765#endif
766 ) {
767 // Calculate new strut height and call reformat() if it has changed
768 int maxH = fontMetrics().height();
769
770 QStatusBarPrivate::SBItem* item = 0;
771 for (int i=0; i<d->items.size(); ++i) {
772 item = d->items.at(i);
773 if (!item)
774 break;
775 int itemH = qMin(qSmartMinSize(item->w).height(), item->w->maximumHeight());
776 maxH = qMax(maxH, itemH);
777 }
778
779#ifndef QT_NO_SIZEGRIP
780 if (d->resizer)
781 maxH = qMax(maxH, d->resizer->sizeHint().height());
782#endif
783
784 if (maxH != d->savedStrut)
785 reformat();
786 else
787 update();
788 }
789 if (e->type() == QEvent::ChildRemoved) {
790 QStatusBarPrivate::SBItem* item = 0;
791 for (int i=0; i<d->items.size(); ++i) {
792 item = d->items.at(i);
793 if (!item)
794 break;
795 if (item->w == ((QChildEvent*)e)->child()) {
796 d->items.removeAt(i);
797 delete item;
798 }
799 }
800 }
801
802// On Mac OS X Leopard it is possible to drag the window by clicking
803// on the tool bar on most applications.
804#ifndef Q_WS_MAC
805 return QWidget::event(e);
806#else
807 if (QSysInfo::MacintoshVersion <= QSysInfo::MV_10_4)
808 return QWidget::event(e);
809
810 // Enable drag-click only if the status bar is the status bar for a
811 // QMainWindow with a unifed toolbar.
812 if (parent() == 0 || qobject_cast<QMainWindow *>(parent()) == 0 ||
813 qobject_cast<QMainWindow *>(parent())->unifiedTitleAndToolBarOnMac() == false )
814 return QWidget::event(e);
815
816 // Check for mouse events.
817 QMouseEvent *mouseEvent;
818 if (e->type() == QEvent::MouseButtonPress ||
819 e->type() == QEvent::MouseMove ||
820 e->type() == QEvent::MouseButtonRelease) {
821 mouseEvent = static_cast <QMouseEvent*>(e);
822 } else {
823 return QWidget::event(e);
824 }
825
826 // The following is a standard mouse drag handler.
827 if (e->type() == QEvent::MouseButtonPress && (mouseEvent->button() == Qt::LeftButton)) {
828 d->dragStart = mouseEvent->pos();
829 } else if (e->type() == QEvent::MouseMove){
830 if (d->dragStart == QPoint())
831 return QWidget::event(e);
832 QPoint pos = mouseEvent->pos();
833 QPoint delta = (pos - d->dragStart);
834 window()->move(window()->pos() + delta);
835 } else if (e->type() == QEvent::MouseButtonRelease && (mouseEvent->button() == Qt::LeftButton)){
836 d->dragStart = QPoint();
837 } else {
838 return QWidget::event(e);
839 }
840
841 return true;
842#endif
843}
844
845QT_END_NAMESPACE
846
847#endif
Note: See TracBrowser for help on using the repository browser.