Back to index

kdeartwork  4.3.2
slideshow.cpp
Go to the documentation of this file.
00001 /* Slide Show Screen Saver
00002  *  (C) 1999 Stefan Taferner <taferner@kde.org>
00003  *  (C) 2001 Martin R. Jones <mjones@kde.org>
00004  *  (C) 2003 Chris Howells <howells@kde.org>
00005  *  (C) 2003 Sven Leiber <s.leiber@web.de>
00006  *
00007  * This code is under GPL
00008  *
00009  * 2001/03/04 Converted to libkscreensaver by Martin R. Jones.
00010  */
00011 
00012 
00013 #include <QDir>
00014 #include <QColor>
00015 #include <QLabel>
00016 #include <QLayout>
00017 #include <QFile>
00018 #include <QFileInfo>
00019 #include <QCheckBox>
00020 #include <QComboBox>
00021 #include <QSpinBox>
00022 #include <QDesktopWidget>
00023 #include <QImage>
00024 #include <QPainter>
00025 #include <QPixmap>
00026 #include <QPolygon>
00027 
00028 
00029 #include <kconfig.h>
00030 #include <kglobal.h>
00031 #include <kapplication.h>
00032 #include <klocale.h>
00033 #include <kmessagebox.h>
00034 #include <kimageio.h>
00035 #include <kfiledialog.h>
00036 #include <kstandarddirs.h>
00037 #include <kurlrequester.h>
00038 #include <kaboutdata.h>
00039 #include <kaboutapplicationdialog.h>
00040 #include <kdebug.h>
00041 #include <krandom.h>
00042 
00043 #include <stdlib.h>
00044 #include <assert.h>
00045 #include <math.h>
00046 #include <time.h>
00047 
00048 #include "slideshow.h"
00049 #include "slideshow.moc"
00050 
00051 
00052 #define SLIDESHOW_VERSION "2.3.0"
00053 static const char version[] = SLIDESHOW_VERSION;
00054 static const char description[] = I18N_NOOP("KSlideshow");
00055 
00056 static KAboutData* s_aboutData = 0;
00057 
00058 // libkscreensaver interface
00059 class KSlideShowSaverInterface : public KScreenSaverInterface
00060 {
00061 public:
00062     virtual KAboutData* aboutData() {
00063         return s_aboutData;
00064     }
00065 
00066     virtual KScreenSaver* create( WId id )
00067     {
00068         return new kSlideShowSaver( id );
00069     }
00070 
00071     virtual QDialog* setup()
00072     {
00073         return new kSlideShowSetup();
00074     }
00075 };
00076 
00077 int main( int argc, char *argv[] )
00078 {
00079     s_aboutData = new KAboutData( "kslideshow.kss", "klock", ki18n("SlideShow"),
00080                                   version, ki18n(description), KAboutData::License_GPL,
00081                                   ki18n("(c) 1999-2003, The KDE Team") );
00082     s_aboutData->addAuthor(ki18n("Stefan Taferner"), KLocalizedString(), "taferner@kde.org");
00083     s_aboutData->addAuthor(ki18n("Chris Howells"), KLocalizedString(), "howells@kde.org");
00084     s_aboutData->addAuthor(ki18n("Sven Leiber"), KLocalizedString(), "s.leiber@web.de");
00085 
00086     KSlideShowSaverInterface kss;
00087     return kScreenSaverMain( argc, argv, kss );
00088 }
00089 
00090 
00091 //=============================================================================
00092 //  Class kSlideShowSaver
00093 //=============================================================================
00094 kSlideShowSaver::kSlideShowSaver( WId id ): KScreenSaver(id)
00095 {
00096   mEffect = NULL;
00097   mNumEffects = 0;
00098   mIntArray = NULL;
00099   registerEffects();
00100 
00101   readConfig();
00102   initNextScreen();
00103 
00104   mFileIdx = 0;
00105 
00106   mEffectRunning = false;
00107 
00108   mTimer.setSingleShot(true);
00109   connect(&mTimer, SIGNAL(timeout()), SLOT(slotTimeout()));
00110   mTimer.start(10);
00111 
00112   QDesktopWidget *d = QApplication::desktop();
00113   if(geometry() == d->geometry() && d->numScreens() > 1)
00114   {
00115     for(int i = 0; i < d->numScreens(); ++i)
00116     {
00117       QRect s = d->screenGeometry(i);
00118       mGeoList.append(mScreenGeo(s.width(), s.height(), s.topLeft().x(), s.topLeft().y()));
00119     }
00120   }
00121   else
00122   {
00123     mGeoList.append(mScreenGeo(width(), height(), 0, 0));
00124   }
00125   setAttribute(Qt::WA_NoSystemBackground);
00126   createNextScreen();
00127   show();
00128 }
00129 
00130 
00131 
00132 //----------------------------------------------------------------------------
00133 kSlideShowSaver::~kSlideShowSaver()
00134 {
00135   delete [] mIntArray;
00136   delete [] mEffectList;
00137 }
00138 
00139 
00140 //-----------------------------------------------------------------------------
00141 void kSlideShowSaver::initNextScreen()
00142 {
00143   int w, h;
00144 
00145   w = width();
00146   h = height();
00147   mNextScreen = QPixmap(w, h);
00148 }
00149 
00150 
00151 //-----------------------------------------------------------------------------
00152 void kSlideShowSaver::readConfig()
00153 {
00154   KConfigGroup config(KGlobal::config(), "Settings");
00155   mShowRandom = config.readEntry("ShowRandom", true);
00156   mZoomImages = config.readEntry("ZoomImages", false);
00157   mPrintName = config.readEntry("PrintName", true);
00158   mDirectory = config.readPathEntry("Directory", KGlobal::dirs()->findDirs("wallpaper", "").last());
00159   mDelay = config.readEntry("Delay", 10) * 1000;
00160   mSubdirectory = config.readEntry("SubDirectory", false);
00161   mRandomPosition = config.readEntry("RandomPosition", false);
00162 
00163   loadDirectory();
00164 }
00165 
00166 
00167 //----------------------------------------------------------------------------
00168 void kSlideShowSaver::registerEffects()
00169 {
00170   int i = 0;
00171 
00172   mEffectList = new EffectMethod[64];
00173   mEffectList[i++] = &kSlideShowSaver::effectChessboard;
00174   mEffectList[i++] = &kSlideShowSaver::effectMultiCircleOut;
00175   mEffectList[i++] = &kSlideShowSaver::effectSpiralIn;
00176   mEffectList[i++] = &kSlideShowSaver::effectSweep;
00177   mEffectList[i++] = &kSlideShowSaver::effectMeltdown;
00178   mEffectList[i++] = &kSlideShowSaver::effectCircleOut;
00179   mEffectList[i++] = &kSlideShowSaver::effectBlobs;
00180   mEffectList[i++] = &kSlideShowSaver::effectHorizLines;
00181   mEffectList[i++] = &kSlideShowSaver::effectVertLines;
00182   mEffectList[i++] = &kSlideShowSaver::effectRandom;
00183   mEffectList[i++] = &kSlideShowSaver::effectGrowing;
00184   mEffectList[i++] = &kSlideShowSaver::effectIncomingEdges;
00185 
00186   mNumEffects = i;
00187   // mNumEffects = 1;  //...for testing
00188 }
00189 
00190 
00191 //----------------------------------------------------------------------------
00192 int kSlideShowSaver::effectMultiCircleOut(bool aInit)
00193 {
00194   int x, y, i;
00195   double alpha;
00196   static QPolygon pa(4);
00197 
00198   if (aInit)
00199   {
00200     mw = width();
00201     mh = height();
00202     mx = mw;
00203     my = mh>>1;
00204     pa.setPoint(0, mw>>1, mh>>1);
00205     pa.setPoint(3, mw>>1, mh>>1);
00206     mfy = sqrt((double)mw*mw + mh*mh) / 2;
00207     mi  = KRandom::random()%15 + 2;
00208     mfd = M_PI*2/mi;
00209     mAlpha = mfd;
00210     mwait = 10 * mi;
00211     mfx = M_PI/32;  // divisor must be powers of 8
00212   }
00213 
00214   if (mAlpha < 0)
00215   {
00216     showNextScreen();
00217     return -1;
00218   }
00219 
00220   QPainter p(this);
00221   QBrush brush;
00222   brush.setTexture(mNextScreen);
00223   p.setBrush(brush);
00224   p.setPen(Qt::NoPen);
00225 
00226   for (alpha=mAlpha, i=mi; i>=0; i--, alpha+=mfd)
00227   {
00228     x = (mw>>1) + (int)(mfy * cos(-alpha));
00229     y = (mh>>1) + (int)(mfy * sin(-alpha));
00230 
00231     mx = (mw>>1) + (int)(mfy * cos(-alpha + mfx));
00232     my = (mh>>1) + (int)(mfy * sin(-alpha + mfx));
00233 
00234     pa.setPoint(1, x, y);
00235     pa.setPoint(2, mx, my);
00236 
00237     p.drawPolygon(pa);
00238   }
00239   mAlpha -= mfx;
00240 
00241   return mwait;
00242 }
00243 
00244 
00245 //----------------------------------------------------------------------------
00246 int kSlideShowSaver::effectSpiralIn(bool aInit)
00247 {
00248   if (aInit)
00249   {
00250     mw = width();
00251     mh = height();
00252     mix = mw / 8;
00253     miy = mh / 8;
00254     mx0 = 0;
00255     mx1 = mw - mix;
00256     my0 = miy;
00257     my1 = mh - miy;
00258     mdx = mix;
00259     mdy = 0;
00260     mi = 0;
00261     mj = 16 * 16;
00262     mx = 0;
00263     my = 0;
00264   }
00265 
00266   if (mi==0 && mx0>=mx1)
00267   {
00268     showNextScreen();
00269     return -1;
00270   }
00271 
00272   if (mi==0 && mx>=mx1) // switch to: down on right side
00273   {
00274     mi = 1;
00275     mdx = 0;
00276     mdy = miy;
00277     mx1 -= mix;
00278   }
00279   else if (mi==1 && my>=my1) // switch to: right to left on bottom side
00280   {
00281     mi = 2;
00282     mdx = -mix;
00283     mdy = 0;
00284     my1 -= miy;
00285   }
00286   else if (mi==2 && mx<=mx0) // switch to: up on left side
00287   {
00288     mi = 3;
00289     mdx = 0;
00290     mdy = -miy;
00291     mx0 += mix;
00292   }
00293   else if (mi==3 && my<=my0) // switch to: left to right on top side
00294   {
00295     mi = 0;
00296     mdx = mix;
00297     mdy = 0;
00298     my0 += miy;
00299   }
00300 
00301   QPainter p(this);
00302   p.drawPixmap(mx, my, mNextScreen, mx, my, mix, miy);
00303 
00304   mx += mdx;
00305   my += mdy;
00306   mj--;
00307 
00308   return 8;
00309 }
00310 
00311 
00312 //----------------------------------------------------------------------------
00313 int kSlideShowSaver::effectMeltdown(bool aInit)
00314 {
00315   int i, x, y;
00316   bool done;
00317 
00318   if (aInit)
00319   {
00320     delete [] mIntArray;
00321     mw = width();
00322     mh = height();
00323     mdx = 4;
00324     mdy = 16;
00325     mix = mw / mdx;
00326     mIntArray = new int[mix];
00327     for (i=mix-1; i>=0; i--)
00328       mIntArray[i] = 0;
00329   }
00330 
00331   done = true;
00332 
00333   QPainter p(this);
00334   for (i=0,x=0; i<mix; i++,x+=mdx)
00335   {
00336     y = mIntArray[i];
00337     if (y >= mh) continue;
00338     done = false;
00339     if ((KRandom::random()&15) < 6) continue;
00340     p.drawPixmap(x, y, mNextScreen, x, y, mdx, mdy);
00341     mIntArray[i] += mdy;
00342   }
00343 
00344   if (done)
00345   {
00346     delete [] mIntArray;
00347     mIntArray = NULL;
00348     return -1;
00349   }
00350 
00351   return 15;
00352 }
00353 
00354 
00355 //----------------------------------------------------------------------------
00356 int kSlideShowSaver::effectCircleOut(bool aInit)
00357 {
00358   int x, y;
00359   static QPolygon pa(4);
00360 
00361   if (aInit)
00362   {
00363     mw = width();
00364     mh = height();
00365     mx = mw;
00366     my = mh>>1;
00367     mAlpha = 2*M_PI;
00368     pa.setPoint(0, mw>>1, mh>>1);
00369     pa.setPoint(3, mw>>1, mh>>1);
00370     mfx = M_PI/16;  // divisor must be powers of 8
00371     mfy = sqrt((double)mw*mw + mh*mh) / 2;
00372   }
00373 
00374   if (mAlpha < 0)
00375   {
00376     showNextScreen();
00377     return -1;
00378   }
00379 
00380   x = mx;
00381   y = my;
00382   mx = (mw>>1) + (int)(mfy * cos(mAlpha));
00383   my = (mh>>1) + (int)(mfy * sin(mAlpha));
00384   mAlpha -= mfx;
00385 
00386   pa.setPoint(1, x, y);
00387   pa.setPoint(2, mx, my);
00388 
00389   QBrush brush;
00390   brush.setTexture(mNextScreen);
00391   QPainter p(this);
00392   p.setBrush(brush);
00393   p.setPen(Qt::NoPen);
00394 
00395   p.drawPolygon(pa);
00396 
00397   return 20;
00398 }
00399 
00400 
00401 //----------------------------------------------------------------------------
00402 int kSlideShowSaver::effectSweep(bool aInit)
00403 {
00404   int w, h, x, y, i;
00405 
00406   if (aInit)
00407   {
00408     // subtype: 0=sweep right to left, 1=sweep left to right
00409     //          2=sweep bottom to top, 3=sweep top to bottom
00410     mSubType = KRandom::random() % 4;
00411     mw  = width();
00412     mh  = height();
00413     mdx = (mSubType==1 ? 16 : -16);
00414     mdy = (mSubType==3 ? 16 : -16);
00415     mx  = (mSubType==1 ? 0 : mw);
00416     my  = (mSubType==3 ? 0 : mh);
00417   }
00418 
00419   QPainter p(this);
00420   if (mSubType==0 || mSubType==1)
00421   {
00422     // horizontal sweep
00423     if ((mSubType==0 && mx < -64) ||
00424        (mSubType==1 && mx > mw+64))
00425     {
00426        return -1;
00427     }
00428     for (w=2,i=4,x=mx; i>0; i--, w<<=1, x-=mdx)
00429     {
00430       p.drawPixmap(x, 0, mNextScreen, x, 0, w, mh);
00431     }
00432     mx += mdx;
00433   }
00434   else
00435   {
00436     // vertical sweep
00437     if ((mSubType==2 && my < -64) ||
00438        (mSubType==3 && my > mh+64))
00439     {
00440       return -1;
00441     }
00442     for (h=2,i=4,y=my; i>0; i--, h<<=1, y-=mdy)
00443     {
00444       p.drawPixmap(0, y, mNextScreen, 0, y, mw, h);
00445     }
00446     my += mdy;
00447   }
00448 
00449   return 20;
00450 }
00451 
00452 
00453 //----------------------------------------------------------------------------
00454 int kSlideShowSaver::effectBlobs(bool aInit)
00455 {
00456   int r;
00457 
00458   if (aInit)
00459   {
00460     mAlpha = M_PI * 2;
00461     mw = width();
00462     mh = height();
00463     mi = 150;
00464   }
00465 
00466   if (mi <= 0)
00467   {
00468     showNextScreen();
00469     return -1;
00470   }
00471 
00472   mx = KRandom::random() % mw;
00473   my = KRandom::random() % mh;
00474   r = (KRandom::random() % 200) + 50;
00475 
00476   QBrush brush;
00477   brush.setTexture(mNextScreen);
00478   QPainter p(this);
00479   p.setBrush(brush);
00480   p.setPen(Qt::NoPen);
00481   p.drawEllipse(mx-r, my-r, r, r);
00482 
00483   mi--;
00484 
00485   return 10;
00486 }
00487 
00488 
00489 //----------------------------------------------------------------------------
00490 int kSlideShowSaver::effectRandom(bool /*aInit*/)
00491 {
00492   int x, y, i, w, h, fact, sz;
00493 
00494   fact = (KRandom::random() % 3) + 1;
00495 
00496   w = width() >> fact;
00497   h = height() >> fact;
00498   sz = 1 << fact;
00499 
00500   QPainter p(this);
00501   for (i = (w*h)<<1; i > 0; i--)
00502   {
00503     x = (KRandom::random() % w) << fact;
00504     y = (KRandom::random() % h) << fact;
00505     p.drawPixmap(x, y, mNextScreen, x, y, sz, sz);
00506   }
00507   p.end();
00508   showNextScreen();
00509 
00510   return -1;
00511 }
00512 
00513 
00514 //----------------------------------------------------------------------------
00515 int kSlideShowSaver::effectGrowing(bool aInit)
00516 {
00517   if (aInit)
00518   {
00519     mw = width();
00520     mh = height();
00521     mx = mw >> 1;
00522     my = mh >> 1;
00523     mi = 0;
00524     mfx = mx / 100.0;
00525     mfy = my / 100.0;
00526   }
00527 
00528   mx = (mw>>1) - (int)(mi * mfx);
00529   my = (mh>>1) - (int)(mi * mfy);
00530   mi++;
00531 
00532   if (mx<0 || my<0)
00533   {
00534     showNextScreen();
00535     return -1;
00536   }
00537 
00538   if((mw - (mx<<1) == 0) && (mh - (my<<1) == 0))
00539     return 1;
00540 
00541   QPainter p(this);
00542   p.drawPixmap(mx, my, mNextScreen, mx, my, mw - (mx<<1), mh - (my<<1));
00543 
00544   return 20;
00545 }
00546 
00547 
00548 //----------------------------------------------------------------------------
00549 int kSlideShowSaver::effectChessboard(bool aInit)
00550 {
00551   int y;
00552 
00553   if (aInit)
00554   {
00555     mw  = width();
00556     mh  = height();
00557     mdx = 8;         // width of one tile
00558     mdy = 8;         // height of one tile
00559     mj  = (mw+mdx-1)/mdx; // number of tiles
00560     mx  = mj*mdx;    // shrinking x-offset from screen border
00561     mix = 0;         // growing x-offset from screen border
00562     miy = 0;         // 0 or mdy for growing tiling effect
00563     my  = mj&1 ? 0 : mdy; // 0 or mdy for shrinking tiling effect
00564     mwait = 800 / mj; // timeout between effects
00565   }
00566 
00567   if (mix >= mw)
00568   {
00569     showNextScreen();
00570     return -1;
00571   }
00572 
00573   mix += mdx;
00574   mx  -= mdx;
00575   miy = miy ? 0 : mdy;
00576   my  = my ? 0 : mdy;
00577 
00578   QPainter p(this);
00579   for (y=0; y<mw; y+=(mdy<<1))
00580   {
00581     p.drawPixmap(mix, y+miy, mNextScreen, mix, y+miy, mdx, mdy);
00582     p.drawPixmap(mx, y+my, mNextScreen, mx, y+my, mdx, mdy);
00583   }
00584 
00585   return mwait;
00586 }
00587 
00588 
00589 //----------------------------------------------------------------------------
00590 int kSlideShowSaver::effectIncomingEdges(bool aInit)
00591 {
00592   int x1, y1;
00593 
00594   if (aInit)
00595   {
00596     mw = width();
00597     mh = height();
00598     mix = mw >> 1;
00599     miy = mh >> 1;
00600     mfx = mix / 100.0;
00601     mfy = miy / 100.0;
00602     mi = 0;
00603     mSubType = KRandom::random() & 1;
00604   }
00605 
00606   mx = (int)(mfx * mi);
00607   my = (int)(mfy * mi);
00608 
00609   if (mx>mix || my>miy)
00610   {
00611     showNextScreen();
00612     return -1;
00613   }
00614 
00615   x1 = mw - mx;
00616   y1 = mh - my;
00617   mi++;
00618 
00619   if((mx==0) && (my==0))
00620     return 1; // otherwise drawPixmap draws the bottom-right of mNextScreen
00621 
00622   QPainter p(this);
00623   if (mSubType)
00624   {
00625     // moving image edges
00626     p.drawPixmap(0, 0, mNextScreen, mix-mx, miy-my, mx, my);
00627     p.drawPixmap(x1, 0, mNextScreen, mix, miy-my, mx, my);
00628     p.drawPixmap(0, y1, mNextScreen, mix-mx, miy, mx, my);
00629     p.drawPixmap(x1, y1, mNextScreen, mix, miy, mx, my);
00630   }
00631   else
00632   {
00633     // fixed image edges
00634     p.drawPixmap(0, 0, mNextScreen,  0,  0, mx, my);
00635     p.drawPixmap(x1, 0, mNextScreen, x1,  0, mx, my);
00636     p.drawPixmap(0, y1, mNextScreen,  0, y1, mx, my);
00637     p.drawPixmap(x1, y1, mNextScreen, x1, y1, mx, my);
00638   }
00639   return 20;
00640 }
00641 
00642 
00643 //----------------------------------------------------------------------------
00644 int kSlideShowSaver::effectHorizLines(bool aInit)
00645 {
00646   static int iyPos[] = { 0, 4, 2, 6, 1, 5, 3, 7, -1 };
00647   int y;
00648 
00649   if (aInit)
00650   {
00651     mw = width();
00652     mh = height();
00653     mi = 0;
00654   }
00655 
00656   if (iyPos[mi] < 0) return -1;
00657 
00658   QPainter p(this);
00659   for (y=iyPos[mi]; y<mh; y+=8)
00660   {
00661     p.drawPixmap(0, y, mNextScreen, 0, y, mw, 1);
00662   }
00663 
00664   mi++;
00665   if (iyPos[mi] >= 0) return 160;
00666   return -1;
00667 }
00668 
00669 
00670 //----------------------------------------------------------------------------
00671 int kSlideShowSaver::effectVertLines(bool aInit)
00672 {
00673   static int ixPos[] = { 0, 4, 2, 6, 1, 5, 3, 7, -1 };
00674   int x;
00675 
00676   if (aInit)
00677   {
00678     mw = width();
00679     mh = height();
00680     mi = 0;
00681   }
00682 
00683   if (ixPos[mi] < 0) return -1;
00684 
00685   QPainter p(this);
00686   for (x=ixPos[mi]; x<mw; x+=8)
00687   {
00688     p.drawPixmap(x, 0, mNextScreen, x, 0, 1, mh);
00689   }
00690 
00691   mi++;
00692   if (ixPos[mi] >= 0) return 160;
00693   return -1;
00694 }
00695 
00696 
00697 //-----------------------------------------------------------------------------
00698 void kSlideShowSaver::restart()
00699 {
00700   mEffectRunning = false;
00701   mEffect = NULL;
00702   update();
00703 }
00704 
00705 
00706 //-----------------------------------------------------------------------------
00707 void kSlideShowSaver::slotTimeout()
00708 {
00709   update();
00710 }
00711 
00712 
00713 //-----------------------------------------------------------------------------
00714 void kSlideShowSaver::paintEvent(QPaintEvent *)
00715 {
00716   int tmout = -1;
00717   int i;
00718 
00719   if (mEffectRunning)
00720   {
00721     tmout = (this->*mEffect)(false);
00722   }
00723   else
00724   {
00725     loadNextImage();
00726     createNextScreen();
00727 
00728     if (mNumEffects > 1) i = KRandom::random() % mNumEffects;
00729     else i = 0;
00730 
00731     mEffect = mEffectList[i];
00732     mEffectRunning = true;
00733     tmout = (this->*mEffect)(true);
00734   }
00735   if (tmout <= 0)
00736   {
00737     tmout = mDelay;
00738     mEffectRunning = false;
00739   }
00740   mTimer.start(tmout);
00741 }
00742 
00743 
00744 //----------------------------------------------------------------------------
00745 void kSlideShowSaver::showNextScreen()
00746 {
00747   QPainter p(this);
00748   p.drawPixmap(0, 0, mNextScreen, 0, 0, mNextScreen.width(), mNextScreen.height());
00749 }
00750 
00751 
00752 //----------------------------------------------------------------------------
00753 void kSlideShowSaver::createNextScreen()
00754 {
00755   QPainter p;
00756   int ww, wh, iw, ih, x, y;
00757   double fx, fy;
00758 
00759   if (mNextScreen.size() != size())
00760     mNextScreen = QPixmap(size());
00761 
00762   mNextScreen.fill(Qt::black);
00763 
00764   p.begin(&mNextScreen);
00765 
00766   foreach( const mScreenGeo& geo, mGeoList )
00767   {
00768     loadNextImage();
00769 
00770     iw = mImage.width();
00771     ih = mImage.height();
00772     ww = geo.mW;
00773     wh = geo.mH;
00774 
00775     if (mFileList.isEmpty())
00776     {
00777       p.setPen(QColor("white"));
00778       p.drawText(20 + (KRandom::random() % (ww>>1)), 20 + (KRandom::random() % (wh>>1)),
00779                 i18n("No images found"));
00780     }
00781     else
00782     {
00783       if (mZoomImages)
00784       {
00785         fx = (double)ww / iw;
00786         fy = (double)wh / ih;
00787         if (fx > fy) fx = fy;
00788         if (fx > 2) fx = 2;
00789         iw = (int)(iw * fx);
00790         ih = (int)(ih * fx);
00791         QImage scaledImg = mImage.scaled(iw, ih,
00792             Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
00793 
00794         x = ((ww - iw) >> 1) + geo.mXorg;
00795         y = ((wh - ih) >> 1) + geo.mYorg;
00796 
00797         p.drawImage(x, y, scaledImg);
00798       }
00799       else
00800       {
00801         if(iw >= ww || ih >= wh)
00802         {
00803           fx = (double)ww / iw;
00804          fy = (double)wh / ih;
00805          if (fx > fy) fx = fy;
00806          if (fx > 2) fx = 2;
00807          iw = (int)(iw * fx);
00808          ih = (int)(ih * fx);
00809           QImage scaledImg = mImage.scaled(iw, ih,
00810               Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
00811 
00812           x = ((ww - iw) >> 1) + geo.mXorg;
00813           y = ((wh - ih) >> 1) + geo.mYorg;
00814 
00815          p.drawImage(x, y, scaledImg);
00816         }
00817         else
00818         {
00819           if(mRandomPosition)
00820           {
00821             x = (KRandom::random() % (ww - iw)) + geo.mXorg;
00822             y = (KRandom::random() % (wh - ih)) + geo.mYorg;
00823           }
00824           else
00825           {
00826             x = ((ww - iw) >> 1) + geo.mXorg;
00827             y = ((wh - ih) >> 1) + geo.mYorg;
00828           }
00829 
00830           // bitBlt(&mNextScreen, x, y, &mImage, 0, 0, iw, ih);
00831           p.drawImage(x, y, mImage);
00832         }
00833       }
00834 
00835       if (mPrintName)
00836       {
00837         p.setPen(QColor("black"));
00838         for (x=9; x<=11; x++)
00839          for (y=21; y>=19; y--)
00840             p.drawText(x + geo.mXorg, wh-y+geo.mYorg, mImageName);
00841         p.setPen(QColor("white"));
00842         p.drawText(10 + geo.mXorg, wh-20 + geo.mYorg, mImageName);
00843       }
00844     }
00845   }
00846   p.end();
00847 }
00848 
00849 
00850 //----------------------------------------------------------------------------
00851 void kSlideShowSaver::loadNextImage()
00852 {
00853   QString fname;
00854   int num;
00855 
00856 nexttry:
00857 
00858   num = mFileList.count();
00859   if (num <= 0) //no files in the directory
00860   {
00861     return;
00862   }
00863 
00864   if (mShowRandom)
00865   {
00866     mFileIdx = KRandom::random() % num;
00867     fname = mFileList.takeAt(mFileIdx);
00868     if (num == 1) //we're about to run out of images
00869     {
00870       mFileList = mRandomList;
00871     }
00872   }
00873   else
00874   {
00875     if (mFileIdx >= num) mFileIdx = 0;
00876     fname = mFileList[mFileIdx];
00877   }
00878 
00879   if (!mImage.load(fname))
00880   {
00881     kDebug() << "Failed to load image " << fname;
00882     mFileList.removeAll(fname);
00883     mRandomList.removeAll(fname);
00884     goto nexttry;
00885   }
00886   mFileIdx++;
00887 
00888   mImageName = QFileInfo(fname).baseName();
00889 }
00890 
00891 
00892 //----------------------------------------------------------------------------
00893 void kSlideShowSaver::loadDirectory()
00894 {
00895   mFileIdx = 0;
00896   mFileList.clear();
00897   traverseDirectory(mDirectory);
00898   mRandomList = mFileList;
00899 }
00900 
00901 void kSlideShowSaver::traverseDirectory(const QString &dirName)
00902 {
00903   QDir dir(dirName);
00904   if (!dir.exists())
00905   {
00906      return ;
00907   }
00908   dir.setFilter(QDir::Dirs | QDir::Files);
00909 
00910   QFileInfoList fileinfolist = dir.entryInfoList();
00911   QFileInfoList::Iterator it = fileinfolist.begin();
00912   while ( it != fileinfolist.end())
00913   {
00914      if (it->fileName() == "." || it->fileName() == "..")
00915      {
00916         ++it;
00917         continue;
00918      }
00919      if (it->isDir() && it->isReadable() && mSubdirectory)
00920      {
00921         traverseDirectory(it->filePath());
00922      }
00923      else
00924      {
00925         if (!it->isDir())
00926         {
00927            mFileList.append(it->filePath());
00928         }
00929      }
00930      ++it;
00931   }
00932 }
00933 
00934 
00935 //=============================================================================
00936 //  Class kSlideShowSetup
00937 //=============================================================================
00938 kSlideShowSetup::kSlideShowSetup(QWidget *aParent)
00939   : KDialog(aParent)
00940 {
00941   setCaption(i18n( "Setup Slide Show Screen Saver" ));
00942   setButtons(Ok|Cancel|Help);
00943   setDefaultButton(Ok);
00944   setModal(true);
00945   setButtonText( Help, i18n( "A&bout" ) );
00946 
00947   QWidget *main = new QWidget(this);
00948   setMainWidget(main);
00949   cfg = new SlideShowCfg();
00950   cfg->setupUi( main );
00951 
00952   cfg->mPreview->setFixedSize(220, 170);
00953   cfg->mPreview->show();    // otherwise saver does not get correct size
00954   mSaver = new kSlideShowSaver(cfg->mPreview->winId());
00955 
00956   cfg->mDirChooser->setMode(KFile::Directory | KFile::ExistingOnly);
00957   connect(cfg->mDirChooser, SIGNAL(returnPressed(const QString &)),
00958       SLOT(slotDirSelected(const QString &)));
00959   connect(cfg->mDirChooser, SIGNAL(urlSelected(const KUrl &)),
00960       SLOT(slotDirSelected(const KUrl &)));
00961   connect(this,SIGNAL(okClicked()),this,SLOT(slotOk()));
00962   connect(this,SIGNAL(helpClicked()),this,SLOT(slotHelp()));
00963   readSettings();
00964 }
00965 
00966 kSlideShowSetup::~kSlideShowSetup()
00967 {
00968     delete mSaver;
00969     delete cfg;
00970 }
00971 
00972 //-----------------------------------------------------------------------------
00973 void kSlideShowSetup::readSettings()
00974 {
00975     KConfigGroup config( KGlobal::config(), "Settings");
00976 
00977     cfg->mCbxRandom->setChecked(config.readEntry("ShowRandom", true));
00978     cfg->mCbxZoom->setChecked(config.readEntry("ZoomImages", false));
00979     cfg->mCbxShowName->setChecked(config.readEntry("PrintName", true));
00980     cfg->mDelay->setValue(config.readEntry("Delay", 20));
00981     cfg->mDirChooser->setPath(config.readPathEntry("Directory", QString()));
00982     cfg->mCbxSubdirectory->setChecked(config.readEntry("SubDirectory", false));
00983     cfg->mCbxRandomPosition->setChecked(config.readEntry("RandomPosition", false));
00984 }
00985 
00986 
00987 //-----------------------------------------------------------------------------
00988 void kSlideShowSetup::writeSettings()
00989 {
00990   KConfigGroup config( KGlobal::config(), "Settings");
00991 
00992   config.writeEntry("ShowRandom", cfg->mCbxRandom->isChecked());
00993   config.writeEntry("ZoomImages", cfg->mCbxZoom->isChecked());
00994   config.writeEntry("PrintName",  cfg->mCbxShowName->isChecked());
00995   config.writeEntry("Delay", cfg->mDelay->value());
00996   config.writePathEntry("Directory", cfg->mDirChooser->url().path());
00997   config.writeEntry("SubDirectory", cfg->mCbxSubdirectory->isChecked());
00998   config.writeEntry("RandomPosition", cfg->mCbxRandomPosition->isChecked());
00999 
01000   config.sync();
01001 
01002   if (mSaver)
01003   {
01004     mSaver->readConfig();
01005     mSaver->restart();
01006   }
01007 }
01008 
01009 
01010 //-----------------------------------------------------------------------------
01011 
01012 void kSlideShowSetup::slotDirSelected(const KUrl &)
01013 {
01014       writeSettings();
01015 }
01016 
01017 void kSlideShowSetup::slotDirSelected(const QString &)
01018 {
01019   writeSettings();
01020 }
01021 
01022 
01023 //-----------------------------------------------------------------------------
01024 void kSlideShowSetup::slotOk()
01025 {
01026   writeSettings();
01027   accept();
01028 }
01029 
01030 
01031 //-----------------------------------------------------------------------------
01032 void kSlideShowSetup::slotHelp()
01033 {
01034   KAboutApplicationDialog mAbout(s_aboutData, this);
01035   mAbout.exec();
01036 }