Back to index

salome-gui  6.5.0
QtxSplash.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // File   : QtxSplash.cxx
00024 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
00025 //
00026 #include "QtxSplash.h"
00027 #include "QtxResourceMgr.h"
00028 #include <cstdio>
00029 
00030 #include <QApplication>
00031 #include <QPainter>
00032 #include <QMessageBox>
00033 #include <QDesktopWidget>
00034 
00041 class ProgressEvent: public QEvent
00042 {
00043 public:
00049   ProgressEvent( const QString& msg, const int progress )
00050     : QEvent( (QEvent::Type)id() ),
00051       myMessage( msg ),
00052       myProgress( progress )
00053   {}
00058   QString    message()  const { return myMessage; } 
00063   int        progress() const { return myProgress; }
00068   static int id()             { return QEvent::User + 10; }
00069 
00070 private:
00071   QString myMessage;
00072   int     myProgress;
00073 };
00074 
00180 
00181 QtxSplash* QtxSplash::mySplash = 0;
00182 
00191 QtxSplash::QtxSplash( const QPixmap& pixmap )
00192 : QWidget( 0, Qt::SplashScreen | Qt::WindowStaysOnTopHint ),
00193   myAlignment( Qt::AlignBottom | Qt::AlignRight ),
00194   myColor( Qt::white ),
00195   myHideOnClick( false ),
00196   myProgress( 0 ),
00197   myTotal( 0 ),
00198   myProgressWidth( 10 ),
00199   myProgressFlags( BottomSide | LeftToRight ),
00200   myMargin( 5 ),
00201   myOpacity( 1.0 ),
00202   myError( 0 ),
00203   myShowPercent( true ),
00204   myShowProgress( true ),
00205   myShowMessage( true )
00206 {
00207   setAttribute( Qt::WA_DeleteOnClose, true );
00208   setPixmap( pixmap );
00209 }
00210 
00214 QtxSplash::~QtxSplash()
00215 {
00216   mySplash = 0;
00217 }
00218 
00229 QtxSplash* QtxSplash::splash( const QPixmap& px )
00230 {
00231   if ( !mySplash )
00232     mySplash = new QtxSplash( px );
00233   else if ( !px.isNull() )
00234     mySplash->setPixmap( px );
00235   return mySplash;
00236 }
00237 
00250 void QtxSplash::setStatus( const QString& msg, const int progress )
00251 {
00252   if ( mySplash ) {
00253     QApplication::postEvent( mySplash, new ProgressEvent( msg, progress ) );
00254     QApplication::instance()->processEvents();
00255   }
00256 }
00257 
00265 void QtxSplash::setError( const QString& error, const QString& title, const int code )
00266 {
00267   if ( mySplash ) {
00268     mySplash->setError( code );
00269     QMessageBox::critical( mySplash, 
00270                            title.isEmpty() ? tr( "Error" ) : title,
00271                            error,
00272                            tr( "&OK" ) );
00273   }
00274   else {
00275     printf( "QtxSplash::error: %s\n",error.toLatin1().constData() );
00276   }
00277 }
00278 
00284 void QtxSplash::setPixmap( const QPixmap& pixmap )
00285 {
00286   if ( pixmap.hasAlpha() ) {
00287     QPixmap opaque( pixmap.size() );
00288     QPainter p( &opaque );
00289     p.fillRect( 0, 0, pixmap.width(), pixmap.height(), palette().background() );
00290     p.drawPixmap( 0, 0, pixmap );
00291     p.end();
00292     myPixmap = opaque;
00293   } 
00294   else {
00295     myPixmap = pixmap;
00296   }
00297   QRect r( 0, 0, myPixmap.size().width(), myPixmap.size().height() );
00298   resize( myPixmap.size() );
00299   move( QApplication::desktop()->screenGeometry().center() - r.center() );
00300   if ( !isVisible() )
00301     drawContents();
00302   else
00303     repaint();
00304 }
00305 
00311 QPixmap QtxSplash::pixmap() const
00312 {
00313   return myPixmap;
00314 }
00315 
00331 void QtxSplash::setHideOnClick( const bool on )
00332 {
00333   myHideOnClick = on;
00334 }
00335 
00341 bool QtxSplash::hideOnClick() const
00342 {
00343   return myHideOnClick;
00344 }
00345 
00351 void QtxSplash::setProgressVisible( const bool on )
00352 {
00353   myShowProgress = on;
00354   repaint();
00355 }
00356 
00362 bool QtxSplash::progressVisible() const
00363 {
00364   return myShowProgress;
00365 }
00366 
00372 void QtxSplash::setMessageVisible( const bool on )
00373 {
00374   myShowMessage = on;
00375   repaint();
00376 }
00377 
00383 bool QtxSplash::messageVisible() const
00384 {
00385   return myShowMessage;
00386 }
00387 
00393 void QtxSplash::setPercentageVisible( const bool enable )
00394 {
00395   myShowPercent = enable;
00396   repaint();
00397 }
00398 
00404 bool QtxSplash::percentageVisible() const
00405 {
00406   return myShowPercent;
00407 }
00408 
00414 void QtxSplash::setTotalSteps( const int total )
00415 {
00416   myTotal = total;
00417   repaint();
00418 }
00419 
00425 int QtxSplash::totalSteps() const
00426 {
00427   return myTotal;
00428 }
00429     
00435 void QtxSplash::setProgress( const int progress )
00436 {
00437   myProgress = progress > 0 ? progress : 0;
00438   repaint();
00439 }
00440 
00446 int QtxSplash::progress() const
00447 {
00448   return myProgress;
00449 }
00450 
00457 void QtxSplash::setProgress( const int progress, const int total )
00458 {
00459   myTotal    = total;
00460   myProgress = progress > 0 ? progress : 0;
00461   repaint();
00462 }
00463 
00473 void QtxSplash::setMargin( const int margin )
00474 {
00475   myMargin = margin > 0 ? margin : 0;
00476   repaint();
00477 }
00478 
00484 int QtxSplash::margin() const
00485 {
00486   return myMargin;
00487 }
00488 
00494 void QtxSplash::setProgressWidth( const int width )
00495 {
00496   myProgressWidth = width > 0 ? width : 0;
00497   repaint();
00498 }
00499 
00505 int QtxSplash::progressWidth() const
00506 {
00507   return myProgressWidth;
00508 }
00509 
00519 void QtxSplash::setProgressFlags( const int flags )
00520 {
00521   myProgressFlags = flags;
00522   if ( !( myProgressFlags & ( LeftSide | RightSide | TopSide | BottomSide ) ) )
00523     myProgressFlags |= BottomSide;
00524   if ( !( myProgressFlags & ( LeftToRight | RightToLeft ) ) )
00525     myProgressFlags |= LeftToRight ;
00526   repaint();
00527 }
00528 
00534 int QtxSplash::progressFlags() const
00535 {
00536   return myProgressFlags;
00537 }
00538 
00555 void QtxSplash::setProgressColors( const QColor&         startColor, 
00556                                    const QColor&         endColor,
00557                                    const Qt::Orientation orientation )
00558 {
00559   if ( !startColor.isValid() )
00560     return;
00561 
00562   QLinearGradient l;
00563   if ( orientation == Qt::Vertical ) {
00564     l.setStart( 0., 0. );
00565     l.setFinalStop( 0., 1. );
00566   }
00567   else {
00568     l.setStart( 0., 0. );
00569     l.setFinalStop( 1., 0. );
00570   }
00571   l.setColorAt( 0., startColor );
00572   l.setColorAt( 1., endColor.isValid() ? endColor : startColor );
00573 
00574   setProgressColors( l );
00575 }
00576 
00607 void QtxSplash::setProgressColors( const QGradient& gradient )
00608 {
00609   myGradient = gradient;
00610   repaint();
00611 }
00612 
00618 const QGradient* QtxSplash::progressColors() const
00619 {
00620   return &myGradient;
00621 }
00622 
00632 void QtxSplash::setOpacity( const double opacity )
00633 {
00634   myOpacity = opacity < 0.0 ? 0.0 : ( opacity > 1.0 ? 1.0 : opacity );
00635   repaint();
00636 }
00637 
00643 double QtxSplash::opacity() const
00644 {
00645   return myOpacity;
00646 }
00647 
00656 void QtxSplash::setTextAlignment( const int alignment )
00657 {
00658   myAlignment = alignment;
00659   repaint();
00660 }
00661 
00667 int QtxSplash::textAlignment() const
00668 {
00669   return myAlignment;
00670 }
00671 
00683 void QtxSplash::setTextColors( const QColor& color, const QColor& shadow )
00684 {
00685   if ( !myColor.isValid() )
00686     return;
00687 
00688   myColor = color;
00689   myShadowColor = shadow;
00690 
00691   repaint();
00692 }
00693 
00700 void QtxSplash::textColors( QColor& color, QColor& shadow ) const
00701 {
00702   color  = myColor;
00703   shadow = myShadowColor;
00704 }
00705 
00716 void QtxSplash::setConstantInfo( const QString& info )
00717 {
00718   myInfo = info;
00719   repaint();
00720 }
00721 
00727 QString QtxSplash::constantInfo() const
00728 {
00729   return myInfo;
00730 }
00731 
00756 void QtxSplash::setOption( const QString& name, const QString& value )
00757 {
00758   myOptions[ name ] = value;
00759   repaint();
00760 }
00761 
00768 QString QtxSplash::option( const QString& name ) const
00769 {
00770   QString val;
00771   if ( myOptions.contains( name ) )
00772     val = myOptions[ name ];
00773   return val;
00774 }
00775 
00781 QString QtxSplash::message() const
00782 {
00783   return myMessage;
00784 }
00785 
00796 int QtxSplash::error() const
00797 {
00798   return myError;
00799 }
00800 
00809 void QtxSplash::finish( QWidget* mainWin )
00810 {
00811   if ( mainWin ) {
00812 #if defined(Q_WS_X11)
00813     extern void qt_x11_wait_for_window_manager(QWidget *mainWin);
00814     qt_x11_wait_for_window_manager(mainWin);
00815 #endif
00816   }
00817   close();
00818 }
00819 
00823 void QtxSplash::repaint()
00824 {
00825   drawContents();
00826   QWidget::repaint();
00827   QApplication::flush();
00828 }
00829 
00856 void QtxSplash::readSettings( QtxResourceMgr* resMgr, const QString& section )
00857 {
00858   QString resSection = section.isEmpty() ? QString( "splash" ) : section;
00859   
00860   // pixmap
00861   QString pxname;
00862   if ( resMgr->value( resSection, "image", pxname ) ) {
00863     QPixmap px( pxname );
00864     if ( !px.isNull() )
00865       setPixmap( px );
00866   }
00867 
00868   // hide-on-click
00869 #ifdef _DEBUG_
00870   setHideOnClick( true );
00871 #else
00872   bool bHide;
00873   if ( resMgr->value( resSection, "hide_on_click", bHide ) ) {
00874     setHideOnClick( bHide );
00875   }
00876 #endif
00877 
00878   // enable progress bar
00879   bool bShowProgress;
00880   if ( resMgr->value( resSection, "show_progress", bShowProgress ) ) {
00881     setProgressVisible( bShowProgress );
00882   }
00883   
00884   // enable status message
00885   bool bShowMessage;
00886   if ( resMgr->value( resSection, "show_message", bShowMessage ) ) {
00887     setMessageVisible( bShowMessage );
00888   }
00889   
00890   // margin
00891   int m;
00892   if ( resMgr->value( resSection, "margin", m ) ) {
00893     setMargin( m );
00894   }
00895 
00896   // progress bar width
00897   int pw;
00898   if ( resMgr->value( resSection, "progress_width", pw ) ) {
00899     setProgressWidth( pw );
00900   }
00901 
00902   // progress bar position and direction
00903   QString pf;
00904   if ( resMgr->value( resSection, "progress_flags", pf ) ) {
00905     bool bOk;
00906     int fl = pf.toInt( &bOk );
00907     if ( !bOk ) {
00908       fl = 0;
00909       QStringList opts = pf.split( QRegExp( "," ), QString::SkipEmptyParts );
00910       for ( int i = 0; i < opts.count(); i++ ) {
00911         QString opt = opts[i].trimmed().toLower();
00912         if ( opt == "left" )
00913           fl = fl | LeftSide;
00914         else if ( opt == "right" )
00915           fl = fl | RightSide;
00916         else if ( opt == "top" )
00917           fl = fl | TopSide;
00918         else if ( opt == "bottom" )
00919           fl = fl | BottomSide;
00920         else if ( opt == "left_to_right" )
00921           fl = fl | LeftToRight;
00922         else if ( opt == "right_to_left" )
00923           fl = fl | RightToLeft;
00924       }
00925     }
00926     setProgressFlags( fl );
00927   }
00928   
00929   // opacity
00930   double op;
00931   if ( resMgr->value( resSection, "opacity", op ) ) {
00932     setOpacity( op );
00933   }
00934 
00935   // font
00936   QFont f;
00937   if ( resMgr->value( resSection, "font", f ) ) {
00938     setFont( f );
00939   }
00940 
00941   // text alignment
00942   QString al;
00943   if ( resMgr->value( resSection, "alignment", al ) ) {
00944     bool bOk;
00945     int fl = al.toInt( &bOk );
00946     if ( !bOk ) {
00947       fl = 0;
00948       QStringList opts = al.split( QRegExp( "," ), QString::SkipEmptyParts );
00949       for ( int i = 0; i < opts.count(); i++ ) {
00950         QString opt = opts[i].trimmed().toLower();
00951         if ( opt == "left" )
00952           fl = fl | Qt::AlignLeft;
00953         else if ( opt == "right" )
00954           fl = fl | Qt::AlignRight;
00955         else if ( opt == "top" )
00956           fl = fl | Qt::AlignTop;
00957         else if ( opt == "bottom" )
00958           fl = fl | Qt::AlignBottom;
00959         else if ( opt == "hcenter" )
00960           fl = fl | Qt::AlignHCenter;
00961         else if ( opt == "vcenter" )
00962           fl = fl | Qt::AlignVCenter;
00963         else if ( opt == "justify" )
00964           fl = fl | Qt::AlignJustify;
00965         else if ( opt == "center" )
00966           fl = fl | Qt::AlignCenter;
00967       }
00968     }
00969     setTextAlignment( fl );
00970   }
00971   // progress color(s)
00972   QString pc;
00973   QLinearGradient  lgrad;
00974   QRadialGradient  rgrad;
00975   QConicalGradient cgrad;
00976   if ( resMgr->value( resSection, "progress_color",  lgrad ) || 
00977        resMgr->value( resSection, "progress_colors", lgrad ) ) {
00978     // linear gradient-colored progress bar
00979     setProgressColors( lgrad );
00980   }
00981   else if ( resMgr->value( resSection, "progress_color",  rgrad ) || 
00982             resMgr->value( resSection, "progress_colors", rgrad ) ) {
00983     // radial gradient-colored progress bar
00984     setProgressColors( rgrad );
00985   }
00986   else if ( resMgr->value( resSection, "progress_color",  cgrad ) || 
00987             resMgr->value( resSection, "progress_colors", cgrad ) ) {
00988     // conical gradient-colored progress bar
00989     setProgressColors( cgrad );
00990   }
00991   else if ( resMgr->value( resSection, "progress_color",  pc ) || 
00992             resMgr->value( resSection, "progress_colors", pc ) ) {
00993     // one/two-colored progress bar
00994     QStringList colors = pc.split( "|", QString::SkipEmptyParts );
00995     QColor c1, c2;
00996     Qt::Orientation o = Qt::Vertical;
00997     if ( colors.count() > 0 ) c1 = QColor( colors[0] );
00998     if ( colors.count() > 1 ) c2 = QColor( colors[1] );
00999     int gt;
01000     if ( colors.count() > 2 ) {
01001       bool bOk;
01002       gt = colors[2].toInt( &bOk );
01003       if ( bOk ) {
01004         if ( gt == 0 )
01005           o = Qt::Horizontal;
01006       }
01007       else {
01008         if ( colors[2].toLower().startsWith( "h" ) )
01009           o = Qt::Horizontal;
01010       }
01011     }
01012     setProgressColors( c1, c2, o );
01013   }
01014   // show percents
01015   bool bPercent;
01016   if ( resMgr->value( resSection, "show_percents", bPercent ) ) {
01017     setPercentageVisible( bPercent );
01018   }
01019 
01020   // text color(s)
01021   QString tc;
01022   if ( resMgr->value( resSection, "text_color",  tc ) || 
01023        resMgr->value( resSection, "text_colors", tc ) ) {
01024     QStringList colors = tc.split( "|", QString::SkipEmptyParts );
01025     QColor c1, c2;
01026     if ( colors.count() > 0 )
01027       c1 = QColor( colors[0] );
01028     if ( colors.count() > 1 )
01029       c2 = QColor( colors[1] );
01030     setTextColors( c1, c2 );
01031   }
01032 
01033   // const info
01034   QString cinfo;
01035   if ( resMgr->value( resSection, "constant_info", cinfo, false ) ||
01036        resMgr->value( resSection, "info", cinfo, false ) ) {
01037     setConstantInfo( cinfo.split( "|", QString::KeepEmptyParts ).join( "\n" ) );
01038   }
01039 }
01040 
01049 void QtxSplash::setMessage( const QString& msg, 
01050                             int            alignment,
01051                             const QColor&  color )
01052 {
01053   myMessage   = msg;
01054   myAlignment = alignment;
01055   if ( color.isValid() )
01056     myColor = color;
01057   repaint();
01058 }
01059 
01066 void QtxSplash::setMessage( const QString& msg )
01067 {
01068   myMessage = msg;
01069   repaint();
01070 }
01071 
01079 void QtxSplash::clear()
01080 {
01081   myMessage.clear();
01082   repaint();
01083 }
01084 
01089 void QtxSplash::drawContents( QPainter* p )
01090 {
01091   // draw progress bar
01092   if ( myTotal > 0 && progressVisible() ) {
01093     p->save();
01094     drawProgressBar( p );
01095     p->restore();
01096   }
01097 
01098   // draw status message
01099   if ( !fullMessage().isEmpty() && messageVisible() ) {
01100     p->save();
01101     drawMessage( p );
01102     p->restore();
01103   }
01104 }
01105 
01114 void QtxSplash::mousePressEvent( QMouseEvent* /*me*/ )
01115 {
01116   if ( myHideOnClick )
01117     hide();
01118 }
01119 
01129 void QtxSplash::paintEvent( QPaintEvent* /*pe*/ )
01130 {
01131   QPainter p( this );
01132   QPixmap pix = palette().brush( backgroundRole() ).texture();
01133   p.drawPixmap( 0, 0, pix );
01134 }
01135 
01141 void QtxSplash::customEvent( QEvent* ce )
01142 {
01143   if ( ce->type() == ProgressEvent::id() ) {
01144     ProgressEvent* pe = (ProgressEvent*)ce;
01145     pe->message().isEmpty() ? clear() : setMessage( pe->message() );
01146     if ( pe->progress() >= 0 )
01147       setProgress( pe->progress() );
01148     QApplication::instance()->processEvents();
01149   }
01150 }
01151 
01157 static bool checkGradient( const QGradient* g )
01158 {
01159 #define BOUNDED( a, min, max ) ( a >= min && a <= max )
01160   if ( g->type() == QGradient::LinearGradient ) {
01161     const QLinearGradient* lg = static_cast<const QLinearGradient*>( g );
01162     return BOUNDED( lg->start().x(), 0.0, 1.0 ) && 
01163            BOUNDED( lg->start().y(), 0.0, 1.0 ) && 
01164            BOUNDED( lg->finalStop().x(), 0.0, 1.0 ) && 
01165            BOUNDED( lg->finalStop().y(), 0.0, 1.0 );
01166   }
01167   if ( g->type() == QGradient::RadialGradient ) {
01168     const QRadialGradient* rg = static_cast<const QRadialGradient*>( g );
01169     return BOUNDED( rg->center().x(), 0.0, 1.0 ) && 
01170            BOUNDED( rg->center().y(), 0.0, 1.0 ) && 
01171            BOUNDED( rg->focalPoint().x(), 0.0, 1.0 ) && 
01172            BOUNDED( rg->focalPoint().y(), 0.0, 1.0 ); // && BOUNDED( rg->radius(), 0.0, 1.0 );
01173   }
01174   if ( g->type() == QGradient::ConicalGradient ) {
01175     const QConicalGradient* cg = static_cast<const QConicalGradient*>( g );
01176     return BOUNDED( cg->center().x(), 0.0, 1.0 ) && 
01177            BOUNDED( cg->center().y(), 0.0, 1.0 );
01178   }
01179   return false;
01180 }
01181 
01187 void QtxSplash::drawProgressBar( QPainter* p )
01188 {
01189   // get rect, margin, progress bar width
01190   QRect r = rect();
01191   int m   = margin();
01192   int pw  = progressWidth();
01193 
01194   // calculate drawing rect
01195   // ... first set default position (if none or wrong position is set)
01196   if ( myProgressFlags & BottomSide )
01197     r = QRect( r.x() + m, r.height() - (m + pw), r.width() - 2 * m, pw );
01198   else if ( myProgressFlags & TopSide )
01199     r = QRect( r.x() + m, r.y() + m, r.width() - 2 * m, pw );
01200   else if ( myProgressFlags & LeftSide )
01201     r = QRect( r.x() + m, r.y() + m, pw, r.height() - 2 * m );
01202   else if ( myProgressFlags & RightSide )
01203     r = QRect( r.width() - (m + pw), r.y() + m, pw, r.height() - 2 * m );
01204 
01205   QRect cr = r;
01206   if ( myProgressFlags & TopSide || myProgressFlags & BottomSide ) {
01207     cr.setWidth( (int)( r.width() * ( myProgress > 0 ? myProgress : 0 ) / myTotal ) );
01208     if ( myProgressFlags & RightToLeft )
01209       cr.translate( r.width() - cr.width(), 0 );
01210   }
01211   else if ( myProgressFlags & LeftSide || myProgressFlags & RightSide ) {
01212     cr.setHeight( (int)( r.height() * ( myProgress > 0 ? myProgress : 0 ) / myTotal ) );
01213     if ( myProgressFlags & RightToLeft)
01214       cr.translate( 0, r.height() - cr.height() );
01215   }
01216   QBrush b;
01217   switch ( progressColors()->type() ) {
01218     case QGradient::LinearGradient:
01219     {
01220       QLinearGradient lg;
01221       const QLinearGradient* other = static_cast<const QLinearGradient*>( progressColors() );
01222       if ( checkGradient( other ) ) {
01223         // gradient is defined in relative coordinates [0.0 - 1.0]
01224         lg.setStart( r.left() + r.width()  * other->start().x(), 
01225                      r.top()  + r.height() * other->start().y() );
01226         lg.setFinalStop( r.left() + r.width()  * other->finalStop().x(), 
01227                          r.top()  + r.height() * other->finalStop().y() );
01228       }
01229       else {
01230         // gradient is defined in absolute coordinates
01231         // according to its dimensions
01232         lg.setStart( r.topLeft() + other->start() );
01233         lg.setFinalStop( r.topLeft() + other->finalStop() );
01234       }
01235       
01236       lg.setStops( other->stops() );
01237       lg.setSpread( other->spread() );
01238       
01239       b = QBrush( lg );
01240       
01241       break;
01242     } // case QGradient::LinearGradient
01243     case QGradient::RadialGradient:
01244     {
01245       QRadialGradient rg;
01246       const QRadialGradient* other = static_cast<const QRadialGradient*>( progressColors() );
01247       if ( checkGradient( other ) ) {
01248         // gradient is defined in relative coordinates [0.0 - 1.0]
01249         rg.setCenter( r.left() + r.width()  * other->center().x(),
01250                       r.top()  + r.height() * other->center().y() );
01251         rg.setFocalPoint( r.left() + r.width()  * other->focalPoint().x(),
01252                           r.top()  + r.height() * other->focalPoint().y() );
01253       }
01254       else {
01255         // gradient is defined in absolute coordinates
01256         // according to its dimensions
01257         rg.setCenter( r.topLeft() + other->center() );
01258         rg.setFocalPoint( r.topLeft() + other->focalPoint() );
01259       }
01260       
01261       // only width is taken into account for the radius in relative mode
01262       rg.setRadius( other->radius() > 1.0 ? other->radius() : r.width() * other->radius() );
01263       
01264       rg.setStops( other->stops() );
01265       rg.setSpread( other->spread() );
01266       
01267       b = QBrush( rg );
01268       
01269       break;
01270     } // case QGradient::RadialGradient
01271     case QGradient::ConicalGradient:
01272     {
01273       QConicalGradient cg;
01274       const QConicalGradient* other = static_cast<const QConicalGradient*>( progressColors() );
01275       if ( checkGradient( other ) ) {
01276         // gradient is defined in relative coordinates [0.0 - 1.0]
01277         cg.setCenter( r.left() + r.width()  * other->center().x(),
01278                       r.top()  + r.height() * other->center().y() );
01279       }
01280       else {
01281         // gradient is defined in absolute coordinates
01282         // according to its dimensions
01283         cg.setCenter( r.topLeft() + other->center() );
01284       }
01285 
01286       cg.setAngle( other->angle() );
01287       cg.setStops( other->stops() );
01288       cg.setSpread( other->spread() );
01289       
01290       b = QBrush( cg );
01291       
01292       break;
01293     } // case QGradient::RadialGradient
01294   default:
01295     b = QBrush( Qt::red ); // default is simple red-colored progress bar
01296     break;
01297   }
01298   
01299   p->setOpacity( myOpacity );
01300 
01301   // draw progress bar outline rectangle
01302   p->setPen( palette().color( QPalette::Dark ) );
01303   p->drawLine( r.left(), r.top(), r.right(), r.top() );
01304   p->drawLine( r.left(), r.top(), r.left(), r.bottom() );
01305   p->setPen( palette().color( QPalette::Light ) );
01306   p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() );
01307   p->drawLine( r.right(), r.top(), r.right(), r.bottom() );
01308 
01309   r.setCoords( r.left()+1, r.top()+1, r.right()-1, r.bottom()-1 );
01310   p->setClipRect( cr );
01311   p->fillRect( r, b );
01312   p->setClipping( false );
01313 
01314   if ( myShowPercent ) {
01315     int percent = ( int )( ( myProgress > 0 ? myProgress : 0 ) * 100 / myTotal );
01316     QFont f = font();
01317     f.setPixelSize( r.height() - 4 );
01318     p->setFont( f );
01319     // draw shadow status text
01320     if ( myShadowColor.isValid() ) {
01321       QRect rs = r;
01322       rs.moveTopLeft( rs.topLeft() + QPoint( 1,1 ) );
01323       p->setPen( myShadowColor );
01324       p->drawText( rs, Qt::AlignCenter, QString( "%1%" ).arg( percent ) );
01325     }
01326     p->setPen( myColor );
01327     p->drawText( r, Qt::AlignCenter, QString( "%1%" ).arg( percent ) );
01328   }
01329 }
01330 
01336 void QtxSplash::drawMessage( QPainter* p )
01337 {
01338   // get rect, margin, progress bar width
01339   QRect r = rect();
01340   int m   = margin();
01341   int pw  = progressVisible() ? progressWidth() : 0;
01342 
01343   // calculate drawing rect
01344   QFontMetrics f( font() );
01345   int spacing = f.lineSpacing();
01346   // ... base rect
01347   QRect r1( r.x() + m, r.y() + m, r.width() - 2 * m, r.height() - 2 * m );
01348   r1.setY( r1.y() - f.leading() );
01349   // ... take into account progress bar
01350   if ( 1 ) {              // if ( myTotal > 0 ) : vsr changed: otherwise text is jumping
01351     if ( myProgressFlags & BottomSide )
01352       r1.setHeight( r1.height() - pw );
01353     else if ( myProgressFlags & TopSide )
01354       r1.setY( r1.y() + pw );
01355     else if ( myProgressFlags & LeftSide )
01356       r1.setX( r1.x() + pw );
01357     else if ( myProgressFlags & RightSide )
01358       r1.setWidth( r1.width() - pw );
01359   }
01360   
01361   // ... take into account trailing '\n' symbols
01362   int shift = 0;
01363   QString msg = fullMessage();
01364   int i = msg.length() - 1;
01365   while( i >= 0 && msg[ i-- ] == '\n' )
01366     shift += spacing;
01367   r1.setHeight( r1.height() - shift );
01368 
01369   p->setOpacity( myOpacity );
01370 
01371   // draw shadow status text
01372   if ( myShadowColor.isValid() ) {
01373     QRect r2 = r1;
01374     if ( myAlignment & Qt::AlignLeft   ) r2.setLeft  ( r2.left()   + 1 );
01375     if ( myAlignment & Qt::AlignTop    ) r2.setTop   ( r2.top()    + 1 );
01376     if ( myAlignment & Qt::AlignRight  ) r2.setRight ( r2.right()  + 1 );
01377     if ( myAlignment & Qt::AlignBottom ) r2.setBottom( r2.bottom() + 1 );
01378     p->setPen( myShadowColor );
01379     p->drawText( r2, myAlignment, msg );
01380   }
01381 
01382   // draw foreground status text
01383   p->setPen( myColor );
01384   p->drawText( r1, myAlignment, msg );
01385 }
01386 
01391 void QtxSplash::drawContents()
01392 {
01393   QPixmap textPix = myPixmap;
01394   QPainter painter( &textPix );
01395   painter.initFrom( this );
01396   drawContents( &painter );
01397   QPalette pal = palette();
01398   pal.setBrush( backgroundRole(), QBrush( textPix ) );
01399   setPalette( pal );
01400 }
01401 
01407 void QtxSplash::setError( const int code )
01408 {
01409   myError = code;
01410 }
01411 
01418 QString QtxSplash::fullMessage() const
01419 {
01420   QStringList info;
01421 
01422   QString cinfo = myInfo;
01423   cinfo = cinfo.replace( QRegExp( "%A" ), option( "%A" ) );
01424   cinfo = cinfo.replace( QRegExp( "%V" ), option( "%V" ) );
01425   cinfo = cinfo.replace( QRegExp( "%L" ), option( "%L" ) );
01426   cinfo = cinfo.replace( QRegExp( "%C" ), option( "%C" ) );
01427 
01428   if ( !cinfo.isEmpty() )
01429     info << cinfo;
01430   if ( !myMessage.isEmpty() )
01431     info << myMessage;
01432   return info.join( "\n" );
01433 }