1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : QtxSplash.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25 #include "QtxSplash.h"
26 #include "QtxResourceMgr.h"
28 #include <QApplication>
30 #include <QMessageBox>
31 #include <QDesktopWidget>
36 \brief Progress change custom event.
39 class ProgressEvent: public QEvent
44 \param msg progress message
45 \param progress current progress (for example, in %)
47 ProgressEvent( const QString& msg, const int progress )
48 : QEvent( (QEvent::Type)id() ),
50 myProgress( progress )
53 \brief Get progress message.
56 QString message() const { return myMessage; }
58 \brief Get current progress.
59 \return current progress
61 int progress() const { return myProgress; }
63 \brief Get message identifier.
64 \return custom message ID
66 static int id() { return QEvent::User + 10; }
75 \brief The QtxSplash widget provides a splash screen that can be shown
76 during application startup.
78 A splash screen is a widget that is usually displayed when an application
80 Splash screens are often used for applications that have long start up times
81 to provide the user with feedback that the application is loading.
83 Only one instance of the QtxSplash widget can be created. To access the splash
84 screen widget, use static method QtxSplash::splash(), which creates an
85 instance of the QtxSplash widget (if it is not yet creaed) and returns a
87 You should not destroy this instance - it is done automatically after
88 application main window is shown. Just use methods finish() to make splash
89 screen wait untill main window is shown.
91 The splash screen appears in the center of the screen.
92 The most common usage is to show a splash screen before the main widget
93 is displayed on the screen.
96 int main(int argc, char *argv[])
98 QApplication app(argc, argv);
99 QPixmap pixmap(":/splash.png");
100 QtxSplash* splash = QtxsSplash::splash(pixmap);
103 ... // do application loading and initialization
106 splash->finish(&window);
111 The user can hide the splash screen by clicking on it with the mouse.
112 Since the splash screen is typically displayed before the event loop
113 has started running, it is necessary to periodically call
114 QApplication::processEvents() to receive the mouse clicks.
115 To activate the possibility of hiding the splash screen on the mouse
116 click, use setHideOnClick() method passing \c true as parameter.
117 By default, this feature is switched off.
119 It is sometimes useful to update the splash screen with any status messages
120 and/or progress information, for example, announcing connections established
121 or modules loaded as the application starts up.
122 QtxSplash class provides the functionality to show status messages
123 and(or) progress bar.
126 QPixmap pixmap(":/splash.png");
127 QtxSplash* splash = QtxSplash::splash(pixmap);
128 splash->setProgress(0, 5); // progress from 0 to 5
132 splash->setMessage("Step 1");
133 splash->setProgress(1); // progress is 20%
134 qApp->processEvents();
135 // ... perform some actions
137 splash->setMessage("Step 2");
138 splash->setProgress(2); // progress is 40%
139 qApp->processEvents();
140 // ... perform some actions
144 There is a static function QtxSplash::setStatus() which allows to put the
145 next status message and current progress with one call.
146 It can substitue two calls: setMessage() and setProgress().
148 QtxSplash class provides also a lot of functions to customize its behavior.
149 Set progress bar width with setProgressWidth() method, its position and
150 direction with setProgressFlags().
151 It can be single-colored or gradient-colored. Use setProgressColors() methods
152 for this. You can even set your own gradient scale with QLinearGradient,
153 QRadialGradient or QConicalGradient and use it for the progress
154 bar coloring. In addition, it is possible to enable/disable displaying
155 of the progress percentage with setPercentageVisible() method.
157 Displaying of the progress bar and status messages can be switched on/off with
158 setProgressVisible() and setMessageVisible() methods.
160 To change the progress bar and status message transparency, use
161 setOpacity() function. The methods setTextAlignment() and setTextColors()
162 can be used to change the attributes of the status messages.
164 The displayed message text can include constant info and status message.
165 The constant info is set by setConstantInfo() method and status message
166 is set by setMessage().
168 Sometimes it is useful to display an error message above the splash screen
169 window. For example, it can be necessary if an error occurs when loading
170 the application. Method setError() can be used to show the error message
171 and set the error code which can be then retrieved with the error() function.
173 There is one more helpful feature. The QtxSplash class can read all the
174 settings from the resource file with help of resource manager
175 (QtxResourceMgr class). Refer to the method readSettings() for more details.
178 //! The only one instance of splash screen
179 QtxSplash* QtxSplash::mySplash = 0;
184 Construct a splash screen that will display the \a pixmap.
186 \param pixmap splash screen pixmap
187 \sa setPixmap(), pixmap()
189 QtxSplash::QtxSplash( const QPixmap& pixmap )
190 : QWidget( 0, Qt::SplashScreen | Qt::WindowStaysOnTopHint ),
191 myAlignment( Qt::AlignBottom | Qt::AlignRight ),
192 myColor( Qt::white ),
193 myHideOnClick( false ),
196 myProgressWidth( 10 ),
197 myProgressFlags( BottomSide | LeftToRight ),
201 myShowPercent( true ),
202 myShowProgress( true ),
203 myShowMessage( true )
205 setAttribute( Qt::WA_DeleteOnClose, true );
212 QtxSplash::~QtxSplash()
218 \brief Get the only instance of the splash screen widget.
220 If the splash screen widget does not exist yet, it is created with specified
221 pixmap. Otherwise, pixmap \a px is set to existing widget.
223 \param px splash screen pixmap
224 \return splash screen widget
225 \sa setPixmap(), pixmap()
227 QtxSplash* QtxSplash::splash( const QPixmap& px )
230 mySplash = new QtxSplash( px );
231 else if ( !px.isNull() )
232 mySplash->setPixmap( px );
237 \brief Send the status message and (optionally) current progress
238 to the splash screen.
240 If the second parameter is less than 0 (default) than it is ignored
241 and only the status message is changed. If you want to modify progress
242 also, pass positive value to the \a progress parameter explicitly.
244 \param msg progress status message
245 \param progress current progress
246 \sa setMessage(), setProgress()
248 void QtxSplash::setStatus( const QString& msg, const int progress )
251 QApplication::postEvent( mySplash, new ProgressEvent( msg, progress ) );
252 QApplication::instance()->processEvents();
257 \brief Set error status and show error message box to the user.
258 \param error error message
259 \param title message box title
260 \param code error code
263 void QtxSplash::setError( const QString& error, const QString& title, const int code )
266 mySplash->setError( code );
267 QMessageBox::critical( mySplash,
268 title.isEmpty() ? tr( "Error" ) : title,
273 printf( "QtxSplash::error: %s\n",error.toLatin1().constData() );
278 \brief Set the pixmap that will be used as the splash screen's image.
279 \param pixmap spash screen image pixmap
282 void QtxSplash::setPixmap( const QPixmap& pixmap )
284 if ( pixmap.hasAlpha() ) {
285 QPixmap opaque( pixmap.size() );
286 QPainter p( &opaque );
287 p.fillRect( 0, 0, pixmap.width(), pixmap.height(), palette().background() );
288 p.drawPixmap( 0, 0, pixmap );
295 QRect r( 0, 0, myPixmap.size().width(), myPixmap.size().height() );
296 resize( myPixmap.size() );
297 move( QApplication::desktop()->screenGeometry().center() - r.center() );
305 \brief Get the pixmap that is used as the splash screen's image.
306 \return spash screen image pixmap
309 QPixmap QtxSplash::pixmap() const
315 \brief Set/clear the 'hide on mouse click' flag.
317 When this flag is set, user can hide the splash screen window
318 by clicking on it with mouse.
319 But for this to work it is necessary to call periodically
320 QApplication::processEvents() in order to allow event loop to process
321 events because usually main application loop is not yet started
324 By default this flag is set to \c false.
326 \param on new flag state
329 void QtxSplash::setHideOnClick( const bool on )
335 \brief Get the 'hide on mouse click' flag.
336 \return 'hide on mouse click' flag
339 bool QtxSplash::hideOnClick() const
341 return myHideOnClick;
345 \brief Enable/disable displaying of the progress bar.
346 \param on if \c true, progress bar will be enabled
347 \sa progressVisible(), setMessageVisible()
349 void QtxSplash::setProgressVisible( const bool on )
356 \brief Check if the progress bar is displayed.
357 \return \c true if progress bar is enabled
358 \sa setProgressVisible()
360 bool QtxSplash::progressVisible() const
362 return myShowProgress;
366 \brief Enable/disable displaying of the status message.
367 \param on if \c true, status message will be enabled
368 \sa messageVisible(), setProgressVisible()
370 void QtxSplash::setMessageVisible( const bool on )
377 \brief Check if the status message is displayed.
378 \return \c true if status message is enabled
379 \sa setMessageVisible()
381 bool QtxSplash::messageVisible() const
383 return myShowMessage;
387 \brief Enable/disable displaying progress percentage.
388 \param enable if \c true, percentage will be displayed
389 \sa percentageVisible()
391 void QtxSplash::setPercentageVisible( const bool enable )
393 myShowPercent = enable;
398 \brief Check if the progress percentage is displayed.
399 \return \c true if percentage displaying is enabled
400 \sa setPercentageVisible()
402 bool QtxSplash::percentageVisible() const
404 return myShowPercent;
408 \brief Set total progress steps to \a total.
409 \param total total number of progress steps
410 \sa totalSteps(), setProgress(), progress()
412 void QtxSplash::setTotalSteps( const int total )
419 \brief Get total progress steps number.
420 \return total number of progress steps
421 \sa setTotalSteps(), setProgress(), progress()
423 int QtxSplash::totalSteps() const
429 \brief Set current progress.
430 \param progress current progress
431 \sa progress(), setTotalSteps(), setTotalSteps(),
433 void QtxSplash::setProgress( const int progress )
435 myProgress = progress > 0 ? progress : 0;
440 \brief Get current progress.
441 \return current progress
442 \sa setProgress(), setTotalSteps(), setTotalSteps(),
444 int QtxSplash::progress() const
450 \brief Set current progress to \a progress and total number of
451 progress steps to \a total.
452 \param progress current progress
453 \param total total number of progress steps
455 void QtxSplash::setProgress( const int progress, const int total )
458 myProgress = progress > 0 ? progress : 0;
463 \brief Set splash window margin (a border width).
465 Note, that margin is used only for drawing the progress bar and status
468 \param margin new margin width
471 void QtxSplash::setMargin( const int margin )
473 myMargin = margin > 0 ? margin : 0;
478 \brief Get splash window margin (a border width).
479 \return current margin width
482 int QtxSplash::margin() const
488 \brief Set progress bar width.
489 \param width new progress bar width
492 void QtxSplash::setProgressWidth( const int width )
494 myProgressWidth = width > 0 ? width : 0;
499 \brief Get progress bar width.
500 \return current progress bar width
501 \sa setProgressWidth()
503 int QtxSplash::progressWidth() const
505 return myProgressWidth;
509 \brief Set progress bar position and direction.
511 By default, progress bar is displayed at the bottom side and
512 shows progress from left to right but this behaviour can be changed.
514 \param flags ORed progress bar flags (QtxSplash::ProgressBarFlags)
517 void QtxSplash::setProgressFlags( const int flags )
519 myProgressFlags = flags;
520 if ( !( myProgressFlags & ( LeftSide | RightSide | TopSide | BottomSide ) ) )
521 myProgressFlags |= BottomSide;
522 if ( !( myProgressFlags & ( LeftToRight | RightToLeft ) ) )
523 myProgressFlags |= LeftToRight ;
528 \brief Get progress bar flags: position and direction.
529 \return ORed progress bar flags (QtxSplash::ProgressBarFlags)
530 \sa setProgressFlags()
532 int QtxSplash::progressFlags() const
534 return myProgressFlags;
538 \brief Set progress bar colors.
540 If the colors differ the two-colored gradient bar is drawn.
542 If the \a endColor is not valid, \a startColor is used instead
543 (i.e. simple, one-colored progress bar is drawn).
545 The parameter \a orientation defines the type of gradient
546 to be drawn - horizontal or vertical. Default is vertical.
548 \param startColor start gradient color (or mono-color)
549 \param endColor end gradient color
550 \param orientation gradient type (Qt::Orientation)
553 void QtxSplash::setProgressColors( const QColor& startColor,
554 const QColor& endColor,
555 const Qt::Orientation orientation )
557 if ( !startColor.isValid() )
561 if ( orientation == Qt::Vertical ) {
562 l.setStart( 0., 0. );
563 l.setFinalStop( 0., 1. );
566 l.setStart( 0., 0. );
567 l.setFinalStop( 1., 0. );
569 l.setColorAt( 0., startColor );
570 l.setColorAt( 1., endColor.isValid() ? endColor : startColor );
572 setProgressColors( l );
576 \brief Set progress bar colors.
578 Use this method to display multi-colored gradient progress bar.
579 You have to use QLinearGradient, QRadialGradient or QConicalGradient
580 classes to define the gradient.
582 Note, that progress bar coordinates can be defined in absolute or
584 In absolute mode the actual coordinates of the gradient key points
585 (like start and final point for linear gradient, center and focal point
586 for radial gradient, etc) are calculated from the top-left progress bar's corner.
587 In relative mode you have to use values from 0 to 1 (including) to define
588 the key points positions.
592 QLinearGradient lg(0.5, 0, 1, 1);
593 lg.setColorAt(0.2, Qt::blue);
594 lg.setColorAt(0.6, Qt::red);
595 lg.setSpread(QGradient::RepeatSpread);
596 splash->setProgressGradient(lg);
598 The above code creates linear gradient, which sets start stop to the
599 center of the progress bar; the final stop is assigned to its right-bottom corner.
600 The color scale (blue to red) is changed by the progress bar diagonal.
602 \param gradient color gradient to be used for progress bar coloring
605 void QtxSplash::setProgressColors( const QGradient& gradient )
607 myGradient = gradient;
612 \brief Get custom progress bar colors.
613 \return color gradient used for progress bar coloring
614 \sa setProgressColors()
616 const QGradient* QtxSplash::progressColors() const
622 \brief Set progress bar and status text message opacity.
624 The value should be in the range 0.0 to 1.0, where 0.0 is fully
625 transparent and 1.0 is fully opaque.
627 \param opacity new opacity value
630 void QtxSplash::setOpacity( const double opacity )
632 myOpacity = opacity < 0.0 ? 0.0 : ( opacity > 1.0 ? 1.0 : opacity );
637 \brief Get progress bar and status text message opacity.
638 \return current opacity value
641 double QtxSplash::opacity() const
647 \brief Set message text alignment flags.
649 Default flags are Qt::AlignBottom | Qt::AlignRight.
651 \param alignment alignment flags (Qt::Alignment)
654 void QtxSplash::setTextAlignment( const int alignment )
656 myAlignment = alignment;
661 \brief Get message text alignment flags.
662 \return alignment flags (Qt::Alignment)
663 \sa setTextAlignment()
665 int QtxSplash::textAlignment() const
671 \brief Set message text colors.
673 If \a shadow parameter is invalid color, the simple one-colored
674 text is drawn. Otherwise, second parameter is used to draw the text
677 \param color message text color
678 \param shadow message text shadow color
681 void QtxSplash::setTextColors( const QColor& color, const QColor& shadow )
683 if ( !myColor.isValid() )
687 myShadowColor = shadow;
693 \brief Get message text colors.
694 \param color message text color
695 \param shadow message text shadow color
698 void QtxSplash::textColors( QColor& color, QColor& shadow ) const
701 shadow = myShadowColor;
705 \brief Set constant info text to be displayed on the splash screen.
707 The displayed text includes constant info and status message.
708 The constant message is set by setConstantInfo() method and status
709 message is set by setMessage().
711 \param info constant info text
712 \sa constantInfo(), message(), setMessage(), option(), setOption()
714 void QtxSplash::setConstantInfo( const QString& info )
721 \brief Get constant info text.
722 \return constant info text
723 \sa setConstantInfo(), message(), setMessage()
725 QString QtxSplash::constantInfo() const
731 \brief Set constant information option value.
733 The option is a part of the constant information text,
734 which is replaced at the time of the displaying.
736 The following options are supported:
737 - \c \%A - could be used as application name
738 - \c \%V - could be used as application version
739 - \c \%L - could be used as application license information
740 - \c \%C - could be used as application copyright information
744 splash->setContantInfo("%A [%V]\n%C");
745 splash->setOption("%A", "MyApplication" );
746 splash->setOption("%V", "Version 1.0" );
747 splash->setOption("%C", "Copyright (C) MyCompany 2008" );
750 \param name option name
752 \sa option(), setConstantInfo(), constantInfo()
754 void QtxSplash::setOption( const QString& name, const QString& value )
756 myOptions[ name ] = value;
761 \brief Get constant information option value.
762 \param name option name
763 \return option value or empty string if option is not set
764 \sa setOption(), setConstantInfo(), constantInfo()
766 QString QtxSplash::option( const QString& name ) const
769 if ( myOptions.contains( name ) )
770 val = myOptions[ name ];
775 \brief Get current status message.
776 \return status message
777 \sa setMessage(), constantInfo(), setConstantInfo()
779 QString QtxSplash::message() const
785 \brief Get error code.
787 This function returns error code, set previously with
789 If no error code has been set, 0 is returned.
791 \return last error code
794 int QtxSplash::error() const
800 \brief Wait until widget \a mainWin is displayed.
802 Makes the splash screen wait until the widget \a mainWin is displayed
803 and then hide and close splash window.
805 \param mainWin application main window
807 void QtxSplash::finish( QWidget* mainWin )
810 #if defined(Q_WS_X11)
811 extern void qt_x11_wait_for_window_manager(QWidget *mainWin);
812 qt_x11_wait_for_window_manager(mainWin);
819 \brief Repaint the splash screen.
821 void QtxSplash::repaint()
825 QApplication::flush();
829 \brief Read splash settings from the resources manager.
831 This method can be used to setup the splash screen look-n-feel.
832 By default, "splash" section of the resources file is used, but you can
833 use any other section.
834 All the splash screen parameters can be defined via resources file:
835 - \c "image" : splash screen image, see setPixmap()
836 - \c "margin" : splash window margin, see setMargin()
837 - \c "show_progress" : show progress bar flag, see setProgressVisible()
838 - \c "show_message" : show status messages flag, see setMessageVisible()
839 - \c "show_percents" : show progress percentage flag, see setPercentageVisible()
840 - \c "progress_width" : progress bar width(), see setProgressWidth()
841 - \c "progress_flags" : progress bar position and direction, see setProgressFlags()
842 - \c "constant_info" : status messages constant info, see setConstantInfo()
843 - \c "text_colors" : status messages color(s), see setTextColors()
844 - \c "progress_colors" : progress bar color(s), see setProgressColors()
845 - \c "opacity" : progress bar and status messages opacity, see setOpacity()
846 - \c "font" : status messages font
847 - \c "alignment" : status messages alignment flags, see setTextAlignment()
848 - \c "hide_on_click" : hide-on-click flag, see setHideOnClick()
850 \param resMgr resources manager
851 \param section resources file section name (if empty, the default "splash"
854 void QtxSplash::readSettings( QtxResourceMgr* resMgr, const QString& section )
856 QString resSection = section.isEmpty() ? QString( "splash" ) : section;
860 if ( resMgr->value( resSection, "image", pxname ) ) {
861 QPixmap px( pxname );
868 setHideOnClick( true );
871 if ( resMgr->value( resSection, "hide_on_click", bHide ) ) {
872 setHideOnClick( bHide );
876 // enable progress bar
878 if ( resMgr->value( resSection, "show_progress", bShowProgress ) ) {
879 setProgressVisible( bShowProgress );
882 // enable status message
884 if ( resMgr->value( resSection, "show_message", bShowMessage ) ) {
885 setMessageVisible( bShowMessage );
890 if ( resMgr->value( resSection, "margin", m ) ) {
894 // progress bar width
896 if ( resMgr->value( resSection, "progress_width", pw ) ) {
897 setProgressWidth( pw );
900 // progress bar position and direction
902 if ( resMgr->value( resSection, "progress_flags", pf ) ) {
904 int fl = pf.toInt( &bOk );
907 QStringList opts = pf.split( QRegExp( "," ), QString::SkipEmptyParts );
908 for ( int i = 0; i < opts.count(); i++ ) {
909 QString opt = opts[i].trimmed().toLower();
912 else if ( opt == "right" )
914 else if ( opt == "top" )
916 else if ( opt == "bottom" )
917 fl = fl | BottomSide;
918 else if ( opt == "left_to_right" )
919 fl = fl | LeftToRight;
920 else if ( opt == "right_to_left" )
921 fl = fl | RightToLeft;
924 setProgressFlags( fl );
929 if ( resMgr->value( resSection, "opacity", op ) ) {
935 if ( resMgr->value( resSection, "font", f ) ) {
941 if ( resMgr->value( resSection, "alignment", al ) ) {
943 int fl = al.toInt( &bOk );
946 QStringList opts = al.split( QRegExp( "," ), QString::SkipEmptyParts );
947 for ( int i = 0; i < opts.count(); i++ ) {
948 QString opt = opts[i].trimmed().toLower();
950 fl = fl | Qt::AlignLeft;
951 else if ( opt == "right" )
952 fl = fl | Qt::AlignRight;
953 else if ( opt == "top" )
954 fl = fl | Qt::AlignTop;
955 else if ( opt == "bottom" )
956 fl = fl | Qt::AlignBottom;
957 else if ( opt == "hcenter" )
958 fl = fl | Qt::AlignHCenter;
959 else if ( opt == "vcenter" )
960 fl = fl | Qt::AlignVCenter;
961 else if ( opt == "justify" )
962 fl = fl | Qt::AlignJustify;
963 else if ( opt == "center" )
964 fl = fl | Qt::AlignCenter;
967 setTextAlignment( fl );
971 QLinearGradient lgrad;
972 QRadialGradient rgrad;
973 QConicalGradient cgrad;
974 if ( resMgr->value( resSection, "progress_color", lgrad ) ||
975 resMgr->value( resSection, "progress_colors", lgrad ) ) {
976 // linear gradient-colored progress bar
977 setProgressColors( lgrad );
979 else if ( resMgr->value( resSection, "progress_color", rgrad ) ||
980 resMgr->value( resSection, "progress_colors", rgrad ) ) {
981 // radial gradient-colored progress bar
982 setProgressColors( rgrad );
984 else if ( resMgr->value( resSection, "progress_color", cgrad ) ||
985 resMgr->value( resSection, "progress_colors", cgrad ) ) {
986 // conical gradient-colored progress bar
987 setProgressColors( cgrad );
989 else if ( resMgr->value( resSection, "progress_color", pc ) ||
990 resMgr->value( resSection, "progress_colors", pc ) ) {
991 // one/two-colored progress bar
992 QStringList colors = pc.split( "|", QString::SkipEmptyParts );
994 Qt::Orientation o = Qt::Vertical;
995 if ( colors.count() > 0 ) c1 = QColor( colors[0] );
996 if ( colors.count() > 1 ) c2 = QColor( colors[1] );
998 if ( colors.count() > 2 ) {
1000 gt = colors[2].toInt( &bOk );
1006 if ( colors[2].toLower().startsWith( "h" ) )
1010 setProgressColors( c1, c2, o );
1014 if ( resMgr->value( resSection, "show_percents", bPercent ) ) {
1015 setPercentageVisible( bPercent );
1020 if ( resMgr->value( resSection, "text_color", tc ) ||
1021 resMgr->value( resSection, "text_colors", tc ) ) {
1022 QStringList colors = tc.split( "|", QString::SkipEmptyParts );
1024 if ( colors.count() > 0 )
1025 c1 = QColor( colors[0] );
1026 if ( colors.count() > 1 )
1027 c2 = QColor( colors[1] );
1028 setTextColors( c1, c2 );
1033 if ( resMgr->value( resSection, "constant_info", cinfo, false ) ||
1034 resMgr->value( resSection, "info", cinfo, false ) ) {
1035 setConstantInfo( cinfo.split( "|", QString::KeepEmptyParts ).join( "\n" ) );
1040 \brief Set status message for the splash screen and define its color
1042 \param msg status message
1043 \param alignment message text alignment flags (Qt::Alignment)
1044 \param color message text color
1045 \sa message(), constantInfo(), setConstantInfo()
1047 void QtxSplash::setMessage( const QString& msg,
1049 const QColor& color )
1052 myAlignment = alignment;
1053 if ( color.isValid() )
1060 \brief Set status message for the splash screen.
1061 \param msg status message
1062 \sa message(), constantInfo(), setConstantInfo()
1064 void QtxSplash::setMessage( const QString& msg )
1071 \brief Remove the message being displayed on the splash screen.
1073 This is equivalent to setMessage("");
1075 \sa message(), setMessage()
1077 void QtxSplash::clear()
1084 \brief Draw the contents of the splash screen.
1087 void QtxSplash::drawContents( QPainter* p )
1089 // draw progress bar
1090 if ( myTotal > 0 && progressVisible() ) {
1092 drawProgressBar( p );
1096 // draw status message
1097 if ( !fullMessage().isEmpty() && messageVisible() ) {
1105 \brief Process mouse button pressing event.
1107 Hides splash screen if the 'hide on mouse click' flag is set.
1109 \param me mouse event (not used)
1110 \sa hideOnClick(), setHideOnClick()
1112 void QtxSplash::mousePressEvent( QMouseEvent* /*me*/ )
1114 if ( myHideOnClick )
1119 \brief Customize paint event.
1121 This function is implemented to work-around the Qt bug
1122 on some Linux distribututions when the drawing on the
1123 splash screen widget is not allowed.
1125 \param pe paint event (not used)
1127 void QtxSplash::paintEvent( QPaintEvent* /*pe*/ )
1130 QPixmap pix = palette().brush( backgroundRole() ).texture();
1131 p.drawPixmap( 0, 0, pix );
1135 \brief Process custom event sent by setStatus() method.
1136 \param ce custom event
1139 void QtxSplash::customEvent( QEvent* ce )
1141 if ( ce->type() == ProgressEvent::id() ) {
1142 ProgressEvent* pe = (ProgressEvent*)ce;
1143 pe->message().isEmpty() ? clear() : setMessage( pe->message() );
1144 if ( pe->progress() >= 0 )
1145 setProgress( pe->progress() );
1146 QApplication::instance()->processEvents();
1151 \brief Check if the gradient is defined in the relative coordinates [static].
1153 \return \c true if gradient is defined in the relative coordinates
1155 static bool checkGradient( const QGradient* g )
1157 #define BOUNDED( a, min, max ) ( a >= min && a <= max )
1158 if ( g->type() == QGradient::LinearGradient ) {
1159 const QLinearGradient* lg = static_cast<const QLinearGradient*>( g );
1160 return BOUNDED( lg->start().x(), 0.0, 1.0 ) &&
1161 BOUNDED( lg->start().y(), 0.0, 1.0 ) &&
1162 BOUNDED( lg->finalStop().x(), 0.0, 1.0 ) &&
1163 BOUNDED( lg->finalStop().y(), 0.0, 1.0 );
1165 if ( g->type() == QGradient::RadialGradient ) {
1166 const QRadialGradient* rg = static_cast<const QRadialGradient*>( g );
1167 return BOUNDED( rg->center().x(), 0.0, 1.0 ) &&
1168 BOUNDED( rg->center().y(), 0.0, 1.0 ) &&
1169 BOUNDED( rg->focalPoint().x(), 0.0, 1.0 ) &&
1170 BOUNDED( rg->focalPoint().y(), 0.0, 1.0 ); // && BOUNDED( rg->radius(), 0.0, 1.0 );
1172 if ( g->type() == QGradient::ConicalGradient ) {
1173 const QConicalGradient* cg = static_cast<const QConicalGradient*>( g );
1174 return BOUNDED( cg->center().x(), 0.0, 1.0 ) &&
1175 BOUNDED( cg->center().y(), 0.0, 1.0 );
1181 \brief Draw progress bar.
1185 void QtxSplash::drawProgressBar( QPainter* p )
1187 // get rect, margin, progress bar width
1190 int pw = progressWidth();
1192 // calculate drawing rect
1193 // ... first set default position (if none or wrong position is set)
1194 if ( myProgressFlags & BottomSide )
1195 r = QRect( r.x() + m, r.height() - (m + pw), r.width() - 2 * m, pw );
1196 else if ( myProgressFlags & TopSide )
1197 r = QRect( r.x() + m, r.y() + m, r.width() - 2 * m, pw );
1198 else if ( myProgressFlags & LeftSide )
1199 r = QRect( r.x() + m, r.y() + m, pw, r.height() - 2 * m );
1200 else if ( myProgressFlags & RightSide )
1201 r = QRect( r.width() - (m + pw), r.y() + m, pw, r.height() - 2 * m );
1204 if ( myProgressFlags & TopSide || myProgressFlags & BottomSide ) {
1205 cr.setWidth( (int)( r.width() * ( myProgress > 0 ? myProgress : 0 ) / myTotal ) );
1206 if ( myProgressFlags & RightToLeft )
1207 cr.translate( r.width() - cr.width(), 0 );
1209 else if ( myProgressFlags & LeftSide || myProgressFlags & RightSide ) {
1210 cr.setHeight( (int)( r.height() * ( myProgress > 0 ? myProgress : 0 ) / myTotal ) );
1211 if ( myProgressFlags & RightToLeft)
1212 cr.translate( 0, r.height() - cr.height() );
1215 switch ( progressColors()->type() ) {
1216 case QGradient::LinearGradient:
1219 const QLinearGradient* other = static_cast<const QLinearGradient*>( progressColors() );
1220 if ( checkGradient( other ) ) {
1221 // gradient is defined in relative coordinates [0.0 - 1.0]
1222 lg.setStart( r.left() + r.width() * other->start().x(),
1223 r.top() + r.height() * other->start().y() );
1224 lg.setFinalStop( r.left() + r.width() * other->finalStop().x(),
1225 r.top() + r.height() * other->finalStop().y() );
1228 // gradient is defined in absolute coordinates
1229 // according to its dimensions
1230 lg.setStart( r.topLeft() + other->start() );
1231 lg.setFinalStop( r.topLeft() + other->finalStop() );
1234 lg.setStops( other->stops() );
1235 lg.setSpread( other->spread() );
1240 } // case QGradient::LinearGradient
1241 case QGradient::RadialGradient:
1244 const QRadialGradient* other = static_cast<const QRadialGradient*>( progressColors() );
1245 if ( checkGradient( other ) ) {
1246 // gradient is defined in relative coordinates [0.0 - 1.0]
1247 rg.setCenter( r.left() + r.width() * other->center().x(),
1248 r.top() + r.height() * other->center().y() );
1249 rg.setFocalPoint( r.left() + r.width() * other->focalPoint().x(),
1250 r.top() + r.height() * other->focalPoint().y() );
1253 // gradient is defined in absolute coordinates
1254 // according to its dimensions
1255 rg.setCenter( r.topLeft() + other->center() );
1256 rg.setFocalPoint( r.topLeft() + other->focalPoint() );
1259 // only width is taken into account for the radius in relative mode
1260 rg.setRadius( other->radius() > 1.0 ? other->radius() : r.width() * other->radius() );
1262 rg.setStops( other->stops() );
1263 rg.setSpread( other->spread() );
1268 } // case QGradient::RadialGradient
1269 case QGradient::ConicalGradient:
1271 QConicalGradient cg;
1272 const QConicalGradient* other = static_cast<const QConicalGradient*>( progressColors() );
1273 if ( checkGradient( other ) ) {
1274 // gradient is defined in relative coordinates [0.0 - 1.0]
1275 cg.setCenter( r.left() + r.width() * other->center().x(),
1276 r.top() + r.height() * other->center().y() );
1279 // gradient is defined in absolute coordinates
1280 // according to its dimensions
1281 cg.setCenter( r.topLeft() + other->center() );
1284 cg.setAngle( other->angle() );
1285 cg.setStops( other->stops() );
1286 cg.setSpread( other->spread() );
1291 } // case QGradient::RadialGradient
1293 b = QBrush( Qt::red ); // default is simple red-colored progress bar
1297 p->setOpacity( myOpacity );
1299 // draw progress bar outline rectangle
1300 p->setPen( palette().color( QPalette::Dark ) );
1301 p->drawLine( r.left(), r.top(), r.right(), r.top() );
1302 p->drawLine( r.left(), r.top(), r.left(), r.bottom() );
1303 p->setPen( palette().color( QPalette::Light ) );
1304 p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() );
1305 p->drawLine( r.right(), r.top(), r.right(), r.bottom() );
1307 r.setCoords( r.left()+1, r.top()+1, r.right()-1, r.bottom()-1 );
1308 p->setClipRect( cr );
1309 p->fillRect( r, b );
1310 p->setClipping( false );
1312 if ( myShowPercent ) {
1313 int percent = ( int )( ( myProgress > 0 ? myProgress : 0 ) * 100 / myTotal );
1315 f.setPixelSize( r.height() - 4 );
1317 // draw shadow status text
1318 if ( myShadowColor.isValid() ) {
1320 rs.moveTopLeft( rs.topLeft() + QPoint( 1,1 ) );
1321 p->setPen( myShadowColor );
1322 p->drawText( rs, Qt::AlignCenter, QString( "%1%" ).arg( percent ) );
1324 p->setPen( myColor );
1325 p->drawText( r, Qt::AlignCenter, QString( "%1%" ).arg( percent ) );
1330 \brief Draw status message.
1332 \sa drawProgressBar()
1334 void QtxSplash::drawMessage( QPainter* p )
1336 // get rect, margin, progress bar width
1339 int pw = progressVisible() ? progressWidth() : 0;
1341 // calculate drawing rect
1342 QFontMetrics f( font() );
1343 int spacing = f.lineSpacing();
1345 QRect r1( r.x() + m, r.y() + m, r.width() - 2 * m, r.height() - 2 * m );
1346 r1.setY( r1.y() - f.leading() );
1347 // ... take into account progress bar
1348 if ( 1 ) { // if ( myTotal > 0 ) : vsr changed: otherwise text is jumping
1349 if ( myProgressFlags & BottomSide )
1350 r1.setHeight( r1.height() - pw );
1351 else if ( myProgressFlags & TopSide )
1352 r1.setY( r1.y() + pw );
1353 else if ( myProgressFlags & LeftSide )
1354 r1.setX( r1.x() + pw );
1355 else if ( myProgressFlags & RightSide )
1356 r1.setWidth( r1.width() - pw );
1359 // ... take into account trailing '\n' symbols
1361 QString msg = fullMessage();
1362 int i = msg.length() - 1;
1363 while( i >= 0 && msg[ i-- ] == '\n' )
1365 r1.setHeight( r1.height() - shift );
1367 p->setOpacity( myOpacity );
1369 // draw shadow status text
1370 if ( myShadowColor.isValid() ) {
1372 if ( myAlignment & Qt::AlignLeft ) r2.setLeft ( r2.left() + 1 );
1373 if ( myAlignment & Qt::AlignTop ) r2.setTop ( r2.top() + 1 );
1374 if ( myAlignment & Qt::AlignRight ) r2.setRight ( r2.right() + 1 );
1375 if ( myAlignment & Qt::AlignBottom ) r2.setBottom( r2.bottom() + 1 );
1376 p->setPen( myShadowColor );
1377 p->drawText( r2, myAlignment, msg );
1380 // draw foreground status text
1381 p->setPen( myColor );
1382 p->drawText( r1, myAlignment, msg );
1386 \brief Draw the splash screen window contents.
1389 void QtxSplash::drawContents()
1391 QPixmap textPix = myPixmap;
1392 QPainter painter( &textPix );
1393 painter.initFrom( this );
1394 drawContents( &painter );
1395 QPalette pal = palette();
1396 pal.setBrush( backgroundRole(), QBrush( textPix ) );
1401 \brief Sets error code.
1402 \param code error code
1405 void QtxSplash::setError( const int code )
1411 \brief Get full message which includes constant info and status message.
1412 \return get fill message text
1413 \sa constantInfo(), setConstantInfo(), message(), setMessage()
1416 QString QtxSplash::fullMessage() const
1420 QString cinfo = myInfo;
1421 cinfo = cinfo.replace( QRegExp( "%A" ), option( "%A" ) );
1422 cinfo = cinfo.replace( QRegExp( "%V" ), option( "%V" ) );
1423 cinfo = cinfo.replace( QRegExp( "%L" ), option( "%L" ) );
1424 cinfo = cinfo.replace( QRegExp( "%C" ), option( "%C" ) );
1426 if ( !cinfo.isEmpty() )
1428 if ( !myMessage.isEmpty() )
1430 return info.join( "\n" );