SVN_SILENT made messages (.desktop file) - always resolve ours
[kdepim.git] / akonadiconsole / notificationmodel.cpp
blobbb74d0a0a7764a944146d6b495c11dd54e71e087
1 /*
2 Copyright (c) 2009 Volker Krause <vkrause@kde.org>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
17 USA.
20 #include "notificationmodel.h"
22 #include <QCoreApplication>
23 #include <QBuffer>
24 #include <QtDBus/QDBusConnection>
25 #include <QtDBus/QDBusPendingCall>
27 #include <QLocale>
29 #include "akonadiconsole_debug.h"
30 #include <AkonadiCore/ServerManager>
32 #include <akonadi/private/imapparser_p.h>
33 #include <akonadi/private/protocol_p.h>
34 #include <QMetaMethod>
36 using namespace Akonadi;
38 class NotificationModel::Item
40 public:
41 Item(int type_): type(type_) {}
42 virtual ~Item() {}
44 int type;
47 class NotificationModel::NotificationBlock: public NotificationModel::Item
49 public:
50 NotificationBlock(const Akonadi::Protocol::ChangeNotification::List &msgs);
51 ~NotificationBlock();
53 QList<NotificationNode *> nodes;
54 QDateTime timestamp;
57 class NotificationModel::NotificationNode: public NotificationModel::Item
59 public:
60 NotificationNode(const Protocol::ChangeNotification &msg_, NotificationBlock *parent_);
61 ~NotificationNode();
63 QByteArray sessionId;
64 Protocol::ChangeNotification::Type type;
65 Protocol::ChangeNotification::Operation operation;
66 QByteArray resource;
67 QByteArray destResource;
68 Protocol::ChangeNotification::Id parentCollection;
69 Protocol::ChangeNotification::Id destCollection;
70 QSet<QByteArray> parts;
71 QSet<QByteArray> addedFlags;
72 QSet<QByteArray> removedFlags;
73 QList<NotificationEntity *> entities;
74 NotificationBlock *parent;
77 class NotificationModel::NotificationEntity: public NotificationModel::Item
79 public:
80 NotificationEntity(const Protocol::ChangeNotification::Entity &entity, NotificationNode *parent_);
82 Protocol::ChangeNotification::Id id;
83 QString remoteId;
84 QString remoteRevision;
85 QString mimeType;
86 NotificationNode *parent;
89 NotificationModel::NotificationBlock::NotificationBlock(const Protocol::ChangeNotification::List &msgs) :
90 Item(0)
92 timestamp = QDateTime::currentDateTime();
93 Q_FOREACH (const Protocol::ChangeNotification &msg, msgs) {
94 nodes << new NotificationNode(msg, this);
98 NotificationModel::NotificationBlock::~NotificationBlock()
100 qDeleteAll(nodes);
103 NotificationModel::NotificationNode::NotificationNode(const Protocol::ChangeNotification &msg, NotificationModel::NotificationBlock *parent_):
104 Item(1),
105 sessionId(msg.sessionId()),
106 type(msg.type()),
107 operation(msg.operation()),
108 resource(msg.resource()),
109 destResource(msg.destinationResource()),
110 parentCollection(msg.parentCollection()),
111 destCollection(msg.parentDestCollection()),
112 parts(msg.itemParts()),
113 addedFlags(msg.addedFlags()),
114 removedFlags(msg.removedFlags()),
115 parent(parent_)
117 Q_FOREACH (const Protocol::ChangeNotification::Entity &entity, msg.entities()) {
118 entities << new NotificationEntity(entity, this);
122 NotificationModel::NotificationNode::~NotificationNode()
124 qDeleteAll(entities);
127 NotificationModel::NotificationEntity::NotificationEntity(const Protocol::ChangeNotification::Entity &entity, NotificationModel::NotificationNode *parent_):
128 Item(2),
129 id(entity.id),
130 remoteId(entity.remoteId),
131 remoteRevision(entity.remoteRevision),
132 mimeType(entity.mimeType),
133 parent(parent_)
137 NotificationModel::NotificationModel(QObject *parent) :
138 QAbstractItemModel(parent)
140 QString service = QStringLiteral("org.freedesktop.Akonadi");
141 if (Akonadi::ServerManager::hasInstanceIdentifier()) {
142 service += QLatin1String(".") + Akonadi::ServerManager::instanceIdentifier();
144 m_manager = new QDBusInterface(service, QStringLiteral("/notifications/debug"),
145 QStringLiteral("org.freedesktop.Akonadi.NotificationManager"),
146 QDBusConnection::sessionBus(),
147 this);
148 if (!m_manager->isValid()) {
149 qCWarning(AKONADICONSOLE_LOG) << "Unable to connect to notification manager";
150 delete m_manager;
151 m_manager = 0;
152 } else {
153 connect(m_manager, SIGNAL(debugNotify(QVector<QByteArray>)),
154 this, SLOT(slotNotify(QVector<QByteArray>)));
158 NotificationModel::~NotificationModel()
160 setEnabled(false);
163 int NotificationModel::columnCount(const QModelIndex &parent) const
165 Q_UNUSED(parent);
166 return 10;
169 int NotificationModel::rowCount(const QModelIndex &parent) const
171 if (!parent.isValid()) {
172 return m_data.size();
175 Item *parentItem = static_cast<Item *>(parent.internalPointer());
176 if (parentItem) {
177 if (parentItem->type == 0) {
178 return static_cast<NotificationBlock *>(parentItem)->nodes.count();
179 } else if (parentItem->type == 1) {
180 return static_cast<NotificationNode *>(parentItem)->entities.count();
184 return 0;
187 QModelIndex NotificationModel::index(int row, int column, const QModelIndex &parent) const
189 if (!parent.isValid()) {
190 if (row >= m_data.count()) {
191 return QModelIndex();
193 return createIndex(row, column, m_data.at(row));
196 Item *parentItem = static_cast<Item *>(parent.internalPointer());
197 if (parentItem) {
198 if (parentItem ->type == 0) {
199 NotificationBlock *parentBlock = static_cast<NotificationBlock *>(parentItem);
200 return createIndex(row, column, parentBlock->nodes.at(row));
201 } else if (parentItem->type == 1) {
202 NotificationNode *parentNode = static_cast<NotificationNode *>(parentItem);
203 return createIndex(row, column, parentNode->entities.at(row));
207 return QModelIndex();
210 QModelIndex NotificationModel::parent(const QModelIndex &child) const
212 if (!child.isValid()) {
213 return QModelIndex();
216 Item *childItem = static_cast<Item *>(child.internalPointer());
217 if (childItem) {
218 if (childItem->type == 0) {
219 return QModelIndex();
220 } else if (childItem->type == 1) {
221 NotificationNode *childNode = static_cast<NotificationNode *>(childItem);
222 return createIndex(m_data.indexOf(childNode->parent), 0, childNode->parent);
223 } else if (childItem->type == 2) {
224 NotificationEntity *childEntity = static_cast<NotificationEntity *>(childItem);
225 NotificationNode *parentNode = childEntity->parent;
226 return createIndex(parentNode->parent->nodes.indexOf(parentNode), 0, childEntity->parent);
230 return QModelIndex();
233 QVariant NotificationModel::data(const QModelIndex &index, int role) const
235 if (!index.isValid()) {
236 return QVariant();
239 Item *item = static_cast<Item *>(index.internalPointer());
240 if (!item) {
241 return QVariant();
244 if (item->type == 0) {
245 NotificationBlock *block = static_cast<NotificationBlock *>(item);
246 if (role == Qt::DisplayRole) {
247 switch (index.column()) {
248 case 0:
249 return QString(QLocale().toString(block->timestamp.time()) +
250 QStringLiteral(".%1").arg(block->timestamp.time().msec(), 3, 10, QLatin1Char('0')));
251 case 1:
252 return block->nodes.count();
255 } else if (item->type == 1) {
256 NotificationNode *node = static_cast<NotificationNode *>(item);
257 if (role == Qt::DisplayRole) {
258 switch (index.column()) {
259 case 0: {
260 switch (node->operation) {
261 case Protocol::ChangeNotification::Add: return QStringLiteral("Add");
262 case Protocol::ChangeNotification::Modify: return QStringLiteral("Modify");
263 case Protocol::ChangeNotification::ModifyFlags: return QStringLiteral("ModifyFlags");
264 case Protocol::ChangeNotification::ModifyTags: return QStringLiteral("ModifyTags");
265 case Protocol::ChangeNotification::Move: return QStringLiteral("Move");
266 case Protocol::ChangeNotification::Remove: return QStringLiteral("Delete");
267 case Protocol::ChangeNotification::Link: return QStringLiteral("Link");
268 case Protocol::ChangeNotification::Unlink: return QStringLiteral("Unlink");
269 case Protocol::ChangeNotification::Subscribe: return QStringLiteral("Subscribe");
270 case Protocol::ChangeNotification::Unsubscribe: return QStringLiteral("Unsubscribe");
271 default: return QStringLiteral("Invalid");
274 case 1: {
275 switch (node->type) {
276 case Protocol::ChangeNotification::Collections: return QStringLiteral("Collections");
277 case Protocol::ChangeNotification::Items: return QStringLiteral("Items");
278 case Protocol::ChangeNotification::Tags: return QStringLiteral("Tags");
279 default: return QStringLiteral("Invalid");
282 case 2:
283 return QString::fromUtf8(node->sessionId);
284 case 3:
285 return QString::fromUtf8(node->resource);
286 case 4:
287 return QString::fromUtf8(node->destResource);
288 case 5:
289 return QString::number(node->parentCollection);
290 case 6:
291 return QString::number(node->destCollection);
292 case 7:
293 return QString::fromUtf8(Akonadi::ImapParser::join(node->parts, ", "));
294 case 8:
295 return QString::fromUtf8(Akonadi::ImapParser::join(node->addedFlags, ", "));
296 case 9:
297 return QString::fromUtf8(Akonadi::ImapParser::join(node->removedFlags, ", "));
300 } else if (item->type == 2) {
301 NotificationEntity *entity = static_cast<NotificationEntity *>(item);
302 if (role == Qt::DisplayRole) {
303 switch (index.column()) {
304 case 0:
305 return entity->id;
306 case 1:
307 return entity->remoteId;
308 case 2:
309 return entity->remoteRevision;
310 case 3:
311 return entity->mimeType;
316 return QVariant();
319 QVariant NotificationModel::headerData(int section, Qt::Orientation orientation, int role) const
321 if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
322 switch (section) {
323 case 0: return QStringLiteral("Operation / ID");
324 case 1: return QStringLiteral("Type / RID");
325 case 2: return QStringLiteral("Session / REV");
326 case 3: return QStringLiteral("Resource / MimeType");
327 case 4: return QStringLiteral("Destination Resource");
328 case 5: return QStringLiteral("Parent");
329 case 6: return QStringLiteral("Destination");
330 case 7: return QStringLiteral("Parts");
331 case 8: return QStringLiteral("Added Flags");
332 case 9: return QStringLiteral("Removed Flags");
335 return QAbstractItemModel::headerData(section, orientation, role);
338 void NotificationModel::slotNotify(const QVector<QByteArray> &data)
340 Protocol::ChangeNotification::List ntfs;
341 ntfs.reserve(data.size());
342 Q_FOREACH (const QByteArray &d, data) {
343 QBuffer buffer(const_cast<QByteArray *>(&d));
344 buffer.open(QIODevice::ReadOnly);
345 ntfs << Protocol::deserialize(&buffer);
348 beginInsertRows(QModelIndex(), m_data.size(), m_data.size());
349 m_data.append(new NotificationBlock(ntfs));
350 endInsertRows();
353 void NotificationModel::clear()
355 qDeleteAll(m_data);
356 m_data.clear();
357 reset();
360 void NotificationModel::setEnabled(bool enable)
362 if (m_manager) {
363 m_manager->asyncCall(QStringLiteral("enableDebug"), enable);