1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File: QtxSplash.cxx
20 // Author: Vadim SANDLER
22 #include "QtxSplash.h"
24 #include <qapplication.h>
27 #include <qmessagebox.h>
29 const int _PROGRESS_EVENT = QEvent::User + 10;
30 const int _PROGRESS_WIDTH = 10;
33 Class ProgressEvent [ internal ].
35 class ProgressEvent: public QCustomEvent
38 ProgressEvent( const QString& msg, const int progress = 0 )
39 : QCustomEvent( id() ),
41 myProgress( progress )
43 QString message() const { return myMessage; }
44 int progress() const { return myProgress; }
45 static int id() { return _PROGRESS_EVENT; }
52 // Only one instance of splash screen is allowed
53 QtxSplash* QtxSplash::mySplash = 0;
56 Construct a splash screen that will display the \a pixmap.
58 QtxSplash::QtxSplash( const QPixmap& pixmap )
59 : QWidget( 0, 0, WStyle_Customize | WStyle_StaysOnTop | WX11BypassWM | WStyle_NoBorder )
61 myAlignment = AlignBottom | AlignRight;
63 myHideOnClick = false;
66 myGradientType = Vertical;
77 QtxSplash::~QtxSplash()
83 Returns an only instance of splash screen.
84 If \a px is valid sets this pixmap to the splash screen.
86 QtxSplash* QtxSplash::splash( const QPixmap& px )
89 mySplash = new QtxSplash( px );
90 else if ( !px.isNull() )
91 mySplash->setPixmap( px );
96 Sends the status message and (optionally) progress to the splash screen.
97 Can be used, for example, from the progress thread.
99 void QtxSplash::setStatus( const QString& msg,
103 QApplication::postEvent( mySplash, new ProgressEvent( msg, progress ) );
104 qApp->processEvents();
109 Sets error status and shows error message box to the user.
111 void QtxSplash::error( const QString& error, const QString& title, const int code )
113 printf("QtxSplash::error: %s\n",error.latin1());
115 mySplash->setError( code );
116 QMessageBox::critical( mySplash,
117 title.isEmpty() ? tr( "Error" ) : title,
124 Sets the pixmap that will be used as the splash screen's image to
127 void QtxSplash::setPixmap( const QPixmap& pixmap )
130 QRect r( 0, 0, myPixmap.size().width(), myPixmap.size().height() );
131 resize( myPixmap.size() );
132 move( QApplication::desktop()->screenGeometry().center() - r.center() );
137 Returns the pixmap that is used in the splash screen.
139 QPixmap QtxSplash::pixmap() const
145 Sets/clear the 'hide on mouse click' flag.
147 When this flag is set, user can hide the splash screen window
148 by clicking on it with mouse.
149 But for this to work it is necessary to call periodically
150 QApplication::processEvents() in order to allow event loop to process
151 events because usually main application loop is not yet started
154 void QtxSplash::setHideOnClick( const bool on )
160 Returns the 'hide on mouse click' flag.
162 bool QtxSplash::hideOnClick() const
164 return myHideOnClick;
168 Sets total progress steps to \a total.
170 void QtxSplash::setTotalSteps( const int total )
177 Return total progress steps number.
178 \sa setTotalSteps(), setProgress()
180 int QtxSplash::totalSteps() const
186 Sets progress to \a progress.
188 void QtxSplash::setProgress( const int progress )
190 myProgress = progress;
195 Return current progress.
196 \sa setProgress(), setTotalSteps()
198 int QtxSplash::progress() const
204 Sets progress to \a progress and total progress steps to \a total.
206 void QtxSplash::setProgress( const int progress, const int total )
209 myProgress = progress;
214 Sets progress bar colors to \a startColor and \a endColor.
215 If the colors differ the gradient color bar is drawed.
216 If the \a endColor is not valid, \a startColor is used instead.
217 \a gradientType sets the type of gradient to be used for progress
218 bar - horizontal or vertical. Default is vertical.
220 void QtxSplash::setProgressColors( const QColor& startColor,
221 const QColor& endColor,
222 const int gradientType )
224 myStartColor = startColor;
225 myEndColor = endColor;
226 myGradientType = gradientType;
231 Return progress colors and gradient type (horizontal or vertical).
232 \sa setProgressColors()
234 int QtxSplash::progressColors( QColor& startColor, QColor& endColor )
236 startColor = myStartColor;
237 endColor = myEndColor;
238 return myGradientType;
242 Sets message text alignment flags to \a alignment.
243 Default is AlignBottom | AlignRight.
245 void QtxSplash::setTextAlignment( const int alignment )
247 myAlignment = alignment;
252 Return message text alignment flags.
253 \sa setTextAlignment()
255 int QtxSplash::textAlignment() const
263 Margin is used when drawing progress bar and status messages.
268 void QtxSplash::setMargin( const int m )
276 \return current margin.
279 int QtxSplash::margin() const
285 Sets message text color to \a color.
289 void QtxSplash::setTextColor( const QColor& color )
292 myShadowColor = QColor();
297 Return message text color.
300 QColor QtxSplash::textColor() const
306 Sets message text color to \a color and text shadow color to \a shadow.
309 void QtxSplash::setTextColors( const QColor& color, const QColor& shadow )
312 myShadowColor = shadow;
317 Return message text color and text shadow color.
320 void QtxSplash::textColors( QColor& color, QColor& shadow ) const
323 shadow = myShadowColor;
327 Returns current status message.
329 QString QtxSplash::message() const
335 Return error code. If no errors were occured returns 0.
336 Error code can be set by error( QString&, QString, int ).
338 int QtxSplash::error() const
344 Makes the splash screen wait until the widget \a mainWin is displayed
345 before calling close() on itself.
347 void QtxSplash::finish( QWidget* mainWin )
350 #if defined(Q_WS_X11)
351 extern void qt_wait_for_window_manager( QWidget* w );
352 qt_wait_for_window_manager( mainWin );
359 Repaint the splash screen.
361 void QtxSplash::repaint()
365 QApplication::flush();
369 Draws the \a message text onto the splash screen with color \a
370 color and aligns the text according to the flags in \a alignment.
372 void QtxSplash::message( const QString& msg,
374 const QColor& color )
377 myAlignment = alignment;
383 This is an overloaded member function, provided for convenience.
384 It behaves essentially like the above function.
385 Draws the \a message text onto the splash screen with default color
386 and aligns the text according to the default alignment flags.
388 void QtxSplash::message( const QString& msg )
395 Removes the message being displayed on the splash screen.
398 void QtxSplash::clear()
400 myMessage = QString::null;
405 Draw the contents of the splash screen using painter \a painter.
407 void QtxSplash::drawContents( QPainter* painter )
413 if ( myGradientType == Horizontal ) {
414 int tng = r.width() - r.x() - m*2;
415 int ng = (int) ( 1.0 * tng * ( myProgress > 0 ? myProgress : 0 ) / myTotal );
416 int h1, h2, s1, s2, v1, v2;
417 myStartColor.hsv( &h1, &s1, &v1 );
418 myEndColor.isValid() ? myEndColor.hsv( &h2, &s2, &v2 ) :
419 myStartColor.hsv( &h2, &s2, &v2 );
420 for ( int i = 0; i < ng; i++ ) {
421 painter->setPen( QColor( h1 + ((h2-h1)*i)/(tng-1),
422 s1 + ((s2-s1)*i)/(tng-1),
423 v1 + ((v2-v1)*i)/(tng-1),
425 painter->drawLine( r.x()+m+i,
426 r.height()-m-_PROGRESS_WIDTH,
432 int ng = (int) ( 1.0 * (r.width() - r.x() - m*2 - 1) * ( myProgress > 0 ? myProgress : 0 ) / myTotal );
433 int h1, h2, s1, s2, v1, v2;
434 myStartColor.hsv( &h1, &s1, &v1 );
435 myEndColor.isValid() ? myEndColor.hsv( &h2, &s2, &v2 ) :
436 myStartColor.hsv( &h2, &s2, &v2 );
437 for ( int i = 0; i < _PROGRESS_WIDTH; i++ ) {
438 painter->setPen( QColor( h1 + ((h2-h1)*i)/(_PROGRESS_WIDTH-1),
439 s1 + ((s2-s1)*i)/(_PROGRESS_WIDTH-1),
440 v1 + ((v2-v1)*i)/(_PROGRESS_WIDTH-1),
442 painter->drawLine( r.x()+m,
443 r.height()-m-_PROGRESS_WIDTH+i,
445 r.height()-m-_PROGRESS_WIDTH+i );
448 // draw progress bar outline rectangle
449 painter->setPen( palette().active().dark() );
450 painter->drawLine( r.x()+m,
451 r.height()-m-_PROGRESS_WIDTH,
453 r.height()-m-_PROGRESS_WIDTH );
454 painter->drawLine( r.x()+m,
455 r.height()-m-_PROGRESS_WIDTH,
458 painter->setPen( palette().active().light() );
459 painter->drawLine( r.x()+m,
463 painter->drawLine( r.width()-m,
464 r.height()-m-_PROGRESS_WIDTH,
469 if ( !myMessage.isEmpty() ) {
470 QFontMetrics f( font() );
471 int spacing = f.lineSpacing();
472 int shift = myTotal > 0 ? _PROGRESS_WIDTH : _PROGRESS_WIDTH; // : 0
473 int i = myMessage.length() - 1;
474 while( i >= 0 && myMessage[ i-- ] == '\n' )
476 QRect r1( r.x() + m, r.y() + m, r.width() - m*2, r.height() - m*2 - shift );
478 if ( myAlignment & Qt::AlignLeft ) r2.setLeft ( r2.left() + 1 );
479 if ( myAlignment & Qt::AlignTop ) r2.setTop ( r2.top() + 1 );
480 if ( myAlignment & Qt::AlignRight ) r2.setRight ( r2.right() + 1 );
481 if ( myAlignment & Qt::AlignBottom ) r2.setBottom( r2.bottom() + 1 );
482 if ( myShadowColor.isValid() ) {
483 painter->setPen( myShadowColor );
484 painter->drawText( r2, myAlignment, myMessage );
486 painter->setPen( myColor );
487 painter->drawText( r1, myAlignment, myMessage );
493 Hides splash screen if the 'hide on mouse click' flag is set.
496 void QtxSplash::mousePressEvent( QMouseEvent* )
503 Processes custom event sent by setStatus() method.
506 void QtxSplash::customEvent( QCustomEvent* ce )
508 if ( ce->type() == ProgressEvent::id() ) {
509 ProgressEvent* pe = (ProgressEvent*)ce;
510 pe->message().isEmpty() ? clear() : message( pe->message() );
511 setProgress( pe->progress() );
512 qApp->processEvents();
517 Draws the splash screen window [ internal ].
519 void QtxSplash::drawContents()
521 QPixmap textPix = myPixmap;
522 QPainter painter( &textPix, this );
523 drawContents( &painter );
524 setErasePixmap( textPix );
528 Sets error code [ internal ].
530 void QtxSplash::setError( const int code )