Back to index

kdeartwork  4.3.2
kpartsaver.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001 Stefan Schimanski <1Stein@gmx.de>
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this program; if not, write to the Free
00016  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00017  */
00018 
00019 #include <stdlib.h>
00020 #include <signal.h>
00021 #include <unistd.h>
00022 #include <time.h>
00023 
00024 #include <qwidget.h>
00025 #include <qdialog.h>
00026 #include <qtimer.h>
00027 #include <qstring.h>
00028 #include <q3valuelist.h>
00029 #include <qpushbutton.h>
00030 #include <qradiobutton.h>
00031 #include <qspinbox.h>
00032 #include <qcheckbox.h>
00033 #include <qlabel.h>
00034 //Added by qt3to4:
00035 #include <QList>
00036 #include <klocale.h>
00037 #include <kapplication.h>
00038 #include <kdebug.h>
00039 #include <klibloader.h>
00040 #include <kconfig.h>
00041 #include <kfiledialog.h>
00042 #include <kurl.h>
00043 #include <kparts/part.h>
00044 #include <kio/jobclasses.h>
00045 #include <kio/job.h>
00046 #include <kmimetype.h>
00047 #include <kmimetypetrader.h>
00048 
00049 #include <kscreensaver.h>
00050 
00051 #include "kpartsaver.h"
00052 #include <kiconloader.h>
00053 #include <kglobal.h>
00054 
00055 
00056 QList<KPartSaver*> g_savers;
00057 bool g_inited = false;
00058 
00059 
00060 class KPartSaverInterface : public KScreenSaverInterface
00061 {
00062 
00063 
00064 public:
00065     virtual KAboutData* aboutData() {
00066         return new KAboutData( "kpartsaver", 0, ki18n( "KPart Screen Saver" ), "1.0", ki18n( "KPart Screen Saver" ) );
00067     }
00068 
00069 
00070     virtual KScreenSaver* create( WId d )
00071     {
00072         KGlobal::locale()->insertCatalog("kpartsaver");
00073         return new KPartSaver( d );
00074     }
00075 
00076     virtual QDialog* setup()
00077     {
00078         KGlobal::locale()->insertCatalog("kpartsaver");
00079         return new SaverConfig;
00080     }
00081 };
00082 
00083 int main( int argc, char *argv[] )
00084 {
00085     KPartSaverInterface kss;
00086     return kScreenSaverMain( argc, argv, kss );
00087 }
00088 
00089 
00090 void exitHandler( int )
00091 {
00092     kDebug() << "exitHandler";
00093     qDeleteAll(g_savers);
00094     //KLibLoader::self()->cleanUp();
00095     exit(0);
00096 }
00097 
00098 
00099 KPartSaver::KPartSaver( WId id )
00100     : KScreenSaver( id ), m_timer(), m_part(0), m_current(-1), m_back(0)
00101 {
00102     // install signal handlers to make sure that nspluginviewer is shutdown correctly
00103     // move this into the nspluginviewer kpart code
00104     if( !g_inited ) {
00105         g_inited = true;
00106 
00107         srand( time(0) );
00108 
00109         // install signal handler
00110         signal( SIGINT, exitHandler );    // Ctrl-C will cause a clean exit...
00111         signal( SIGTERM, exitHandler );   // "kill"...
00112         signal( SIGHUP, exitHandler );    // "kill -HUP" (hangup)...
00113         signal( SIGKILL, exitHandler );    // "kill -KILL"
00114         //atexit( ( void (*)(void) ) exitHandler );
00115     }
00116 
00117     g_savers.append( this );
00118 
00119     closeUrl();
00120 
00121     // load config
00122     KConfigGroup cfg(KGlobal::config(), "Misc");
00123 
00124     m_single = cfg.readEntry( "Single", true );
00125     m_delay = cfg.readEntry( "Delay", 60 );
00126     m_random = cfg.readEntry( "Random", false );
00127     m_files = cfg.readEntry( "Files",QStringList() );
00128 
00129     if( m_files.count()==0 ) {
00130 
00131         // create background widget
00132         m_back = new QLabel( i18n("The screen saver is not configured yet."), this );
00133         m_back->setWordWrap( true );
00134         m_back->setAlignment( Qt::AlignCenter );
00135         embed( m_back );
00136         m_back->show();
00137 
00138     } else {
00139 
00140         // queue files
00141         for( int n=0; n<m_files.count(); n++ )
00142             queue( KUrl( m_files[n] ) );
00143 
00144         // play files
00145         if( m_single )
00146             next( m_random );
00147         else {
00148             next( m_random );
00149             QTimer::singleShot( m_delay*1000, this, SLOT(timeout()) );
00150         }
00151     }
00152 }
00153 
00154 
00155 KPartSaver::~KPartSaver()
00156 {
00157     g_savers.removeAll( this );
00158     closeUrl();
00159 }
00160 
00161 
00162 void KPartSaver::closeUrl()
00163 {
00164     if( m_part ) {
00165         m_part->closeUrl();
00166         delete m_part;
00167         m_part = 0;
00168     }
00169 }
00170 
00171 
00172 bool KPartSaver::openUrl( const KUrl &url )
00173 {
00174     if( m_part )
00175         closeUrl();
00176 
00177     // find mime type
00178     QString mime = KMimeType::findByUrl( url )->name();
00179 
00180     // load part
00181     m_part = KMimeTypeTrader::createPartInstanceFromQuery<KParts::ReadOnlyPart>(
00182         mime, this, this, QString() );
00183 
00184     if( !m_part ) {
00185         kDebug() << "Part for " << url << " can't be constructed";
00186         closeUrl();
00187         return false;
00188     } else
00189         embed( m_part->widget() );
00190 
00191     // show kpart
00192     delete m_back;
00193     m_back = 0;
00194 
00195     show();
00196     m_part->widget()->show();
00197 
00198     // load url
00199     if( !m_part->openUrl( url ) ) {
00200         kDebug() << "Can't load " << url.url();
00201         delete m_part;
00202         m_part = 0;
00203         closeUrl();
00204         return false;
00205     }
00206 
00207     return true;
00208 }
00209 
00210 
00211 void KPartSaver::queue( const KUrl &url )
00212 {
00213     Medium medium;
00214     medium.url = url;
00215     medium.failed = false;
00216     m_media.append( medium );
00217 }
00218 
00219 
00220 void KPartSaver::timeout()
00221 {
00222     next( m_random );
00223     QTimer::singleShot( m_delay*1000, this, SLOT(timeout()) );
00224 }
00225 
00226 
00227 void KPartSaver::next( bool random )
00228 {
00229     // try to find working media
00230     while( m_media.count()>0 ) {
00231 
00232         if( random )
00233             m_current = rand() % m_media.count();
00234         else
00235             m_current++;
00236 
00237         if( m_current>=(int)m_media.count() )
00238             m_current = 0;
00239 
00240         kDebug() << "Trying medium " << m_media[m_current].url.url();
00241 
00242         // either start immediately or start mimejob first
00243         if( !openUrl( m_media[m_current].url ) ) {
00244             m_media.removeAll( m_media.at(m_current) );
00245             m_current--;
00246         } else
00247             return;
00248 
00249     }
00250 
00251     // create background widget
00252     m_back = new QLabel( i18n("All of your files are unsupported"), this );
00253     m_back->setWordWrap( true );
00254     m_back->setAlignment( Qt::AlignCenter );
00255     embed( m_back );
00256     m_back->show();
00257 
00258     // nothing found, set to invalid
00259     m_current = -1;
00260 }
00261 
00262 
00263 /*******************************************************************************/
00264 
00265 
00266 SaverConfig::SaverConfig( QWidget* parent )
00267     : ConfigWidget( parent )
00268 {
00269     setModal(true);
00270     connect( m_ok, SIGNAL(clicked()), SLOT(apply()) );
00271     connect( m_ok, SIGNAL(clicked()), SLOT(accept()) );
00272     connect( m_cancel, SIGNAL(clicked()), SLOT(reject()) );
00273 
00274     connect( m_multiple, SIGNAL(toggled(bool)), m_delayLabel, SLOT(setEnabled(bool)) );
00275     connect( m_multiple, SIGNAL(toggled(bool)), m_delay, SLOT(setEnabled(bool)) );
00276     connect( m_multiple, SIGNAL(toggled(bool)), m_secondsLabel, SLOT(setEnabled(bool)) );
00277     connect( m_multiple, SIGNAL(toggled(bool)), m_random, SLOT(setEnabled(bool)) );
00278 
00279     connect( m_files, SIGNAL(itemSelectionChanged()), SLOT(select()) );
00280     connect( m_add, SIGNAL(clicked()), SLOT(add()) );
00281     connect( m_remove, SIGNAL(clicked()), SLOT(remove()) );
00282     connect( m_up, SIGNAL(clicked()), SLOT(up()) );
00283     connect( m_down, SIGNAL(clicked()), SLOT(down()) );
00284 
00285     m_up->setIcon( KIcon("go-up") );
00286     m_down->setIcon( KIcon("go-down") );
00287 
00288     // load config
00289     KConfigGroup cfg(KGlobal::config(), "Misc");
00290 
00291     bool single = cfg.readEntry( "Single", true );
00292     m_single->setChecked( single );
00293     m_multiple->setChecked( !single );
00294     m_delay->setMinimum( 1 );
00295     m_delay->setMaximum( 10000 );
00296     m_delay->setValue( cfg.readEntry( "Delay", 60 ) );
00297     m_random->setChecked( cfg.readEntry( "Random", false ) );
00298     m_files->addItems( cfg.readEntry( "Files",QStringList() ) );
00299 
00300     // update buttons
00301     select();
00302 }
00303 
00304 
00305 SaverConfig::~SaverConfig()
00306 {
00307 }
00308 
00309 
00310 void SaverConfig::apply()
00311 {
00312     kDebug() << "apply";
00313 
00314     KConfigGroup cfg(KGlobal::config(), "Misc");
00315 
00316     cfg.writeEntry( "Single", m_single->isChecked() );
00317     cfg.writeEntry( "Delay", m_delay->value() );
00318     cfg.writeEntry( "Random", m_random->isChecked() );
00319 
00320     int num = m_files->count();
00321     QStringList files;
00322     for( int n=0; n<num; n++ )
00323         files << m_files->item(n)->text();
00324 
00325     cfg.writeEntry( "Files", files );
00326 
00327     cfg.sync();
00328 }
00329 
00330 
00331 void SaverConfig::add()
00332 {
00333     KUrl::List files = KFileDialog::getOpenUrls( KUrl(), QString(),
00334                                                  this, i18n("Select Media Files") );
00335     for( int n=0; n<files.count(); n++ )
00336         m_files->addItem( files[n].prettyUrl() );
00337 }
00338 
00339 
00340 void SaverConfig::remove()
00341 {
00342     int current = m_files->currentRow();
00343     if( current!=-1 )
00344         m_files->takeItem( current );
00345 }
00346 
00347 
00348 void SaverConfig::select()
00349 {
00350     bool enabled = m_files->currentRow()!=-1;
00351     m_remove->setEnabled( enabled );
00352     m_up->setEnabled( enabled && m_files->currentRow()!=0 );
00353     m_down->setEnabled( enabled && m_files->currentRow()!=(int)m_files->count()-1 );
00354 }
00355 
00356 
00357 void SaverConfig::up()
00358 {
00359     int current = m_files->currentRow();
00360     if ( current>0 ) {
00361         QString txt = m_files->currentItem()->text();
00362         m_files->takeItem( current );
00363         m_files->insertItem( current-1, txt );
00364         m_files->setCurrentRow( current-1 );
00365     }
00366 }
00367 
00368 
00369 void SaverConfig::down()
00370 {
00371     int current = m_files->currentRow();
00372     if ( current!=-1 && current<(int)m_files->count()-1 ) {
00373         QString txt = m_files->currentItem()->text();
00374         m_files->takeItem( current );
00375         m_files->insertItem( current+1, txt );
00376         m_files->setCurrentRow( current+1 );
00377     }
00378 }
00379 
00380 #include "kpartsaver.moc"