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

akonadi

changerecorder_p.h
00001 /*
00002     Copyright (c) 2007 Volker Krause <vkrause@kde.org>
00003 
00004     This library is free software; you can redistribute it and/or modify it
00005     under the terms of the GNU Library General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or (at your
00007     option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful, but WITHOUT
00010     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00011     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00012     License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to the
00016     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017     02110-1301, USA.
00018 */
00019 
00020 #ifndef AKONADI_CHANGERECORDER_P_H
00021 #define AKONADI_CHANGERECORDER_P_H
00022 
00023 #include "akonadiprivate_export.h"
00024 #include "monitor_p.h"
00025 
00026 class AKONADI_TESTS_EXPORT Akonadi::ChangeRecorderPrivate : public Akonadi::MonitorPrivate
00027 {
00028   public:
00029     ChangeRecorderPrivate( ChangeNotificationDependenciesFactory *dependenciesFactory_, ChangeRecorder* parent ) :
00030       MonitorPrivate( dependenciesFactory_, parent ),
00031       settings( 0 ),
00032       enableChangeRecording( true )
00033     {
00034     }
00035 
00036     Q_DECLARE_PUBLIC( ChangeRecorder )
00037     QSettings *settings;
00038     bool enableChangeRecording;
00039 
00040     virtual int pipelineSize() const
00041     {
00042       if ( enableChangeRecording )
00043         return 0; // we fill the pipeline ourselves when using change recording
00044       return MonitorPrivate::pipelineSize();
00045     }
00046 
00047     virtual void slotNotify( const NotificationMessage::List &msgs )
00048     {
00049       Q_Q( ChangeRecorder );
00050       const int oldChanges = pendingNotifications.size();
00051       MonitorPrivate::slotNotify( msgs ); // with change recording disabled this will automatically take care of dispatching notification messages
00052       if ( enableChangeRecording && pendingNotifications.size() != oldChanges ) {
00053         saveNotifications();
00054         emit q->changesAdded();
00055       }
00056     }
00057 
00058     virtual bool emitNotification(const Akonadi::NotificationMessage& msg)
00059     {
00060       const bool someoneWasListening = MonitorPrivate::emitNotification( msg );
00061       if ( !someoneWasListening && enableChangeRecording )
00062         QMetaObject::invokeMethod( q_ptr, "replayNext", Qt::QueuedConnection ); // skip notifications no one was listening to
00063       return someoneWasListening;
00064     }
00065 
00066     QString notificationsFileName() const
00067     {
00068       return settings->fileName() + QLatin1String( "_changes.dat" );
00069     }
00070 
00071     void loadNotifications()
00072     {
00073       pendingNotifications.clear();
00074 
00075       const QString changesFileName = notificationsFileName();
00076 
00083       if ( !QFile::exists( changesFileName ) ) {
00084         QStringList list;
00085         settings->beginGroup( QLatin1String( "ChangeRecorder" ) );
00086         const int size = settings->beginReadArray( QLatin1String( "change" ) );
00087 
00088         for ( int i = 0; i < size; ++i ) {
00089           settings->setArrayIndex( i );
00090           NotificationMessage msg;
00091           msg.setSessionId( settings->value( QLatin1String( "sessionId" ) ).toByteArray() );
00092           msg.setType( (NotificationMessage::Type)settings->value( QLatin1String( "type" ) ).toInt() );
00093           msg.setOperation( (NotificationMessage::Operation)settings->value( QLatin1String( "op" ) ).toInt() );
00094           msg.setUid( settings->value( QLatin1String( "uid" ) ).toLongLong() );
00095           msg.setRemoteId( settings->value( QLatin1String( "rid" ) ).toString() );
00096           msg.setResource( settings->value( QLatin1String( "resource" ) ).toByteArray() );
00097           msg.setParentCollection( settings->value( QLatin1String( "parentCol" ) ).toLongLong() );
00098           msg.setParentDestCollection( settings->value( QLatin1String( "parentDestCol" ) ).toLongLong() );
00099           msg.setMimeType( settings->value( QLatin1String( "mimeType" ) ).toString() );
00100           list = settings->value( QLatin1String( "itemParts" ) ).toStringList();
00101           QSet<QByteArray> itemParts;
00102           Q_FOREACH( const QString &entry, list )
00103             itemParts.insert( entry.toLatin1() );
00104           msg.setItemParts( itemParts );
00105           pendingNotifications << msg;
00106         }
00107 
00108         settings->endArray();
00109 
00110         // save notifications to the new file...
00111         saveNotifications();
00112 
00113         // ...delete the legacy list...
00114         settings->remove( QString() );
00115         settings->endGroup();
00116 
00117         // ...and continue as usually
00118       }
00119 
00120       QFile file( changesFileName );
00121       if ( !file.open( QIODevice::ReadOnly ) )
00122         return;
00123       pendingNotifications = loadFrom( &file );
00124     }
00125 
00126     QQueue<NotificationMessage> loadFrom( QIODevice *device )
00127     {
00128       QDataStream stream( device );
00129       stream.setVersion( QDataStream::Qt_4_6 );
00130 
00131       qulonglong size;
00132       QByteArray sessionId, resource;
00133       int type, operation;
00134       qlonglong uid, parentCollection, parentDestCollection;
00135       QString remoteId, mimeType;
00136       QSet<QByteArray> itemParts;
00137 
00138       QQueue<NotificationMessage> list;
00139 
00140       stream >> size;
00141       for ( qulonglong i = 0; i < size; ++i ) {
00142         NotificationMessage msg;
00143 
00144         stream >> sessionId;
00145         stream >> type;
00146         stream >> operation;
00147         stream >> uid;
00148         stream >> remoteId;
00149         stream >> resource;
00150         stream >> parentCollection;
00151         stream >> parentDestCollection;
00152         stream >> mimeType;
00153         stream >> itemParts;
00154 
00155         msg.setSessionId( sessionId );
00156         msg.setType( static_cast<NotificationMessage::Type>( type ) );
00157         msg.setOperation( static_cast<NotificationMessage::Operation>( operation ) );
00158         msg.setUid( uid );
00159         msg.setRemoteId( remoteId );
00160         msg.setResource( resource );
00161         msg.setParentCollection( parentCollection );
00162         msg.setParentDestCollection( parentDestCollection );
00163         msg.setMimeType( mimeType );
00164         msg.setItemParts( itemParts );
00165         list << msg;
00166       }
00167       return list;
00168     }
00169 
00170     QString dumpNotificationListToString() const
00171     {
00172       QString result;
00173       const QString changesFileName = notificationsFileName();
00174       QFile file( changesFileName );
00175       if ( file.open( QIODevice::ReadOnly ) ) {
00176         QDataStream stream( &file );
00177         stream.setVersion( QDataStream::Qt_4_6 );
00178 
00179         qulonglong size;
00180         QByteArray sessionId, resource;
00181         int type, operation;
00182         qlonglong uid, parentCollection, parentDestCollection;
00183         QString remoteId, mimeType;
00184         QSet<QByteArray> itemParts;
00185 
00186         QStringList list;
00187 
00188         stream >> size;
00189         for ( qulonglong i = 0; i < size; ++i ) {
00190           stream >> sessionId;
00191           stream >> type;
00192           stream >> operation;
00193           stream >> uid;
00194           stream >> remoteId;
00195           stream >> resource;
00196           stream >> parentCollection;
00197           stream >> parentDestCollection;
00198           stream >> mimeType;
00199           stream >> itemParts;
00200 
00201           QString typeString;
00202           switch ( type ) {
00203           case NotificationMessage::Collection:
00204             typeString = QLatin1String( "Collection" );
00205             break;
00206           case NotificationMessage::Item:
00207             typeString = QLatin1String( "Item" );
00208             break;
00209           default:
00210             typeString = QLatin1String( "InvalidType" );
00211             break;
00212           };
00213 
00214           QString operationString;
00215           switch ( operation ) {
00216           case NotificationMessage::Add:
00217             operationString = QLatin1String( "Add" );
00218             break;
00219           case NotificationMessage::Modify:
00220             operationString = QLatin1String( "Modify" );
00221             break;
00222           case NotificationMessage::Move:
00223             operationString = QLatin1String( "Move" );
00224             break;
00225           case NotificationMessage::Remove:
00226             operationString = QLatin1String( "Remove" );
00227             break;
00228           case NotificationMessage::Link:
00229             operationString = QLatin1String( "Link" );
00230             break;
00231           case NotificationMessage::Unlink:
00232             operationString = QLatin1String( "Unlink" );
00233             break;
00234           case NotificationMessage::Subscribe:
00235             operationString = QLatin1String( "Subscribe" );
00236             break;
00237           case NotificationMessage::Unsubscribe:
00238             operationString = QLatin1String( "Unsubscribe" );
00239             break;
00240           default:
00241             operationString = QLatin1String( "InvalidOp" );
00242             break;
00243           };
00244 
00245           QStringList itemPartsList;
00246           foreach( const QByteArray &b, itemParts )
00247             itemPartsList.push_back( QString::fromLatin1(b) );
00248 
00249           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")
00250                                 .arg( QString::fromLatin1( sessionId ) )
00251                                 .arg( typeString )
00252                                 .arg( operationString )
00253                                 .arg( uid )
00254                                 .arg( remoteId )
00255                                 .arg( QString::fromLatin1( resource ) )
00256                                 .arg( parentCollection )
00257                                 .arg( parentDestCollection )
00258                                 .arg( mimeType )
00259                                 .arg( itemPartsList.join(QLatin1String(", " )) );
00260 
00261           result += entry + QLatin1Char('\n');
00262         }
00263 
00264       }
00265       return result;
00266     }
00267 
00268     void addToStream( QDataStream &stream, const NotificationMessage &msg )
00269     {
00270         stream << msg.sessionId();
00271         stream << int(msg.type());
00272         stream << int(msg.operation());
00273         stream << qulonglong(msg.uid());
00274         stream << msg.remoteId();
00275         stream << msg.resource();
00276         stream << qulonglong(msg.parentCollection());
00277         stream << qulonglong(msg.parentDestCollection());
00278         stream << msg.mimeType();
00279         stream << msg.itemParts();
00280     }
00281 
00282     void saveNotifications()
00283     {
00284       if ( !settings )
00285         return;
00286 
00287       QFile file( notificationsFileName() );
00288       QFileInfo info( file );
00289       if ( !QFile::exists( info.absolutePath() ) ) {
00290         QDir dir;
00291         dir.mkpath( info.absolutePath() );
00292       }
00293       if ( !file.open( QIODevice::WriteOnly ) ) {
00294         qWarning() << "could not save notifications to file " << file.fileName();
00295         return;
00296       }
00297       saveTo(&file);
00298     }
00299 
00300     void saveTo( QIODevice *device )
00301     {
00302 
00303       QDataStream stream( device );
00304       stream.setVersion( QDataStream::Qt_4_6 );
00305 
00306       stream << (qulonglong)(pipeline.count() + pendingNotifications.count());
00307 
00308       for ( int i = 0; i < pipeline.count(); ++i ) {
00309         const NotificationMessage msg = pipeline.at( i );
00310         addToStream( stream, msg );
00311       }
00312 
00313       for ( int i = 0; i < pendingNotifications.count(); ++i ) {
00314         const NotificationMessage msg = pendingNotifications.at( i );
00315         addToStream( stream, msg );
00316       }
00317     }
00318 };
00319 
00320 #endif
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu Aug 2 2012 15:25:17 by doxygen 1.7.5 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.8.5 API Reference

Skip menu "kdepimlibs-4.8.5 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