akonadi
changerecorder.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "changerecorder.h"
00021 #include "monitor_p.h"
00022
00023 #include <kdebug.h>
00024 #include <QtCore/QSettings>
00025
00026 using namespace Akonadi;
00027
00028 class Akonadi::ChangeRecorderPrivate : public MonitorPrivate
00029 {
00030 public:
00031 ChangeRecorderPrivate( ChangeRecorder* parent ) :
00032 MonitorPrivate( parent ),
00033 settings( 0 ),
00034 enableChangeRecording( true )
00035 {
00036 }
00037
00038 Q_DECLARE_PUBLIC( ChangeRecorder )
00039 NotificationMessage::List pendingNotifications;
00040 QSettings *settings;
00041 bool enableChangeRecording;
00042
00043 virtual void slotNotify( const NotificationMessage::List &msgs )
00044 {
00045 if ( !enableChangeRecording ) {
00046 foreach( const NotificationMessage &msg, msgs )
00047 processNotification( msg );
00048 return;
00049 }
00050
00051 Q_Q( ChangeRecorder );
00052 int oldChanges = pendingNotifications.count();
00053 foreach ( const NotificationMessage &msg, msgs ) {
00054 if ( acceptNotification( msg ) )
00055 NotificationMessage::appendAndCompress( pendingNotifications, msg );
00056 }
00057 if ( pendingNotifications.count() != oldChanges ) {
00058 saveNotifications();
00059 emit q->changesAdded();
00060 }
00061 }
00062
00063 void loadNotifications()
00064 {
00065 pendingNotifications.clear();
00066 QStringList list;
00067 settings->beginGroup( QLatin1String( "ChangeRecorder" ) );
00068 int size = settings->beginReadArray( QLatin1String( "change" ) );
00069 for ( int i = 0; i < size; ++i ) {
00070 settings->setArrayIndex( i );
00071 NotificationMessage msg;
00072 msg.setSessionId( settings->value( QLatin1String( "sessionId" ) ).toByteArray() );
00073 msg.setType( (NotificationMessage::Type)settings->value( QLatin1String( "type" ) ).toInt() );
00074 msg.setOperation( (NotificationMessage::Operation)settings->value( QLatin1String( "op" ) ).toInt() );
00075 msg.setUid( settings->value( QLatin1String( "uid" ) ).toLongLong() );
00076 msg.setRemoteId( settings->value( QLatin1String( "rid" ) ).toString() );
00077 msg.setResource( settings->value( QLatin1String( "resource" ) ).toByteArray() );
00078 msg.setParentCollection( settings->value( QLatin1String( "parentCol" ) ).toLongLong() );
00079 msg.setParentDestCollection( settings->value( QLatin1String( "parentDestCol" ) ).toLongLong() );
00080 msg.setMimeType( settings->value( QLatin1String( "mimeType" ) ).toString() );
00081 list = settings->value( QLatin1String( "itemParts" ) ).toStringList();
00082 QSet<QByteArray> itemParts;
00083 Q_FOREACH( const QString &entry, list )
00084 itemParts.insert( entry.toLatin1() );
00085 msg.setItemParts( itemParts );
00086 pendingNotifications << msg;
00087 }
00088 settings->endArray();
00089 settings->endGroup();
00090 }
00091
00092 void saveNotifications()
00093 {
00094 if ( !settings )
00095 return;
00096 settings->beginGroup( QLatin1String( "ChangeRecorder" ) );
00097 settings->beginWriteArray( QLatin1String( "change" ), pendingNotifications.count() );
00098 for ( int i = 0; i < pendingNotifications.count(); ++i ) {
00099 settings->setArrayIndex( i );
00100 NotificationMessage msg = pendingNotifications.at( i );
00101 settings->setValue( QLatin1String( "sessionId" ), msg.sessionId() );
00102 settings->setValue( QLatin1String( "type" ), msg.type() );
00103 settings->setValue( QLatin1String( "op" ), msg.operation() );
00104 settings->setValue( QLatin1String( "uid" ), msg.uid() );
00105 settings->setValue( QLatin1String( "rid" ), msg.remoteId() );
00106 settings->setValue( QLatin1String( "resource" ), msg.resource() );
00107 settings->setValue( QLatin1String( "parentCol" ), msg.parentCollection() );
00108 settings->setValue( QLatin1String( "parentDestCol" ), msg.parentDestCollection() );
00109 settings->setValue( QLatin1String( "mimeType" ), msg.mimeType() );
00110
00111 QStringList list;
00112 const QSet<QByteArray> itemParts = msg.itemParts();
00113 QSetIterator<QByteArray> it( itemParts );
00114 while ( it.hasNext() )
00115 list.append( QString::fromLatin1( it.next() ) );
00116
00117 settings->setValue( QLatin1String( "itemParts" ), list );
00118 }
00119 settings->endArray();
00120 settings->endGroup();
00121 }
00122
00123 };
00124
00125 ChangeRecorder::ChangeRecorder(QObject * parent) :
00126 Monitor( new ChangeRecorderPrivate( this ), parent )
00127 {
00128 Q_D( ChangeRecorder );
00129 d->connectToNotificationManager();
00130 }
00131
00132 ChangeRecorder::~ ChangeRecorder()
00133 {
00134 Q_D( ChangeRecorder );
00135 d->saveNotifications();
00136 }
00137
00138 void ChangeRecorder::setConfig(QSettings * settings)
00139 {
00140 Q_D( ChangeRecorder );
00141 if ( settings ) {
00142 d->settings = settings;
00143 Q_ASSERT( d->pendingNotifications.isEmpty() );
00144 d->loadNotifications();
00145 } else if ( d->settings ) {
00146 d->saveNotifications();
00147 d->settings = settings;
00148 }
00149 }
00150
00151 void ChangeRecorder::replayNext()
00152 {
00153 Q_D( ChangeRecorder );
00154 while( !d->pendingNotifications.isEmpty() ) {
00155 const NotificationMessage msg = d->pendingNotifications.first();
00156 if ( d->processNotification( msg ) )
00157 break;
00158 d->pendingNotifications.takeFirst();
00159 }
00160 d->saveNotifications();
00161 }
00162
00163 bool ChangeRecorder::isEmpty() const
00164 {
00165 Q_D( const ChangeRecorder );
00166 return d->pendingNotifications.isEmpty();
00167 }
00168
00169 void ChangeRecorder::changeProcessed()
00170 {
00171 Q_D( ChangeRecorder );
00172 if ( !d->pendingNotifications.isEmpty() )
00173 d->pendingNotifications.removeFirst();
00174 d->saveNotifications();
00175 }
00176
00177 void ChangeRecorder::setChangeRecordingEnabled( bool enable )
00178 {
00179 Q_D( ChangeRecorder );
00180 d->enableChangeRecording = enable;
00181 Q_ASSERT( enable || d->pendingNotifications.isEmpty() );
00182 }
00183
00184 #include "changerecorder.moc"