New Appointment -> New Task
[kdepim.git] / akonadiconsole / jobtracker.cpp
blob6a2aa59040497c8abba8c1300eb7103a301d7bab
1 /*
2 This file is part of Akonadi.
4 Copyright (c) 2009 KDAB
5 Author: Till Adam <adam@kde.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 USA.
23 #include "jobtracker.h"
24 #include "jobtrackeradaptor.h"
26 #include <QtCore/QString>
27 #include <QtCore/QStringList>
28 #include <QtCore/QDebug>
29 #include <QtCore/QPair>
30 #include <QtCore/QList>
32 #include <cassert>
34 QString JobInfo::stateAsString() const
36 switch( state )
38 case Initial:
39 return QLatin1String("Initial");
40 case Running:
41 return QLatin1String("Running");
42 case Ended:
43 return QLatin1String("Ended");
44 case Failed:
45 return QString::fromLatin1( "Failed: %1" ).arg( error );
46 default:
47 return QLatin1String("Unknown state!");
52 class JobTracker::Private
54 public:
55 Private( JobTracker *_q )
56 :lastId( 42 ), timer( _q ), q( _q )
58 timer.setSingleShot( true );
59 timer.setInterval( 200 );
60 connect( &timer, SIGNAL(timeout()), q, SLOT(signalUpdates()) );
63 bool isSession( int id ) const
65 return id < -1;
68 void emitUpdated()
70 if ( !timer.isActive() && !disabled )
71 timer.start();
74 QStringList sessions;
75 QMap<QString, int> idToSequence;
76 QMap<int, QString> sequenceToId;
77 QMap<QString, QStringList> jobs;
78 QMap<QString, JobInfo> infos;
79 int lastId;
80 QTimer timer;
81 bool disabled;
82 QList< QPair<int, int> > unpublishedAdds;
83 QList< QPair<int, int> > unpublishedUpdates;
84 private:
85 JobTracker* const q;
88 JobTracker::JobTracker( const char *name, QObject* parent )
89 :QObject( parent ), d( new Private( this ) )
91 new JobTrackerAdaptor( this );
92 QDBusConnection::sessionBus().registerService( QLatin1String("org.kde.akonadiconsole") );
93 QDBusConnection::sessionBus().registerObject( '/'+QLatin1String(name),
94 this, QDBusConnection::ExportAdaptors );
96 #if 0
97 // dummy data for testing
98 d->sessions << "one" << "two" << "three";
99 d->jobs.insert("one", QStringList() << "eins" );
100 d->jobs.insert("two", QStringList() );
101 d->jobs.insert("three", QStringList() );
103 // create some fake jobs
104 d->jobs.insert( "eins", QStringList() << "sub-eins" << "sub-zwei" );
105 d->idToSequence.insert( "eins", 0 );
106 d->sequenceToId.insert( 0, "eins" );
107 JobInfo info;
108 info.id = "eins";
109 info.parent = -2;
110 d->infos.insert( "eins", info );
112 d->jobs.insert( "sub-eins", QStringList() );
113 d->idToSequence.insert( "sub-eins", 1 );
114 d->sequenceToId.insert( 1, "sub-eins" );
115 info.id = "sub-eins";
116 info.parent = 0;
117 d->infos.insert( "sub-eins", info );
119 d->jobs.insert( "sub-zwei", QStringList() );
120 d->idToSequence.insert( "sub-zwei", 2 );
121 d->sequenceToId.insert( 2, "sub-zwei" );
122 info.id = "sub-zwei";
123 info.parent = 0;
124 d->infos.insert( "sub-zwei", info );
125 #endif
128 JobTracker::~JobTracker()
130 delete d;
133 void JobTracker::jobCreated( const QString & session, const QString & job, const QString & parent, const QString & jobType )
135 if ( d->disabled || session.isEmpty() || job.isEmpty() ) return;
137 if ( !parent.isEmpty() && !d->jobs.contains( parent ) )
139 qWarning() << "JobTracker: Job arrived before it's parent! Fix the library!";
140 jobCreated( session, parent, QString(),"dummy job type" );
142 // check if it's a new session, if so, add it
143 if (!d->sessions.contains( session ) )
145 d->sessions.append( session );
146 d->jobs.insert( session, QStringList() );
147 d->unpublishedAdds << QPair<int, int>( d->sessions.count()-1, -1 );
150 // deal with the job
151 if ( d->jobs.contains( job ) ) return; // duplicate?
153 d->jobs.insert( job, QStringList() );
155 JobInfo info;
156 info.id = job;
157 if ( parent.isEmpty() )
158 info.parent = idForSession( session );
159 else
160 info.parent = idForJob( parent );
161 info.state = JobInfo::Initial;
162 info.timestamp = QDateTime::currentDateTime();
163 info.type = jobType;
164 d->infos.insert( job, info );
165 const int id = d->lastId++;
166 d->idToSequence.insert( job, id );
167 d->sequenceToId.insert( id, job );
169 QString daddy;
170 if ( parent.isEmpty() )
171 daddy = session;
172 else
173 daddy = parent;
175 assert(!daddy.isEmpty());
176 QStringList kids = d->jobs[daddy];
177 kids << job;
178 const int pos = d->jobs[daddy].size();
179 d->jobs[daddy] = kids;
181 d->unpublishedAdds << QPair<int, int>( pos, info.parent );
182 d->emitUpdated();
185 void JobTracker::jobEnded( const QString& job, const QString& error )
187 // this is called from dbus, so better be defensive
188 if ( d->disabled || !d->jobs.contains( job ) || !d->infos.contains( job ) ) return;
190 JobInfo info = d->infos[job];
191 if ( error.isEmpty() ) {
192 info.state = JobInfo::Ended;
193 } else {
194 info.state = JobInfo::Failed;
195 info.error = error;
197 d->infos[job] = info;
199 d->unpublishedUpdates << QPair<int, int>( d->jobs[jobForId(info.parent)].size()-1, info.parent );
200 d->emitUpdated();
203 void JobTracker::jobStarted( const QString & job )
205 // this is called from dbus, so better be defensive
206 if ( d->disabled || !d->jobs.contains( job ) || !d->infos.contains( job ) ) return;
208 JobInfo info = d->infos[job];
209 info.state = JobInfo::Running;
210 d->infos[job] = info;
212 d->unpublishedUpdates << QPair<int, int>( d->jobs[jobForId(info.parent)].size()-1, info.parent );
213 d->emitUpdated();
216 QStringList JobTracker::sessions() const
218 return d->sessions;
221 QList<JobInfo> JobTracker::jobs( int id ) const
223 if ( d->isSession( id ) )
224 return jobs( sessionForId( id ) );
225 return jobs( jobForId( id ) );
228 QList<JobInfo> JobTracker::jobs( const QString & parent ) const
230 assert( d->jobs.contains(parent) );
231 const QStringList jobs = d->jobs[parent];
232 QList<JobInfo> infos;
233 Q_FOREACH( const QString &job, jobs )
235 infos << d->infos[job];
237 return infos;
240 // only works on jobs
241 int JobTracker::idForJob(const QString & job) const
243 assert( d->idToSequence.contains(job) );
244 return d->idToSequence[job];
247 QString JobTracker::jobForId(int id) const
249 if ( d->isSession( id ) )
250 return sessionForId( id );
251 assert( d->sequenceToId.contains(id) );
252 return d->sequenceToId[id];
256 // To find a session, we take the offset in the list of sessions
257 // in order of appearance, add one, and make it negative. That
258 // way we can discern session ids from job ids and use -1 for invalid
259 int JobTracker::idForSession(const QString & session) const
261 assert( d->sessions.contains( session ) );
262 return ( d->sessions.indexOf(session) + 2 ) * -1;
265 QString JobTracker::sessionForId(int _id) const
267 const int id = (-_id)-2;
268 assert( d->sessions.size() > id );
269 return d->sessions.at(id);
272 int JobTracker::parentId( int id ) const
274 if ( d->isSession( id ) )
276 return -1;
278 else
280 const QString job = d->sequenceToId[id];
281 return d->infos[job].parent;
286 JobInfo JobTracker::info( int id) const
288 return info( jobForId( id ) );
291 JobInfo JobTracker::info(const QString & job) const
293 assert( d->infos.contains(job) );
294 return d->infos[job];
297 void JobTracker::triggerReset()
299 d->sessions.clear();
300 d->idToSequence.clear();
301 d->sequenceToId.clear();
302 d->jobs.clear();
303 d->infos.clear();
305 emit reset();
308 void JobTracker::setEnabled( bool on )
310 d->disabled = !on;
313 bool JobTracker::isEnabled() const
315 return !d->disabled;
318 void JobTracker::signalUpdates()
320 emit added( d->unpublishedAdds );
321 emit updated( d->unpublishedUpdates );
322 d->unpublishedAdds.clear();
323 d->unpublishedUpdates.clear();
326 #include "jobtracker.moc"