Back to index

kdeartwork  4.3.2
banner.cpp
Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 //
00003 // kbanner - Basic screen saver for KDE
00004 //
00005 // Copyright (c)  Martin R. Jones 1996
00006 //
00007 // layout management added 1998/04/19 by Mario Weilguni <mweilguni@kde.org>
00008 // clock function and color cycling added 2000/01/09 by Alexander Neundorf <alexander.neundorf@rz.tu-ilmenau.de>
00009 // 2001/03/04 Converted to use libkscreensaver by Martin R. Jones
00010 // 2002/04/07 Added random vertical position of text,
00011 //            changed horizontal step size to reduce jerkyness,
00012 //            text will return to right margin immediately (and not be drawn half a screen width off-screen)
00013 //            Harald H.-J. Bongartz <harald@bongartz.org>
00014 // 2003/09/06 Converted to use KDialog - Nadeem Hasan <nhasan@kde.org>
00015 #include <stdlib.h>
00016 
00017 #include <qlabel.h>
00018 #include <qlineedit.h>
00019 #include <qcombobox.h>
00020 #include <qcheckbox.h>
00021 #include <qgroupbox.h>
00022 #include <qslider.h>
00023 #include <qlayout.h>
00024 #include <qdatetime.h>
00025 #include <qfontdatabase.h>
00026 #include <qpainter.h>
00027 
00028 #include <kapplication.h>
00029 #include <krandomsequence.h>
00030 #include <kglobal.h>
00031 #include <klocale.h>
00032 #include <kconfig.h>
00033 #include <kmessagebox.h>
00034 #include <kcolorbutton.h>
00035 #include <kfontcombobox.h>
00036 
00037 #include "banner.h"
00038 #include "banner.moc"
00039 #include <QDesktopWidget>
00040 // libkscreensaver interface
00041 class KBannerSaverInterface : public KScreenSaverInterface
00042 {
00043 
00044 
00045 public:
00046     virtual KAboutData* aboutData() {
00047         return new KAboutData( "kbanner.kss", "klock", ki18n( "KBanner" ), "2.2.0", ki18n( "KBanner" ) );
00048     }
00049 
00050 
00051     virtual KScreenSaver* create( WId id )
00052     {
00053         return new KBannerSaver( id );
00054     }
00055 
00056     virtual QDialog* setup()
00057     {
00058         return new KBannerSetup();
00059     }
00060 };
00061 
00062 int main( int argc, char *argv[] )
00063 {
00064     KBannerSaverInterface kss;
00065     return kScreenSaverMain( argc, argv, kss );
00066 }
00067 
00068 //-----------------------------------------------------------------------------
00069 
00070 KBannerSetup::KBannerSetup( QWidget *parent )
00071        : KDialog( parent)
00072          , saver( 0 ), ed(0), speed( 50 )
00073 {
00074        setButtons(Ok|Cancel|Help);
00075        setDefaultButton(Ok);
00076        setCaption(i18n( "Setup Banner Screen Saver" ));
00077        setModal(true);
00078        setButtonText( Help, i18n( "A&bout" ) );
00079        readSettings();
00080 
00081         QWidget *main = new QWidget(this);
00082        setMainWidget(main);
00083 
00084        QLabel *label;
00085 
00086        QVBoxLayout *tl = new QVBoxLayout( main );
00087        QHBoxLayout *tl1 = new QHBoxLayout();
00088        tl->addLayout(tl1);
00089        QVBoxLayout *tl11 = new QVBoxLayout();
00090        tl1->addLayout(tl11);
00091 
00092        QGroupBox *group = new QGroupBox( i18n("Font"), main );
00093         QVBoxLayout *vbox = new QVBoxLayout;
00094         group->setLayout(vbox);
00095         QGridLayout *gl = new QGridLayout();
00096         vbox->addLayout(gl);
00097         gl->setSpacing(spacingHint());
00098 
00099        label = new QLabel( i18n("Family:"), group );
00100        gl->addWidget(label, 1, 0);
00101 
00102        KFontComboBox* comboFonts = new KFontComboBox( group );
00103        comboFonts->setCurrentFont( fontFamily );
00104        gl->addWidget(comboFonts, 1, 1);
00105        connect( comboFonts, SIGNAL(currentFontChanged( const QFont& ) ),
00106                      SLOT( slotFamily( const QFont& ) ) );
00107 
00108        label = new QLabel( i18n("Size:"), group );
00109        gl->addWidget(label, 2, 0);
00110 
00111        comboSizes = new QComboBox( group );
00112         comboSizes->setEditable( true );
00113         fillFontSizes();
00114        gl->addWidget(comboSizes, 2, 1);
00115        connect( comboSizes, SIGNAL( activated( int ) ), SLOT( slotSize( int ) ) );
00116        connect( comboSizes, SIGNAL( editTextChanged( const QString & ) ),
00117                      SLOT( slotSizeEdit( const QString &  ) ) );
00118 
00119        QCheckBox *cb = new QCheckBox( i18n("Bold"),
00120                                    group );
00121        cb->setChecked( bold );
00122        connect( cb, SIGNAL( toggled( bool ) ), SLOT( slotBold( bool ) ) );
00123        gl->addWidget(cb, 3, 0);
00124 
00125        cb = new QCheckBox( i18n("Italic"), group );
00126        cb->setChecked( italic );
00127        gl->addWidget(cb, 3, 1);
00128        connect( cb, SIGNAL( toggled( bool ) ), SLOT( slotItalic( bool ) ) );
00129 
00130        label = new QLabel( i18n("Color:"), group );
00131        gl->addWidget(label, 4, 0);
00132 
00133        colorPush = new KColorButton( fontColor, group );
00134        gl->addWidget(colorPush, 4, 1);
00135        connect( colorPush, SIGNAL( changed(const QColor &) ),
00136                SLOT( slotColor(const QColor &) ) );
00137 
00138         QCheckBox *cyclingColorCb=new QCheckBox(i18n("Cycling color"),group);
00139         cyclingColorCb->setMinimumSize(cyclingColorCb->sizeHint());
00140         gl->addWidget(cyclingColorCb, 5, 0,5,1);
00141         connect(cyclingColorCb,SIGNAL(toggled(bool)),this,SLOT(slotCyclingColor(bool)));
00142         cyclingColorCb->setChecked(cyclingColor);
00143 
00144        preview = new QWidget( main );
00145        preview->setFixedSize( 220, 170 );
00146         {
00147             QPalette palette;
00148             palette.setColor( preview->backgroundRole(), Qt::black );
00149             preview->setPalette( palette );
00150            preview->setAutoFillBackground(true);
00151         }
00152        preview->show();    // otherwise saver does not get correct size
00153        saver = new KBannerSaver( preview->winId() );
00154        tl1->addWidget(preview);
00155 
00156        tl11->addWidget(group);
00157 
00158        label = new QLabel( i18n("Speed:"), main );
00159        tl11->addStretch(1);
00160        tl11->addWidget(label);
00161 
00162        QSlider *sb = new QSlider( Qt::Horizontal, main );
00163         sb->setMinimum(0);
00164         sb->setMaximum(100);
00165         sb->setPageStep(10);
00166         sb->setValue(speed);
00167        sb->setMinimumWidth( 180);
00168        sb->setFixedHeight(20);
00169         sb->setTickPosition(QSlider::TicksBelow);
00170         sb->setTickInterval(10);
00171        tl11->addWidget(sb);
00172        connect( sb, SIGNAL( valueChanged( int ) ), SLOT( slotSpeed( int ) ) );
00173 
00174        QHBoxLayout *tl2 = new QHBoxLayout;
00175        tl->addLayout(tl2);
00176 
00177        label = new QLabel( i18n("Message:"), main );
00178        tl2->addWidget(label);
00179 
00180        ed = new QLineEdit( main );
00181        tl2->addWidget(ed);
00182        ed->setText( message );
00183        connect( ed, SIGNAL( textChanged( const QString & ) ),
00184                      SLOT( slotMessage( const QString &  ) ) );
00185 
00186    QCheckBox *timeCb=new QCheckBox( i18n("Show current time"), main);
00187    timeCb->setFixedSize(timeCb->sizeHint());
00188    tl->addWidget(timeCb,0,Qt::AlignLeft);
00189    connect(timeCb,SIGNAL(toggled(bool)),this,SLOT(slotTimeToggled(bool)));
00190    timeCb->setChecked(showTime);
00191    connect(this,SIGNAL(okClicked()),this,SLOT(slotOk()));
00192    connect(this,SIGNAL(helpClicked()),this,SLOT(slotHelp()));
00193    tl->addStretch();
00194 }
00195 
00196 // read settings from config file
00197 void KBannerSetup::readSettings()
00198 {
00199     KConfigGroup config(KGlobal::config(), "Settings");
00200 
00201    speed=config.readEntry("Speed",50);
00202 /*     if ( speed > 100 )
00203               speed = 100;
00204        else if ( speed < 50 )
00205               speed = 50;*/
00206 
00207    message=config.readEntry("Message","KDE");
00208    showTime=config.readEntry("ShowTime",false);
00209    fontFamily=config.readEntry("FontFamily",(QApplication::font()).family());
00210    fontSize=config.readEntry("FontSize",48);
00211    fontColor.setNamedColor(config.readEntry("FontColor","red"));
00212    cyclingColor=config.readEntry("CyclingColor",false);
00213    bold=config.readEntry("FontBold",false);
00214    italic=config.readEntry("FontItalic",false);
00215 }
00216 
00217 void KBannerSetup::fillFontSizes()
00218 {
00219     bool block = comboSizes->signalsBlocked();
00220     comboSizes->blockSignals( true );
00221     comboSizes->clear();
00222     int i = 0;
00223     sizes = QFontDatabase().pointSizes( fontFamily );
00224     sizes << 96 << 128 << 156 << 0;
00225     int current = 0;
00226     while ( sizes[i] )
00227        {
00228        QString num;
00229        num.setNum( sizes[i] );
00230        comboSizes->insertItem( i, num );
00231        if ( fontSize == sizes[i] ) // fontsize equals one of the defined ones
00232            {
00233             current = i;
00234            comboSizes->setCurrentIndex( current );
00235            slotSize( current );
00236            }
00237        i++;
00238        }
00239     if ( current == 0 ) // fontsize seems to be entered by hand
00240         {
00241        QString fsize;
00242        fsize.setNum( fontSize );
00243        comboSizes->setEditText(fsize);
00244        slotSizeEdit( fsize );
00245        }
00246     comboSizes->blockSignals( block );
00247 }
00248 
00249 void KBannerSetup::slotFamily( const QFont& f )
00250 {
00251        fontFamily = f.family();
00252         fillFontSizes(); // different font, different sizes
00253        if ( saver )
00254               saver->setFont( fontFamily, fontSize, fontColor, bold, italic );
00255 }
00256 
00257 void KBannerSetup::slotSize( int indx )
00258 {
00259        fontSize = sizes[indx];
00260        if ( saver )
00261               saver->setFont( fontFamily, fontSize, fontColor, bold, italic );
00262 }
00263 
00264 void KBannerSetup::slotSizeEdit( const QString& fs )
00265 {
00266        bool ok;
00267         fontSize = fs.toInt( &ok, 10 );
00268        if ( ok )
00269               if ( saver )
00270                      saver->setFont( fontFamily, fontSize, fontColor, bold, italic );
00271 }
00272 
00273 void KBannerSetup::slotColor( const QColor &col )
00274 {
00275     fontColor = col;
00276     if ( saver )
00277        saver->setColor(fontColor);
00278 }
00279 
00280 void KBannerSetup::slotCyclingColor(bool on)
00281 {
00282    colorPush->setEnabled(!on);
00283    cyclingColor=on;
00284 
00285    if ( saver )
00286    {
00287       saver->setCyclingColor( on );
00288       if ( !on )
00289          saver->setColor( fontColor );
00290    }
00291 }
00292 
00293 void KBannerSetup::slotBold( bool state )
00294 {
00295        bold = state;
00296        if ( saver )
00297               saver->setFont( fontFamily, fontSize, fontColor, bold, italic );
00298 }
00299 
00300 void KBannerSetup::slotItalic( bool state )
00301 {
00302        italic = state;
00303        if ( saver )
00304               saver->setFont( fontFamily, fontSize, fontColor, bold, italic );
00305 }
00306 
00307 void KBannerSetup::slotSpeed( int num )
00308 {
00309        speed = num;
00310        if ( saver )
00311               saver->setSpeed( speed );
00312 }
00313 
00314 void KBannerSetup::slotMessage( const QString &msg )
00315 {
00316        message = msg;
00317        if ( saver )
00318               saver->setMessage( message );
00319 }
00320 
00321 void KBannerSetup::slotTimeToggled( bool on )
00322 {
00323    ed->setEnabled(!on);
00324    showTime=on;
00325    if (saver)
00326    {
00327       if (showTime)
00328          saver->setTimeDisplay();
00329       else
00330       {
00331          message=ed->text();
00332          saver->setMessage(message);
00333       }
00334    }
00335 }
00336 
00337 // Ok pressed - save settings and exit
00338 void KBannerSetup::slotOk()
00339 {
00340        KConfigGroup config(KGlobal::config(), "Settings");
00341 
00342        config.writeEntry( "Speed", speed );
00343        config.writeEntry( "Message", message );
00344        config.writeEntry( "ShowTime", showTime );
00345        config.writeEntry( "FontFamily", fontFamily );
00346 
00347        QString fsize;
00348        if (fontSize == 0) // an non-number was entered in the font size combo
00349        {
00350               fontSize = 48;
00351        }
00352        fsize.setNum( fontSize );
00353        config.writeEntry( "FontSize", fsize );
00354 
00355        QString colName;
00356        colName.sprintf( "#%02x%02x%02x", fontColor.red(), fontColor.green(),
00357               fontColor.blue() );
00358        config.writeEntry( "FontColor", colName );
00359        config.writeEntry( "CyclingColor", cyclingColor );
00360        config.writeEntry( "FontBold", bold );
00361        config.writeEntry( "FontItalic", italic );
00362 
00363        config.sync();
00364 
00365        accept();
00366 }
00367 
00368 void KBannerSetup::slotHelp()
00369 {
00370        KMessageBox::about(this,
00371                           i18n("Banner Version 2.2.1\n\nWritten by Martin R. Jones 1996\nmjones@kde.org\nExtended by Alexander Neundorf 2000\nalexander.neundorf@rz.tu-ilmenau.de\n"));
00372 }
00373 
00374 //-----------------------------------------------------------------------------
00375 
00376 KBannerSaver::KBannerSaver( WId id ) : KScreenSaver( id )
00377 {
00378         QPalette palette;
00379         palette.setColor( backgroundRole(), Qt::black );
00380         setPalette( palette );
00381        krnd = new KRandomSequence();
00382        readSettings();
00383        initialize();
00384        timer.start( speed );
00385        connect( &timer, SIGNAL( timeout() ), SLOT( slotTimeout() ) );
00386        show();
00387 }
00388 
00389 KBannerSaver::~KBannerSaver()
00390 {
00391        timer.stop();
00392        delete krnd;
00393 }
00394 
00395 void KBannerSaver::setSpeed( int spd )
00396 {
00397        timer.stop();
00398        int inv = 100 - spd;
00399        speed = 1 + ((inv * inv) / 100);
00400        timer.start( speed );
00401 }
00402 
00403 void KBannerSaver::setFont( const QString& family, int size, const QColor &color,
00404               bool b, bool i )
00405 {
00406        fontFamily = family;
00407        fontSize = size;
00408        fontColor = color;
00409        bold = b;
00410        italic = i;
00411 
00412        initialize();
00413 }
00414 
00415 void KBannerSaver::setColor(QColor &color)
00416 {
00417     fontColor = color;
00418     cyclingColor = false;
00419     needUpdate = true;
00420 }
00421 
00422 void KBannerSaver::setCyclingColor( bool on )
00423 {
00424     cyclingColor = on;
00425     needUpdate = true;
00426 }
00427 
00428 void KBannerSaver::setMessage( const QString &msg )
00429 {
00430     showTime = false;
00431     message = msg;
00432     pixmapSize = QSize();
00433     setAttribute( Qt::WA_NoSystemBackground, false );
00434 }
00435 
00436 void KBannerSaver::setTimeDisplay()
00437 {
00438     showTime = true;
00439     pixmapSize = QSize();
00440     setAttribute( Qt::WA_NoSystemBackground, false );
00441 }
00442 
00443 // read settings from config file
00444 void KBannerSaver::readSettings()
00445 {
00446     KConfigGroup config(KGlobal::config(), "Settings");
00447 
00448    setSpeed( config.readEntry("Speed",50) );
00449 
00450    message=config.readEntry("Message","KDE");
00451 
00452    showTime=config.readEntry("ShowTime",false);
00453 
00454    fontFamily=config.readEntry("FontFamily",(QApplication::font()).family());
00455 
00456    fontSize=config.readEntry("FontSize",48);
00457 
00458    fontColor.setNamedColor(config.readEntry("FontColor","red"));
00459 
00460    cyclingColor=config.readEntry("CyclingColor",false);
00461 
00462    bold=config.readEntry("FontBold",false);
00463    italic=config.readEntry("FontItalic",false);
00464 
00465     if ( cyclingColor )
00466     {
00467         currentHue=0;
00468         fontColor.setHsv(0,SATURATION,VALUE);
00469     }
00470 }
00471 
00472 // initialize font
00473 void KBannerSaver::initialize()
00474 {
00475        fsize = fontSize * height() / QApplication::desktop()->height();
00476 
00477        font = QFont( fontFamily, fsize, bold ? QFont::Bold : QFont::Normal, italic );
00478 
00479        pixmapSize = QSize();
00480        setAttribute( Qt::WA_NoSystemBackground, false );
00481 
00482        xpos = width();
00483        ypos = fsize + (int) ((double)(height() - 3 * fsize) * krnd->getDouble());
00484        step = 2 * width() / QApplication::desktop()->width(); // 6 -> 2 -hhjb-
00485        if ( step == 0 )
00486               step = 1;
00487 }
00488 
00489 void KBannerSaver::slotTimeout()
00490 {
00491   update();
00492 }
00493 // erase old text and draw in new position
00494 void KBannerSaver::paintEvent(QPaintEvent *event)
00495 {
00496     Q_UNUSED( event )
00497 
00498     setAttribute( Qt::WA_NoSystemBackground ); // Only after requested clear is done
00499 
00500     if (cyclingColor)
00501     {
00502         int hueStep = speed/10;
00503         currentHue=(currentHue+hueStep)%360;
00504         fontColor.setHsv(currentHue,SATURATION,VALUE);
00505     }
00506     if (showTime)
00507     {
00508         QString new_message = KGlobal::locale()->formatTime(QTime::currentTime(), true);
00509        if( new_message != message )
00510            needUpdate = true;
00511        message = new_message;
00512     }
00513     if ( !pixmapSize.isValid() || cyclingColor || needUpdate || !testAttribute( Qt::WA_NoSystemBackground ) )
00514     {
00515         QRect rect = QFontMetrics( font ).boundingRect( message );
00516        rect.setWidth( rect.width() + step );
00517        if ( rect.width() > pixmapSize.width() )
00518            pixmapSize.setWidth( rect.width() );
00519        if ( rect.height() > pixmapSize.height() )
00520            pixmapSize.setHeight( rect.height() );
00521        pixmap = QPixmap( pixmapSize );
00522        pixmap.fill( Qt::black );
00523        QPainter p( &pixmap );
00524        p.setFont( font );
00525        p.setPen( fontColor );
00526        p.drawText( -rect.x(), -rect.y(), message );
00527        needUpdate = false;
00528     }
00529     xpos -= step;
00530 
00531     QPainter p( this );
00532 
00533     if ( xpos < -pixmapSize.width() ) {
00534        p.fillRect( xpos + step, ypos, pixmapSize.width(), pixmapSize.height(), Qt::black );
00535        xpos = width();
00536        ypos = fsize + (int) ((double)(height() - 3 * fsize) * krnd->getDouble());
00537     }
00538 
00539     p.drawPixmap( xpos, ypos, pixmap );
00540 }