00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef AKONADI_MONITOR_P_H
00021 #define AKONADI_MONITOR_P_H
00022
00023 #include "akonadiprivate_export.h"
00024 #include "monitor.h"
00025 #include "collection.h"
00026 #include "collectionstatisticsjob.h"
00027 #include "collectionfetchscope.h"
00028 #include "item.h"
00029 #include "itemfetchscope.h"
00030 #include "job.h"
00031 #include <akonadi/private/notificationmessage_p.h>
00032 #include "notificationmanagerinterface.h"
00033 #include "entitycache_p.h"
00034
00035 #include <kmimetype.h>
00036
00037 #include <QtCore/QObject>
00038 #include <QtCore/QTimer>
00039
00040 namespace Akonadi {
00041
00042 class Monitor;
00043
00047 class AKONADI_TESTS_EXPORT MonitorPrivate
00048 {
00049 public:
00050 MonitorPrivate( Monitor *parent );
00051 virtual ~MonitorPrivate() {}
00052 void init();
00053
00054 Monitor *q_ptr;
00055 Q_DECLARE_PUBLIC( Monitor )
00056 org::freedesktop::Akonadi::NotificationManager *nm;
00057 Collection::List collections;
00058 QSet<QByteArray> resources;
00059 QSet<Item::Id> items;
00060 QSet<QString> mimetypes;
00061 bool monitorAll;
00062 QList<QByteArray> sessions;
00063 ItemFetchScope mItemFetchScope;
00064 CollectionFetchScope mCollectionFetchScope;
00065 Session *session;
00066 CollectionCache collectionCache;
00067 ItemCache itemCache;
00068 QQueue<NotificationMessage> pendingNotifications;
00069 QQueue<NotificationMessage> pipeline;
00070 bool fetchCollection;
00071 bool fetchCollectionStatistics;
00072
00073
00074 virtual bool connectToNotificationManager();
00075 bool acceptNotification( const NotificationMessage &msg );
00076 void dispatchNotifications();
00077
00078
00079
00080 void cleanOldNotifications();
00081
00082 bool ensureDataAvailable( const NotificationMessage &msg );
00083 void emitNotification( const NotificationMessage &msg );
00084 void updatePendingStatistics( const NotificationMessage &msg );
00085 void invalidateCaches( const NotificationMessage &msg );
00086
00090 void invalidateCache( const Collection &col );
00091
00092 virtual int pipelineSize() const;
00093
00094
00095 void dataAvailable();
00096 void slotSessionDestroyed( QObject* );
00097 void slotStatisticsChangedFinished( KJob* );
00098 void slotFlushRecentlyChangedCollections();
00099
00100 void appendAndCompress( const NotificationMessage &msg );
00101
00102 virtual void slotNotify( const NotificationMessage::List &msgs );
00103
00104 void emitItemNotification( const NotificationMessage &msg, const Item &item = Item(),
00105 const Collection &collection = Collection(), const Collection &collectionDest = Collection() );
00106 void emitCollectionNotification( const NotificationMessage &msg, const Collection &col = Collection(),
00107 const Collection &par = Collection(), const Collection &dest = Collection() );
00108
00109
00122 class PurgeBuffer
00123 {
00124
00125 static const int MAXBUFFERSIZE = 10;
00126 public:
00127 explicit PurgeBuffer()
00128 : m_index( 0 ),
00129 m_bufferSize( MAXBUFFERSIZE )
00130 {
00131 }
00132
00138 Collection::Id buffer( Collection::Id id );
00139
00143 void purge( Collection::Id id );
00144
00145 bool isBuffered( Collection::Id id ) const
00146 {
00147 return m_buffer.contains( id );
00148 }
00149
00150 private:
00151 QList<Collection::Id> m_buffer;
00152 int m_index;
00153 int m_bufferSize;
00154 } m_buffer;
00155
00156
00157 QHash<Collection::Id, int> refCountMap;
00158 bool useRefCounting;
00159 void ref( Collection::Id id );
00160 Collection::Id deref( Collection::Id id );
00161
00162 private:
00163
00164 QSet<Collection::Id> recentlyChangedCollections;
00165
00169 bool isLazilyIgnored( const NotificationMessage & msg ) const;
00170
00171 bool isCollectionMonitored( Collection::Id collection ) const
00172 {
00173 if ( collections.contains( Collection( collection ) ) )
00174 return true;
00175 if ( collections.contains( Collection::root() ) )
00176 return true;
00177 return false;
00178 }
00179
00180 bool isMimeTypeMonitored( const QString& mimetype ) const
00181 {
00182 if ( mimetypes.contains( mimetype ) )
00183 return true;
00184
00185 KMimeType::Ptr mimeType = KMimeType::mimeType( mimetype, KMimeType::ResolveAliases );
00186 if ( mimeType.isNull() )
00187 return false;
00188
00189 foreach ( const QString &mt, mimetypes ) {
00190 if ( mimeType->is( mt ) )
00191 return true;
00192 }
00193
00194 return false;
00195 }
00196
00197 bool isMoveDestinationResourceMonitored( const NotificationMessage &msg )
00198 {
00199 if ( msg.operation() != NotificationMessage::Move || msg.itemParts().isEmpty() )
00200 return false;
00201 const QByteArray res = *(msg.itemParts().begin());
00202 return resources.contains( res );
00203 }
00204
00205 void fetchStatistics( Collection::Id colId )
00206 {
00207 CollectionStatisticsJob *job = new CollectionStatisticsJob( Collection( colId ), session );
00208 QObject::connect( job, SIGNAL( result( KJob* ) ), q_ptr, SLOT( slotStatisticsChangedFinished( KJob* ) ) );
00209 }
00210
00211 void notifyCollectionStatisticsWatchers( Collection::Id collection, const QByteArray &resource )
00212 {
00213 if ( collection > 0 && (monitorAll || isCollectionMonitored( collection ) || resources.contains( resource ) ) ) {
00214 if (recentlyChangedCollections.empty() )
00215 QTimer::singleShot( 500, q_ptr, SLOT( slotFlushRecentlyChangedCollections() ) );
00216 recentlyChangedCollections.insert( collection );
00217 }
00218 }
00219 };
00220
00221 }
00222
00223 #endif