• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.9.1 API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • akonadi
changerecorder_p.h
1 /*
2  Copyright (c) 2007 Volker Krause <vkrause@kde.org>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #ifndef AKONADI_CHANGERECORDER_P_H
21 #define AKONADI_CHANGERECORDER_P_H
22 
23 #include "akonadiprivate_export.h"
24 #include "monitor_p.h"
25 
26 class AKONADI_TESTS_EXPORT Akonadi::ChangeRecorderPrivate : public Akonadi::MonitorPrivate
27 {
28  public:
29  ChangeRecorderPrivate( ChangeNotificationDependenciesFactory *dependenciesFactory_, ChangeRecorder* parent ) :
30  MonitorPrivate( dependenciesFactory_, parent ),
31  settings( 0 ),
32  enableChangeRecording( true )
33  {
34  }
35 
36  Q_DECLARE_PUBLIC( ChangeRecorder )
37  QSettings *settings;
38  bool enableChangeRecording;
39 
40  virtual int pipelineSize() const
41  {
42  if ( enableChangeRecording )
43  return 0; // we fill the pipeline ourselves when using change recording
44  return MonitorPrivate::pipelineSize();
45  }
46 
47  virtual void slotNotify( const NotificationMessage::List &msgs )
48  {
49  Q_Q( ChangeRecorder );
50  const int oldChanges = pendingNotifications.size();
51  MonitorPrivate::slotNotify( msgs ); // with change recording disabled this will automatically take care of dispatching notification messages
52  if ( enableChangeRecording && pendingNotifications.size() != oldChanges ) {
53  saveNotifications();
54  emit q->changesAdded();
55  }
56  }
57 
58  virtual bool emitNotification(const Akonadi::NotificationMessage& msg)
59  {
60  const bool someoneWasListening = MonitorPrivate::emitNotification( msg );
61  if ( !someoneWasListening && enableChangeRecording )
62  QMetaObject::invokeMethod( q_ptr, "replayNext", Qt::QueuedConnection ); // skip notifications no one was listening to
63  return someoneWasListening;
64  }
65 
66  QString notificationsFileName() const
67  {
68  return settings->fileName() + QLatin1String( "_changes.dat" );
69  }
70 
71  void loadNotifications()
72  {
73  pendingNotifications.clear();
74 
75  const QString changesFileName = notificationsFileName();
76 
83  if ( !QFile::exists( changesFileName ) ) {
84  QStringList list;
85  settings->beginGroup( QLatin1String( "ChangeRecorder" ) );
86  const int size = settings->beginReadArray( QLatin1String( "change" ) );
87 
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;
106  }
107 
108  settings->endArray();
109 
110  // save notifications to the new file...
111  saveNotifications();
112 
113  // ...delete the legacy list...
114  settings->remove( QString() );
115  settings->endGroup();
116 
117  // ...and continue as usually
118  }
119 
120  QFile file( changesFileName );
121  if ( !file.open( QIODevice::ReadOnly ) )
122  return;
123  pendingNotifications = loadFrom( &file );
124  }
125 
126  QQueue<NotificationMessage> loadFrom( QIODevice *device )
127  {
128  QDataStream stream( device );
129  stream.setVersion( QDataStream::Qt_4_6 );
130 
131  qulonglong size;
132  QByteArray sessionId, resource;
133  int type, operation;
134  qlonglong uid, parentCollection, parentDestCollection;
135  QString remoteId, mimeType;
136  QSet<QByteArray> itemParts;
137 
138  QQueue<NotificationMessage> list;
139 
140  stream >> size;
141  for ( qulonglong i = 0; i < size; ++i ) {
142  NotificationMessage msg;
143 
144  stream >> sessionId;
145  stream >> type;
146  stream >> operation;
147  stream >> uid;
148  stream >> remoteId;
149  stream >> resource;
150  stream >> parentCollection;
151  stream >> parentDestCollection;
152  stream >> mimeType;
153  stream >> itemParts;
154 
155  msg.setSessionId( sessionId );
156  msg.setType( static_cast<NotificationMessage::Type>( type ) );
157  msg.setOperation( static_cast<NotificationMessage::Operation>( operation ) );
158  msg.setUid( uid );
159  msg.setRemoteId( remoteId );
160  msg.setResource( resource );
161  msg.setParentCollection( parentCollection );
162  msg.setParentDestCollection( parentDestCollection );
163  msg.setMimeType( mimeType );
164  msg.setItemParts( itemParts );
165  list << msg;
166  }
167  return list;
168  }
169 
170  QString dumpNotificationListToString() const
171  {
172  if ( !settings )
173  return QString::fromLatin1( "No settings set in ChangeRecorder yet." );
174  QString result;
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 );
180 
181  qulonglong size;
182  QByteArray sessionId, resource;
183  int type, operation;
184  qlonglong uid, parentCollection, parentDestCollection;
185  QString remoteId, mimeType;
186  QSet<QByteArray> itemParts;
187 
188  QStringList list;
189 
190  stream >> size;
191  for ( qulonglong i = 0; i < size; ++i ) {
192  stream >> sessionId;
193  stream >> type;
194  stream >> operation;
195  stream >> uid;
196  stream >> remoteId;
197  stream >> resource;
198  stream >> parentCollection;
199  stream >> parentDestCollection;
200  stream >> mimeType;
201  stream >> itemParts;
202 
203  QString typeString;
204  switch ( type ) {
205  case NotificationMessage::Collection:
206  typeString = QLatin1String( "Collection" );
207  break;
208  case NotificationMessage::Item:
209  typeString = QLatin1String( "Item" );
210  break;
211  default:
212  typeString = QLatin1String( "InvalidType" );
213  break;
214  };
215 
216  QString operationString;
217  switch ( operation ) {
218  case NotificationMessage::Add:
219  operationString = QLatin1String( "Add" );
220  break;
221  case NotificationMessage::Modify:
222  operationString = QLatin1String( "Modify" );
223  break;
224  case NotificationMessage::Move:
225  operationString = QLatin1String( "Move" );
226  break;
227  case NotificationMessage::Remove:
228  operationString = QLatin1String( "Remove" );
229  break;
230  case NotificationMessage::Link:
231  operationString = QLatin1String( "Link" );
232  break;
233  case NotificationMessage::Unlink:
234  operationString = QLatin1String( "Unlink" );
235  break;
236  case NotificationMessage::Subscribe:
237  operationString = QLatin1String( "Subscribe" );
238  break;
239  case NotificationMessage::Unsubscribe:
240  operationString = QLatin1String( "Unsubscribe" );
241  break;
242  default:
243  operationString = QLatin1String( "InvalidOp" );
244  break;
245  };
246 
247  QStringList itemPartsList;
248  foreach( const QByteArray &b, itemParts )
249  itemPartsList.push_back( QString::fromLatin1(b) );
250 
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 ) )
253  .arg( typeString )
254  .arg( operationString )
255  .arg( uid )
256  .arg( remoteId )
257  .arg( QString::fromLatin1( resource ) )
258  .arg( parentCollection )
259  .arg( parentDestCollection )
260  .arg( mimeType )
261  .arg( itemPartsList.join(QLatin1String(", " )) );
262 
263  result += entry + QLatin1Char('\n');
264  }
265 
266  }
267  return result;
268  }
269 
270  void addToStream( QDataStream &stream, const NotificationMessage &msg )
271  {
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();
282  }
283 
284  void saveNotifications()
285  {
286  if ( !settings )
287  return;
288 
289  QFile file( notificationsFileName() );
290  QFileInfo info( file );
291  if ( !QFile::exists( info.absolutePath() ) ) {
292  QDir dir;
293  dir.mkpath( info.absolutePath() );
294  }
295  if ( !file.open( QIODevice::WriteOnly ) ) {
296  qWarning() << "could not save notifications to file " << file.fileName();
297  return;
298  }
299  saveTo(&file);
300  }
301 
302  void saveTo( QIODevice *device )
303  {
304 
305  QDataStream stream( device );
306  stream.setVersion( QDataStream::Qt_4_6 );
307 
308  stream << (qulonglong)(pipeline.count() + pendingNotifications.count());
309 
310  for ( int i = 0; i < pipeline.count(); ++i ) {
311  const NotificationMessage msg = pipeline.at( i );
312  addToStream( stream, msg );
313  }
314 
315  for ( int i = 0; i < pendingNotifications.count(); ++i ) {
316  const NotificationMessage msg = pendingNotifications.at( i );
317  addToStream( stream, msg );
318  }
319  }
320 };
321 
322 #endif
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Sep 24 2012 09:06:24 by doxygen 1.8.1.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules
  • Related Pages

kdepimlibs-4.9.1 API Reference

Skip menu "kdepimlibs-4.9.1 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal