1 // Copyright (C) 2007-2016 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, or (at your option) any later version.
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
23 // File : QtxSplash.cxx
24 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
26 #include "QtxSplash.h"
27 #include "QtxResourceMgr.h"
30 #include <QApplication>
32 #include <QMessageBox>
33 #include <QDesktopWidget>
38 \brief Progress change custom event.
41 class ProgressEvent: public QEvent
46 \param msg progress message
47 \param progress current progress (for example, in %)
49 ProgressEvent( const QString& msg, const int progress )
50 : QEvent( (QEvent::Type)id() ),
52 myProgress( progress )
55 \brief Get progress message.
58 QString message() const { return myMessage; }
60 \brief Get current progress.
61 \return current progress
63 int progress() const { return myProgress; }
65 \brief Get message identifier.
66 \return custom message ID
68 static int id() { return QEvent::User + 10; }
77 \brief The QtxSplash widget provides a splash screen that can be shown
78 during application startup.
80 A splash screen is a widget that is usually displayed when an application
82 Splash screens are often used for applications that have long start up times
83 to provide the user with feedback that the application is loading.
85 Only one instance of the QtxSplash widget can be created. To access the splash
86 screen widget, use static method QtxSplash::splash(), which creates an
87 instance of the QtxSplash widget (if it is not yet creaed) and returns a
89 You should not destroy this instance - it is done automatically after
90 application main window is shown. Just use methods finish() to make splash
91 screen wait untill main window is shown.
93 The splash screen appears in the center of the screen.
94 The most common usage is to show a splash screen before the main widget
95 is displayed on the screen.
98 int main(int argc, char *argv[])
100 QApplication app(argc, argv);
101 QPixmap pixmap(":/splash.png");
102 QtxSplash* splash = QtxsSplash::splash(pixmap);
105 ... // do application loading and initialization
108 splash->finish(&window);
113 The user can hide the splash screen by clicking on it with the mouse.
114 Since the splash screen is typically displayed before the event loop
115 has started running, it is necessary to periodically call
116 QApplication::processEvents() to receive the mouse clicks.
117 To activate the possibility of hiding the splash screen on the mouse
118 click, use setHideOnClick() method passing \c true as parameter.
119 By default, this feature is switched off.
121 It is sometimes useful to update the splash screen with any status messages
122 and/or progress information, for example, announcing connections established
123 or modules loaded as the application starts up.
124 QtxSplash class provides the functionality to show status messages
125 and(or) progress bar.
128 QPixmap pixmap(":/splash.png");
129 QtxSplash* splash = QtxSplash::splash(pixmap);
130 splash->setProgress(0, 5); // progress from 0 to 5
134 splash->setMessage("Step 1");
135 splash->setProgress(1); // progress is 20%
136 qApp->processEvents();
137 // ... perform some actions
139 splash->setMessage("Step 2");
140 splash->setProgress(2); // progress is 40%
141 qApp->processEvents();
142 // ... perform some actions
146 There is a static function QtxSplash::setStatus() which allows to put the
147 next status message and current progress with one call.
148 It can substitue two calls: setMessage() and setProgress().
150 QtxSplash class provides also a lot of functions to customize its behavior.
151 Set progress bar width with setProgressWidth() method, its position and
152 direction with setProgressFlags().
153 It can be single-colored or gradient-colored. Use setProgressColors() methods
154 for this. You can even set your own gradient scale with QLinearGradient,
155 QRadialGradient or QConicalGradient and use it for the progress
156 bar coloring. In addition, it is possible to enable/disable displaying
157 of the progress percentage with setPercentageVisible() method.
159 Displaying of the progress bar and status messages can be switched on/off with
160 setProgressVisible() and setMessageVisible() methods.
162 To change the progress bar and status message transparency, use
163 setOpacity() function. The methods setTextAlignment() and setTextColors()
164 can be used to change the attributes of the status messages.
166 The displayed message text can include constant info and status message.
167 The constant info is set by setConstantInfo() method and status message
168 is set by setMessage().
170 Sometimes it is useful to display an error message above the splash screen
171 window. For example, it can be necessary if an error occurs when loading
172 the application. Method setError() can be used to show the error message
173 and set the error code which can be then retrieved with the error() function.
175 There is one more helpful feature. The QtxSplash class can read all the
176 settings from the resource file with help of resource manager
177 (QtxResourceMgr class). Refer to the method readSettings() for more details.
180 //! The only one instance of splash screen
181 QtxSplash* QtxSplash::mySplash = 0;
186 Construct a splash screen that will display the \a pixmap.
188 \param pixmap splash screen pixmap
189 \sa setPixmap(), pixmap()
191 QtxSplash::QtxSplash( const QPixmap& pixmap )
192 : QWidget( 0, Qt::SplashScreen | Qt::WindowStaysOnTopHint ),
193 myAlignment( Qt::AlignBottom | Qt::AlignRight ),
194 myColor( Qt::white ),
195 myHideOnClick( false ),
198 myProgressWidth( 10 ),
199 myProgressFlags( BottomSide | LeftToRight ),
203 myShowPercent( true ),
204 myShowProgress( true ),
205 myShowMessage( true )
207 setAttribute( Qt::WA_DeleteOnClose, true );
214 QtxSplash::~QtxSplash()
220 \brief Get the only instance of the splash screen widget.
222 If the splash screen widget does not exist yet, it is created with specified
223 pixmap. Otherwise, pixmap \a px is set to existing widget.
225 \param px splash screen pixmap
226 \return splash screen widget
227 \sa setPixmap(), pixmap()
229 QtxSplash* QtxSplash::splash( const QPixmap& px )
232 mySplash = new QtxSplash( px );
233 else if ( !px.isNull() )
234 mySplash->setPixmap( px );
239 \brief Send the status message and (optionally) current progress
240 to the splash screen.
242 If the second parameter is less than 0 (default) than it is ignored
243 and only the status message is changed. If you want to modify progress
244 also, pass positive value to the \a progress parameter explicitly.
246 \param msg progress status message
247 \param progress current progress
248 \sa setMessage(), setProgress()
250 void QtxSplash::setStatus( const QString& msg, const int progress )
253 QApplication::postEvent( mySplash, new ProgressEvent( msg, progress ) );
254 QApplication::instance()->processEvents();
259 \brief Set error status and show error message box to the user.
260 \param error error message
261 \param title message box title
262 \param code error code
265 void QtxSplash::setError( const QString& error, const QString& title, const int code )
268 mySplash->setError( code );
269 QMessageBox::critical( mySplash,
270 title.isEmpty() ? tr( "Error" ) : title,
275 printf( "QtxSplash::error: %s\n",error.toLatin1().constData() );
280 \brief Set the pixmap that will be used as the splash screen's image.
281 \param pixmap spash screen image pixmap
284 void QtxSplash::setPixmap( const QPixmap& pixmap )
286 if ( pixmap.hasAlpha() ) {
287 QPixmap opaque( pixmap.size() );
288 QPainter p( &opaque );
289 p.fillRect( 0, 0, pixmap.width(), pixmap.height(), palette().background() );
290 p.drawPixmap( 0, 0, pixmap );
297 QRect r( 0, 0, myPixmap.size().width(), myPixmap.size().height() );
298 resize( myPixmap.size() );
299 move( QApplication::desktop()->screenGeometry().center() - r.center() );
307 \brief Get the pixmap that is used as the splash screen's image.
308 \return spash screen image pixmap
311 QPixmap QtxSplash::pixmap() const
317 \brief Set/clear the 'hide on mouse click' flag.
319 When this flag is set, user can hide the splash screen window
320 by clicking on it with mouse.
321 But for this to work it is necessary to call periodically
322 QApplication::processEvents() in order to allow event loop to process
323 events because usually main application loop is not yet started
326 By default this flag is set to \c false.
328 \param on new flag state
331 void QtxSplash::setHideOnClick( const bool on )
337 \brief Get the 'hide on mouse click' flag.
338 \return 'hide on mouse click' flag
341 bool QtxSplash::hideOnClick() const
343 return myHideOnClick;
347 \brief Enable/disable displaying of the progress bar.
348 \param on if \c true, progress bar will be enabled
349 \sa progressVisible(), setMessageVisible()
351 void QtxSplash::setProgressVisible( const bool on )
358 \brief Check if the progress bar is displayed.
359 \return \c true if progress bar is enabled
360 \sa setProgressVisible()
362 bool QtxSplash::progressVisible() const
364 return myShowProgress;
368 \brief Enable/disable displaying of the status message.
369 \param on if \c true, status message will be enabled
370 \sa messageVisible(), setProgressVisible()
372 void QtxSplash::setMessageVisible( const bool on )
379 \brief Check if the status message is displayed.
380 \return \c true if status message is enabled
381 \sa setMessageVisible()
383 bool QtxSplash::messageVisible() const
385 return myShowMessage;
389 \brief Enable/disable displaying progress percentage.
390 \param enable if \c true, percentage will be displayed
391 \sa percentageVisible()
393 void QtxSplash::setPercentageVisible( const bool enable )
395 myShowPercent = enable;
400 \brief Check if the progress percentage is displayed.
401 \return \c true if percentage displaying is enabled
402 \sa setPercentageVisible()
404 bool QtxSplash::percentageVisible() const
406 return myShowPercent;
410 \brief Set total progress steps to \a total.
411 \param total total number of progress steps
412 \sa totalSteps(), setProgress(), progress()
414 void QtxSplash::setTotalSteps( const int total )
421 \brief Get total progress steps number.
422 \return total number of progress steps
423 \sa setTotalSteps(), setProgress(), progress()
425 int QtxSplash::totalSteps() const
431 \brief Set current progress.
432 \param progress current progress
433 \sa progress(), setTotalSteps(), setTotalSteps(),
435 void QtxSplash::setProgress( const int progress )
437 myProgress = progress > 0 ? progress : 0;
442 \brief Get current progress.
443 \return current progress
444 \sa setProgress(), setTotalSteps(), setTotalSteps(),
446 int QtxSplash::progress() const
452 \brief Set current progress to \a progress and total number of
453 progress steps to \a total.
454 \param progress current progress
455 \param total total number of progress steps
457 void QtxSplash::setProgress( const int progress, const int total )
460 myProgress = progress > 0 ? progress : 0;
465 \brief Set splash window margin (a border width).
467 Note, that margin is used only for drawing the progress bar and status
470 \param margin new margin width
473 void QtxSplash::setMargin( const int margin )
475 myMargin = margin > 0 ? margin : 0;
480 \brief Get splash window margin (a border width).
481 \return current margin width
484 int QtxSplash::margin() const
490 \brief Set progress bar width.
491 \param width new progress bar width
494 void QtxSplash::setProgressWidth( const int width )
496 myProgressWidth = width > 0 ? width : 0;
501 \brief Get progress bar width.
502 \return current progress bar width
503 \sa setProgressWidth()
505 int QtxSplash::progressWidth() const
507 return myProgressWidth;
511 \brief Set progress bar position and direction.
513 By default, progress bar is displayed at the bottom side and
514 shows progress from left to right but this behaviour can be changed.
516 \param flags ORed progress bar flags (QtxSplash::ProgressBarFlags)
519 void QtxSplash::setProgressFlags( const int flags )
521 myProgressFlags = flags;
522 if ( !( myProgressFlags & ( LeftSide | RightSide | TopSide | BottomSide ) ) )
523 myProgressFlags |= BottomSide;
524 if ( !( myProgressFlags & ( LeftToRight | RightToLeft ) ) )
525 myProgressFlags |= LeftToRight ;
530 \brief Get progress bar flags: position and direction.
531 \return ORed progress bar flags (QtxSplash::ProgressBarFlags)
532 \sa setProgressFlags()
534 int QtxSplash::progressFlags() const
536 return myProgressFlags;
540 \brief Set progress bar colors.
542 If the colors differ the two-colored gradient bar is drawn.
544 If the \a endColor is not valid, \a startColor is used instead
545 (i.e. simple, one-colored progress bar is drawn).
547 The parameter \a orientation defines the type of gradient
548 to be drawn - horizontal or vertical. Default is vertical.
550 \param startColor start gradient color (or mono-color)
551 \param endColor end gradient color
552 \param orientation gradient type (Qt::Orientation)
555 void QtxSplash::setProgressColors( const QColor& startColor,
556 const QColor& endColor,
557 const Qt::Orientation orientation )
559 if ( !startColor.isValid() )
563 if ( orientation == Qt::Vertical ) {
564 l.setStart( 0., 0. );
565 l.setFinalStop( 0., 1. );
568 l.setStart( 0., 0. );
569 l.setFinalStop( 1., 0. );
571 l.setColorAt( 0., startColor );
572 l.setColorAt( 1., endColor.isValid() ? endColor : startColor );
574 setProgressColors( l );
578 \brief Set progress bar colors.
580 Use this method to display multi-colored gradient progress bar.
581 You have to use QLinearGradient, QRadialGradient or QConicalGradient
582 classes to define the gradient.
584 Note, that progress bar coordinates can be defined in absolute or
586 In absolute mode the actual coordinates of the gradient key points
587 (like start and final point for linear gradient, center and focal point
588 for radial gradient, etc) are calculated from the top-left progress bar's corner.
589 In relative mode you have to use values from 0 to 1 (including) to define
590 the key points positions.
594 QLinearGradient lg(0.5, 0, 1, 1);
595 lg.setColorAt(0.2, Qt::blue);
596 lg.setColorAt(0.6, Qt::red);
597 lg.setSpread(QGradient::RepeatSpread);
598 splash->setProgressGradient(lg);
600 The above code creates linear gradient, which sets start stop to the
601 center of the progress bar; the final stop is assigned to its right-bottom corner.
602 The color scale (blue to red) is changed by the progress bar diagonal.
604 \param gradient color gradient to be used for progress bar coloring
607 void QtxSplash::setProgressColors( const QGradient& gradient )
609 myGradient = gradient;
614 \brief Get custom progress bar colors.
615 \return color gradient used for progress bar coloring
616 \sa setProgressColors()
618 const QGradient* QtxSplash::progressColors() const
624 \brief Set progress bar and status text message opacity.
626 The value should be in the range 0.0 to 1.0, where 0.0 is fully
627 transparent and 1.0 is fully opaque.
629 \param opacity new opacity value
632 void QtxSplash::setOpacity( const double opacity )
634 myOpacity = opacity < 0.0 ? 0.0 : ( opacity > 1.0 ? 1.0 : opacity );
639 \brief Get progress bar and status text message opacity.
640 \return current opacity value
643 double QtxSplash::opacity() const
649 \brief Set message text alignment flags.
651 Default flags are Qt::AlignBottom | Qt::AlignRight.
653 \param alignment alignment flags (Qt::Alignment)
656 void QtxSplash::setTextAlignment( const int alignment )
658 myAlignment = alignment;
663 \brief Get message text alignment flags.
664 \return alignment flags (Qt::Alignment)
665 \sa setTextAlignment()
667 int QtxSplash::textAlignment() const
673 \brief Set message text colors.
675 If \a shadow parameter is invalid color, the simple one-colored
676 text is drawn. Otherwise, second parameter is used to draw the text
679 \param color message text color
680 \param shadow message text shadow color
683 void QtxSplash::setTextColors( const QColor& color, const QColor& shadow )
685 if ( !myColor.isValid() )
689 myShadowColor = shadow;
695 \brief Get message text colors.
696 \param color message text color
697 \param shadow message text shadow color
700 void QtxSplash::textColors( QColor& color, QColor& shadow ) const
703 shadow = myShadowColor;
707 \brief Set constant info text to be displayed on the splash screen.
709 The displayed text includes constant info and status message.
710 The constant message is set by setConstantInfo() method and status
711 message is set by setMessage().
713 \param info constant info text
714 \sa constantInfo(), message(), setMessage(), option(), setOption()
716 void QtxSplash::setConstantInfo( const QString& info )
723 \brief Get constant info text.
724 \return constant info text
725 \sa setConstantInfo(), message(), setMessage()
727 QString QtxSplash::constantInfo() const
733 \brief Set constant information option value.
735 The option is a part of the constant information text,
736 which is replaced at the time of the displaying.
738 The following options are supported:
739 - \c \%A - could be used as application name
740 - \c \%V - could be used as application version
741 - \c \%L - could be used as application license information
742 - \c \%C - could be used as application copyright information
746 splash->setContantInfo("%A [%V]\n%C");
747 splash->setOption("%A", "MyApplication" );
748 splash->setOption("%V", "Version 1.0" );
749 splash->setOption("%C", "Copyright (C) MyCompany 2008" );
752 \param name option name
754 \sa option(), setConstantInfo(), constantInfo()
756 void QtxSplash::setOption( const QString& name, const QString& value )
758 myOptions[ name ] = value;
763 \brief Get constant information option value.
764 \param name option name
765 \return option value or empty string if option is not set
766 \sa setOption(), setConstantInfo(), constantInfo()
768 QString QtxSplash::option( const QString& name ) const
771 if ( myOptions.contains( name ) )
772 val = myOptions[ name ];
777 \brief Get current status message.
778 \return status message
779 \sa setMessage(), constantInfo(), setConstantInfo()
781 QString QtxSplash::message() const
787 \brief Get error code.
789 This function returns error code, set previously with
791 If no error code has been set, 0 is returned.
793 \return last error code
796 int QtxSplash::error() const
802 \brief Wait until widget \a mainWin is displayed.
804 Makes the splash screen wait until the widget \a mainWin is displayed
805 and then hide and close splash window.
807 \param mainWin application main window
809 void QtxSplash::finish( QWidget* mainWin )
812 #if defined(Q_WS_X11)
813 extern void qt_x11_wait_for_window_manager(QWidget *mainWin);
814 qt_x11_wait_for_window_manager(mainWin);
821 \brief Repaint the splash screen.
823 void QtxSplash::repaint()
827 QApplication::flush();
831 \brief Read splash settings from the resources manager.
833 This method can be used to setup the splash screen look-n-feel.
834 By default, "splash" section of the resources file is used, but you can
835 use any other section.
836 All the splash screen parameters can be defined via resources file:
837 - \c "image" : splash screen image, see setPixmap()
838 - \c "margin" : splash window margin, see setMargin()
839 - \c "show_progress" : show progress bar flag, see setProgressVisible()
840 - \c "show_message" : show status messages flag, see setMessageVisible()
841 - \c "show_percents" : show progress percentage flag, see setPercentageVisible()
842 - \c "progress_width" : progress bar width(), see setProgressWidth()
843 - \c "progress_flags" : progress bar position and direction, see setProgressFlags()
844 - \c "constant_info" : status messages constant info, see setConstantInfo()
845 - \c "text_colors" : status messages color(s), see setTextColors()
846 - \c "progress_colors" : progress bar color(s), see setProgressColors()
847 - \c "opacity" : progress bar and status messages opacity, see setOpacity()
848 - \c "font" : status messages font
849 - \c "alignment" : status messages alignment flags, see setTextAlignment()
850 - \c "hide_on_click" : hide-on-click flag, see setHideOnClick()
852 \param resMgr resources manager
853 \param section resources file section name (if empty, the default "splash"
856 void QtxSplash::readSettings( QtxResourceMgr* resMgr, const QString& section )
858 QString resSection = section.isEmpty() ? QString( "splash" ) : section;
862 if ( resMgr->value( resSection, "image", pxname ) ) {
863 QPixmap px( pxname );
870 setHideOnClick( true );
873 if ( resMgr->value( resSection, "hide_on_click", bHide ) ) {
874 setHideOnClick( bHide );
878 // enable progress bar
880 if ( resMgr->value( resSection, "show_progress", bShowProgress ) ) {
881 setProgressVisible( bShowProgress );
884 // enable status message
886 if ( resMgr->value( resSection, "show_message", bShowMessage ) ) {
887 setMessageVisible( bShowMessage );
892 if ( resMgr->value( resSection, "margin", m ) ) {
896 // progress bar width
898 if ( resMgr->value( resSection, "progress_width", pw ) ) {
899 setProgressWidth( pw );
902 // progress bar position and direction
904 if ( resMgr->value( resSection, "progress_flags", pf ) ) {
906 int fl = pf.toInt( &bOk );
909 QStringList opts = pf.split( QRegExp( "," ), QString::SkipEmptyParts );
910 for ( int i = 0; i < opts.count(); i++ ) {
911 QString opt = opts[i].trimmed().toLower();
914 else if ( opt == "right" )
916 else if ( opt == "top" )
918 else if ( opt == "bottom" )
919 fl = fl | BottomSide;
920 else if ( opt == "left_to_right" )
921 fl = fl | LeftToRight;
922 else if ( opt == "right_to_left" )
923 fl = fl | RightToLeft;
926 setProgressFlags( fl );
931 if ( resMgr->value( resSection, "opacity", op ) ) {
937 if ( resMgr->value( resSection, "font", f ) ) {
943 if ( resMgr->value( resSection, "alignment", al ) ) {
945 int fl = al.toInt( &bOk );
948 QStringList opts = al.split( QRegExp( "," ), QString::SkipEmptyParts );
949 for ( int i = 0; i < opts.count(); i++ ) {
950 QString opt = opts[i].trimmed().toLower();
952 fl = fl | Qt::AlignLeft;
953 else if ( opt == "right" )
954 fl = fl | Qt::AlignRight;
955 else if ( opt == "top" )
956 fl = fl | Qt::AlignTop;
957 else if ( opt == "bottom" )
958 fl = fl | Qt::AlignBottom;
959 else if ( opt == "hcenter" )
960 fl = fl | Qt::AlignHCenter;
961 else if ( opt == "vcenter" )
962 fl = fl | Qt::AlignVCenter;
963 else if ( opt == "justify" )
964 fl = fl | Qt::AlignJustify;
965 else if ( opt == "center" )
966 fl = fl | Qt::AlignCenter;
969 setTextAlignment( fl );
973 QLinearGradient lgrad;
974 QRadialGradient rgrad;
975 QConicalGradient cgrad;
976 if ( resMgr->value( resSection, "progress_color", lgrad ) ||
977 resMgr->value( resSection, "progress_colors", lgrad ) ) {
978 // linear gradient-colored progress bar
979 setProgressColors( lgrad );
981 else if ( resMgr->value( resSection, "progress_color", rgrad ) ||
982 resMgr->value( resSection, "progress_colors", rgrad ) ) {
983 // radial gradient-colored progress bar
984 setProgressColors( rgrad );
986 else if ( resMgr->value( resSection, "progress_color", cgrad ) ||
987 resMgr->value( resSection, "progress_colors", cgrad ) ) {
988 // conical gradient-colored progress bar
989 setProgressColors( cgrad );
991 else if ( resMgr->value( resSection, "progress_color", pc ) ||
992 resMgr->value( resSection, "progress_colors", pc ) ) {
993 // one/two-colored progress bar
994 QStringList colors = pc.split( "|", QString::SkipEmptyParts );
996 Qt::Orientation o = Qt::Vertical;
997 if ( colors.count() > 0 ) c1 = QColor( colors[0] );
998 if ( colors.count() > 1 ) c2 = QColor( colors[1] );
1000 if ( colors.count() > 2 ) {
1002 gt = colors[2].toInt( &bOk );
1008 if ( colors[2].toLower().startsWith( "h" ) )
1012 setProgressColors( c1, c2, o );
1016 if ( resMgr->value( resSection, "show_percents", bPercent ) ) {
1017 setPercentageVisible( bPercent );
1022 if ( resMgr->value( resSection, "text_color", tc ) ||
1023 resMgr->value( resSection, "text_colors", tc ) ) {
1024 QStringList colors = tc.split( "|", QString::SkipEmptyParts );
1026 if ( colors.count() > 0 )
1027 c1 = QColor( colors[0] );
1028 if ( colors.count() > 1 )
1029 c2 = QColor( colors[1] );
1030 setTextColors( c1, c2 );
1035 if ( resMgr->value( resSection, "constant_info", cinfo, false ) ||
1036 resMgr->value( resSection, "info", cinfo, false ) ) {
1037 setConstantInfo( cinfo.split( "|", QString::KeepEmptyParts ).join( "\n" ) );
1042 \brief Set status message for the splash screen and define its color
1044 \param msg status message
1045 \param alignment message text alignment flags (Qt::Alignment)
1046 \param color message text color
1047 \sa message(), constantInfo(), setConstantInfo()
1049 void QtxSplash::setMessage( const QString& msg,
1051 const QColor& color )
1054 myAlignment = alignment;
1055 if ( color.isValid() )
1062 \brief Set status message for the splash screen.
1063 \param msg status message
1064 \sa message(), constantInfo(), setConstantInfo()
1066 void QtxSplash::setMessage( const QString& msg )
1073 \brief Remove the message being displayed on the splash screen.
1075 This is equivalent to setMessage("");
1077 \sa message(), setMessage()
1079 void QtxSplash::clear()
1086 \brief Draw the contents of the splash screen.
1089 void QtxSplash::drawContents( QPainter* p )
1091 // draw progress bar
1092 if ( myTotal > 0 && progressVisible() ) {
1094 drawProgressBar( p );
1098 // draw status message
1099 if ( !fullMessage().isEmpty() && messageVisible() ) {
1107 \brief Process mouse button pressing event.
1109 Hides splash screen if the 'hide on mouse click' flag is set.
1111 \param me mouse event (not used)
1112 \sa hideOnClick(), setHideOnClick()
1114 void QtxSplash::mousePressEvent( QMouseEvent* /*me*/ )
1116 if ( myHideOnClick )
1121 \brief Customize paint event.
1123 This function is implemented to work-around the Qt bug
1124 on some Linux distribututions when the drawing on the
1125 splash screen widget is not allowed.
1127 \param pe paint event (not used)
1129 void QtxSplash::paintEvent( QPaintEvent* /*pe*/ )
1132 QPixmap pix = palette().brush( backgroundRole() ).texture();
1133 p.drawPixmap( 0, 0, pix );
1137 \brief Process custom event sent by setStatus() method.
1138 \param ce custom event
1141 void QtxSplash::customEvent( QEvent* ce )
1143 if ( ce->type() == ProgressEvent::id() ) {
1144 ProgressEvent* pe = (ProgressEvent*)ce;
1145 pe->message().isEmpty() ? clear() : setMessage( pe->message() );
1146 if ( pe->progress() >= 0 )
1147 setProgress( pe->progress() );
1148 QApplication::instance()->processEvents();
1153 \brief Check if the gradient is defined in the relative coordinates [static].
1155 \return \c true if gradient is defined in the relative coordinates
1157 static bool checkGradient( const QGradient* g )
1159 #define BOUNDED( a, min, max ) ( a >= min && a <= max )
1160 if ( g->type() == QGradient::LinearGradient ) {
1161 const QLinearGradient* lg = static_cast<const QLinearGradient*>( g );
1162 return BOUNDED( lg->start().x(), 0.0, 1.0 ) &&
1163 BOUNDED( lg->start().y(), 0.0, 1.0 ) &&
1164 BOUNDED( lg->finalStop().x(), 0.0, 1.0 ) &&
1165 BOUNDED( lg->finalStop().y(), 0.0, 1.0 );
1167 if ( g->type() == QGradient::RadialGradient ) {
1168 const QRadialGradient* rg = static_cast<const QRadialGradient*>( g );
1169 return BOUNDED( rg->center().x(), 0.0, 1.0 ) &&
1170 BOUNDED( rg->center().y(), 0.0, 1.0 ) &&
1171 BOUNDED( rg->focalPoint().x(), 0.0, 1.0 ) &&
1172 BOUNDED( rg->focalPoint().y(), 0.0, 1.0 ); // && BOUNDED( rg->radius(), 0.0, 1.0 );
1174 if ( g->type() == QGradient::ConicalGradient ) {
1175 const QConicalGradient* cg = static_cast<const QConicalGradient*>( g );
1176 return BOUNDED( cg->center().x(), 0.0, 1.0 ) &&
1177 BOUNDED( cg->center().y(), 0.0, 1.0 );
1183 \brief Draw progress bar.
1187 void QtxSplash::drawProgressBar( QPainter* p )
1189 // get rect, margin, progress bar width
1192 int pw = progressWidth();
1194 // calculate drawing rect
1195 // ... first set default position (if none or wrong position is set)
1196 if ( myProgressFlags & BottomSide )
1197 r = QRect( r.x() + m, r.height() - (m + pw), r.width() - 2 * m, pw );
1198 else if ( myProgressFlags & TopSide )
1199 r = QRect( r.x() + m, r.y() + m, r.width() - 2 * m, pw );
1200 else if ( myProgressFlags & LeftSide )
1201 r = QRect( r.x() + m, r.y() + m, pw, r.height() - 2 * m );
1202 else if ( myProgressFlags & RightSide )
1203 r = QRect( r.width() - (m + pw), r.y() + m, pw, r.height() - 2 * m );
1206 if ( myProgressFlags & TopSide || myProgressFlags & BottomSide ) {
1207 cr.setWidth( (int)( r.width() * ( myProgress > 0 ? myProgress : 0 ) / myTotal ) );
1208 if ( myProgressFlags & RightToLeft )
1209 cr.translate( r.width() - cr.width(), 0 );
1211 else if ( myProgressFlags & LeftSide || myProgressFlags & RightSide ) {
1212 cr.setHeight( (int)( r.height() * ( myProgress > 0 ? myProgress : 0 ) / myTotal ) );
1213 if ( myProgressFlags & RightToLeft)
1214 cr.translate( 0, r.height() - cr.height() );
1217 switch ( progressColors()->type() ) {
1218 case QGradient::LinearGradient:
1221 const QLinearGradient* other = static_cast<const QLinearGradient*>( progressColors() );
1222 if ( checkGradient( other ) ) {
1223 // gradient is defined in relative coordinates [0.0 - 1.0]
1224 lg.setStart( r.left() + r.width() * other->start().x(),
1225 r.top() + r.height() * other->start().y() );
1226 lg.setFinalStop( r.left() + r.width() * other->finalStop().x(),
1227 r.top() + r.height() * other->finalStop().y() );
1230 // gradient is defined in absolute coordinates
1231 // according to its dimensions
1232 lg.setStart( r.topLeft() + other->start() );
1233 lg.setFinalStop( r.topLeft() + other->finalStop() );
1236 lg.setStops( other->stops() );
1237 lg.setSpread( other->spread() );
1242 } // case QGradient::LinearGradient
1243 case QGradient::RadialGradient:
1246 const QRadialGradient* other = static_cast<const QRadialGradient*>( progressColors() );
1247 if ( checkGradient( other ) ) {
1248 // gradient is defined in relative coordinates [0.0 - 1.0]
1249 rg.setCenter( r.left() + r.width() * other->center().x(),
1250 r.top() + r.height() * other->center().y() );
1251 rg.setFocalPoint( r.left() + r.width() * other->focalPoint().x(),
1252 r.top() + r.height() * other->focalPoint().y() );
1255 // gradient is defined in absolute coordinates
1256 // according to its dimensions
1257 rg.setCenter( r.topLeft() + other->center() );
1258 rg.setFocalPoint( r.topLeft() + other->focalPoint() );
1261 // only width is taken into account for the radius in relative mode
1262 rg.setRadius( other->radius() > 1.0 ? other->radius() : r.width() * other->radius() );
1264 rg.setStops( other->stops() );
1265 rg.setSpread( other->spread() );
1270 } // case QGradient::RadialGradient
1271 case QGradient::ConicalGradient:
1273 QConicalGradient cg;
1274 const QConicalGradient* other = static_cast<const QConicalGradient*>( progressColors() );
1275 if ( checkGradient( other ) ) {
1276 // gradient is defined in relative coordinates [0.0 - 1.0]
1277 cg.setCenter( r.left() + r.width() * other->center().x(),
1278 r.top() + r.height() * other->center().y() );
1281 // gradient is defined in absolute coordinates
1282 // according to its dimensions
1283 cg.setCenter( r.topLeft() + other->center() );
1286 cg.setAngle( other->angle() );
1287 cg.setStops( other->stops() );
1288 cg.setSpread( other->spread() );
1293 } // case QGradient::RadialGradient
1295 b = QBrush( Qt::red ); // default is simple red-colored progress bar
1299 p->setOpacity( myOpacity );
1301 // draw progress bar outline rectangle
1302 p->setPen( palette().color( QPalette::Dark ) );
1303 p->drawLine( r.left(), r.top(), r.right(), r.top() );
1304 p->drawLine( r.left(), r.top(), r.left(), r.bottom() );
1305 p->setPen( palette().color( QPalette::Light ) );
1306 p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() );
1307 p->drawLine( r.right(), r.top(), r.right(), r.bottom() );
1309 r.setCoords( r.left()+1, r.top()+1, r.right()-1, r.bottom()-1 );
1310 p->setClipRect( cr );
1311 p->fillRect( r, b );
1312 p->setClipping( false );
1314 if ( myShowPercent ) {
1315 int percent = ( int )( ( myProgress > 0 ? myProgress : 0 ) * 100 / myTotal );
1317 f.setPixelSize( r.height() - 4 );
1319 // draw shadow status text
1320 if ( myShadowColor.isValid() ) {
1322 rs.moveTopLeft( rs.topLeft() + QPoint( 1,1 ) );
1323 p->setPen( myShadowColor );
1324 p->drawText( rs, Qt::AlignCenter, QString( "%1%" ).arg( percent ) );
1326 p->setPen( myColor );
1327 p->drawText( r, Qt::AlignCenter, QString( "%1%" ).arg( percent ) );
1332 \brief Draw status message.
1334 \sa drawProgressBar()
1336 void QtxSplash::drawMessage( QPainter* p )
1338 // get rect, margin, progress bar width
1341 int pw = progressVisible() ? progressWidth() : 0;
1343 // calculate drawing rect
1344 QFontMetrics f( font() );
1345 int spacing = f.lineSpacing();
1347 QRect r1( r.x() + m, r.y() + m, r.width() - 2 * m, r.height() - 2 * m );
1348 r1.setY( r1.y() - f.leading() );
1349 // ... take into account progress bar
1350 if ( 1 ) { // if ( myTotal > 0 ) : vsr changed: otherwise text is jumping
1351 if ( myProgressFlags & BottomSide )
1352 r1.setHeight( r1.height() - pw );
1353 else if ( myProgressFlags & TopSide )
1354 r1.setY( r1.y() + pw );
1355 else if ( myProgressFlags & LeftSide )
1356 r1.setX( r1.x() + pw );
1357 else if ( myProgressFlags & RightSide )
1358 r1.setWidth( r1.width() - pw );
1361 // ... take into account trailing '\n' symbols
1363 QString msg = fullMessage();
1364 int i = msg.length() - 1;
1365 while( i >= 0 && msg[ i-- ] == '\n' )
1367 r1.setHeight( r1.height() - shift );
1369 p->setOpacity( myOpacity );
1371 // draw shadow status text
1372 if ( myShadowColor.isValid() ) {
1374 if ( myAlignment & Qt::AlignLeft ) r2.setLeft ( r2.left() + 1 );
1375 if ( myAlignment & Qt::AlignTop ) r2.setTop ( r2.top() + 1 );
1376 if ( myAlignment & Qt::AlignRight ) r2.setRight ( r2.right() + 1 );
1377 if ( myAlignment & Qt::AlignBottom ) r2.setBottom( r2.bottom() + 1 );
1378 p->setPen( myShadowColor );
1379 p->drawText( r2, myAlignment, msg );
1382 // draw foreground status text
1383 p->setPen( myColor );
1384 p->drawText( r1, myAlignment, msg );
1388 \brief Draw the splash screen window contents.
1391 void QtxSplash::drawContents()
1393 QPixmap textPix = myPixmap;
1394 QPainter painter( &textPix );
1395 painter.initFrom( this );
1396 drawContents( &painter );
1397 QPalette pal = palette();
1398 pal.setBrush( backgroundRole(), QBrush( textPix ) );
1403 \brief Sets error code.
1404 \param code error code
1407 void QtxSplash::setError( const int code )
1413 \brief Get full message which includes constant info and status message.
1414 \return get fill message text
1415 \sa constantInfo(), setConstantInfo(), message(), setMessage()
1418 QString QtxSplash::fullMessage() const
1422 QString cinfo = myInfo;
1423 cinfo = cinfo.replace( QRegExp( "%A" ), option( "%A" ) );
1424 cinfo = cinfo.replace( QRegExp( "%V" ), option( "%V" ) );
1425 cinfo = cinfo.replace( QRegExp( "%L" ), option( "%L" ) );
1426 cinfo = cinfo.replace( QRegExp( "%C" ), option( "%C" ) );
1428 if ( !cinfo.isEmpty() )
1430 if ( !myMessage.isEmpty() )
1432 return info.join( "\n" );