• Skip to content
  • Skip to link menu
KDE 4.2 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     delete d;
00125 }
00126 
00127 void KTimerPref::saveAllJobs() {
00128     saveJobs( KGlobal::config().data() );
00129 }
00130 
00131 
00132 void KTimerPref::add()
00133 {
00134     KTimerJob *job = new KTimerJob;
00135     KTimerJobItem *item = new KTimerJobItem( job, m_list );
00136 
00137     connect( job, SIGNAL(delayChanged(KTimerJob*,unsigned int)),
00138              SLOT(jobChanged(KTimerJob*)) );
00139     connect( job, SIGNAL(valueChanged(KTimerJob*,unsigned int)),
00140              SLOT(jobChanged(KTimerJob*)) );
00141     connect( job, SIGNAL(stateChanged(KTimerJob*,States)),
00142              SLOT(jobChanged(KTimerJob*)) );
00143     connect( job, SIGNAL(commandChanged(KTimerJob*,const QString&)),
00144              SLOT(jobChanged(KTimerJob*)) );
00145     connect( job, SIGNAL(finished(KTimerJob*,bool)),
00146              SLOT(jobFinished(KTimerJob*,bool)) );
00147 
00148     job->setUser( item );
00149 
00150     // Qt drops currentChanged signals on first item (bug?)
00151     if( m_list->topLevelItemCount()==1 )
00152       currentChanged( item , NULL);
00153 
00154     m_list->setCurrentItem( item );
00155     m_list->update();
00156 }
00157 
00158 
00159 void KTimerPref::remove()
00160 {
00161     delete m_list->currentItem();
00162     m_list->update();
00163 }
00164 
00165 
00166 // note, don't use old, but added it so we can connect to the new one
00167 void KTimerPref::currentChanged( QTreeWidgetItem *i , QTreeWidgetItem * /* old */)
00168 {
00169     KTimerJobItem *item = static_cast<KTimerJobItem*>(i);
00170     if( item ) {
00171         KTimerJob *job = item->job();
00172 
00173         m_state->setEnabled( true );
00174         m_settings->setEnabled( true );
00175         m_remove->setEnabled( true );
00176 
00177         m_delay->disconnect();
00178         m_loop->disconnect();
00179         m_one->disconnect();
00180         m_start->disconnect();
00181         m_pause->disconnect();
00182         m_stop->disconnect();
00183         m_counter->disconnect();
00184         m_slider->disconnect();
00185         m_commandLine->disconnect();
00186         m_commandLine->lineEdit()->disconnect();
00187 
00188         connect( m_commandLine->lineEdit(), SIGNAL(textChanged(const QString &)),
00189                  job, SLOT(setCommand(const QString &)) );
00190         connect( m_delay, SIGNAL(valueChanged(int)),
00191                  job, SLOT(setDelay(int)) );
00192         connect( m_loop, SIGNAL(toggled(bool)),
00193                  job, SLOT(setLoop(bool)) );
00194         connect( m_one, SIGNAL(toggled(bool)),
00195                  job, SLOT(setOneInstance(bool)) );
00196         connect( m_stop, SIGNAL(clicked()),
00197                  job, SLOT(stop()) );
00198         connect( m_pause, SIGNAL(clicked()),
00199                  job, SLOT(pause()) );
00200         connect( m_start, SIGNAL(clicked()),
00201                  job, SLOT(start()) );
00202         connect( m_slider, SIGNAL(valueChanged(int)),
00203                  job, SLOT(setValue(int)) );
00204 
00205         m_commandLine->lineEdit()->setText( job->command() );
00206         m_delay->setValue( job->delay() );
00207         m_loop->setChecked( job->loop() );
00208         m_one->setChecked( job->oneInstance() );
00209         m_counter->display( (int)job->value() );
00210         m_slider->setMaximum( job->delay() );
00211         m_slider->setValue( job->value() );
00212 
00213     } else {
00214         m_state->setEnabled( false );
00215         m_settings->setEnabled( false );
00216         m_remove->setEnabled( false );
00217     }
00218 }
00219 
00220 const QString KTimerPref::formatSeconds( int seconds ) {
00221    if(seconds<60) return QString("%1").arg(seconds);
00222     return QString("%1:%2").arg( (int)seconds/60, 2, 10, QChar('0') ).arg( (int)seconds%60, 2, 10, QChar('0') ); 
00223 }
00224 
00225 void KTimerPref::jobChanged( KTimerJob *job )
00226 {
00227     KTimerJobItem *item = static_cast<KTimerJobItem*>(job->user());
00228     if( item ) {
00229         item->update();
00230         m_list->update();
00231 
00232         if( item==m_list->currentItem() ) {
00233 
00234             // XXX optimize
00235             m_slider->setMaximum( job->delay() );
00236             m_slider->setValue( job->value() );
00237             m_counter->display( (int)job->value() );
00238         }
00239     }
00240 }
00241 
00242 
00243 void KTimerPref::jobFinished( KTimerJob *job, bool error )
00244 {
00245     KTimerJobItem *item = static_cast<KTimerJobItem*>(job->user());
00246     item->setStatus( error );
00247     m_list->update();
00248 }
00249 
00250 void KTimerPref::done(int result) {
00251     saveAllJobs();
00252     QDialog::done(result);
00253 }
00254 
00255 void KTimerPref::saveJobs( KConfig *cfg )
00256 {
00257     for (int num = 0; num < m_list->topLevelItemCount(); ++num)
00258     {
00259         KTimerJobItem *item = static_cast<KTimerJobItem*>(m_list->topLevelItem(num));
00260         item->job()->save( cfg, QString("Job%1").arg( num ) );
00261         
00262     }
00263 
00264     KConfigGroup jobscfg = cfg->group("Jobs");
00265     jobscfg.writeEntry( "Number", m_list->topLevelItemCount());
00266 
00267     jobscfg.sync();
00268 }
00269 
00270 
00271 void KTimerPref::loadJobs( KConfig *cfg )
00272 {
00273     int num = cfg->group("Jobs").readEntry( "Number", 0 );
00274     for( int n=0; n<num; n++ ) {
00275             KTimerJob *job = new KTimerJob;
00276             KTimerJobItem *item = new KTimerJobItem( job, m_list );
00277 
00278             connect( job, SIGNAL(delayChanged(KTimerJob*,unsigned int)),
00279                      SLOT(jobChanged(KTimerJob*)) );
00280             connect( job, SIGNAL(valueChanged(KTimerJob*,unsigned int)),
00281                      SLOT(jobChanged(KTimerJob*)) );
00282             connect( job, SIGNAL(stateChanged(KTimerJob*,States)),
00283                      SLOT(jobChanged(KTimerJob*)) );
00284             connect( job, SIGNAL(commandChanged(KTimerJob*,const QString&)),
00285                      SLOT(jobChanged(KTimerJob*)) );
00286             connect( job, SIGNAL(finished(KTimerJob*,bool)),
00287                      SLOT(jobFinished(KTimerJob*,bool)) );
00288 
00289             job->load( cfg, QString( "Job%1" ).arg(n) );
00290 
00291             job->setUser( item );
00292             jobChanged ( job);
00293     }
00294 
00295     m_list->update();
00296 }
00297 
00298 
00299 /*********************************************************************/
00300 
00301 
00302 struct KTimerJobPrivate {
00303     unsigned delay;
00304     QString command;
00305     bool loop;
00306     bool oneInstance;
00307     unsigned value;
00308     KTimerJob::States state;
00309     QList<QProcess *> processes;
00310     void *user;
00311 
00312     QTimer *timer;
00313 };
00314 
00315 
00316 KTimerJob::KTimerJob( QObject *parent)
00317     : QObject( parent )
00318 {
00319     d = new KTimerJobPrivate;
00320 
00321     d->delay = 100;
00322     d->loop = false;
00323     d->oneInstance = true;
00324     d->value = 100;
00325     d->state = Stopped;
00326     d->user = 0;
00327 
00328     d->timer = new QTimer( this );
00329     connect( d->timer, SIGNAL(timeout()), SLOT(timeout()) );
00330 }
00331 
00332 
00333 KTimerJob::~KTimerJob()
00334 {
00335     delete d;
00336 }
00337 
00338 
00339 void KTimerJob::save( KConfig *cfg, const QString& grp )
00340 {
00341     KConfigGroup groupcfg = cfg->group(grp);
00342     groupcfg.writeEntry( "Delay", d->delay );
00343     groupcfg.writePathEntry( "Command", d->command );
00344     groupcfg.writeEntry( "Loop", d->loop );
00345     groupcfg.writeEntry( "OneInstance", d->oneInstance );
00346     groupcfg.writeEntry( "State", (int)d->state );
00347 }
00348 
00349 
00350 void KTimerJob::load( KConfig *cfg, const QString& grp )
00351 {
00352     KConfigGroup groupcfg = cfg->group(grp);
00353     setDelay( groupcfg.readEntry( "Delay", 100 ) );
00354     setCommand( groupcfg.readPathEntry( "Command", QString() ) );
00355     setLoop( groupcfg.readEntry( "Loop", false ) );
00356     setOneInstance( groupcfg.readEntry( "OneInstance", d->oneInstance ) );
00357     setState( (States)groupcfg.readEntry( "State", (int)Stopped ) );
00358 }
00359 
00360 
00361 void *KTimerJob::user()
00362 {
00363     return d->user;
00364 }
00365 
00366 
00367 void KTimerJob::setUser( void *user )
00368 {
00369     d->user = user;
00370 }
00371 
00372 
00373 unsigned KTimerJob::delay() const
00374 {
00375     return d->delay;
00376 }
00377 
00378 
00379 void KTimerJob::pause()
00380 {
00381     setState( Paused );
00382 }
00383 
00384 void KTimerJob::stop()
00385 {
00386     setState( Stopped );
00387 }
00388 
00389 void KTimerJob::start()
00390 {
00391     setState( Started );
00392 }
00393 
00394 void KTimerJob::setDelay( int sec )
00395 {
00396     setDelay( (unsigned)sec );
00397 }
00398 
00399 void KTimerJob::setValue( int value )
00400 {
00401     setValue( (unsigned)value );
00402 }
00403 
00404 void KTimerJob::setDelay( unsigned sec )
00405 {
00406     if( d->delay!=sec ) {
00407         d->delay = sec;
00408 
00409         if( d->state==Stopped )
00410             setValue( sec );
00411 
00412         emit delayChanged( this, sec );
00413         emit changed( this );
00414     }
00415 }
00416 
00417 
00418 QString KTimerJob::command() const
00419 {
00420     return d->command;
00421 }
00422 
00423 
00424 void KTimerJob::setCommand( const QString &cmd )
00425 {
00426     if( d->command!=cmd ) {
00427         d->command = cmd;
00428         emit commandChanged( this, cmd );
00429         emit changed( this );
00430     }
00431 }
00432 
00433 
00434 bool KTimerJob::loop() const
00435 {
00436     return d->loop;
00437 }
00438 
00439 
00440 void KTimerJob::setLoop( bool loop )
00441 {
00442     if( d->loop!=loop ) {
00443         d->loop = loop;
00444         emit loopChanged( this, loop );
00445         emit changed( this );
00446     }
00447 }
00448 
00449 
00450 bool KTimerJob::oneInstance() const
00451 {
00452     return d->oneInstance;
00453 }
00454 
00455 
00456 void KTimerJob::setOneInstance( bool one )
00457 {
00458     if( d->oneInstance!=one ) {
00459         d->oneInstance = one;
00460         emit oneInstanceChanged( this, one );
00461         emit changed( this );
00462     }
00463 }
00464 
00465 
00466 unsigned KTimerJob::value() const
00467 {
00468     return d->value;
00469 }
00470 
00471 
00472 void KTimerJob::setValue( unsigned value )
00473 {
00474     if( d->value!=value ) {
00475         d->value = value;
00476         emit valueChanged( this, value );
00477         emit changed( this );
00478     }
00479 }
00480 
00481 
00482 KTimerJob::States KTimerJob::state() const
00483 {
00484     return d->state;
00485 }
00486 
00487 
00488 void KTimerJob::setState( KTimerJob::States state )
00489 {
00490     if( d->state!=state ) {
00491         if( state==Started )
00492             d->timer->start( 1000 );
00493         else
00494             d->timer->stop();
00495 
00496         if( state==Stopped )
00497             setValue( d->delay );
00498 
00499         d->state = state;
00500         emit stateChanged( this, state );
00501         emit changed( this );
00502     }
00503 }
00504 
00505 
00506 void KTimerJob::timeout()
00507 {
00508     if( d->state==Started && d->value!=0 ) {
00509         setValue( d->value-1 );
00510         if( d->value==0 ) {
00511             fire();
00512             if( d->loop )
00513                 setValue( d->delay );
00514             else
00515                 stop();
00516         }
00517     }
00518 }
00519 
00520 
00521 void KTimerJob::processExited(int, QProcess::ExitStatus status)
00522 {
00523     QProcess * proc = static_cast<QProcess*>(sender());
00524     bool ok = status==0;
00525     int i = d->processes.indexOf( proc);
00526     if (i != -1)
00527         delete d->processes.takeAt(i);
00528 
00529     if( !ok ) emit error( this );
00530     emit finished( this, !ok );
00531 }
00532 
00533 
00534 
00535 
00536 void KTimerJob::fire()
00537 {
00538     if( !d->oneInstance || d->processes.isEmpty() ) {
00539         QProcess *proc = new QProcess;
00540         d->processes.append( proc );
00541         connect( proc, SIGNAL(finished(int, QProcess::ExitStatus)),
00542                  SLOT(processExited(int, QProcess::ExitStatus)) );
00543         if (!d->command.isEmpty()) {
00544             proc->start(d->command);
00545             emit fired( this );
00546         }
00547         if(proc->state() == QProcess::NotRunning) {
00548             int i = d->processes.indexOf( proc);
00549             if (i != -1)
00550                 delete d->processes.takeAt(i);
00551             emit error( this );
00552             emit finished( this, true );
00553         }
00554     }
00555 }
00556 #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
  • kdessh
  • kdf
  • kfloppy
  • kgpg
  • ktimer
  • kwallet
  • okteta
  • printer-applet
  • superkaramba
  • sweeper
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