Astyle kdelibs
[kdepim.git] / akonadiconsole / jobtrackermodel.cpp
blob2533740a63d494983e197d8ac6523a6a75d70ffa
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 "jobtrackermodel.h"
24 #include "jobtracker.h"
26 #include <QLocale>
27 #include <QStringList>
28 #include <QModelIndex>
29 #include <QDateTime>
30 #include <QFont>
31 #include <QPair>
32 #include <QColor>
34 #include <cassert>
36 class JobTrackerModel::Private
38 public:
39 Private(const char *name, JobTrackerModel *_q)
40 : q(_q), tracker(name)
44 int rowForParentId(int parentid)
46 const int grandparentid = tracker.parentId(parentid);
47 int row = -1;
48 if (grandparentid == -1) {
49 const QString session = tracker.sessionForId(parentid);
50 if (!session.isEmpty()) {
51 row = tracker.sessions().indexOf(session);
53 } else {
54 // offset of the parent in the list of children of the grandparent
55 row = tracker.jobNames(grandparentid).indexOf(tracker.jobForId(parentid));
57 return row;
60 private:
61 JobTrackerModel *const q;
62 public:
63 JobTracker tracker;
66 JobTrackerModel::JobTrackerModel(const char *name, QObject *parent)
67 : QAbstractItemModel(parent), d(new Private(name, this))
69 connect(&d->tracker, SIGNAL(reset()),
70 this, SIGNAL(modelReset()));
71 connect(&d->tracker, &JobTracker::added,
72 this, &JobTrackerModel::jobsAdded);
73 connect(&d->tracker, &JobTracker::updated,
74 this, &JobTrackerModel::jobsUpdated);
77 JobTrackerModel::~JobTrackerModel()
79 delete d;
82 QModelIndex JobTrackerModel::index(int row, int column, const QModelIndex &parent) const
84 if (!parent.isValid()) { // session, at top level
85 if (row < 0 || row >= d->tracker.sessions().size()) {
86 return QModelIndex();
88 return createIndex(row, column, d->tracker.idForSession(d->tracker.sessions().at(row)));
90 // non-toplevel job
91 const QStringList jobs = d->tracker.jobNames(parent.internalId());
92 if (row >= jobs.size()) {
93 return QModelIndex();
95 return createIndex(row, column, d->tracker.idForJob(jobs.at(row)));
98 QModelIndex JobTrackerModel::parent(const QModelIndex &idx) const
100 if (!idx.isValid()) {
101 return QModelIndex();
104 const int parentid = d->tracker.parentId(idx.internalId());
105 if (parentid == -1) {
106 return QModelIndex(); // top level session
109 const int row = d->rowForParentId(parentid);
110 if (row >= 0) {
111 return createIndex(row, 0, parentid);
112 } else {
113 return QModelIndex();
117 int JobTrackerModel::rowCount(const QModelIndex &parent) const
119 if (!parent.isValid()) {
120 return d->tracker.sessions().size();
121 } else {
122 return d->tracker.jobNames(parent.internalId()).size();
126 int JobTrackerModel::columnCount(const QModelIndex &parent) const
128 Q_UNUSED(parent);
129 return 7;
132 static QString formatTimeWithMsec(const QTime &time)
134 return QString(QLocale().toString(time)
135 + QStringLiteral(".%1").arg(time.msec(), 3, 10, QLatin1Char('0')));
138 static QString formatDurationWithMsec(qint64 msecs)
140 QTime time(0, 0, 0);
141 time = time.addMSecs(msecs);
142 return formatTimeWithMsec(time);
145 QVariant JobTrackerModel::data(const QModelIndex &idx, int role) const
147 // top level items are sessions
148 if (!idx.parent().isValid()) {
149 if (role == Qt::DisplayRole) {
150 const QStringList sessions = d->tracker.sessions();
151 if (idx.column() == 0 && idx.row() <= sessions.size()) {
152 return sessions.at(idx.row());
155 } else { // not top level, so a job or subjob
156 const int id = idx.internalId();
157 const JobInfo info = d->tracker.info(id);
158 if (role == Qt::DisplayRole) {
159 switch (idx.column()) {
160 case 0:
161 return info.id;
162 case 1:
163 return formatTimeWithMsec(info.timestamp.time());
164 case 2:
165 if (info.startedTimestamp.isNull() || info.timestamp.isNull()) {
166 return QString();
168 return formatDurationWithMsec(info.timestamp.msecsTo(info.startedTimestamp));
169 case 3:
170 if (info.endedTimestamp.isNull() || info.startedTimestamp.isNull()) {
171 return QString();
173 return formatDurationWithMsec(info.startedTimestamp.msecsTo(info.endedTimestamp));
174 case 4:
175 return info.type;
176 case 5:
177 return info.stateAsString();
178 case 6:
179 return info.debugString;
181 } else if (role == Qt::ForegroundRole) {
182 if (info.state == JobInfo::Failed) {
183 return QColor(Qt::red);
185 } else if (role == Qt::FontRole) {
186 if (info.state == JobInfo::Running) {
187 QFont f;
188 f.setBold(true);
189 return f;
191 } else if (role == Qt::ToolTipRole) {
192 if (info.state == JobInfo::Failed) {
193 return info.error;
197 return QVariant();
200 QVariant JobTrackerModel::headerData(int section, Qt::Orientation orientation, int role) const
202 if (role == Qt::DisplayRole) {
203 if (orientation == Qt::Horizontal) {
204 switch (section) {
205 case 0:
206 return QStringLiteral("Job ID");
207 case 1:
208 return QStringLiteral("Created");
209 case 2:
210 return QStringLiteral("Wait time"); // duration (time started - time created)
211 case 3:
212 return QStringLiteral("Job duration"); // duration (time ended - time started)
213 case 4:
214 return QStringLiteral("Job Type");
215 case 5:
216 return QStringLiteral("State");
217 case 6:
218 return QStringLiteral("Info");
222 return QVariant();
225 void JobTrackerModel::resetTracker()
227 d->tracker.triggerReset();
230 bool JobTrackerModel::isEnabled() const
232 return d->tracker.isEnabled();
235 void JobTrackerModel::setEnabled(bool on)
237 d->tracker.setEnabled(on);
240 void JobTrackerModel::jobsAdded(const QList< QPair< int, int > > &jobs)
242 // TODO group them by parent? It's likely that multiple jobs for the same
243 // parent will come in in the same batch, isn't it?
244 #define PAIR QPair<int, int> // the parser in foreach barfs otherwise
245 Q_FOREACH (const PAIR &job, jobs) {
246 const int pos = job.first;
247 const int parentId = job.second;
248 QModelIndex parentIdx;
249 if (parentId != -1) {
250 const int row = d->rowForParentId(parentId);
251 if (row >= 0) {
252 parentIdx = createIndex(row, 0, parentId);
255 beginInsertRows(parentIdx, pos, pos);
256 endInsertRows();
258 #undef PAIR
261 void JobTrackerModel::jobsUpdated(const QList< QPair< int, int > > &jobs)
263 // TODO group them by parent? It's likely that multiple jobs for the same
264 // parent will come in in the same batch, isn't it?
265 #define PAIR QPair<int, int> // the parser in foreach barfs otherwise
266 Q_FOREACH (const PAIR &job, jobs) {
267 const int pos = job.first;
268 const int parentId = job.second;
269 QModelIndex parentIdx;
270 if (parentId != -1) {
271 const int row = d->rowForParentId(parentId);
272 if (row >= 0) {
273 parentIdx = createIndex(row, 0, parentId);
276 dataChanged(index(pos, 0, parentIdx), index(pos, 3, parentIdx));
278 #undef PAIR