20 #ifndef AKONADI_CHANGERECORDER_P_H
21 #define AKONADI_CHANGERECORDER_P_H
23 #include "akonadiprivate_export.h"
24 #include "monitor_p.h"
26 class AKONADI_TESTS_EXPORT Akonadi::ChangeRecorderPrivate :
public Akonadi::MonitorPrivate
29 ChangeRecorderPrivate( ChangeNotificationDependenciesFactory *dependenciesFactory_, ChangeRecorder* parent ) :
30 MonitorPrivate( dependenciesFactory_, parent ),
32 enableChangeRecording( true )
36 Q_DECLARE_PUBLIC( ChangeRecorder )
38 bool enableChangeRecording;
40 virtual
int pipelineSize()
const
42 if ( enableChangeRecording )
44 return MonitorPrivate::pipelineSize();
47 virtual void slotNotify(
const NotificationMessage::List &msgs )
49 Q_Q( ChangeRecorder );
50 const int oldChanges = pendingNotifications.size();
51 MonitorPrivate::slotNotify( msgs );
52 if ( enableChangeRecording && pendingNotifications.size() != oldChanges ) {
54 emit q->changesAdded();
58 virtual bool emitNotification(
const Akonadi::NotificationMessage& msg)
60 const bool someoneWasListening = MonitorPrivate::emitNotification( msg );
61 if ( !someoneWasListening && enableChangeRecording )
62 QMetaObject::invokeMethod( q_ptr,
"replayNext", Qt::QueuedConnection );
63 return someoneWasListening;
66 QString notificationsFileName()
const
68 return settings->fileName() + QLatin1String(
"_changes.dat" );
71 void loadNotifications()
73 pendingNotifications.clear();
75 const QString changesFileName = notificationsFileName();
83 if ( !QFile::exists( changesFileName ) ) {
85 settings->beginGroup( QLatin1String(
"ChangeRecorder" ) );
86 const int size = settings->beginReadArray( QLatin1String(
"change" ) );
88 for (
int i = 0; i < size; ++i ) {
89 settings->setArrayIndex( i );
90 NotificationMessage msg;
91 msg.setSessionId( settings->value( QLatin1String(
"sessionId" ) ).toByteArray() );
92 msg.setType( (NotificationMessage::Type)settings->value( QLatin1String(
"type" ) ).toInt() );
93 msg.setOperation( (NotificationMessage::Operation)settings->value( QLatin1String(
"op" ) ).toInt() );
94 msg.setUid( settings->value( QLatin1String(
"uid" ) ).toLongLong() );
95 msg.setRemoteId( settings->value( QLatin1String(
"rid" ) ).toString() );
96 msg.setResource( settings->value( QLatin1String(
"resource" ) ).toByteArray() );
97 msg.setParentCollection( settings->value( QLatin1String(
"parentCol" ) ).toLongLong() );
98 msg.setParentDestCollection( settings->value( QLatin1String(
"parentDestCol" ) ).toLongLong() );
99 msg.setMimeType( settings->value( QLatin1String(
"mimeType" ) ).toString() );
100 list = settings->value( QLatin1String(
"itemParts" ) ).toStringList();
101 QSet<QByteArray> itemParts;
102 Q_FOREACH(
const QString &entry, list )
103 itemParts.insert( entry.toLatin1() );
104 msg.setItemParts( itemParts );
105 pendingNotifications << msg;
108 settings->endArray();
114 settings->remove( QString() );
115 settings->endGroup();
120 QFile file( changesFileName );
121 if ( !file.open( QIODevice::ReadOnly ) )
123 pendingNotifications = loadFrom( &file );
126 QQueue<NotificationMessage> loadFrom( QIODevice *device )
128 QDataStream stream( device );
129 stream.setVersion( QDataStream::Qt_4_6 );
132 QByteArray sessionId, resource;
134 qlonglong uid, parentCollection, parentDestCollection;
135 QString remoteId, mimeType;
136 QSet<QByteArray> itemParts;
138 QQueue<NotificationMessage> list;
141 for ( qulonglong i = 0; i < size; ++i ) {
142 NotificationMessage msg;
150 stream >> parentCollection;
151 stream >> parentDestCollection;
155 msg.setSessionId( sessionId );
156 msg.setType( static_cast<NotificationMessage::Type>( type ) );
157 msg.setOperation( static_cast<NotificationMessage::Operation>( operation ) );
159 msg.setRemoteId( remoteId );
160 msg.setResource( resource );
161 msg.setParentCollection( parentCollection );
162 msg.setParentDestCollection( parentDestCollection );
163 msg.setMimeType( mimeType );
164 msg.setItemParts( itemParts );
170 QString dumpNotificationListToString()
const
173 return QString::fromLatin1(
"No settings set in ChangeRecorder yet." );
175 const QString changesFileName = notificationsFileName();
176 QFile file( changesFileName );
177 if ( file.open( QIODevice::ReadOnly ) ) {
178 QDataStream stream( &file );
179 stream.setVersion( QDataStream::Qt_4_6 );
182 QByteArray sessionId, resource;
184 qlonglong uid, parentCollection, parentDestCollection;
185 QString remoteId, mimeType;
186 QSet<QByteArray> itemParts;
191 for ( qulonglong i = 0; i < size; ++i ) {
198 stream >> parentCollection;
199 stream >> parentDestCollection;
205 case NotificationMessage::Collection:
206 typeString = QLatin1String(
"Collection" );
208 case NotificationMessage::Item:
209 typeString = QLatin1String(
"Item" );
212 typeString = QLatin1String(
"InvalidType" );
216 QString operationString;
217 switch ( operation ) {
218 case NotificationMessage::Add:
219 operationString = QLatin1String(
"Add" );
221 case NotificationMessage::Modify:
222 operationString = QLatin1String(
"Modify" );
224 case NotificationMessage::Move:
225 operationString = QLatin1String(
"Move" );
227 case NotificationMessage::Remove:
228 operationString = QLatin1String(
"Remove" );
230 case NotificationMessage::Link:
231 operationString = QLatin1String(
"Link" );
233 case NotificationMessage::Unlink:
234 operationString = QLatin1String(
"Unlink" );
236 case NotificationMessage::Subscribe:
237 operationString = QLatin1String(
"Subscribe" );
239 case NotificationMessage::Unsubscribe:
240 operationString = QLatin1String(
"Unsubscribe" );
243 operationString = QLatin1String(
"InvalidOp" );
247 QStringList itemPartsList;
248 foreach(
const QByteArray &b, itemParts )
249 itemPartsList.push_back( QString::fromLatin1(b) );
251 const QString entry = QString::fromLatin1(
"session=%1 type=%2 operation=%3 uid=%4 remoteId=%5 resource=%6 parentCollection=%7 parentDestCollection=%8 mimeType=%9 itemParts=%10")
252 .arg( QString::fromLatin1( sessionId ) )
254 .arg( operationString )
257 .arg( QString::fromLatin1( resource ) )
258 .arg( parentCollection )
259 .arg( parentDestCollection )
261 .arg( itemPartsList.join(QLatin1String(
", " )) );
263 result += entry + QLatin1Char(
'\n');
270 void addToStream( QDataStream &stream,
const NotificationMessage &msg )
272 stream << msg.sessionId();
273 stream << int(msg.type());
274 stream << int(msg.operation());
275 stream << qulonglong(msg.uid());
276 stream << msg.remoteId();
277 stream << msg.resource();
278 stream << qulonglong(msg.parentCollection());
279 stream << qulonglong(msg.parentDestCollection());
280 stream << msg.mimeType();
281 stream << msg.itemParts();
284 void saveNotifications()
289 QFile file( notificationsFileName() );
290 QFileInfo info( file );
291 if ( !QFile::exists( info.absolutePath() ) ) {
293 dir.mkpath( info.absolutePath() );
295 if ( !file.open( QIODevice::WriteOnly ) ) {
296 qWarning() <<
"could not save notifications to file " << file.fileName();
302 void saveTo( QIODevice *device )
305 QDataStream stream( device );
306 stream.setVersion( QDataStream::Qt_4_6 );
308 stream << (qulonglong)(pipeline.count() + pendingNotifications.count());
310 for (
int i = 0; i < pipeline.count(); ++i ) {
311 const NotificationMessage msg = pipeline.at( i );
312 addToStream( stream, msg );
315 for (
int i = 0; i < pendingNotifications.count(); ++i ) {
316 const NotificationMessage msg = pendingNotifications.at( i );
317 addToStream( stream, msg );