src/gui/widgets/qsplashscreen.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 "qsplashscreen.h"
       
    43 
       
    44 #ifndef QT_NO_SPLASHSCREEN
       
    45 
       
    46 #include "qapplication.h"
       
    47 #include "qdesktopwidget.h"
       
    48 #include "qpainter.h"
       
    49 #include "qpixmap.h"
       
    50 #include "qtextdocument.h"
       
    51 #include "qtextcursor.h"
       
    52 #include <QtCore/qdebug.h>
       
    53 #include <private/qwidget_p.h>
       
    54 
       
    55 QT_BEGIN_NAMESPACE
       
    56 
       
    57 class QSplashScreenPrivate : public QWidgetPrivate
       
    58 {
       
    59     Q_DECLARE_PUBLIC(QSplashScreen)
       
    60 public:
       
    61     QPixmap pixmap;
       
    62     QString currStatus;
       
    63     QColor currColor;
       
    64     int currAlign;
       
    65 
       
    66     inline QSplashScreenPrivate();
       
    67     void drawContents();
       
    68 };
       
    69 
       
    70 /*!
       
    71    \class QSplashScreen
       
    72    \brief The QSplashScreen widget provides a splash screen that can
       
    73    be shown during application startup.
       
    74 
       
    75    A splash screen is a widget that is usually displayed when an
       
    76    application is being started. Splash screens are often used for
       
    77    applications that have long start up times (e.g. database or
       
    78    networking applications that take time to establish connections) to
       
    79    provide the user with feedback that the application is loading.
       
    80 
       
    81    The splash screen appears in the center of the screen. It may be
       
    82    useful to add the Qt::WindowStaysOnTopHint to the splash widget's
       
    83    window flags if you want to keep it above all the other windows on
       
    84    the desktop.
       
    85 
       
    86    Some X11 window managers do not support the "stays on top" flag. A
       
    87    solution is to set up a timer that periodically calls raise() on
       
    88    the splash screen to simulate the "stays on top" effect.
       
    89 
       
    90    The most common usage is to show a splash screen before the main
       
    91    widget is displayed on the screen. This is illustrated in the
       
    92    following code snippet in which a splash screen is displayed and
       
    93    some initialization tasks are performed before the application's
       
    94    main window is shown:
       
    95 
       
    96    \snippet doc/src/snippets/qsplashscreen/main.cpp 0
       
    97    \dots
       
    98    \snippet doc/src/snippets/qsplashscreen/main.cpp 1
       
    99 
       
   100    The user can hide the splash screen by clicking on it with the
       
   101    mouse. Since the splash screen is typically displayed before the
       
   102    event loop has started running, it is necessary to periodically
       
   103    call QApplication::processEvents() to receive the mouse clicks.
       
   104 
       
   105    It is sometimes useful to update the splash screen with messages,
       
   106    for example, announcing connections established or modules loaded
       
   107    as the application starts up:
       
   108 
       
   109    \snippet doc/src/snippets/code/src_gui_widgets_qsplashscreen.cpp 0
       
   110 
       
   111    QSplashScreen supports this with the showMessage() function. If you
       
   112    wish to do your own drawing you can get a pointer to the pixmap
       
   113    used in the splash screen with pixmap().  Alternatively, you can
       
   114    subclass QSplashScreen and reimplement drawContents().
       
   115 */
       
   116 
       
   117 /*!
       
   118     Construct a splash screen that will display the \a pixmap.
       
   119 
       
   120     There should be no need to set the widget flags, \a f, except
       
   121     perhaps Qt::WindowStaysOnTopHint.
       
   122 */
       
   123 QSplashScreen::QSplashScreen(const QPixmap &pixmap, Qt::WindowFlags f)
       
   124     : QWidget(*(new QSplashScreenPrivate()), 0, Qt::SplashScreen | f)
       
   125 {
       
   126     d_func()->pixmap = pixmap;
       
   127     setPixmap(d_func()->pixmap);  // Does an implicit repaint
       
   128 }
       
   129 
       
   130 /*!
       
   131     \overload
       
   132 
       
   133     This function allows you to specify a parent for your splashscreen. The
       
   134     typical use for this constructor is if you have a multiple screens and
       
   135     prefer to have the splash screen on a different screen than your primary
       
   136     one. In that case pass the proper desktop() as the \a parent.
       
   137 */
       
   138 QSplashScreen::QSplashScreen(QWidget *parent, const QPixmap &pixmap, Qt::WindowFlags f)
       
   139     : QWidget(*new QSplashScreenPrivate, parent, Qt::SplashScreen | f)
       
   140 {
       
   141     d_func()->pixmap = pixmap;
       
   142     setPixmap(d_func()->pixmap);  // Does an implicit repaint
       
   143 }
       
   144 
       
   145 /*!
       
   146   Destructor.
       
   147 */
       
   148 QSplashScreen::~QSplashScreen()
       
   149 {
       
   150 }
       
   151 
       
   152 /*!
       
   153     \reimp
       
   154 */
       
   155 void QSplashScreen::mousePressEvent(QMouseEvent *)
       
   156 {
       
   157     hide();
       
   158 }
       
   159 
       
   160 /*!
       
   161     This overrides QWidget::repaint(). It differs from the standard
       
   162     repaint function in that it also calls QApplication::flush() to
       
   163     ensure the updates are displayed, even when there is no event loop
       
   164     present.
       
   165 */
       
   166 void QSplashScreen::repaint()
       
   167 {
       
   168     d_func()->drawContents();
       
   169     QWidget::repaint();
       
   170     QApplication::flush();
       
   171 }
       
   172 
       
   173 /*!
       
   174     \fn QSplashScreen::messageChanged(const QString &message)
       
   175 
       
   176     This signal is emitted when the message on the splash screen
       
   177     changes. \a message is the new message and is a null-string
       
   178     when the message has been removed.
       
   179 
       
   180     \sa showMessage(), clearMessage()
       
   181 */
       
   182 
       
   183 
       
   184 
       
   185 /*!
       
   186     Draws the \a message text onto the splash screen with color \a
       
   187     color and aligns the text according to the flags in \a alignment.
       
   188 
       
   189     \sa Qt::Alignment, clearMessage()
       
   190 */
       
   191 void QSplashScreen::showMessage(const QString &message, int alignment,
       
   192                                 const QColor &color)
       
   193 {
       
   194     Q_D(QSplashScreen);
       
   195     d->currStatus = message;
       
   196     d->currAlign = alignment;
       
   197     d->currColor = color;
       
   198     emit messageChanged(d->currStatus);
       
   199     repaint();
       
   200 }
       
   201 
       
   202 /*!
       
   203     Removes the message being displayed on the splash screen
       
   204 
       
   205     \sa showMessage()
       
   206  */
       
   207 void QSplashScreen::clearMessage()
       
   208 {
       
   209     d_func()->currStatus.clear();
       
   210     emit messageChanged(d_func()->currStatus);
       
   211     repaint();
       
   212 }
       
   213 
       
   214 /*!
       
   215     Makes the splash screen wait until the widget \a mainWin is displayed
       
   216     before calling close() on itself.
       
   217 */
       
   218 void QSplashScreen::finish(QWidget *mainWin)
       
   219 {
       
   220     if (mainWin) {
       
   221 #if defined(Q_WS_X11)
       
   222         extern void qt_x11_wait_for_window_manager(QWidget *mainWin);
       
   223         qt_x11_wait_for_window_manager(mainWin);
       
   224 #endif
       
   225     }
       
   226     close();
       
   227 }
       
   228 
       
   229 /*!
       
   230     Sets the pixmap that will be used as the splash screen's image to
       
   231     \a pixmap.
       
   232 */
       
   233 void QSplashScreen::setPixmap(const QPixmap &pixmap)
       
   234 {
       
   235     Q_D(QSplashScreen);
       
   236 
       
   237     if (pixmap.hasAlpha()) {
       
   238         QPixmap opaque(pixmap.size());
       
   239         QPainter p(&opaque);
       
   240         p.fillRect(0, 0, pixmap.width(), pixmap.height(), palette().background());
       
   241         p.drawPixmap(0, 0, pixmap);
       
   242         p.end();
       
   243         d->pixmap = opaque;
       
   244     } else {
       
   245         d->pixmap = pixmap;
       
   246     }
       
   247 
       
   248     QRect r(0, 0, d->pixmap.size().width(), d->pixmap.size().height());
       
   249     resize(d->pixmap.size());
       
   250     move(QApplication::desktop()->screenGeometry().center() - r.center());
       
   251     if (!isVisible())
       
   252         d->drawContents();
       
   253     else
       
   254         repaint();
       
   255 }
       
   256 
       
   257 /*!
       
   258     Returns the pixmap that is used in the splash screen. The image
       
   259     does not have any of the text drawn by showMessage() calls.
       
   260 */
       
   261 const QPixmap QSplashScreen::pixmap() const
       
   262 {
       
   263     return d_func()->pixmap;
       
   264 }
       
   265 
       
   266 /*!
       
   267   \internal
       
   268 */
       
   269 void QSplashScreenPrivate::drawContents()
       
   270 {
       
   271     Q_Q(QSplashScreen);
       
   272     QPixmap textPix = pixmap;
       
   273     if (!textPix.isNull()) {
       
   274         QPainter painter(&textPix);
       
   275         painter.initFrom(q);
       
   276         q->drawContents(&painter);
       
   277         QPalette p = q->palette();
       
   278         p.setBrush(q->backgroundRole(), QBrush(textPix));
       
   279         q->setPalette(p);
       
   280     }
       
   281 }
       
   282 
       
   283 /*!
       
   284     \internal
       
   285 */
       
   286 inline QSplashScreenPrivate::QSplashScreenPrivate() : currAlign(Qt::AlignLeft)
       
   287 {
       
   288 }
       
   289 
       
   290 /*!
       
   291     Draw the contents of the splash screen using painter \a painter.
       
   292     The default implementation draws the message passed by showMessage().
       
   293     Reimplement this function if you want to do your own drawing on
       
   294     the splash screen.
       
   295 */
       
   296 void QSplashScreen::drawContents(QPainter *painter)
       
   297 {
       
   298     Q_D(QSplashScreen);
       
   299     painter->setPen(d->currColor);
       
   300     QRect r = rect();
       
   301     r.setRect(r.x() + 5, r.y() + 5, r.width() - 10, r.height() - 10);
       
   302     if (Qt::mightBeRichText(d->currStatus)) {
       
   303         QTextDocument doc;
       
   304 #ifdef QT_NO_TEXTHTMLPARSER
       
   305         doc.setPlainText(d->currStatus);
       
   306 #else
       
   307         doc.setHtml(d->currStatus);
       
   308 #endif
       
   309         doc.setTextWidth(r.width());
       
   310         QTextCursor cursor(&doc);
       
   311         cursor.select(QTextCursor::Document);
       
   312         QTextBlockFormat fmt;
       
   313         fmt.setAlignment(Qt::Alignment(d->currAlign));
       
   314         cursor.mergeBlockFormat(fmt);
       
   315         painter->save();
       
   316         painter->translate(r.topLeft());
       
   317         doc.drawContents(painter);
       
   318         painter->restore();
       
   319     } else {
       
   320         painter->drawText(r, d->currAlign, d->currStatus);
       
   321     }
       
   322 }
       
   323 
       
   324 /*!
       
   325     \fn void QSplashScreen::message(const QString &message, int alignment,
       
   326                                     const QColor &color)
       
   327     \compat
       
   328 
       
   329     Use showMessage() instead.
       
   330 */
       
   331 
       
   332 /*!
       
   333     \fn void QSplashScreen::clear()
       
   334     \compat
       
   335 
       
   336     Use clearMessage() instead.
       
   337 */
       
   338 
       
   339 /*! \reimp */
       
   340 bool QSplashScreen::event(QEvent *e)
       
   341 {
       
   342     return QWidget::event(e);
       
   343 }
       
   344 
       
   345 QT_END_NAMESPACE
       
   346 
       
   347 #endif //QT_NO_SPLASHSCREEN