src/gui/widgets/qstatusbar.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 
       
    59 QT_BEGIN_NAMESPACE
       
    60 
       
    61 class QStatusBarPrivate : public QWidgetPrivate
       
    62 {
       
    63     Q_DECLARE_PUBLIC(QStatusBar)
       
    64 public:
       
    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 
       
   121 QRect 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() - 2);
       
   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 mainwindow-classes
       
   162     \ingroup helpsystem
       
   163 
       
   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 */
       
   236 QStatusBar::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 */
       
   276 QStatusBar::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 */
       
   295 QStatusBar::~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 
       
   317 void 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 */
       
   343 int 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 
       
   382 void 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 */
       
   408 int 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 
       
   440 void 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 
       
   478 bool 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 
       
   488 void 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 */
       
   519 void 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 */
       
   595 void 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 
       
   623 void 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 */
       
   642 QString 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 */
       
   676 void 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  */
       
   701 void 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 */
       
   717 void 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().intersects(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 */
       
   749 void QStatusBar::resizeEvent(QResizeEvent * e)
       
   750 {
       
   751     QWidget::resizeEvent(e);
       
   752 }
       
   753 
       
   754 /*!
       
   755     \reimp
       
   756 */
       
   757 
       
   758 bool 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 
       
   845 QT_END_NAMESPACE
       
   846 
       
   847 #endif