1 //-----------------------------------------------------------------------------
3 // kbanner - Basic screen saver for KDE
5 // Copyright (c) Martin R. Jones 1996
7 // layout management added 1998/04/19 by Mario Weilguni <mweilguni@kde.org>
8 // clock function and color cycling added 2000/01/09 by Alexander Neundorf <alexander.neundorf@rz.tu-ilmenau.de>
9 // 2001/03/04 Converted to use libkscreensaver by Martin R. Jones
10 // 2002/04/07 Added random vertical position of text,
11 // changed horizontal step size to reduce jerkyness,
12 // text will return to right margin immediately (and not be drawn half a screen width off-screen)
13 // Harald H.-J. Bongartz <harald@bongartz.org>
14 // 2003/09/06 Converted to use KDialog - Nadeem Hasan <nhasan@kde.org>
18 #include <qlineedit.h>
19 #include <qcombobox.h>
20 #include <qcheckbox.h>
21 #include <qgroupbox.h>
24 #include <qdatetime.h>
25 #include <qfontdatabase.h>
28 #include <kapplication.h>
29 #include <krandomsequence.h>
33 #include <kmessagebox.h>
34 #include <kcolorbutton.h>
35 #include <kfontcombobox.h>
39 #include <QDesktopWidget>
40 // libkscreensaver interface
41 class KBannerSaverInterface
: public KScreenSaverInterface
46 virtual KAboutData
* aboutData() {
47 return new KAboutData( "kbanner.kss", 0, ki18n( "KBanner" ), "2.2.0", ki18n( "KBanner" ) );
51 virtual KScreenSaver
* create( WId id
)
53 return new KBannerSaver( id
);
56 virtual QDialog
* setup()
58 return new KBannerSetup();
62 int main( int argc
, char *argv
[] )
64 KBannerSaverInterface kss
;
65 return kScreenSaverMain( argc
, argv
, kss
);
68 //-----------------------------------------------------------------------------
70 KBannerSetup::KBannerSetup( QWidget
*parent
)
72 , saver( 0 ), ed(0), speed( 50 )
74 setButtons(Ok
|Cancel
|Help
);
76 setCaption(i18n( "Setup Banner Screen Saver" ));
78 setButtonText( Help
, i18n( "A&bout" ) );
81 QWidget
*main
= new QWidget(this);
86 QVBoxLayout
*tl
= new QVBoxLayout( main
);
87 QHBoxLayout
*tl1
= new QHBoxLayout();
89 QVBoxLayout
*tl11
= new QVBoxLayout();
92 QGroupBox
*group
= new QGroupBox( i18n("Font"), main
);
93 QVBoxLayout
*vbox
= new QVBoxLayout
;
94 group
->setLayout(vbox
);
95 QGridLayout
*gl
= new QGridLayout();
97 gl
->setSpacing(spacingHint());
99 label
= new QLabel( i18n("Family:"), group
);
100 gl
->addWidget(label
, 1, 0);
102 KFontComboBox
* comboFonts
= new KFontComboBox( group
);
103 comboFonts
->setCurrentFont( fontFamily
);
104 gl
->addWidget(comboFonts
, 1, 1);
105 connect( comboFonts
, SIGNAL(currentFontChanged( const QFont
& ) ),
106 SLOT( slotFamily( const QFont
& ) ) );
108 label
= new QLabel( i18n("Size:"), group
);
109 gl
->addWidget(label
, 2, 0);
111 comboSizes
= new QComboBox( group
);
112 comboSizes
->setEditable( true );
114 gl
->addWidget(comboSizes
, 2, 1);
115 connect( comboSizes
, SIGNAL( activated( int ) ), SLOT( slotSize( int ) ) );
116 connect( comboSizes
, SIGNAL( textChanged( const QString
& ) ),
117 SLOT( slotSizeEdit( const QString
& ) ) );
119 QCheckBox
*cb
= new QCheckBox( i18n("Bold"),
121 cb
->setChecked( bold
);
122 connect( cb
, SIGNAL( toggled( bool ) ), SLOT( slotBold( bool ) ) );
123 gl
->addWidget(cb
, 3, 0);
125 cb
= new QCheckBox( i18n("Italic"), group
);
126 cb
->setChecked( italic
);
127 gl
->addWidget(cb
, 3, 1);
128 connect( cb
, SIGNAL( toggled( bool ) ), SLOT( slotItalic( bool ) ) );
130 label
= new QLabel( i18n("Color:"), group
);
131 gl
->addWidget(label
, 4, 0);
133 colorPush
= new KColorButton( fontColor
, group
);
134 gl
->addWidget(colorPush
, 4, 1);
135 connect( colorPush
, SIGNAL( changed(const QColor
&) ),
136 SLOT( slotColor(const QColor
&) ) );
138 QCheckBox
*cyclingColorCb
=new QCheckBox(i18n("Cycling color"),group
);
139 cyclingColorCb
->setMinimumSize(cyclingColorCb
->sizeHint());
140 gl
->addWidget(cyclingColorCb
, 5, 5, 0, 1);
141 connect(cyclingColorCb
,SIGNAL(toggled(bool)),this,SLOT(slotCyclingColor(bool)));
142 cyclingColorCb
->setChecked(cyclingColor
);
144 preview
= new QWidget( main
);
145 preview
->setFixedSize( 220, 170 );
148 palette
.setColor( preview
->backgroundRole(), Qt::black
);
149 preview
->setPalette( palette
);
151 preview
->show(); // otherwise saver does not get correct size
152 saver
= new KBannerSaver( preview
->winId() );
153 tl1
->addWidget(preview
);
155 tl11
->addWidget(group
);
157 label
= new QLabel( i18n("Speed:"), main
);
159 tl11
->addWidget(label
);
161 QSlider
*sb
= new QSlider( Qt::Horizontal
, main
);
166 sb
->setMinimumWidth( 180);
167 sb
->setFixedHeight(20);
168 sb
->setTickPosition(QSlider::TicksBelow
);
169 sb
->setTickInterval(10);
171 connect( sb
, SIGNAL( valueChanged( int ) ), SLOT( slotSpeed( int ) ) );
173 QHBoxLayout
*tl2
= new QHBoxLayout
;
176 label
= new QLabel( i18n("Message:"), main
);
177 tl2
->addWidget(label
);
179 ed
= new QLineEdit( main
);
181 ed
->setText( message
);
182 connect( ed
, SIGNAL( textChanged( const QString
& ) ),
183 SLOT( slotMessage( const QString
& ) ) );
185 QCheckBox
*timeCb
=new QCheckBox( i18n("Show current time"), main
);
186 timeCb
->setFixedSize(timeCb
->sizeHint());
187 tl
->addWidget(timeCb
,0,Qt::AlignLeft
);
188 connect(timeCb
,SIGNAL(toggled(bool)),this,SLOT(slotTimeToggled(bool)));
189 timeCb
->setChecked(showTime
);
190 connect(this,SIGNAL(okClicked()),this,SLOT(slotOk()));
191 connect(this,SIGNAL(helpClicked()),this,SLOT(slotHelp()));
195 // read settings from config file
196 void KBannerSetup::readSettings()
198 KConfigGroup
config(KGlobal::config(), "Settings");
200 speed
=config
.readEntry("Speed",50);
201 /* if ( speed > 100 )
203 else if ( speed < 50 )
206 message
=config
.readEntry("Message","KDE");
207 showTime
=config
.readEntry("ShowTime",false);
208 fontFamily
=config
.readEntry("FontFamily",(QApplication::font()).family());
209 fontSize
=config
.readEntry("FontSize",48);
210 fontColor
.setNamedColor(config
.readEntry("FontColor","red"));
211 cyclingColor
=config
.readEntry("CyclingColor",false);
212 bold
=config
.readEntry("FontBold",false);
213 italic
=config
.readEntry("FontItalic",false);
216 void KBannerSetup::fillFontSizes()
218 bool block
= comboSizes
->signalsBlocked();
219 comboSizes
->blockSignals( true );
222 sizes
= QFontDatabase().pointSizes( fontFamily
);
223 sizes
<< 96 << 128 << 156 << 0;
228 num
.setNum( sizes
[i
] );
229 comboSizes
->insertItem( i
, num
);
230 if ( fontSize
== sizes
[i
] ) // fontsize equals one of the defined ones
233 comboSizes
->setCurrentIndex( current
);
238 if ( current
== 0 ) // fontsize seems to be entered by hand
241 fsize
.setNum( fontSize
);
242 comboSizes
->setEditText(fsize
);
243 slotSizeEdit( fsize
);
245 comboSizes
->blockSignals( block
);
248 void KBannerSetup::slotFamily( const QFont
& f
)
250 fontFamily
= f
.family();
251 fillFontSizes(); // different font, different sizes
253 saver
->setFont( fontFamily
, fontSize
, fontColor
, bold
, italic
);
256 void KBannerSetup::slotSize( int indx
)
258 fontSize
= sizes
[indx
];
260 saver
->setFont( fontFamily
, fontSize
, fontColor
, bold
, italic
);
263 void KBannerSetup::slotSizeEdit( const QString
& fs
)
266 fontSize
= fs
.toInt( &ok
, 10 );
269 saver
->setFont( fontFamily
, fontSize
, fontColor
, bold
, italic
);
272 void KBannerSetup::slotColor( const QColor
&col
)
276 saver
->setColor(fontColor
);
279 void KBannerSetup::slotCyclingColor(bool on
)
281 colorPush
->setEnabled(!on
);
286 saver
->setCyclingColor( on
);
288 saver
->setColor( fontColor
);
292 void KBannerSetup::slotBold( bool state
)
296 saver
->setFont( fontFamily
, fontSize
, fontColor
, bold
, italic
);
299 void KBannerSetup::slotItalic( bool state
)
303 saver
->setFont( fontFamily
, fontSize
, fontColor
, bold
, italic
);
306 void KBannerSetup::slotSpeed( int num
)
310 saver
->setSpeed( speed
);
313 void KBannerSetup::slotMessage( const QString
&msg
)
317 saver
->setMessage( message
);
320 void KBannerSetup::slotTimeToggled( bool on
)
327 saver
->setTimeDisplay();
331 saver
->setMessage(message
);
336 // Ok pressed - save settings and exit
337 void KBannerSetup::slotOk()
339 KConfigGroup
config(KGlobal::config(), "Settings");
341 config
.writeEntry( "Speed", speed
);
342 config
.writeEntry( "Message", message
);
343 config
.writeEntry( "ShowTime", showTime
);
344 config
.writeEntry( "FontFamily", fontFamily
);
347 if (fontSize
== 0) // an non-number was entered in the font size combo
351 fsize
.setNum( fontSize
);
352 config
.writeEntry( "FontSize", fsize
);
355 colName
.sprintf( "#%02x%02x%02x", fontColor
.red(), fontColor
.green(),
357 config
.writeEntry( "FontColor", colName
);
358 config
.writeEntry( "CyclingColor", cyclingColor
);
359 config
.writeEntry( "FontBold", bold
);
360 config
.writeEntry( "FontItalic", italic
);
367 void KBannerSetup::slotHelp()
369 KMessageBox::about(this,
370 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"));
373 //-----------------------------------------------------------------------------
375 KBannerSaver::KBannerSaver( WId id
) : KScreenSaver( id
)
378 palette
.setColor( backgroundRole(), Qt::black
);
379 setPalette( palette
);
380 krnd
= new KRandomSequence();
383 timer
.start( speed
);
384 connect( &timer
, SIGNAL( timeout() ), SLOT( slotTimeout() ) );
388 KBannerSaver::~KBannerSaver()
394 void KBannerSaver::setSpeed( int spd
)
398 speed
= 1 + ((inv
* inv
) / 100);
399 timer
.start( speed
);
402 void KBannerSaver::setFont( const QString
& family
, int size
, const QColor
&color
,
414 void KBannerSaver::setColor(QColor
&color
)
417 cyclingColor
= false;
421 void KBannerSaver::setCyclingColor( bool on
)
427 void KBannerSaver::setMessage( const QString
&msg
)
431 pixmapSize
= QSize();
432 setAttribute( Qt::WA_NoSystemBackground
, false );
435 void KBannerSaver::setTimeDisplay()
438 pixmapSize
= QSize();
439 setAttribute( Qt::WA_NoSystemBackground
, false );
442 // read settings from config file
443 void KBannerSaver::readSettings()
445 KConfigGroup
config(KGlobal::config(), "Settings");
447 setSpeed( config
.readEntry("Speed",50) );
449 message
=config
.readEntry("Message","KDE");
451 showTime
=config
.readEntry("ShowTime",false);
453 fontFamily
=config
.readEntry("FontFamily",(QApplication::font()).family());
455 fontSize
=config
.readEntry("FontSize",48);
457 fontColor
.setNamedColor(config
.readEntry("FontColor","red"));
459 cyclingColor
=config
.readEntry("CyclingColor",false);
461 bold
=config
.readEntry("FontBold",false);
462 italic
=config
.readEntry("FontItalic",false);
467 fontColor
.setHsv(0,SATURATION
,VALUE
);
472 void KBannerSaver::initialize()
474 fsize
= fontSize
* height() / QApplication::desktop()->height();
476 font
= QFont( fontFamily
, fsize
, bold
? QFont::Bold
: QFont::Normal
, italic
);
478 pixmapSize
= QSize();
479 setAttribute( Qt::WA_NoSystemBackground
, false );
482 ypos
= fsize
+ (int) ((double)(height() - 3 * fsize
) * krnd
->getDouble());
483 step
= 2 * width() / QApplication::desktop()->width(); // 6 -> 2 -hhjb-
488 void KBannerSaver::slotTimeout()
492 // erase old text and draw in new position
493 void KBannerSaver::paintEvent(QPaintEvent
*event
)
497 setAttribute( Qt::WA_NoSystemBackground
); // Only after requested clear is done
501 int hueStep
= speed
/10;
502 currentHue
=(currentHue
+hueStep
)%360;
503 fontColor
.setHsv(currentHue
,SATURATION
,VALUE
);
507 QString new_message
= KGlobal::locale()->formatTime(QTime::currentTime(), true);
508 if( new_message
!= message
)
510 message
= new_message
;
512 if ( !pixmapSize
.isValid() || cyclingColor
|| needUpdate
|| !testAttribute( Qt::WA_NoSystemBackground
) )
514 QRect rect
= QFontMetrics( font
).boundingRect( message
);
515 rect
.setWidth( rect
.width() + step
);
516 if ( rect
.width() > pixmapSize
.width() )
517 pixmapSize
.setWidth( rect
.width() );
518 if ( rect
.height() > pixmapSize
.height() )
519 pixmapSize
.setHeight( rect
.height() );
520 pixmap
= QPixmap( pixmapSize
);
521 pixmap
.fill( Qt::black
);
522 QPainter
p( &pixmap
);
524 p
.setPen( fontColor
);
525 p
.drawText( -rect
.x(), -rect
.y(), message
);
532 if ( xpos
< -pixmapSize
.width() ) {
533 p
.fillRect( xpos
+ step
, ypos
, pixmapSize
.width(), pixmapSize
.height(), Qt::black
);
535 ypos
= fsize
+ (int) ((double)(height() - 3 * fsize
) * krnd
->getDouble());
538 p
.drawPixmap( xpos
, ypos
, pixmap
);