-// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
//
-// This library is distributed in the hope that it will be useful
+// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-// File: QtxSplash.cxx
-// Author: Vadim SANDLER
+// File : QtxSplash.cxx
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
#include "QtxSplash.h"
+#include "QtxResourceMgr.h"
+#include <cstdio>
-#include <qapplication.h>
-#include <qpainter.h>
-#include <qpixmap.h>
-#include <qmessagebox.h>
-
-const int _PROGRESS_EVENT = QEvent::User + 10;
-const int _PROGRESS_WIDTH = 10;
+#include <QApplication>
+#include <QPainter>
+#include <QMessageBox>
+#include <QDesktopWidget>
/*!
- Class ProgressEvent [ internal ].
+ \class ProgressEvent
+ \internal
+ \brief Progress change custom event.
*/
-class ProgressEvent: public QCustomEvent
+
+class ProgressEvent: public QEvent
{
public:
- ProgressEvent( const QString& msg, const int progress = 0 )
- : QCustomEvent( id() ),
+ /*!
+ \brief Constructor.
+ \param msg progress message
+ \param progress current progress (for example, in %)
+ */
+ ProgressEvent( const QString& msg, const int progress )
+ : QEvent( (QEvent::Type)id() ),
myMessage( msg ),
myProgress( progress )
{}
- QString message() const { return myMessage; }
- int progress() const { return myProgress; }
- static int id() { return _PROGRESS_EVENT; }
+ /*!
+ \brief Get progress message.
+ \return message
+ */
+ QString message() const { return myMessage; }
+ /*!
+ \brief Get current progress.
+ \return current progress
+ */
+ int progress() const { return myProgress; }
+ /*!
+ \brief Get message identifier.
+ \return custom message ID
+ */
+ static int id() { return QEvent::User + 10; }
private:
QString myMessage;
int myProgress;
};
-// Only one instance of splash screen is allowed
+/*!
+ \class QtxSplash
+ \brief The QtxSplash widget provides a splash screen that can be shown
+ during application startup.
+
+ A splash screen is a widget that is usually displayed when an application
+ is being started.
+ Splash screens are often used for applications that have long start up times
+ to provide the user with feedback that the application is loading.
+
+ Only one instance of the QtxSplash widget can be created. To access the splash
+ screen widget, use static method QtxSplash::splash(), which creates an
+ instance of the QtxSplash widget (if it is not yet creaed) and returns a
+ pointer to it.
+ You should not destroy this instance - it is done automatically after
+ application main window is shown. Just use methods finish() to make splash
+ screen wait untill main window is shown.
+
+ The splash screen appears in the center of the screen.
+ The most common usage is to show a splash screen before the main widget
+ is displayed on the screen.
+ For example,
+ \code
+ int main(int argc, char *argv[])
+ {
+ QApplication app(argc, argv);
+ QPixmap pixmap(":/splash.png");
+ QtxSplash* splash = QtxsSplash::splash(pixmap);
+ splash->show();
+ app.processEvents();
+ ... // do application loading and initialization
+ MainWindow window;
+ window.show();
+ splash->finish(&window);
+ return app.exec();
+ }
+ \endcode
+
+ The user can hide the splash screen by clicking on it with the mouse.
+ Since the splash screen is typically displayed before the event loop
+ has started running, it is necessary to periodically call
+ QApplication::processEvents() to receive the mouse clicks.
+ To activate the possibility of hiding the splash screen on the mouse
+ click, use setHideOnClick() method passing \c true as parameter.
+ By default, this feature is switched off.
+
+ It is sometimes useful to update the splash screen with any status messages
+ and/or progress information, for example, announcing connections established
+ or modules loaded as the application starts up.
+ QtxSplash class provides the functionality to show status messages
+ and(or) progress bar.
+
+ \code
+ QPixmap pixmap(":/splash.png");
+ QtxSplash* splash = QtxSplash::splash(pixmap);
+ splash->setProgress(0, 5); // progress from 0 to 5
+ splash->show();
+ app.processEvents();
+ // doing first step
+ splash->setMessage("Step 1");
+ splash->setProgress(1); // progress is 20%
+ qApp->processEvents();
+ // ... perform some actions
+ // doing second step
+ splash->setMessage("Step 2");
+ splash->setProgress(2); // progress is 40%
+ qApp->processEvents();
+ // ... perform some actions
+ ... et cetera
+ \endcode
+
+ There is a static function QtxSplash::setStatus() which allows to put the
+ next status message and current progress with one call.
+ It can substitue two calls: setMessage() and setProgress().
+
+ QtxSplash class provides also a lot of functions to customize its behavior.
+ Set progress bar width with setProgressWidth() method, its position and
+ direction with setProgressFlags().
+ It can be single-colored or gradient-colored. Use setProgressColors() methods
+ for this. You can even set your own gradient scale with QLinearGradient,
+ QRadialGradient or QConicalGradient and use it for the progress
+ bar coloring. In addition, it is possible to enable/disable displaying
+ of the progress percentage with setPercentageVisible() method.
+
+ Displaying of the progress bar and status messages can be switched on/off with
+ setProgressVisible() and setMessageVisible() methods.
+
+ To change the progress bar and status message transparency, use
+ setOpacity() function. The methods setTextAlignment() and setTextColors()
+ can be used to change the attributes of the status messages.
+
+ The displayed message text can include constant info and status message.
+ The constant info is set by setConstantInfo() method and status message
+ is set by setMessage().
+
+ Sometimes it is useful to display an error message above the splash screen
+ window. For example, it can be necessary if an error occurs when loading
+ the application. Method setError() can be used to show the error message
+ and set the error code which can be then retrieved with the error() function.
+
+ There is one more helpful feature. The QtxSplash class can read all the
+ settings from the resource file with help of resource manager
+ (QtxResourceMgr class). Refer to the method readSettings() for more details.
+*/
+
+//! The only one instance of splash screen
QtxSplash* QtxSplash::mySplash = 0;
/*!
+ \brief Constructor.
+
Construct a splash screen that will display the \a pixmap.
+
+ \param pixmap splash screen pixmap
+ \sa setPixmap(), pixmap()
*/
QtxSplash::QtxSplash( const QPixmap& pixmap )
- : QWidget( 0, 0, WStyle_Customize | WStyle_StaysOnTop | WX11BypassWM | WStyle_NoBorder )
+: QWidget( 0, Qt::SplashScreen | Qt::WindowStaysOnTopHint ),
+ myAlignment( Qt::AlignBottom | Qt::AlignRight ),
+ myColor( Qt::white ),
+ myHideOnClick( false ),
+ myProgress( 0 ),
+ myTotal( 0 ),
+ myProgressWidth( 10 ),
+ myProgressFlags( BottomSide | LeftToRight ),
+ myMargin( 5 ),
+ myOpacity( 1.0 ),
+ myError( 0 ),
+ myShowProgress( true ),
+ myShowMessage( true ),
+ myShowPercent( true )
{
- myAlignment = AlignBottom | AlignRight;
- myColor = white;
- myHideOnClick = false;
- myProgress = 0;
- myTotal = 0;
- myGradientType = Vertical;
- myError = 0;
- myStartColor = red;
-
+ setAttribute( Qt::WA_DeleteOnClose, true );
setPixmap( pixmap );
}
/*!
- Destructor.
+ \brief Destructor.
*/
QtxSplash::~QtxSplash()
{
}
/*!
- Returns an only instance of splash screen.
- If \a px is valid sets this pixmap to the splash screen.
+ \brief Get the only instance of the splash screen widget.
+
+ If the splash screen widget does not exist yet, it is created with specified
+ pixmap. Otherwise, pixmap \a px is set to existing widget.
+
+ \param px splash screen pixmap
+ \return splash screen widget
+ \sa setPixmap(), pixmap()
*/
QtxSplash* QtxSplash::splash( const QPixmap& px )
{
}
/*!
- Sends the status message and (optionally) progress to the splash screen.
- Can be used, for example, from the progress thread.
+ \brief Send the status message and (optionally) current progress
+ to the splash screen.
+
+ If the second parameter is less than 0 (default) than it is ignored
+ and only the status message is changed. If you want to modify progress
+ also, pass positive value to the \a progress parameter explicitly.
+
+ \param msg progress status message
+ \param progress current progress
+ \sa setMessage(), setProgress()
*/
-void QtxSplash::setStatus( const QString& msg,
- const int progress )
+void QtxSplash::setStatus( const QString& msg, const int progress )
{
if ( mySplash ) {
QApplication::postEvent( mySplash, new ProgressEvent( msg, progress ) );
- qApp->processEvents();
+ QApplication::instance()->processEvents();
}
}
/*!
- Sets error status and shows error message box to the user.
+ \brief Set error status and show error message box to the user.
+ \param error error message
+ \param title message box title
+ \param code error code
+ \sa error()
*/
-void QtxSplash::error( const QString& error, const QString& title, const int code )
+void QtxSplash::setError( const QString& error, const QString& title, const int code )
{
- printf("QtxSplash::error: %s\n",error.latin1());
if ( mySplash ) {
mySplash->setError( code );
QMessageBox::critical( mySplash,
- title.isEmpty() ? tr( "Error" ) : title,
- error,
- tr( "&OK" ) );
+ title.isEmpty() ? tr( "Error" ) : title,
+ error,
+ tr( "&OK" ) );
}
+ else {
+ qCritical( "QtxSplash::error: %s\n", qPrintable( error ) );
+ }
+}
+
+/*!
+ \brief Set fixed size of splash screen.
+
+ If size is not set explicitly, it is inherited from image being used.
+ Otherwise, image is rescaled to given size.
+
+ Width and height can be given indepdently; not given dimension
+ (zero of negative value) is ignored.
+
+ \param size fixed splash size
+ \sa fixedSize()
+*/
+void QtxSplash::setSize( const QSize& size )
+{
+ mySize = size;
+ setPixmap( pixmap() );
+}
+
+/*!
+ \brief This is an overloaded function.
+
+ \param w width
+ \param h height
+ \sa fixedSize()
+*/
+void QtxSplash::setSize( int w, int h )
+{
+ setSize( QSize( w, h ) );
}
/*!
- Sets the pixmap that will be used as the splash screen's image to
- \a pixmap.
+ \brief Get fixed splash screen's size if it was set.
+ \sa setSize()
+*/
+QSize QtxSplash::fixedSize() const
+{
+ return mySize;
+}
+
+
+/*!
+ \brief Set the pixmap that will be used as the splash screen's image.
+ \param pixmap spash screen image pixmap
+ \sa pixmap()
*/
void QtxSplash::setPixmap( const QPixmap& pixmap )
{
- myPixmap = pixmap;
+ if ( pixmap.isNull() )
+ return;
+
+ if ( pixmap.hasAlpha() ) {
+ QPixmap opaque( pixmap.size() );
+ QPainter p( &opaque );
+ p.fillRect( 0, 0, pixmap.width(), pixmap.height(), palette().background() );
+ p.drawPixmap( 0, 0, pixmap );
+ p.end();
+ myPixmap = opaque;
+ }
+ else {
+ myPixmap = pixmap;
+ }
+
+ int width = fixedSize().width();
+ int height = fixedSize().height();
+ if ( width > 0 || height > 0 ) {
+ QImage img = myPixmap.toImage();
+ img = img.scaled( width > 0 ? width : myPixmap.width(),
+ height > 0 ? height : myPixmap.height(),
+ Qt::IgnoreAspectRatio,
+ Qt::SmoothTransformation );
+ myPixmap = QPixmap::fromImage( img );
+ }
+
QRect r( 0, 0, myPixmap.size().width(), myPixmap.size().height() );
resize( myPixmap.size() );
move( QApplication::desktop()->screenGeometry().center() - r.center() );
- repaint();
+ if ( !isVisible() )
+ drawContents();
+ else
+ repaint();
}
/*!
- Returns the pixmap that is used in the splash screen.
+ \brief Get the pixmap that is used as the splash screen's image.
+ \return spash screen image pixmap
+ \sa setPixmap()
*/
QPixmap QtxSplash::pixmap() const
{
}
/*!
- Sets/clear the 'hide on mouse click' flag.
- Default is FALSE.
+ \brief Set/clear the 'hide on mouse click' flag.
+
When this flag is set, user can hide the splash screen window
by clicking on it with mouse.
But for this to work it is necessary to call periodically
QApplication::processEvents() in order to allow event loop to process
events because usually main application loop is not yet started
at that moment.
+
+ By default this flag is set to \c false.
+
+ \param on new flag state
+ \sa hideOnClick()
*/
void QtxSplash::setHideOnClick( const bool on )
{
}
/*!
- Returns the 'hide on mouse click' flag.
+ \brief Get the 'hide on mouse click' flag.
+ \return 'hide on mouse click' flag
+ \sa setHideOnClick()
*/
bool QtxSplash::hideOnClick() const
{
}
/*!
- Sets total progress steps to \a total.
+ \brief Enable/disable displaying of the progress bar.
+ \param on if \c true, progress bar will be enabled
+ \sa progressVisible(), setMessageVisible()
+*/
+void QtxSplash::setProgressVisible( const bool on )
+{
+ myShowProgress = on;
+ repaint();
+}
+
+/*!
+ \brief Check if the progress bar is displayed.
+ \return \c true if progress bar is enabled
+ \sa setProgressVisible()
+*/
+bool QtxSplash::progressVisible() const
+{
+ return myShowProgress;
+}
+
+/*!
+ \brief Enable/disable displaying of the status message.
+ \param on if \c true, status message will be enabled
+ \sa messageVisible(), setProgressVisible()
+*/
+void QtxSplash::setMessageVisible( const bool on )
+{
+ myShowMessage = on;
+ repaint();
+}
+
+/*!
+ \brief Check if the status message is displayed.
+ \return \c true if status message is enabled
+ \sa setMessageVisible()
+*/
+bool QtxSplash::messageVisible() const
+{
+ return myShowMessage;
+}
+
+/*!
+ \brief Enable/disable displaying progress percentage.
+ \param enable if \c true, percentage will be displayed
+ \sa percentageVisible()
+*/
+void QtxSplash::setPercentageVisible( const bool enable )
+{
+ myShowPercent = enable;
+ repaint();
+}
+
+/*!
+ \brief Check if the progress percentage is displayed.
+ \return \c true if percentage displaying is enabled
+ \sa setPercentageVisible()
+*/
+bool QtxSplash::percentageVisible() const
+{
+ return myShowPercent;
+}
+
+/*!
+ \brief Set total progress steps to \a total.
+ \param total total number of progress steps
+ \sa totalSteps(), setProgress(), progress()
*/
void QtxSplash::setTotalSteps( const int total )
{
}
/*!
- Return total progress steps number.
- \sa setTotalSteps(), setProgress()
+ \brief Get total progress steps number.
+ \return total number of progress steps
+ \sa setTotalSteps(), setProgress(), progress()
*/
int QtxSplash::totalSteps() const
{
}
/*!
- Sets progress to \a progress.
+ \brief Set current progress.
+ \param progress current progress
+ \sa progress(), setTotalSteps(), setTotalSteps(),
*/
void QtxSplash::setProgress( const int progress )
{
- myProgress = progress;
+ myProgress = progress > 0 ? progress : 0;
repaint();
}
/*!
- Return current progress.
- \sa setProgress(), setTotalSteps()
+ \brief Get current progress.
+ \return current progress
+ \sa setProgress(), setTotalSteps(), setTotalSteps(),
*/
int QtxSplash::progress() const
{
}
/*!
- Sets progress to \a progress and total progress steps to \a total.
+ \brief Set current progress to \a progress and total number of
+ progress steps to \a total.
+ \param progress current progress
+ \param total total number of progress steps
*/
void QtxSplash::setProgress( const int progress, const int total )
{
myTotal = total;
- myProgress = progress;
+ myProgress = progress > 0 ? progress : 0;
+ repaint();
+}
+
+/*!
+ \brief Set splash window margin (a border width).
+
+ Note, that margin is used only for drawing the progress bar and status
+ messages.
+
+ \param margin new margin width
+ \sa margin()
+*/
+void QtxSplash::setMargin( const int margin )
+{
+ myMargin = margin > 0 ? margin : 0;
+ repaint();
+}
+
+/*!
+ \brief Get splash window margin (a border width).
+ \return current margin width
+ \sa setMargin()
+*/
+int QtxSplash::margin() const
+{
+ return myMargin;
+}
+
+/*!
+ \brief Set progress bar width.
+ \param width new progress bar width
+ \sa progressWidth()
+*/
+void QtxSplash::setProgressWidth( const int width )
+{
+ myProgressWidth = width > 0 ? width : 0;
+ repaint();
+}
+
+/*!
+ \brief Get progress bar width.
+ \return current progress bar width
+ \sa setProgressWidth()
+*/
+int QtxSplash::progressWidth() const
+{
+ return myProgressWidth;
+}
+
+/*!
+ \brief Set progress bar position and direction.
+
+ By default, progress bar is displayed at the bottom side and
+ shows progress from left to right but this behaviour can be changed.
+
+ \param flags ORed progress bar flags (QtxSplash::ProgressBarFlags)
+ \sa progressFlags()
+*/
+void QtxSplash::setProgressFlags( const int flags )
+{
+ myProgressFlags = flags;
+ if ( !( myProgressFlags & ( LeftSide | RightSide | TopSide | BottomSide ) ) )
+ myProgressFlags |= BottomSide;
+ if ( !( myProgressFlags & ( LeftToRight | RightToLeft ) ) )
+ myProgressFlags |= LeftToRight ;
repaint();
}
/*!
- Sets progress bar colors to \a startColor and \a endColor.
- If the colors differ the gradient color bar is drawed.
- If the \a endColor is not valid, \a startColor is used instead.
- \a gradientType sets the type of gradient to be used for progress
- bar - horizontal or vertical. Default is vertical.
+ \brief Get progress bar flags: position and direction.
+ \return ORed progress bar flags (QtxSplash::ProgressBarFlags)
+ \sa setProgressFlags()
+*/
+int QtxSplash::progressFlags() const
+{
+ return myProgressFlags;
+}
+
+/*!
+ \brief Set progress bar colors.
+
+ If the colors differ the two-colored gradient bar is drawn.
+
+ If the \a endColor is not valid, \a startColor is used instead
+ (i.e. simple, one-colored progress bar is drawn).
+
+ The parameter \a orientation defines the type of gradient
+ to be drawn - horizontal or vertical. Default is vertical.
+
+ \param startColor start gradient color (or mono-color)
+ \param endColor end gradient color
+ \param orientation gradient type (Qt::Orientation)
+ \sa progressColors()
*/
-void QtxSplash::setProgressColors( const QColor& startColor,
- const QColor& endColor,
- const int gradientType )
+void QtxSplash::setProgressColors( const QColor& startColor,
+ const QColor& endColor,
+ const Qt::Orientation orientation )
{
- myStartColor = startColor;
- myEndColor = endColor;
- myGradientType = gradientType;
+ if ( !startColor.isValid() )
+ return;
+
+ QLinearGradient l;
+ if ( orientation == Qt::Vertical ) {
+ l.setStart( 0., 0. );
+ l.setFinalStop( 0., 1. );
+ }
+ else {
+ l.setStart( 0., 0. );
+ l.setFinalStop( 1., 0. );
+ }
+ l.setColorAt( 0., startColor );
+ l.setColorAt( 1., endColor.isValid() ? endColor : startColor );
+
+ setProgressColors( l );
+}
+
+/*!
+ \brief Set progress bar colors.
+
+ Use this method to display multi-colored gradient progress bar.
+ You have to use QLinearGradient, QRadialGradient or QConicalGradient
+ classes to define the gradient.
+
+ Note, that progress bar coordinates can be defined in absolute or
+ relative mode.
+ In absolute mode the actual coordinates of the gradient key points
+ (like start and final point for linear gradient, center and focal point
+ for radial gradient, etc) are calculated from the top-left progress bar's corner.
+ In relative mode you have to use values from 0 to 1 (including) to define
+ the key points positions.
+
+ For example:
+ \code
+ QLinearGradient lg(0.5, 0, 1, 1);
+ lg.setColorAt(0.2, Qt::blue);
+ lg.setColorAt(0.6, Qt::red);
+ lg.setSpread(QGradient::RepeatSpread);
+ splash->setProgressGradient(lg);
+ \endcode
+ The above code creates linear gradient, which sets start stop to the
+ center of the progress bar; the final stop is assigned to its right-bottom corner.
+ The color scale (blue to red) is changed by the progress bar diagonal.
+
+ \param gradient color gradient to be used for progress bar coloring
+ \sa progressColors()
+*/
+void QtxSplash::setProgressColors( const QGradient& gradient )
+{
+ myGradient = gradient;
repaint();
}
/*!
- Return progress colors and gradient type (horizontal or vertical).
+ \brief Get custom progress bar colors.
+ \return color gradient used for progress bar coloring
\sa setProgressColors()
*/
-int QtxSplash::progressColors( QColor& startColor, QColor& endColor )
+const QGradient* QtxSplash::progressColors() const
{
- startColor = myStartColor;
- endColor = myEndColor;
- return myGradientType;
+ return &myGradient;
}
/*!
- Sets message text alignment flags to \a alignment.
- Default is AlignBottom | AlignRight.
+ \brief Set progress bar and status text message opacity.
+
+ The value should be in the range 0.0 to 1.0, where 0.0 is fully
+ transparent and 1.0 is fully opaque.
+
+ \param opacity new opacity value
+ \sa opacity()
*/
-void QtxSplash::setTextAlignment( const int alignment )
+void QtxSplash::setOpacity( const double opacity )
{
- myAlignment = alignment;
+ myOpacity = opacity < 0.0 ? 0.0 : ( opacity > 1.0 ? 1.0 : opacity );
repaint();
}
/*!
- Return message text alignment flags.
- \sa setTextAlignment()
+ \brief Get progress bar and status text message opacity.
+ \return current opacity value
+ \sa setOpacity()
*/
-int QtxSplash::textAlignment() const
+double QtxSplash::opacity() const
{
- return myAlignment;
+ return myOpacity;
}
/*!
- Sets message text color to \a color.
- Default is white.
- \sa setTextColors()
+ \brief Set message text alignment flags.
+
+ Default flags are Qt::AlignBottom | Qt::AlignRight.
+
+ \param alignment alignment flags (Qt::Alignment)
+ \sa textAlignment()
*/
-void QtxSplash::setTextColor( const QColor& color )
+void QtxSplash::setTextAlignment( const int alignment )
{
- myColor = color;
- myShadowColor = QColor();
+ myAlignment = alignment;
repaint();
}
/*!
- Return message text color.
- \sa setTextColor()
+ \brief Get message text alignment flags.
+ \return alignment flags (Qt::Alignment)
+ \sa setTextAlignment()
*/
-QColor QtxSplash::textColor() const
+int QtxSplash::textAlignment() const
{
- return myColor;
+ return myAlignment;
}
/*!
- Sets message text color to \a color and text shadow color to \a shadow.
- \sa setTextColor()
+ \brief Set message text colors.
+
+ If \a shadow parameter is invalid color, the simple one-colored
+ text is drawn. Otherwise, second parameter is used to draw the text
+ shadow.
+
+ \param color message text color
+ \param shadow message text shadow color
+ \sa textColors()
*/
void QtxSplash::setTextColors( const QColor& color, const QColor& shadow )
{
- myColor = color;
+ if ( !myColor.isValid() )
+ return;
+
+ myColor = color;
myShadowColor = shadow;
+
repaint();
}
/*!
- Return message text color and text shadow color.
+ \brief Get message text colors.
+ \param color message text color
+ \param shadow message text shadow color
\sa setTextColors()
*/
void QtxSplash::textColors( QColor& color, QColor& shadow ) const
}
/*!
- Returns current status message.
+ \brief Set constant info text to be displayed on the splash screen.
+
+ The displayed text includes constant info and status message.
+ The constant message is set by setConstantInfo() method and status
+ message is set by setMessage().
+
+ \param info constant info text
+ \sa constantInfo(), message(), setMessage(), option(), setOption()
+*/
+void QtxSplash::setConstantInfo( const QString& info )
+{
+ myInfo = info;
+ repaint();
+}
+
+/*!
+ \brief Get constant info text.
+ \return constant info text
+ \sa setConstantInfo(), message(), setMessage()
+*/
+QString QtxSplash::constantInfo() const
+{
+ return myInfo;
+}
+
+/*!
+ \brief Set constant information option value.
+
+ The option is a part of the constant information text,
+ which is replaced at the time of the displaying.
+
+ The following options are supported:
+ - \c \%A - could be used as application name
+ - \c \%V - could be used as application version
+ - \c \%L - could be used as application license information
+ - \c \%C - could be used as application copyright information
+
+ For example,
+ \code
+ splash->setContantInfo("%A [%V]\n%C");
+ splash->setOption("%A", "MyApplication" );
+ splash->setOption("%V", "Version 1.0" );
+ splash->setOption("%C", "Copyright (C) MyCompany 2008" );
+ \endcode
+
+ \param name option name
+ \param option value
+ \sa option(), setConstantInfo(), constantInfo()
+*/
+void QtxSplash::setOption( const QString& name, const QString& value )
+{
+ myOptions[ name ] = value;
+ repaint();
+}
+
+/*!
+ \brief Get constant information option value.
+ \param name option name
+ \return option value or empty string if option is not set
+ \sa setOption(), setConstantInfo(), constantInfo()
+*/
+QString QtxSplash::option( const QString& name ) const
+{
+ QString val;
+ if ( myOptions.contains( name ) )
+ val = myOptions[ name ];
+ return val;
+}
+
+/*!
+ \brief Get current status message.
+ \return status message
+ \sa setMessage(), constantInfo(), setConstantInfo()
*/
QString QtxSplash::message() const
{
}
/*!
- Return error code. If no errors were occured returns 0.
- Error code can be set by error( QString&, QString, int ).
+ \brief Get error code.
+
+ This function returns error code, set previously with
+ setError() method.
+ If no error code has been set, 0 is returned.
+
+ \return last error code
+ \sa setError()
*/
int QtxSplash::error() const
{
}
/*!
- Makes the splash screen wait until the widget \a mainWin is displayed
- before calling close() on itself.
+ \brief Wait until widget \a mainWin is displayed.
+
+ Makes the splash screen wait until the widget \a mainWin is displayed
+ and then hide and close splash window.
+
+ \param mainWin application main window
*/
void QtxSplash::finish( QWidget* mainWin )
{
if ( mainWin ) {
#if defined(Q_WS_X11)
- extern void qt_wait_for_window_manager( QWidget* w );
- qt_wait_for_window_manager( mainWin );
+ extern void qt_x11_wait_for_window_manager(QWidget *mainWin);
+ qt_x11_wait_for_window_manager(mainWin);
#endif
}
close();
}
/*!
- Repaint the splash screen.
+ \brief Repaint the splash screen.
*/
void QtxSplash::repaint()
{
}
/*!
- Draws the \a message text onto the splash screen with color \a
- color and aligns the text according to the flags in \a alignment.
+ \brief Read splash settings from the resources manager.
+
+ This method can be used to setup the splash screen look-n-feel.
+ By default, "splash" section of the resources file is used, but you can
+ use any other section.
+ All the splash screen parameters can be defined via resources file:
+ - \c "image" : splash screen image, see setPixmap()
+ - \c "margin" : splash window margin, see setMargin()
+ - \c "show_progress" : show progress bar flag, see setProgressVisible()
+ - \c "show_message" : show status messages flag, see setMessageVisible()
+ - \c "show_percents" : show progress percentage flag, see setPercentageVisible()
+ - \c "progress_width" : progress bar width(), see setProgressWidth()
+ - \c "progress_flags" : progress bar position and direction, see setProgressFlags()
+ - \c "constant_info" : status messages constant info, see setConstantInfo()
+ - \c "text_colors" : status messages color(s), see setTextColors()
+ - \c "progress_colors" : progress bar color(s), see setProgressColors()
+ - \c "opacity" : progress bar and status messages opacity, see setOpacity()
+ - \c "font" : status messages font
+ - \c "alignment" : status messages alignment flags, see setTextAlignment()
+ - \c "hide_on_click" : hide-on-click flag, see setHideOnClick()
+
+ \param resMgr resources manager
+ \param section resources file section name (if empty, the default "splash"
+ section is used).
*/
-void QtxSplash::message( const QString& msg,
- int alignment,
- const QColor& color )
+void QtxSplash::readSettings( QtxResourceMgr* resMgr, const QString& section )
+{
+ QString resSection = section.isEmpty() ? QString( "splash" ) : section;
+
+ // size
+ setSize( resMgr->integerValue( resSection, "width", 0 ),
+ resMgr->integerValue( resSection, "height", 0 ) );
+
+ // pixmap
+ QString pxname;
+ if ( resMgr->value( resSection, "image", pxname ) ) {
+ QPixmap px( pxname );
+ if ( !px.isNull() )
+ setPixmap( px );
+ }
+
+ // hide-on-click
+#ifdef _DEBUG_
+ setHideOnClick( true );
+#else
+ bool bHide;
+ if ( resMgr->value( resSection, "hide_on_click", bHide ) ) {
+ setHideOnClick( bHide );
+ }
+#endif
+
+ // enable progress bar
+ bool bShowProgress;
+ if ( resMgr->value( resSection, "show_progress", bShowProgress ) ) {
+ setProgressVisible( bShowProgress );
+ }
+
+ // enable status message
+ bool bShowMessage;
+ if ( resMgr->value( resSection, "show_message", bShowMessage ) ) {
+ setMessageVisible( bShowMessage );
+ }
+
+ // margin
+ int m;
+ if ( resMgr->value( resSection, "margin", m ) ) {
+ setMargin( m );
+ }
+
+ // progress bar width
+ int pw;
+ if ( resMgr->value( resSection, "progress_width", pw ) ) {
+ setProgressWidth( pw );
+ }
+
+ // progress bar position and direction
+ QString pf;
+ if ( resMgr->value( resSection, "progress_flags", pf ) ) {
+ bool bOk;
+ int fl = pf.toInt( &bOk );
+ if ( !bOk ) {
+ fl = 0;
+ QStringList opts = pf.split( QRegExp( "," ), QString::SkipEmptyParts );
+ for ( int i = 0; i < opts.count(); i++ ) {
+ QString opt = opts[i].trimmed().toLower();
+ if ( opt == "left" )
+ fl = fl | LeftSide;
+ else if ( opt == "right" )
+ fl = fl | RightSide;
+ else if ( opt == "top" )
+ fl = fl | TopSide;
+ else if ( opt == "bottom" )
+ fl = fl | BottomSide;
+ else if ( opt == "left_to_right" )
+ fl = fl | LeftToRight;
+ else if ( opt == "right_to_left" )
+ fl = fl | RightToLeft;
+ }
+ }
+ setProgressFlags( fl );
+ }
+
+ // opacity
+ double op;
+ if ( resMgr->value( resSection, "opacity", op ) ) {
+ setOpacity( op );
+ }
+
+ // font
+ QFont f;
+ if ( resMgr->value( resSection, "font", f ) ) {
+ setFont( f );
+ }
+
+ // text alignment
+ QString al;
+ if ( resMgr->value( resSection, "alignment", al ) ) {
+ bool bOk;
+ int fl = al.toInt( &bOk );
+ if ( !bOk ) {
+ fl = 0;
+ QStringList opts = al.split( QRegExp( "," ), QString::SkipEmptyParts );
+ for ( int i = 0; i < opts.count(); i++ ) {
+ QString opt = opts[i].trimmed().toLower();
+ if ( opt == "left" )
+ fl = fl | Qt::AlignLeft;
+ else if ( opt == "right" )
+ fl = fl | Qt::AlignRight;
+ else if ( opt == "top" )
+ fl = fl | Qt::AlignTop;
+ else if ( opt == "bottom" )
+ fl = fl | Qt::AlignBottom;
+ else if ( opt == "hcenter" )
+ fl = fl | Qt::AlignHCenter;
+ else if ( opt == "vcenter" )
+ fl = fl | Qt::AlignVCenter;
+ else if ( opt == "justify" )
+ fl = fl | Qt::AlignJustify;
+ else if ( opt == "center" )
+ fl = fl | Qt::AlignCenter;
+ }
+ }
+ setTextAlignment( fl );
+ }
+ // progress color(s)
+ QString pc;
+ QLinearGradient lgrad;
+ QRadialGradient rgrad;
+ QConicalGradient cgrad;
+ if ( resMgr->value( resSection, "progress_color", lgrad ) ||
+ resMgr->value( resSection, "progress_colors", lgrad ) ) {
+ // linear gradient-colored progress bar
+ setProgressColors( lgrad );
+ }
+ else if ( resMgr->value( resSection, "progress_color", rgrad ) ||
+ resMgr->value( resSection, "progress_colors", rgrad ) ) {
+ // radial gradient-colored progress bar
+ setProgressColors( rgrad );
+ }
+ else if ( resMgr->value( resSection, "progress_color", cgrad ) ||
+ resMgr->value( resSection, "progress_colors", cgrad ) ) {
+ // conical gradient-colored progress bar
+ setProgressColors( cgrad );
+ }
+ else if ( resMgr->value( resSection, "progress_color", pc ) ||
+ resMgr->value( resSection, "progress_colors", pc ) ) {
+ // one/two-colored progress bar
+ QStringList colors = pc.split( "|", QString::SkipEmptyParts );
+ QColor c1, c2;
+ Qt::Orientation o = Qt::Vertical;
+ if ( colors.count() > 0 ) c1 = QColor( colors[0] );
+ if ( colors.count() > 1 ) c2 = QColor( colors[1] );
+ int gt;
+ if ( colors.count() > 2 ) {
+ bool bOk;
+ gt = colors[2].toInt( &bOk );
+ if ( bOk ) {
+ if ( gt == 0 )
+ o = Qt::Horizontal;
+ }
+ else {
+ if ( colors[2].toLower().startsWith( "h" ) )
+ o = Qt::Horizontal;
+ }
+ }
+ setProgressColors( c1, c2, o );
+ }
+ // show percents
+ bool bPercent;
+ if ( resMgr->value( resSection, "show_percents", bPercent ) ) {
+ setPercentageVisible( bPercent );
+ }
+
+ // text color(s)
+ QString tc;
+ if ( resMgr->value( resSection, "text_color", tc ) ||
+ resMgr->value( resSection, "text_colors", tc ) ) {
+ QStringList colors = tc.split( "|", QString::SkipEmptyParts );
+ QColor c1, c2;
+ if ( colors.count() > 0 )
+ c1 = QColor( colors[0] );
+ if ( colors.count() > 1 )
+ c2 = QColor( colors[1] );
+ setTextColors( c1, c2 );
+ }
+
+ // const info
+ QString cinfo;
+ if ( resMgr->value( resSection, "constant_info", cinfo, false ) ||
+ resMgr->value( resSection, "info", cinfo, false ) ) {
+ setConstantInfo( cinfo.split( "|", QString::KeepEmptyParts ).join( "\n" ) );
+ }
+}
+
+/*!
+ \brief Set status message for the splash screen and define its color
+ and aligment flags.
+ \param msg status message
+ \param alignment message text alignment flags (Qt::Alignment)
+ \param color message text color
+ \sa message(), constantInfo(), setConstantInfo()
+*/
+void QtxSplash::setMessage( const QString& msg,
+ int alignment,
+ const QColor& color )
{
myMessage = msg;
myAlignment = alignment;
- myColor = color;
+ if ( color.isValid() )
+ myColor = color;
repaint();
}
/*!
- This is an overloaded member function, provided for convenience.
- It behaves essentially like the above function.
- Draws the \a message text onto the splash screen with default color
- and aligns the text according to the default alignment flags.
+ \overload
+ \brief Set status message for the splash screen.
+ \param msg status message
+ \sa message(), constantInfo(), setConstantInfo()
*/
-void QtxSplash::message( const QString& msg )
+void QtxSplash::setMessage( const QString& msg )
{
myMessage = msg;
repaint();
}
/*!
- Removes the message being displayed on the splash screen.
- \sa message()
+ \brief Remove the message being displayed on the splash screen.
+
+ This is equivalent to setMessage("");
+
+ \sa message(), setMessage()
*/
void QtxSplash::clear()
{
- myMessage = QString::null;
+ myMessage.clear();
repaint();
}
/*!
- Draw the contents of the splash screen using painter \a painter.
+ \brief Draw the contents of the splash screen.
+ \param p painter
*/
-void QtxSplash::drawContents( QPainter* painter )
+void QtxSplash::drawContents( QPainter* p )
{
- QRect r = rect();
- if ( myTotal > 0 ) {
- // draw progress bar outline rectangle
- painter->setPen( palette().active().dark() );
- painter->drawLine( r.x()+5,
- r.height()-5-_PROGRESS_WIDTH,
- r.width()-5,
- r.height()-5-_PROGRESS_WIDTH );
- painter->drawLine( r.x()+5,
- r.height()-5-_PROGRESS_WIDTH,
- r.x()+5,
- r.height()-5 );
- painter->setPen( palette().active().light() );
- painter->drawLine( r.x()+5,
- r.height()-5,
- r.width()-5,
- r.height()-5 );
- painter->drawLine( r.width()-5,
- r.height()-5-_PROGRESS_WIDTH,
- r.width()-5,
- r.height()-5 );
- // draw progress bar
- if ( myGradientType == Horizontal ) {
- int tng = r.width() - r.x() - 11;
- int ng = (int) ( 1.0 * tng * ( myProgress > 0 ? myProgress : 0 ) / myTotal );
- int h1, h2, s1, s2, v1, v2;
- myStartColor.hsv( &h1, &s1, &v1 );
- myEndColor.isValid() ? myEndColor.hsv( &h2, &s2, &v2 ) :
- myStartColor.hsv( &h2, &s2, &v2 );
- for ( int i = 0; i < ng; i++ ) {
- painter->setPen( QColor( h1 + ((h2-h1)*i)/(tng-1),
- s1 + ((s2-s1)*i)/(tng-1),
- v1 + ((v2-v1)*i)/(tng-1),
- QColor::Hsv ) );
- painter->drawLine( r.x()+6+i,
- r.height()-5-_PROGRESS_WIDTH+1,
- r.x()+6+i,
- r.height()-6 );
- }
- }
- else {
- int ng = (int) ( 1.0 * (r.width() - r.x() - 11) * ( myProgress > 0 ? myProgress : 0 ) / myTotal );
- int h1, h2, s1, s2, v1, v2;
- myStartColor.hsv( &h1, &s1, &v1 );
- myEndColor.isValid() ? myEndColor.hsv( &h2, &s2, &v2 ) :
- myStartColor.hsv( &h2, &s2, &v2 );
- for ( int i = 0; i < _PROGRESS_WIDTH-1; i++ ) {
- painter->setPen( QColor( h1 + ((h2-h1)*i)/(_PROGRESS_WIDTH-2),
- s1 + ((s2-s1)*i)/(_PROGRESS_WIDTH-2),
- v1 + ((v2-v1)*i)/(_PROGRESS_WIDTH-2),
- QColor::Hsv ) );
- painter->drawLine( r.x()+6,
- r.height()-5-_PROGRESS_WIDTH+1+i,
- r.x()+6+ng-1,
- r.height()-5-_PROGRESS_WIDTH+1+i );
- }
- }
+ // draw progress bar
+ if ( myTotal > 0 && progressVisible() ) {
+ p->save();
+ drawProgressBar( p );
+ p->restore();
}
- // draw status
- if ( !myMessage.isEmpty() ) {
- QFontMetrics f( font() );
- int spacing = f.lineSpacing();
- int shift = myTotal > 0 ? _PROGRESS_WIDTH : _PROGRESS_WIDTH; // : 0
- int i = myMessage.length() - 1;
- while( i >= 0 && myMessage[ i-- ] == '\n' )
- shift += spacing;
- QRect r1( r.x() + 5, r.y() + 5, r.width() - 10, r.height() - 10 - shift );
- QRect r2 = r1;
- if ( myAlignment & Qt::AlignLeft ) r2.setLeft ( r2.left() + 1 );
- if ( myAlignment & Qt::AlignTop ) r2.setTop ( r2.top() + 1 );
- if ( myAlignment & Qt::AlignRight ) r2.setRight ( r2.right() + 1 );
- if ( myAlignment & Qt::AlignBottom ) r2.setBottom( r2.bottom() + 1 );
- if ( myShadowColor.isValid() ) {
- painter->setPen( myShadowColor );
- painter->drawText( r2, myAlignment, myMessage );
- }
- painter->setPen( myColor );
- painter->drawText( r1, myAlignment, myMessage );
+
+ // draw status message
+ if ( !fullMessage().isEmpty() && messageVisible() ) {
+ p->save();
+ drawMessage( p );
+ p->restore();
}
}
/*!
- Mouse press event.
+ \brief Process mouse button pressing event.
+
Hides splash screen if the 'hide on mouse click' flag is set.
- \sa setHideOnClick()
+
+ \param me mouse event (not used)
+ \sa hideOnClick(), setHideOnClick()
*/
-void QtxSplash::mousePressEvent( QMouseEvent* )
+void QtxSplash::mousePressEvent( QMouseEvent* /*me*/ )
{
if ( myHideOnClick )
hide();
}
/*!
- Processes custom event sent by setStatus() method.
+ \brief Customize paint event.
+
+ This function is implemented to work-around the Qt bug
+ on some Linux distribututions when the drawing on the
+ splash screen widget is not allowed.
+
+ \param pe paint event (not used)
+*/
+void QtxSplash::paintEvent( QPaintEvent* /*pe*/ )
+{
+ QPainter p( this );
+ QPixmap pix = palette().brush( backgroundRole() ).texture();
+ p.drawPixmap( 0, 0, pix );
+}
+
+/*!
+ \brief Process custom event sent by setStatus() method.
+ \param ce custom event
\sa setStatus().
*/
-void QtxSplash::customEvent( QCustomEvent* ce )
+void QtxSplash::customEvent( QEvent* ce )
{
if ( ce->type() == ProgressEvent::id() ) {
ProgressEvent* pe = (ProgressEvent*)ce;
- pe->message().isEmpty() ? clear() : message( pe->message() );
- setProgress( pe->progress() );
- qApp->processEvents();
+ pe->message().isEmpty() ? clear() : setMessage( pe->message() );
+ if ( pe->progress() >= 0 )
+ setProgress( pe->progress() );
+ QApplication::instance()->processEvents();
+ }
+}
+
+/*!
+ \brief Check if the gradient is defined in the relative coordinates [static].
+ \internal
+ \return \c true if gradient is defined in the relative coordinates
+*/
+static bool checkGradient( const QGradient* g )
+{
+#define BOUNDED( a, min, max ) ( a >= min && a <= max )
+ if ( g->type() == QGradient::LinearGradient ) {
+ const QLinearGradient* lg = static_cast<const QLinearGradient*>( g );
+ return BOUNDED( lg->start().x(), 0.0, 1.0 ) &&
+ BOUNDED( lg->start().y(), 0.0, 1.0 ) &&
+ BOUNDED( lg->finalStop().x(), 0.0, 1.0 ) &&
+ BOUNDED( lg->finalStop().y(), 0.0, 1.0 );
+ }
+ if ( g->type() == QGradient::RadialGradient ) {
+ const QRadialGradient* rg = static_cast<const QRadialGradient*>( g );
+ return BOUNDED( rg->center().x(), 0.0, 1.0 ) &&
+ BOUNDED( rg->center().y(), 0.0, 1.0 ) &&
+ BOUNDED( rg->focalPoint().x(), 0.0, 1.0 ) &&
+ BOUNDED( rg->focalPoint().y(), 0.0, 1.0 ); // && BOUNDED( rg->radius(), 0.0, 1.0 );
+ }
+ if ( g->type() == QGradient::ConicalGradient ) {
+ const QConicalGradient* cg = static_cast<const QConicalGradient*>( g );
+ return BOUNDED( cg->center().x(), 0.0, 1.0 ) &&
+ BOUNDED( cg->center().y(), 0.0, 1.0 );
+ }
+ return false;
+}
+
+/*!
+ \brief Draw progress bar.
+ \param p painter
+ \sa drawMessage()
+*/
+void QtxSplash::drawProgressBar( QPainter* p )
+{
+ // get rect, margin, progress bar width
+ QRect r = rect();
+ int m = margin();
+ int pw = progressWidth();
+
+ // calculate drawing rect
+ // ... first set default position (if none or wrong position is set)
+ if ( myProgressFlags & BottomSide )
+ r = QRect( r.x() + m, r.height() - (m + pw), r.width() - 2 * m, pw );
+ else if ( myProgressFlags & TopSide )
+ r = QRect( r.x() + m, r.y() + m, r.width() - 2 * m, pw );
+ else if ( myProgressFlags & LeftSide )
+ r = QRect( r.x() + m, r.y() + m, pw, r.height() - 2 * m );
+ else if ( myProgressFlags & RightSide )
+ r = QRect( r.width() - (m + pw), r.y() + m, pw, r.height() - 2 * m );
+
+ QRect cr = r;
+ if ( myProgressFlags & TopSide || myProgressFlags & BottomSide ) {
+ cr.setWidth( (int)( r.width() * ( myProgress > 0 ? myProgress : 0 ) / myTotal ) );
+ if ( myProgressFlags & RightToLeft )
+ cr.translate( r.width() - cr.width(), 0 );
+ }
+ else if ( myProgressFlags & LeftSide || myProgressFlags & RightSide ) {
+ cr.setHeight( (int)( r.height() * ( myProgress > 0 ? myProgress : 0 ) / myTotal ) );
+ if ( myProgressFlags & RightToLeft)
+ cr.translate( 0, r.height() - cr.height() );
+ }
+ QBrush b;
+ switch ( progressColors()->type() ) {
+ case QGradient::LinearGradient:
+ {
+ QLinearGradient lg;
+ const QLinearGradient* other = static_cast<const QLinearGradient*>( progressColors() );
+ if ( checkGradient( other ) ) {
+ // gradient is defined in relative coordinates [0.0 - 1.0]
+ lg.setStart( r.left() + r.width() * other->start().x(),
+ r.top() + r.height() * other->start().y() );
+ lg.setFinalStop( r.left() + r.width() * other->finalStop().x(),
+ r.top() + r.height() * other->finalStop().y() );
+ }
+ else {
+ // gradient is defined in absolute coordinates
+ // according to its dimensions
+ lg.setStart( r.topLeft() + other->start() );
+ lg.setFinalStop( r.topLeft() + other->finalStop() );
+ }
+
+ lg.setStops( other->stops() );
+ lg.setSpread( other->spread() );
+
+ b = QBrush( lg );
+
+ break;
+ } // case QGradient::LinearGradient
+ case QGradient::RadialGradient:
+ {
+ QRadialGradient rg;
+ const QRadialGradient* other = static_cast<const QRadialGradient*>( progressColors() );
+ if ( checkGradient( other ) ) {
+ // gradient is defined in relative coordinates [0.0 - 1.0]
+ rg.setCenter( r.left() + r.width() * other->center().x(),
+ r.top() + r.height() * other->center().y() );
+ rg.setFocalPoint( r.left() + r.width() * other->focalPoint().x(),
+ r.top() + r.height() * other->focalPoint().y() );
+ }
+ else {
+ // gradient is defined in absolute coordinates
+ // according to its dimensions
+ rg.setCenter( r.topLeft() + other->center() );
+ rg.setFocalPoint( r.topLeft() + other->focalPoint() );
+ }
+
+ // only width is taken into account for the radius in relative mode
+ rg.setRadius( other->radius() > 1.0 ? other->radius() : r.width() * other->radius() );
+
+ rg.setStops( other->stops() );
+ rg.setSpread( other->spread() );
+
+ b = QBrush( rg );
+
+ break;
+ } // case QGradient::RadialGradient
+ case QGradient::ConicalGradient:
+ {
+ QConicalGradient cg;
+ const QConicalGradient* other = static_cast<const QConicalGradient*>( progressColors() );
+ if ( checkGradient( other ) ) {
+ // gradient is defined in relative coordinates [0.0 - 1.0]
+ cg.setCenter( r.left() + r.width() * other->center().x(),
+ r.top() + r.height() * other->center().y() );
+ }
+ else {
+ // gradient is defined in absolute coordinates
+ // according to its dimensions
+ cg.setCenter( r.topLeft() + other->center() );
+ }
+
+ cg.setAngle( other->angle() );
+ cg.setStops( other->stops() );
+ cg.setSpread( other->spread() );
+
+ b = QBrush( cg );
+
+ break;
+ } // case QGradient::RadialGradient
+ default:
+ b = QBrush( Qt::red ); // default is simple red-colored progress bar
+ break;
+ }
+
+ p->setOpacity( myOpacity );
+
+ // draw progress bar outline rectangle
+ p->setPen( palette().color( QPalette::Dark ) );
+ p->drawLine( r.left(), r.top(), r.right(), r.top() );
+ p->drawLine( r.left(), r.top(), r.left(), r.bottom() );
+ p->setPen( palette().color( QPalette::Light ) );
+ p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() );
+ p->drawLine( r.right(), r.top(), r.right(), r.bottom() );
+
+ r.setCoords( r.left()+1, r.top()+1, r.right()-1, r.bottom()-1 );
+ p->setClipRect( cr );
+ p->fillRect( r, b );
+ p->setClipping( false );
+
+ if ( myShowPercent ) {
+ int percent = ( int )( ( myProgress > 0 ? myProgress : 0 ) * 100 / myTotal );
+ QFont f = font();
+ f.setPixelSize( r.height() - 4 );
+ p->setFont( f );
+ // draw shadow status text
+ if ( myShadowColor.isValid() ) {
+ QRect rs = r;
+ rs.moveTopLeft( rs.topLeft() + QPoint( 1,1 ) );
+ p->setPen( myShadowColor );
+ p->drawText( rs, Qt::AlignCenter, QString( "%1%" ).arg( percent ) );
+ }
+ p->setPen( myColor );
+ p->drawText( r, Qt::AlignCenter, QString( "%1%" ).arg( percent ) );
}
}
/*!
- Draws the splash screen window [ internal ].
+ \brief Draw status message.
+ \param p painter
+ \sa drawProgressBar()
+*/
+void QtxSplash::drawMessage( QPainter* p )
+{
+ // get rect, margin, progress bar width
+ QRect r = rect();
+ int m = margin();
+ int pw = progressVisible() ? progressWidth() : 0;
+
+ // calculate drawing rect
+ QFontMetrics f( font() );
+ int spacing = f.lineSpacing();
+ // ... base rect
+ QRect r1( r.x() + m, r.y() + m, r.width() - 2 * m, r.height() - 2 * m );
+ r1.setY( r1.y() - f.leading() );
+ // ... take into account progress bar
+ if ( 1 ) { // if ( myTotal > 0 ) : vsr changed: otherwise text is jumping
+ if ( myProgressFlags & BottomSide )
+ r1.setHeight( r1.height() - pw );
+ else if ( myProgressFlags & TopSide )
+ r1.setY( r1.y() + pw );
+ else if ( myProgressFlags & LeftSide )
+ r1.setX( r1.x() + pw );
+ else if ( myProgressFlags & RightSide )
+ r1.setWidth( r1.width() - pw );
+ }
+
+ // ... take into account trailing '\n' symbols
+ int shift = 0;
+ QString msg = fullMessage();
+ int i = msg.length() - 1;
+ while( i >= 0 && msg[ i-- ] == '\n' )
+ shift += spacing;
+ r1.setHeight( r1.height() - shift );
+
+ p->setOpacity( myOpacity );
+
+ // draw shadow status text
+ if ( myShadowColor.isValid() ) {
+ QRect r2 = r1;
+ if ( myAlignment & Qt::AlignLeft ) r2.setLeft ( r2.left() + 1 );
+ if ( myAlignment & Qt::AlignTop ) r2.setTop ( r2.top() + 1 );
+ if ( myAlignment & Qt::AlignRight ) r2.setRight ( r2.right() + 1 );
+ if ( myAlignment & Qt::AlignBottom ) r2.setBottom( r2.bottom() + 1 );
+ p->setPen( myShadowColor );
+ p->drawText( r2, myAlignment, msg );
+ }
+
+ // draw foreground status text
+ p->setPen( myColor );
+ p->drawText( r1, myAlignment, msg );
+}
+
+/*!
+ \brief Draw the splash screen window contents.
+ \internal
*/
void QtxSplash::drawContents()
{
QPixmap textPix = myPixmap;
- QPainter painter( &textPix, this );
+ QPainter painter( &textPix );
+ painter.initFrom( this );
drawContents( &painter );
- setErasePixmap( textPix );
+ QPalette pal = palette();
+ pal.setBrush( backgroundRole(), QBrush( textPix ) );
+ setPalette( pal );
}
/*!
- Sets error code [ internal ].
+ \brief Sets error code.
+ \param code error code
+ \internal
*/
void QtxSplash::setError( const int code )
{
myError = code;
}
+
+/*!
+ \brief Get full message which includes constant info and status message.
+ \return get fill message text
+ \sa constantInfo(), setConstantInfo(), message(), setMessage()
+ \internal
+*/
+QString QtxSplash::fullMessage() const
+{
+ QStringList info;
+
+ QString cinfo = myInfo;
+ cinfo = cinfo.replace( QRegExp( "%A" ), option( "%A" ) );
+ cinfo = cinfo.replace( QRegExp( "%V" ), option( "%V" ) );
+ cinfo = cinfo.replace( QRegExp( "%L" ), option( "%L" ) );
+ cinfo = cinfo.replace( QRegExp( "%C" ), option( "%C" ) );
+
+ if ( !cinfo.isEmpty() )
+ info << cinfo;
+ if ( !myMessage.isEmpty() )
+ info << myMessage;
+ return info.join( "\n" );
+}