1 // Copyright (C) 2007-2023 CEA, EDF, 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 myShowProgress( true ),
204 myShowMessage( true ),
205 myShowPercent( 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 qCritical( "QtxSplash::error: %s\n", qPrintable( error ) );
280 \brief Set fixed size of splash screen.
282 If size is not set explicitly, it is inherited from image being used.
283 Otherwise, image is rescaled to given size.
285 Width and height can be given indepdently; not given dimension
286 (zero of negative value) is ignored.
288 \param size fixed splash size
291 void QtxSplash::setSize( const QSize& size )
294 setPixmap( pixmap() );
298 \brief This is an overloaded function.
304 void QtxSplash::setSize( int w, int h )
306 setSize( QSize( w, h ) );
310 \brief Get fixed splash screen's size if it was set.
313 QSize QtxSplash::fixedSize() const
320 \brief Set the pixmap that will be used as the splash screen's image.
321 \param pixmap spash screen image pixmap
324 void QtxSplash::setPixmap( const QPixmap& pixmap )
326 if ( pixmap.isNull() )
329 if ( pixmap.hasAlpha() ) {
330 QPixmap opaque( pixmap.size() );
331 QPainter p( &opaque );
332 p.fillRect( 0, 0, pixmap.width(), pixmap.height(), palette().background() );
333 p.drawPixmap( 0, 0, pixmap );
341 int width = fixedSize().width();
342 int height = fixedSize().height();
343 if ( width > 0 || height > 0 ) {
344 QImage img = myPixmap.toImage();
345 img = img.scaled( width > 0 ? width : myPixmap.width(),
346 height > 0 ? height : myPixmap.height(),
347 Qt::IgnoreAspectRatio,
348 Qt::SmoothTransformation );
349 myPixmap = QPixmap::fromImage( img );
352 QRect r( 0, 0, myPixmap.size().width(), myPixmap.size().height() );
353 resize( myPixmap.size() );
354 move( QApplication::desktop()->screenGeometry().center() - r.center() );
362 \brief Get the pixmap that is used as the splash screen's image.
363 \return spash screen image pixmap
366 QPixmap QtxSplash::pixmap() const
372 \brief Set/clear the 'hide on mouse click' flag.
374 When this flag is set, user can hide the splash screen window
375 by clicking on it with mouse.
376 But for this to work it is necessary to call periodically
377 QApplication::processEvents() in order to allow event loop to process
378 events because usually main application loop is not yet started
381 By default this flag is set to \c false.
383 \param on new flag state
386 void QtxSplash::setHideOnClick( const bool on )
392 \brief Get the 'hide on mouse click' flag.
393 \return 'hide on mouse click' flag
396 bool QtxSplash::hideOnClick() const
398 return myHideOnClick;
402 \brief Enable/disable displaying of the progress bar.
403 \param on if \c true, progress bar will be enabled
404 \sa progressVisible(), setMessageVisible()
406 void QtxSplash::setProgressVisible( const bool on )
413 \brief Check if the progress bar is displayed.
414 \return \c true if progress bar is enabled
415 \sa setProgressVisible()
417 bool QtxSplash::progressVisible() const
419 return myShowProgress;
423 \brief Enable/disable displaying of the status message.
424 \param on if \c true, status message will be enabled
425 \sa messageVisible(), setProgressVisible()
427 void QtxSplash::setMessageVisible( const bool on )
434 \brief Check if the status message is displayed.
435 \return \c true if status message is enabled
436 \sa setMessageVisible()
438 bool QtxSplash::messageVisible() const
440 return myShowMessage;
444 \brief Enable/disable displaying progress percentage.
445 \param enable if \c true, percentage will be displayed
446 \sa percentageVisible()
448 void QtxSplash::setPercentageVisible( const bool enable )
450 myShowPercent = enable;
455 \brief Check if the progress percentage is displayed.
456 \return \c true if percentage displaying is enabled
457 \sa setPercentageVisible()
459 bool QtxSplash::percentageVisible() const
461 return myShowPercent;
465 \brief Set total progress steps to \a total.
466 \param total total number of progress steps
467 \sa totalSteps(), setProgress(), progress()
469 void QtxSplash::setTotalSteps( const int total )
476 \brief Get total progress steps number.
477 \return total number of progress steps
478 \sa setTotalSteps(), setProgress(), progress()
480 int QtxSplash::totalSteps() const
486 \brief Set current progress.
487 \param progress current progress
488 \sa progress(), setTotalSteps(), setTotalSteps(),
490 void QtxSplash::setProgress( const int progress )
492 myProgress = progress > 0 ? progress : 0;
497 \brief Get current progress.
498 \return current progress
499 \sa setProgress(), setTotalSteps(), setTotalSteps(),
501 int QtxSplash::progress() const
507 \brief Set current progress to \a progress and total number of
508 progress steps to \a total.
509 \param progress current progress
510 \param total total number of progress steps
512 void QtxSplash::setProgress( const int progress, const int total )
515 myProgress = progress > 0 ? progress : 0;
520 \brief Set splash window margin (a border width).
522 Note, that margin is used only for drawing the progress bar and status
525 \param margin new margin width
528 void QtxSplash::setMargin( const int margin )
530 myMargin = margin > 0 ? margin : 0;
535 \brief Get splash window margin (a border width).
536 \return current margin width
539 int QtxSplash::margin() const
545 \brief Set progress bar width.
546 \param width new progress bar width
549 void QtxSplash::setProgressWidth( const int width )
551 myProgressWidth = width > 0 ? width : 0;
556 \brief Get progress bar width.
557 \return current progress bar width
558 \sa setProgressWidth()
560 int QtxSplash::progressWidth() const
562 return myProgressWidth;
566 \brief Set progress bar position and direction.
568 By default, progress bar is displayed at the bottom side and
569 shows progress from left to right but this behaviour can be changed.
571 \param flags ORed progress bar flags (QtxSplash::ProgressBarFlags)
574 void QtxSplash::setProgressFlags( const int flags )
576 myProgressFlags = flags;
577 if ( !( myProgressFlags & ( LeftSide | RightSide | TopSide | BottomSide ) ) )
578 myProgressFlags |= BottomSide;
579 if ( !( myProgressFlags & ( LeftToRight | RightToLeft ) ) )
580 myProgressFlags |= LeftToRight ;
585 \brief Get progress bar flags: position and direction.
586 \return ORed progress bar flags (QtxSplash::ProgressBarFlags)
587 \sa setProgressFlags()
589 int QtxSplash::progressFlags() const
591 return myProgressFlags;
595 \brief Set progress bar colors.
597 If the colors differ the two-colored gradient bar is drawn.
599 If the \a endColor is not valid, \a startColor is used instead
600 (i.e. simple, one-colored progress bar is drawn).
602 The parameter \a orientation defines the type of gradient
603 to be drawn - horizontal or vertical. Default is vertical.
605 \param startColor start gradient color (or mono-color)
606 \param endColor end gradient color
607 \param orientation gradient type (Qt::Orientation)
610 void QtxSplash::setProgressColors( const QColor& startColor,
611 const QColor& endColor,
612 const Qt::Orientation orientation )
614 if ( !startColor.isValid() )
618 if ( orientation == Qt::Vertical ) {
619 l.setStart( 0., 0. );
620 l.setFinalStop( 0., 1. );
623 l.setStart( 0., 0. );
624 l.setFinalStop( 1., 0. );
626 l.setColorAt( 0., startColor );
627 l.setColorAt( 1., endColor.isValid() ? endColor : startColor );
629 setProgressColors( l );
633 \brief Set progress bar colors.
635 Use this method to display multi-colored gradient progress bar.
636 You have to use QLinearGradient, QRadialGradient or QConicalGradient
637 classes to define the gradient.
639 Note, that progress bar coordinates can be defined in absolute or
641 In absolute mode the actual coordinates of the gradient key points
642 (like start and final point for linear gradient, center and focal point
643 for radial gradient, etc) are calculated from the top-left progress bar's corner.
644 In relative mode you have to use values from 0 to 1 (including) to define
645 the key points positions.
649 QLinearGradient lg(0.5, 0, 1, 1);
650 lg.setColorAt(0.2, Qt::blue);
651 lg.setColorAt(0.6, Qt::red);
652 lg.setSpread(QGradient::RepeatSpread);
653 splash->setProgressGradient(lg);
655 The above code creates linear gradient, which sets start stop to the
656 center of the progress bar; the final stop is assigned to its right-bottom corner.
657 The color scale (blue to red) is changed by the progress bar diagonal.
659 \param gradient color gradient to be used for progress bar coloring
662 void QtxSplash::setProgressColors( const QGradient& gradient )
664 myGradient = gradient;
669 \brief Get custom progress bar colors.
670 \return color gradient used for progress bar coloring
671 \sa setProgressColors()
673 const QGradient* QtxSplash::progressColors() const
679 \brief Set progress bar and status text message opacity.
681 The value should be in the range 0.0 to 1.0, where 0.0 is fully
682 transparent and 1.0 is fully opaque.
684 \param opacity new opacity value
687 void QtxSplash::setOpacity( const double opacity )
689 myOpacity = opacity < 0.0 ? 0.0 : ( opacity > 1.0 ? 1.0 : opacity );
694 \brief Get progress bar and status text message opacity.
695 \return current opacity value
698 double QtxSplash::opacity() const
704 \brief Set message text alignment flags.
706 Default flags are Qt::AlignBottom | Qt::AlignRight.
708 \param alignment alignment flags (Qt::Alignment)
711 void QtxSplash::setTextAlignment( const int alignment )
713 myAlignment = alignment;
718 \brief Get message text alignment flags.
719 \return alignment flags (Qt::Alignment)
720 \sa setTextAlignment()
722 int QtxSplash::textAlignment() const
728 \brief Set message text colors.
730 If \a shadow parameter is invalid color, the simple one-colored
731 text is drawn. Otherwise, second parameter is used to draw the text
734 \param color message text color
735 \param shadow message text shadow color
738 void QtxSplash::setTextColors( const QColor& color, const QColor& shadow )
740 if ( !myColor.isValid() )
744 myShadowColor = shadow;
750 \brief Get message text colors.
751 \param color message text color
752 \param shadow message text shadow color
755 void QtxSplash::textColors( QColor& color, QColor& shadow ) const
758 shadow = myShadowColor;
762 \brief Set constant info text to be displayed on the splash screen.
764 The displayed text includes constant info and status message.
765 The constant message is set by setConstantInfo() method and status
766 message is set by setMessage().
768 \param info constant info text
769 \sa constantInfo(), message(), setMessage(), option(), setOption()
771 void QtxSplash::setConstantInfo( const QString& info )
778 \brief Get constant info text.
779 \return constant info text
780 \sa setConstantInfo(), message(), setMessage()
782 QString QtxSplash::constantInfo() const
788 \brief Set constant information option value.
790 The option is a part of the constant information text,
791 which is replaced at the time of the displaying.
793 The following options are supported:
794 - \c \%A - could be used as application name
795 - \c \%V - could be used as application version
796 - \c \%L - could be used as application license information
797 - \c \%C - could be used as application copyright information
801 splash->setContantInfo("%A [%V]\n%C");
802 splash->setOption("%A", "MyApplication" );
803 splash->setOption("%V", "Version 1.0" );
804 splash->setOption("%C", "Copyright (C) MyCompany 2008" );
807 \param name option name
809 \sa option(), setConstantInfo(), constantInfo()
811 void QtxSplash::setOption( const QString& name, const QString& value )
813 myOptions[ name ] = value;
818 \brief Get constant information option value.
819 \param name option name
820 \return option value or empty string if option is not set
821 \sa setOption(), setConstantInfo(), constantInfo()
823 QString QtxSplash::option( const QString& name ) const
826 if ( myOptions.contains( name ) )
827 val = myOptions[ name ];
832 \brief Get current status message.
833 \return status message
834 \sa setMessage(), constantInfo(), setConstantInfo()
836 QString QtxSplash::message() const
842 \brief Get error code.
844 This function returns error code, set previously with
846 If no error code has been set, 0 is returned.
848 \return last error code
851 int QtxSplash::error() const
857 \brief Wait until widget \a mainWin is displayed.
859 Makes the splash screen wait until the widget \a mainWin is displayed
860 and then hide and close splash window.
862 \param mainWin application main window
864 void QtxSplash::finish( QWidget* mainWin )
867 #if defined(Q_WS_X11)
868 extern void qt_x11_wait_for_window_manager(QWidget *mainWin);
869 qt_x11_wait_for_window_manager(mainWin);
876 \brief Repaint the splash screen.
878 void QtxSplash::repaint()
882 QApplication::flush();
886 \brief Read splash settings from the resources manager.
888 This method can be used to setup the splash screen look-n-feel.
889 By default, "splash" section of the resources file is used, but you can
890 use any other section.
891 All the splash screen parameters can be defined via resources file:
892 - \c "image" : splash screen image, see setPixmap()
893 - \c "margin" : splash window margin, see setMargin()
894 - \c "show_progress" : show progress bar flag, see setProgressVisible()
895 - \c "show_message" : show status messages flag, see setMessageVisible()
896 - \c "show_percents" : show progress percentage flag, see setPercentageVisible()
897 - \c "progress_width" : progress bar width(), see setProgressWidth()
898 - \c "progress_flags" : progress bar position and direction, see setProgressFlags()
899 - \c "constant_info" : status messages constant info, see setConstantInfo()
900 - \c "text_colors" : status messages color(s), see setTextColors()
901 - \c "progress_colors" : progress bar color(s), see setProgressColors()
902 - \c "opacity" : progress bar and status messages opacity, see setOpacity()
903 - \c "font" : status messages font
904 - \c "alignment" : status messages alignment flags, see setTextAlignment()
905 - \c "hide_on_click" : hide-on-click flag, see setHideOnClick()
907 \param resMgr resources manager
908 \param section resources file section name (if empty, the default "splash"
911 void QtxSplash::readSettings( QtxResourceMgr* resMgr, const QString& section )
913 QString resSection = section.isEmpty() ? QString( "splash" ) : section;
916 setSize( resMgr->integerValue( resSection, "width", 0 ),
917 resMgr->integerValue( resSection, "height", 0 ) );
921 if ( resMgr->value( resSection, "image", pxname ) ) {
922 QPixmap px( pxname );
929 setHideOnClick( true );
932 if ( resMgr->value( resSection, "hide_on_click", bHide ) ) {
933 setHideOnClick( bHide );
937 // enable progress bar
939 if ( resMgr->value( resSection, "show_progress", bShowProgress ) ) {
940 setProgressVisible( bShowProgress );
943 // enable status message
945 if ( resMgr->value( resSection, "show_message", bShowMessage ) ) {
946 setMessageVisible( bShowMessage );
951 if ( resMgr->value( resSection, "margin", m ) ) {
955 // progress bar width
957 if ( resMgr->value( resSection, "progress_width", pw ) ) {
958 setProgressWidth( pw );
961 // progress bar position and direction
963 if ( resMgr->value( resSection, "progress_flags", pf ) ) {
965 int fl = pf.toInt( &bOk );
968 QStringList opts = pf.split( QRegExp( "," ), QString::SkipEmptyParts );
969 for ( int i = 0; i < opts.count(); i++ ) {
970 QString opt = opts[i].trimmed().toLower();
973 else if ( opt == "right" )
975 else if ( opt == "top" )
977 else if ( opt == "bottom" )
978 fl = fl | BottomSide;
979 else if ( opt == "left_to_right" )
980 fl = fl | LeftToRight;
981 else if ( opt == "right_to_left" )
982 fl = fl | RightToLeft;
985 setProgressFlags( fl );
990 if ( resMgr->value( resSection, "opacity", op ) ) {
996 if ( resMgr->value( resSection, "font", f ) ) {
1002 if ( resMgr->value( resSection, "alignment", al ) ) {
1004 int fl = al.toInt( &bOk );
1007 QStringList opts = al.split( QRegExp( "," ), QString::SkipEmptyParts );
1008 for ( int i = 0; i < opts.count(); i++ ) {
1009 QString opt = opts[i].trimmed().toLower();
1010 if ( opt == "left" )
1011 fl = fl | Qt::AlignLeft;
1012 else if ( opt == "right" )
1013 fl = fl | Qt::AlignRight;
1014 else if ( opt == "top" )
1015 fl = fl | Qt::AlignTop;
1016 else if ( opt == "bottom" )
1017 fl = fl | Qt::AlignBottom;
1018 else if ( opt == "hcenter" )
1019 fl = fl | Qt::AlignHCenter;
1020 else if ( opt == "vcenter" )
1021 fl = fl | Qt::AlignVCenter;
1022 else if ( opt == "justify" )
1023 fl = fl | Qt::AlignJustify;
1024 else if ( opt == "center" )
1025 fl = fl | Qt::AlignCenter;
1028 setTextAlignment( fl );
1030 // progress color(s)
1032 QLinearGradient lgrad;
1033 QRadialGradient rgrad;
1034 QConicalGradient cgrad;
1035 if ( resMgr->value( resSection, "progress_color", lgrad ) ||
1036 resMgr->value( resSection, "progress_colors", lgrad ) ) {
1037 // linear gradient-colored progress bar
1038 setProgressColors( lgrad );
1040 else if ( resMgr->value( resSection, "progress_color", rgrad ) ||
1041 resMgr->value( resSection, "progress_colors", rgrad ) ) {
1042 // radial gradient-colored progress bar
1043 setProgressColors( rgrad );
1045 else if ( resMgr->value( resSection, "progress_color", cgrad ) ||
1046 resMgr->value( resSection, "progress_colors", cgrad ) ) {
1047 // conical gradient-colored progress bar
1048 setProgressColors( cgrad );
1050 else if ( resMgr->value( resSection, "progress_color", pc ) ||
1051 resMgr->value( resSection, "progress_colors", pc ) ) {
1052 // one/two-colored progress bar
1053 QStringList colors = pc.split( "|", QString::SkipEmptyParts );
1055 Qt::Orientation o = Qt::Vertical;
1056 if ( colors.count() > 0 ) c1 = QColor( colors[0] );
1057 if ( colors.count() > 1 ) c2 = QColor( colors[1] );
1059 if ( colors.count() > 2 ) {
1061 gt = colors[2].toInt( &bOk );
1067 if ( colors[2].toLower().startsWith( "h" ) )
1071 setProgressColors( c1, c2, o );
1075 if ( resMgr->value( resSection, "show_percents", bPercent ) ) {
1076 setPercentageVisible( bPercent );
1081 if ( resMgr->value( resSection, "text_color", tc ) ||
1082 resMgr->value( resSection, "text_colors", tc ) ) {
1083 QStringList colors = tc.split( "|", QString::SkipEmptyParts );
1085 if ( colors.count() > 0 )
1086 c1 = QColor( colors[0] );
1087 if ( colors.count() > 1 )
1088 c2 = QColor( colors[1] );
1089 setTextColors( c1, c2 );
1094 if ( resMgr->value( resSection, "constant_info", cinfo, false ) ||
1095 resMgr->value( resSection, "info", cinfo, false ) ) {
1096 setConstantInfo( cinfo.split( "|", QString::KeepEmptyParts ).join( "\n" ) );
1101 \brief Set status message for the splash screen and define its color
1103 \param msg status message
1104 \param alignment message text alignment flags (Qt::Alignment)
1105 \param color message text color
1106 \sa message(), constantInfo(), setConstantInfo()
1108 void QtxSplash::setMessage( const QString& msg,
1110 const QColor& color )
1113 myAlignment = alignment;
1114 if ( color.isValid() )
1121 \brief Set status message for the splash screen.
1122 \param msg status message
1123 \sa message(), constantInfo(), setConstantInfo()
1125 void QtxSplash::setMessage( const QString& msg )
1132 \brief Remove the message being displayed on the splash screen.
1134 This is equivalent to setMessage("");
1136 \sa message(), setMessage()
1138 void QtxSplash::clear()
1145 \brief Draw the contents of the splash screen.
1148 void QtxSplash::drawContents( QPainter* p )
1150 // draw progress bar
1151 if ( myTotal > 0 && progressVisible() ) {
1153 drawProgressBar( p );
1157 // draw status message
1158 if ( !fullMessage().isEmpty() && messageVisible() ) {
1166 \brief Process mouse button pressing event.
1168 Hides splash screen if the 'hide on mouse click' flag is set.
1170 \param me mouse event (not used)
1171 \sa hideOnClick(), setHideOnClick()
1173 void QtxSplash::mousePressEvent( QMouseEvent* /*me*/ )
1175 if ( myHideOnClick )
1180 \brief Customize paint event.
1182 This function is implemented to work-around the Qt bug
1183 on some Linux distribututions when the drawing on the
1184 splash screen widget is not allowed.
1186 \param pe paint event (not used)
1188 void QtxSplash::paintEvent( QPaintEvent* /*pe*/ )
1191 QPixmap pix = palette().brush( backgroundRole() ).texture();
1192 p.drawPixmap( 0, 0, pix );
1196 \brief Process custom event sent by setStatus() method.
1197 \param ce custom event
1200 void QtxSplash::customEvent( QEvent* ce )
1202 if ( ce->type() == ProgressEvent::id() ) {
1203 ProgressEvent* pe = (ProgressEvent*)ce;
1204 pe->message().isEmpty() ? clear() : setMessage( pe->message() );
1205 if ( pe->progress() >= 0 )
1206 setProgress( pe->progress() );
1207 QApplication::instance()->processEvents();
1212 \brief Check if the gradient is defined in the relative coordinates [static].
1214 \return \c true if gradient is defined in the relative coordinates
1216 static bool checkGradient( const QGradient* g )
1218 #define BOUNDED( a, min, max ) ( a >= min && a <= max )
1219 if ( g->type() == QGradient::LinearGradient ) {
1220 const QLinearGradient* lg = static_cast<const QLinearGradient*>( g );
1221 return BOUNDED( lg->start().x(), 0.0, 1.0 ) &&
1222 BOUNDED( lg->start().y(), 0.0, 1.0 ) &&
1223 BOUNDED( lg->finalStop().x(), 0.0, 1.0 ) &&
1224 BOUNDED( lg->finalStop().y(), 0.0, 1.0 );
1226 if ( g->type() == QGradient::RadialGradient ) {
1227 const QRadialGradient* rg = static_cast<const QRadialGradient*>( g );
1228 return BOUNDED( rg->center().x(), 0.0, 1.0 ) &&
1229 BOUNDED( rg->center().y(), 0.0, 1.0 ) &&
1230 BOUNDED( rg->focalPoint().x(), 0.0, 1.0 ) &&
1231 BOUNDED( rg->focalPoint().y(), 0.0, 1.0 ); // && BOUNDED( rg->radius(), 0.0, 1.0 );
1233 if ( g->type() == QGradient::ConicalGradient ) {
1234 const QConicalGradient* cg = static_cast<const QConicalGradient*>( g );
1235 return BOUNDED( cg->center().x(), 0.0, 1.0 ) &&
1236 BOUNDED( cg->center().y(), 0.0, 1.0 );
1242 \brief Draw progress bar.
1246 void QtxSplash::drawProgressBar( QPainter* p )
1248 // get rect, margin, progress bar width
1251 int pw = progressWidth();
1253 // calculate drawing rect
1254 // ... first set default position (if none or wrong position is set)
1255 if ( myProgressFlags & BottomSide )
1256 r = QRect( r.x() + m, r.height() - (m + pw), r.width() - 2 * m, pw );
1257 else if ( myProgressFlags & TopSide )
1258 r = QRect( r.x() + m, r.y() + m, r.width() - 2 * m, pw );
1259 else if ( myProgressFlags & LeftSide )
1260 r = QRect( r.x() + m, r.y() + m, pw, r.height() - 2 * m );
1261 else if ( myProgressFlags & RightSide )
1262 r = QRect( r.width() - (m + pw), r.y() + m, pw, r.height() - 2 * m );
1265 if ( myProgressFlags & TopSide || myProgressFlags & BottomSide ) {
1266 cr.setWidth( (int)( r.width() * ( myProgress > 0 ? myProgress : 0 ) / myTotal ) );
1267 if ( myProgressFlags & RightToLeft )
1268 cr.translate( r.width() - cr.width(), 0 );
1270 else if ( myProgressFlags & LeftSide || myProgressFlags & RightSide ) {
1271 cr.setHeight( (int)( r.height() * ( myProgress > 0 ? myProgress : 0 ) / myTotal ) );
1272 if ( myProgressFlags & RightToLeft)
1273 cr.translate( 0, r.height() - cr.height() );
1276 switch ( progressColors()->type() ) {
1277 case QGradient::LinearGradient:
1280 const QLinearGradient* other = static_cast<const QLinearGradient*>( progressColors() );
1281 if ( checkGradient( other ) ) {
1282 // gradient is defined in relative coordinates [0.0 - 1.0]
1283 lg.setStart( r.left() + r.width() * other->start().x(),
1284 r.top() + r.height() * other->start().y() );
1285 lg.setFinalStop( r.left() + r.width() * other->finalStop().x(),
1286 r.top() + r.height() * other->finalStop().y() );
1289 // gradient is defined in absolute coordinates
1290 // according to its dimensions
1291 lg.setStart( r.topLeft() + other->start() );
1292 lg.setFinalStop( r.topLeft() + other->finalStop() );
1295 lg.setStops( other->stops() );
1296 lg.setSpread( other->spread() );
1301 } // case QGradient::LinearGradient
1302 case QGradient::RadialGradient:
1305 const QRadialGradient* other = static_cast<const QRadialGradient*>( progressColors() );
1306 if ( checkGradient( other ) ) {
1307 // gradient is defined in relative coordinates [0.0 - 1.0]
1308 rg.setCenter( r.left() + r.width() * other->center().x(),
1309 r.top() + r.height() * other->center().y() );
1310 rg.setFocalPoint( r.left() + r.width() * other->focalPoint().x(),
1311 r.top() + r.height() * other->focalPoint().y() );
1314 // gradient is defined in absolute coordinates
1315 // according to its dimensions
1316 rg.setCenter( r.topLeft() + other->center() );
1317 rg.setFocalPoint( r.topLeft() + other->focalPoint() );
1320 // only width is taken into account for the radius in relative mode
1321 rg.setRadius( other->radius() > 1.0 ? other->radius() : r.width() * other->radius() );
1323 rg.setStops( other->stops() );
1324 rg.setSpread( other->spread() );
1329 } // case QGradient::RadialGradient
1330 case QGradient::ConicalGradient:
1332 QConicalGradient cg;
1333 const QConicalGradient* other = static_cast<const QConicalGradient*>( progressColors() );
1334 if ( checkGradient( other ) ) {
1335 // gradient is defined in relative coordinates [0.0 - 1.0]
1336 cg.setCenter( r.left() + r.width() * other->center().x(),
1337 r.top() + r.height() * other->center().y() );
1340 // gradient is defined in absolute coordinates
1341 // according to its dimensions
1342 cg.setCenter( r.topLeft() + other->center() );
1345 cg.setAngle( other->angle() );
1346 cg.setStops( other->stops() );
1347 cg.setSpread( other->spread() );
1352 } // case QGradient::RadialGradient
1354 b = QBrush( Qt::red ); // default is simple red-colored progress bar
1358 p->setOpacity( myOpacity );
1360 // draw progress bar outline rectangle
1361 p->setPen( palette().color( QPalette::Dark ) );
1362 p->drawLine( r.left(), r.top(), r.right(), r.top() );
1363 p->drawLine( r.left(), r.top(), r.left(), r.bottom() );
1364 p->setPen( palette().color( QPalette::Light ) );
1365 p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() );
1366 p->drawLine( r.right(), r.top(), r.right(), r.bottom() );
1368 r.setCoords( r.left()+1, r.top()+1, r.right()-1, r.bottom()-1 );
1369 p->setClipRect( cr );
1370 p->fillRect( r, b );
1371 p->setClipping( false );
1373 if ( myShowPercent ) {
1374 int percent = ( int )( ( myProgress > 0 ? myProgress : 0 ) * 100 / myTotal );
1376 f.setPixelSize( r.height() - 4 );
1378 // draw shadow status text
1379 if ( myShadowColor.isValid() ) {
1381 rs.moveTopLeft( rs.topLeft() + QPoint( 1,1 ) );
1382 p->setPen( myShadowColor );
1383 p->drawText( rs, Qt::AlignCenter, QString( "%1%" ).arg( percent ) );
1385 p->setPen( myColor );
1386 p->drawText( r, Qt::AlignCenter, QString( "%1%" ).arg( percent ) );
1391 \brief Draw status message.
1393 \sa drawProgressBar()
1395 void QtxSplash::drawMessage( QPainter* p )
1397 // get rect, margin, progress bar width
1400 int pw = progressVisible() ? progressWidth() : 0;
1402 // calculate drawing rect
1403 QFontMetrics f( font() );
1404 int spacing = f.lineSpacing();
1406 QRect r1( r.x() + m, r.y() + m, r.width() - 2 * m, r.height() - 2 * m );
1407 r1.setY( r1.y() - f.leading() );
1408 // ... take into account progress bar
1409 if ( 1 ) { // if ( myTotal > 0 ) : vsr changed: otherwise text is jumping
1410 if ( myProgressFlags & BottomSide )
1411 r1.setHeight( r1.height() - pw );
1412 else if ( myProgressFlags & TopSide )
1413 r1.setY( r1.y() + pw );
1414 else if ( myProgressFlags & LeftSide )
1415 r1.setX( r1.x() + pw );
1416 else if ( myProgressFlags & RightSide )
1417 r1.setWidth( r1.width() - pw );
1420 // ... take into account trailing '\n' symbols
1422 QString msg = fullMessage();
1423 int i = msg.length() - 1;
1424 while( i >= 0 && msg[ i-- ] == '\n' )
1426 r1.setHeight( r1.height() - shift );
1428 p->setOpacity( myOpacity );
1430 // draw shadow status text
1431 if ( myShadowColor.isValid() ) {
1433 if ( myAlignment & Qt::AlignLeft ) r2.setLeft ( r2.left() + 1 );
1434 if ( myAlignment & Qt::AlignTop ) r2.setTop ( r2.top() + 1 );
1435 if ( myAlignment & Qt::AlignRight ) r2.setRight ( r2.right() + 1 );
1436 if ( myAlignment & Qt::AlignBottom ) r2.setBottom( r2.bottom() + 1 );
1437 p->setPen( myShadowColor );
1438 p->drawText( r2, myAlignment, msg );
1441 // draw foreground status text
1442 p->setPen( myColor );
1443 p->drawText( r1, myAlignment, msg );
1447 \brief Draw the splash screen window contents.
1450 void QtxSplash::drawContents()
1452 QPixmap textPix = myPixmap;
1453 QPainter painter( &textPix );
1454 painter.initFrom( this );
1455 drawContents( &painter );
1456 QPalette pal = palette();
1457 pal.setBrush( backgroundRole(), QBrush( textPix ) );
1462 \brief Sets error code.
1463 \param code error code
1466 void QtxSplash::setError( const int code )
1472 \brief Get full message which includes constant info and status message.
1473 \return get fill message text
1474 \sa constantInfo(), setConstantInfo(), message(), setMessage()
1477 QString QtxSplash::fullMessage() const
1481 QString cinfo = myInfo;
1482 cinfo = cinfo.replace( QRegExp( "%A" ), option( "%A" ) );
1483 cinfo = cinfo.replace( QRegExp( "%V" ), option( "%V" ) );
1484 cinfo = cinfo.replace( QRegExp( "%L" ), option( "%L" ) );
1485 cinfo = cinfo.replace( QRegExp( "%C" ), option( "%C" ) );
1487 if ( !cinfo.isEmpty() )
1489 if ( !myMessage.isEmpty() )
1491 return info.join( "\n" );