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 QSettings *settings;
00040 bool enableChangeRecording;
00041
00042 virtual int pipelineSize() const
00043 {
00044 if ( enableChangeRecording )
00045 return 0;
00046 return MonitorPrivate::pipelineSize();
00047 }
00048
00049 virtual void slotNotify( const NotificationMessage::List &msgs )
00050 {
00051 Q_Q( ChangeRecorder );
00052 const int oldChanges = pendingNotifications.size();
00053 MonitorPrivate::slotNotify( msgs );
00054 if ( enableChangeRecording && pendingNotifications.size() != oldChanges ) {
00055 saveNotifications();
00056 emit q->changesAdded();
00057 }
00058 }
00059
00060 void loadNotifications()
00061 {
00062 pendingNotifications.clear();
00063 QStringList list;
00064 settings->beginGroup( QLatin1String( "ChangeRecorder" ) );
00065 int size = settings->beginReadArray( QLatin1String( "change" ) );
00066 for ( int i = 0; i < size; ++i ) {
00067 settings->setArrayIndex( i );
00068 NotificationMessage msg;
00069 msg.setSessionId( settings->value( QLatin1String( "sessionId" ) ).toByteArray() );
00070 msg.setType( (NotificationMessage::Type)settings->value( QLatin1String( "type" ) ).toInt() );
00071 msg.setOperation( (NotificationMessage::Operation)settings->value( QLatin1String( "op" ) ).toInt() );
00072 msg.setUid( settings->value( QLatin1String( "uid" ) ).toLongLong() );
00073 msg.setRemoteId( settings->value( QLatin1String( "rid" ) ).toString() );
00074 msg.setResource( settings->value( QLatin1String( "resource" ) ).toByteArray() );
00075 msg.setParentCollection( settings->value( QLatin1String( "parentCol" ) ).toLongLong() );
00076 msg.setParentDestCollection( settings->value( QLatin1String( "parentDestCol" ) ).toLongLong() );
00077 msg.setMimeType( settings->value( QLatin1String( "mimeType" ) ).toString() );
00078 list = settings->value( QLatin1String( "itemParts" ) ).toStringList();
00079 QSet<QByteArray> itemParts;
00080 Q_FOREACH( const QString &entry, list )
00081 itemParts.insert( entry.toLatin1() );
00082 msg.setItemParts( itemParts );
00083 pendingNotifications << msg;
00084 }
00085 settings->endArray();
00086 settings->endGroup();
00087 }
00088
00089 void saveNotifications()
00090 {
00091 if ( !settings )
00092 return;
00093 settings->beginGroup( QLatin1String( "ChangeRecorder" ) );
00094 settings->beginWriteArray( QLatin1String( "change" ), pendingNotifications.count() );
00095 for ( int i = 0; i < pendingNotifications.count(); ++i ) {
00096 settings->setArrayIndex( i );
00097 NotificationMessage msg = pendingNotifications.at( i );
00098 settings->setValue( QLatin1String( "sessionId" ), msg.sessionId() );
00099 settings->setValue( QLatin1String( "type" ), msg.type() );
00100 settings->setValue( QLatin1String( "op" ), msg.operation() );
00101 settings->setValue( QLatin1String( "uid" ), msg.uid() );
00102 settings->setValue( QLatin1String( "rid" ), msg.remoteId() );
00103 settings->setValue( QLatin1String( "resource" ), msg.resource() );
00104 settings->setValue( QLatin1String( "parentCol" ), msg.parentCollection() );
00105 settings->setValue( QLatin1String( "parentDestCol" ), msg.parentDestCollection() );
00106 settings->setValue( QLatin1String( "mimeType" ), msg.mimeType() );
00107
00108 QStringList list;
00109 const QSet<QByteArray> itemParts = msg.itemParts();
00110 QSetIterator<QByteArray> it( itemParts );
00111 while ( it.hasNext() )
00112 list.append( QString::fromLatin1( it.next() ) );
00113
00114 settings->setValue( QLatin1String( "itemParts" ), list );
00115 }
00116 settings->endArray();
00117 settings->endGroup();
00118 }
00119
00120 };
00121
00122 ChangeRecorder::ChangeRecorder(QObject * parent) :
00123 Monitor( new ChangeRecorderPrivate( this ), parent )
00124 {
00125 Q_D( ChangeRecorder );
00126 d->init();
00127 d->connectToNotificationManager();
00128 }
00129
00130 ChangeRecorder::~ ChangeRecorder()
00131 {
00132 Q_D( ChangeRecorder );
00133 d->saveNotifications();
00134 }
00135
00136 void ChangeRecorder::setConfig(QSettings * settings)
00137 {
00138 Q_D( ChangeRecorder );
00139 if ( settings ) {
00140 d->settings = settings;
00141 Q_ASSERT( d->pendingNotifications.isEmpty() );
00142 d->loadNotifications();
00143 } else if ( d->settings ) {
00144 d->saveNotifications();
00145 d->settings = settings;
00146 }
00147 }
00148
00149 void ChangeRecorder::replayNext()
00150 {
00151 Q_D( ChangeRecorder );
00152 if ( !d->pendingNotifications.isEmpty() ) {
00153 const NotificationMessage msg = d->pendingNotifications.first();
00154 if ( d->ensureDataAvailable( msg ) )
00155 d->emitNotification( msg );
00156 else
00157 d->pipeline.enqueue( msg );
00158 } else {
00159
00160
00161
00162 emit nothingToReplay();
00163 }
00164 d->saveNotifications();
00165 }
00166
00167 bool ChangeRecorder::isEmpty() const
00168 {
00169 Q_D( const ChangeRecorder );
00170 return d->pendingNotifications.isEmpty();
00171 }
00172
00173 void ChangeRecorder::changeProcessed()
00174 {
00175 Q_D( ChangeRecorder );
00176 if ( !d->pendingNotifications.isEmpty() )
00177 d->pendingNotifications.removeFirst();
00178 d->saveNotifications();
00179 }
00180
00181 void ChangeRecorder::setChangeRecordingEnabled( bool enable )
00182 {
00183 Q_D( ChangeRecorder );
00184 if ( d->enableChangeRecording == enable )
00185 return;
00186 d->enableChangeRecording = enable;
00187 if ( !enable )
00188 d->dispatchNotifications();
00189 }
00190
00191 #include "changerecorder.moc"