• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • kdeutils
  • Sitemap
  • Contact Us
 

ktimer

ktimer.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright 2001 Stefan Schimanski <1Stein@gmx.de>
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (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
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00017  */
00018 
00019 #include "ktimer.h"
00020 
00021 #include <QProcess>
00022 #include <QTimer>
00023 
00024 #include <klineedit.h>
00025 #include <kiconloader.h>
00026 #include <kapplication.h>
00027 #include <ksystemtrayicon.h>
00028 #include <kfiledialog.h>
00029 #include <kglobal.h>
00030 
00031 class KTimerJobItem : public QTreeWidgetItem {
00032 public:
00033     KTimerJobItem( KTimerJob *job, QTreeWidget *parent )
00034         : QTreeWidgetItem() {
00035             parent->addTopLevelItem(this);
00036         m_job = job;
00037         m_error = false;
00038         update();
00039     }
00040 
00041     KTimerJobItem( KTimerJob *job, QTreeWidget * parent, QTreeWidgetItem *after )
00042         : QTreeWidgetItem() {
00043             int otherItemIndex = parent->indexOfTopLevelItem(after);
00044             parent->insertTopLevelItem(otherItemIndex + 1, this);
00045         m_job = job;
00046         m_error = false;
00047         update();
00048     }
00049 
00050     virtual ~KTimerJobItem() {
00051         delete m_job;
00052     }
00053 
00054     KTimerJob *job() { return m_job; }
00055 
00056     void setStatus( bool error ) {
00057         m_error = error;
00058         update();
00059     }
00060 
00061     void update() {
00062         setText( 0, QString::number(m_job->value()) );
00063 
00064         if( m_error )
00065             setIcon( 0, KIcon("process-stop") );
00066         else
00067             setIcon( 0, QPixmap() );
00068 
00069         setText( 1, QString::number(m_job->delay()) );
00070 
00071         switch( m_job->state() ) {
00072             case KTimerJob::Stopped: setIcon( 2, KIcon("media-playback-stop") ); break;
00073             case KTimerJob::Paused: setIcon( 2, KIcon("media-playback-pause") ); break;
00074             case KTimerJob::Started: setIcon( 2, KIcon("arrow-right") ); break;
00075         }
00076 
00077         setText( 3, m_job->command() );
00078     }
00079 
00080 private:
00081     bool m_error;
00082     KTimerJob *m_job;
00083 };
00084 
00085 
00086 /***************************************************************/
00087 
00088 
00089 struct KTimerPrefPrivate
00090 {
00091     QList<KTimerJob *> jobs;
00092 };
00093 
00094 KTimerPref::KTimerPref( QWidget *parent)
00095     : QDialog( parent )
00096 {
00097     d = new KTimerPrefPrivate;
00098 
00099     setupUi(this);
00100 
00101     // set icons
00102     m_stop->setIcon( KIcon("media-playback-stop") );
00103     m_pause->setIcon( KIcon("media-playback-pause") );
00104     m_start->setIcon( KIcon("arrow-right") );
00105 
00106     // create tray icon
00107     KSystemTrayIcon *tray = new KSystemTrayIcon( this );
00108     tray->show();
00109     tray->setIcon( KIcon( "ktimer" ) );
00110 
00111     // connect
00112     connect( m_add, SIGNAL(clicked()), SLOT(add()) );
00113     connect( m_remove, SIGNAL(clicked()), SLOT(remove()) );
00114     connect( m_list, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
00115              SLOT(currentChanged(QTreeWidgetItem *, QTreeWidgetItem *)) );
00116     loadJobs( KGlobal::config().data() );
00117 
00118     show();
00119 }
00120 
00121 
00122 KTimerPref::~KTimerPref()
00123 {
00124     saveJobs( KGlobal::config().data() );
00125     delete d;
00126 }
00127 
00128 
00129 void KTimerPref::add()
00130 {
00131     KTimerJob *job = new KTimerJob;
00132     KTimerJobItem *item = new KTimerJobItem( job, m_list );
00133 
00134     connect( job, SIGNAL(delayChanged(KTimerJob*,unsigned int)),
00135              SLOT(jobChanged(KTimerJob*)) );
00136     connect( job, SIGNAL(valueChanged(KTimerJob*,unsigned int)),
00137              SLOT(jobChanged(KTimerJob*)) );
00138     connect( job, SIGNAL(stateChanged(KTimerJob*,States)),
00139              SLOT(jobChanged(KTimerJob*)) );
00140     connect( job, SIGNAL(commandChanged(KTimerJob*,const QString&)),
00141              SLOT(jobChanged(KTimerJob*)) );
00142     connect( job, SIGNAL(finished(KTimerJob*,bool)),
00143              SLOT(jobFinished(KTimerJob*,bool)) );
00144 
00145     job->setUser( item );
00146 
00147     // Qt drops currentChanged signals on first item (bug?)
00148     if( m_list->topLevelItemCount()==1 )
00149       currentChanged( item , NULL);
00150 
00151     m_list->setCurrentItem( item );
00152     m_list->update();
00153 }
00154 
00155 
00156 void KTimerPref::remove()
00157 {
00158     delete m_list->currentItem();
00159     m_list->update();
00160 }
00161 
00162 
00163 // note, don't use old, but added it so we can connect to the new one
00164 void KTimerPref::currentChanged( QTreeWidgetItem *i , QTreeWidgetItem * /* old */)
00165 {
00166     KTimerJobItem *item = static_cast<KTimerJobItem*>(i);
00167     if( item ) {
00168         KTimerJob *job = item->job();
00169 
00170         m_state->setEnabled( true );
00171         m_settings->setEnabled( true );
00172         m_remove->setEnabled( true );
00173 
00174         m_delay->disconnect();
00175         m_loop->disconnect();
00176         m_one->disconnect();
00177         m_start->disconnect();
00178         m_pause->disconnect();
00179         m_stop->disconnect();
00180         m_counter->disconnect();
00181         m_slider->disconnect();
00182         m_commandLine->disconnect();
00183         m_commandLine->lineEdit()->disconnect();
00184 
00185         connect( m_commandLine->lineEdit(), SIGNAL(textChanged(const QString &)),
00186                  job, SLOT(setCommand(const QString &)) );
00187         connect( m_delay, SIGNAL(valueChanged(int)),
00188                  job, SLOT(setDelay(int)) );
00189         connect( m_loop, SIGNAL(toggled(bool)),
00190                  job, SLOT(setLoop(bool)) );
00191         connect( m_one, SIGNAL(toggled(bool)),
00192                  job, SLOT(setOneInstance(bool)) );
00193         connect( m_stop, SIGNAL(clicked()),
00194                  job, SLOT(stop()) );
00195         connect( m_pause, SIGNAL(clicked()),
00196                  job, SLOT(pause()) );
00197         connect( m_start, SIGNAL(clicked()),
00198                  job, SLOT(start()) );
00199         connect( m_slider, SIGNAL(valueChanged(int)),
00200                  job, SLOT(setValue(int)) );
00201 
00202         m_commandLine->lineEdit()->setText( job->command() );
00203         m_delay->setValue( job->delay() );
00204         m_loop->setChecked( job->loop() );
00205         m_one->setChecked( job->oneInstance() );
00206         m_counter->display( (int)job->value() );
00207         m_slider->setMaximum( job->delay() );
00208         m_slider->setValue( job->value() );
00209 
00210     } else {
00211         m_state->setEnabled( false );
00212         m_settings->setEnabled( false );
00213         m_remove->setEnabled( false );
00214     }
00215 }
00216 
00217 
00218 void KTimerPref::jobChanged( KTimerJob *job )
00219 {
00220     KTimerJobItem *item = static_cast<KTimerJobItem*>(job->user());
00221     if( item ) {
00222         item->update();
00223         m_list->update();
00224 
00225         if( item==m_list->currentItem() ) {
00226 
00227             // XXX optimize
00228             m_slider->setMaximum( job->delay() );
00229             m_slider->setValue( job->value() );
00230             m_counter->display( (int)job->value() );
00231         }
00232     }
00233 }
00234 
00235 
00236 void KTimerPref::jobFinished( KTimerJob *job, bool error )
00237 {
00238     KTimerJobItem *item = static_cast<KTimerJobItem*>(job->user());
00239     item->setStatus( error );
00240     m_list->update();
00241 }
00242 
00243 
00244 void KTimerPref::saveJobs( KConfig *cfg )
00245 {
00246     for (int num = 0; num < m_list->topLevelItemCount(); ++num)
00247     {
00248         KTimerJobItem *item = static_cast<KTimerJobItem*>(m_list->topLevelItem(num));
00249         item->job()->save( cfg, QString("Job%1").arg( num ) );
00250         
00251     }
00252 
00253     KConfigGroup jobscfg = cfg->group("Jobs");
00254     jobscfg.writeEntry( "Number", m_list->topLevelItemCount());
00255 
00256     jobscfg.sync();
00257 }
00258 
00259 
00260 void KTimerPref::loadJobs( KConfig *cfg )
00261 {
00262     int num = cfg->group("Jobs").readEntry( "Number", 0 );
00263     for( int n=0; n<num; n++ ) {
00264             KTimerJob *job = new KTimerJob;
00265             KTimerJobItem *item = new KTimerJobItem( job, m_list );
00266 
00267             connect( job, SIGNAL(delayChanged(KTimerJob*,unsigned int)),
00268                      SLOT(jobChanged(KTimerJob*)) );
00269             connect( job, SIGNAL(valueChanged(KTimerJob*,unsigned int)),
00270                      SLOT(jobChanged(KTimerJob*)) );
00271             connect( job, SIGNAL(stateChanged(KTimerJob*,States)),
00272                      SLOT(jobChanged(KTimerJob*)) );
00273             connect( job, SIGNAL(commandChanged(KTimerJob*,const QString&)),
00274                      SLOT(jobChanged(KTimerJob*)) );
00275             connect( job, SIGNAL(finished(KTimerJob*,bool)),
00276                      SLOT(jobFinished(KTimerJob*,bool)) );
00277 
00278             job->load( cfg, QString( "Job%1" ).arg(n) );
00279 
00280             job->setUser( item );
00281     }
00282 
00283     m_list->update();
00284 }
00285 
00286 
00287 /*********************************************************************/
00288 
00289 
00290 struct KTimerJobPrivate {
00291     unsigned delay;
00292     QString command;
00293     bool loop;
00294     bool oneInstance;
00295     unsigned value;
00296     KTimerJob::States state;
00297     QList<QProcess *> processes;
00298     void *user;
00299 
00300     QTimer *timer;
00301 };
00302 
00303 
00304 KTimerJob::KTimerJob( QObject *parent)
00305     : QObject( parent )
00306 {
00307     d = new KTimerJobPrivate;
00308 
00309     d->delay = 100;
00310     d->loop = false;
00311     d->oneInstance = true;
00312     d->value = 100;
00313     d->state = Stopped;
00314     d->user = 0;
00315 
00316     d->timer = new QTimer( this );
00317     connect( d->timer, SIGNAL(timeout()), SLOT(timeout()) );
00318 }
00319 
00320 
00321 KTimerJob::~KTimerJob()
00322 {
00323     delete d;
00324 }
00325 
00326 
00327 void KTimerJob::load( KConfig *cfg, const QString& grp )
00328 {
00329     KConfigGroup groupcfg = cfg->group(grp);
00330     groupcfg.writeEntry( "Delay", d->delay );
00331     groupcfg.writePathEntry( "Command", d->command );
00332     groupcfg.writeEntry( "Loop", d->loop );
00333     groupcfg.writeEntry( "OneInstance", d->oneInstance );
00334     groupcfg.writeEntry( "State", (int)d->state );
00335 }
00336 
00337 
00338 void KTimerJob::save( KConfig *cfg, const QString& grp )
00339 {
00340     KConfigGroup groupcfg = cfg->group(grp);
00341     setDelay( groupcfg.readEntry( "Delay", 100 ) );
00342     setCommand( groupcfg.readPathEntry( "Command", QString() ) );
00343     setLoop( groupcfg.readEntry( "Loop", false ) );
00344     setOneInstance( groupcfg.readEntry( "OneInstance", d->oneInstance ) );
00345     setState( (States)groupcfg.readEntry( "State", (int)Stopped ) );
00346 }
00347 
00348 
00349 void *KTimerJob::user()
00350 {
00351     return d->user;
00352 }
00353 
00354 
00355 void KTimerJob::setUser( void *user )
00356 {
00357     d->user = user;
00358 }
00359 
00360 
00361 unsigned KTimerJob::delay() const
00362 {
00363     return d->delay;
00364 }
00365 
00366 
00367 void KTimerJob::pause()
00368 {
00369     setState( Paused );
00370 }
00371 
00372 void KTimerJob::stop()
00373 {
00374     setState( Stopped );
00375 }
00376 
00377 void KTimerJob::start()
00378 {
00379     setState( Started );
00380 }
00381 
00382 void KTimerJob::setDelay( int sec )
00383 {
00384     setDelay( (unsigned)sec );
00385 }
00386 
00387 void KTimerJob::setValue( int value )
00388 {
00389     setValue( (unsigned)value );
00390 }
00391 
00392 void KTimerJob::setDelay( unsigned sec )
00393 {
00394     if( d->delay!=sec ) {
00395         d->delay = sec;
00396 
00397         if( d->state==Stopped )
00398             setValue( sec );
00399 
00400         emit delayChanged( this, sec );
00401         emit changed( this );
00402     }
00403 }
00404 
00405 
00406 QString KTimerJob::command() const
00407 {
00408     return d->command;
00409 }
00410 
00411 
00412 void KTimerJob::setCommand( const QString &cmd )
00413 {
00414     if( d->command!=cmd ) {
00415         d->command = cmd;
00416         emit commandChanged( this, cmd );
00417         emit changed( this );
00418     }
00419 }
00420 
00421 
00422 bool KTimerJob::loop() const
00423 {
00424     return d->loop;
00425 }
00426 
00427 
00428 void KTimerJob::setLoop( bool loop )
00429 {
00430     if( d->loop!=loop ) {
00431         d->loop = loop;
00432         emit loopChanged( this, loop );
00433         emit changed( this );
00434     }
00435 }
00436 
00437 
00438 bool KTimerJob::oneInstance() const
00439 {
00440     return d->oneInstance;
00441 }
00442 
00443 
00444 void KTimerJob::setOneInstance( bool one )
00445 {
00446     if( d->oneInstance!=one ) {
00447         d->oneInstance = one;
00448         emit oneInstanceChanged( this, one );
00449         emit changed( this );
00450     }
00451 }
00452 
00453 
00454 unsigned KTimerJob::value() const
00455 {
00456     return d->value;
00457 }
00458 
00459 
00460 void KTimerJob::setValue( unsigned value )
00461 {
00462     if( d->value!=value ) {
00463         d->value = value;
00464         emit valueChanged( this, value );
00465         emit changed( this );
00466     }
00467 }
00468 
00469 
00470 KTimerJob::States KTimerJob::state() const
00471 {
00472     return d->state;
00473 }
00474 
00475 
00476 void KTimerJob::setState( KTimerJob::States state )
00477 {
00478     if( d->state!=state ) {
00479         if( state==Started )
00480             d->timer->start( 1000 );
00481         else
00482             d->timer->stop();
00483 
00484         if( state==Stopped )
00485             setValue( d->delay );
00486 
00487         d->state = state;
00488         emit stateChanged( this, state );
00489         emit changed( this );
00490     }
00491 }
00492 
00493 
00494 void KTimerJob::timeout()
00495 {
00496     if( d->state==Started && d->value!=0 ) {
00497         setValue( d->value-1 );
00498         if( d->value==0 ) {
00499             fire();
00500             if( d->loop )
00501                 setValue( d->delay );
00502             else
00503                 stop();
00504         }
00505     }
00506 }
00507 
00508 
00509 void KTimerJob::processExited(int, QProcess::ExitStatus status)
00510 {
00511     QProcess * proc = static_cast<QProcess*>(sender());
00512     bool ok = status==0;
00513     int i = d->processes.indexOf( proc);
00514     if (i != -1)
00515         delete d->processes.takeAt(i);
00516 
00517     if( !ok ) emit error( this );
00518     emit finished( this, !ok );
00519 }
00520 
00521 
00522 void KTimerJob::fire()
00523 {
00524     if( !d->oneInstance || d->processes.isEmpty() ) {
00525         QProcess *proc = new QProcess;
00526         d->processes.append( proc );
00527         connect( proc, SIGNAL(finished(int, QProcess::ExitStatus)),
00528                  SLOT(processExited(int, QProcess::ExitStatus)) );
00529         if (!d->command.isEmpty()) {
00530             proc->start(d->command);
00531             emit fired( this );
00532         }
00533         if(proc->state() == QProcess::NotRunning) {
00534             int i = d->processes.indexOf( proc);
00535             if (i != -1)
00536                 delete d->processes.takeAt(i);
00537             emit error( this );
00538             emit finished( this, true );
00539         }
00540     }
00541 }
00542 #include "ktimer.moc"

ktimer

Skip menu "ktimer"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members

kdeutils

Skip menu "kdeutils"
  • ark
  • kcalc
  • kcharselect
  • kdelirc
  • kdessh
  • kdf
  • kfloppy
  • kgpg
  • kjots
  • klaptopdaemon
  • kmilo
  • ksim
  • ktimer
  • kwallet
  • superkaramba
Generated for kdeutils by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal