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 bool isCollectionMonitored( Collection::Id collection, const QByteArray &resource ) const
00074 {
00075 if ( monitorAll || isCollectionMonitored( collection ) || resources.contains( resource ) )
00076 return true;
00077 return false;
00078 }
00079
00080 bool isItemMonitored( Item::Id item, Collection::Id collection, Collection::Id collectionDest,
00081 const QString &mimetype, const QByteArray &resource ) const
00082 {
00083 if ( monitorAll || isCollectionMonitored( collection ) ||
00084 isCollectionMonitored( collectionDest ) ||items.contains( item ) ||
00085 resources.contains( resource ) || isMimeTypeMonitored( mimetype ) )
00086 return true;
00087 return false;
00088 }
00089
00090 bool isSessionIgnored( const QByteArray &sessionId ) const
00091 {
00092 return sessions.contains( sessionId );
00093 }
00094
00095 bool isMoveDestinationResourceMonitored( const NotificationMessage &msg )
00096 {
00097 if ( msg.operation() != NotificationMessage::Move || msg.itemParts().isEmpty() )
00098 return false;
00099 const QByteArray res = *(msg.itemParts().begin());
00100 return resources.contains( res );
00101 }
00102
00103
00104 virtual bool connectToNotificationManager();
00105 bool acceptNotification( const NotificationMessage &msg );
00106 void dispatchNotifications();
00107
00108
00109
00110 void cleanOldNotifications();
00111
00112 bool ensureDataAvailable( const NotificationMessage &msg );
00113 void emitNotification( const NotificationMessage &msg );
00114 void updatePendingStatistics( const NotificationMessage &msg );
00115 void invalidateCaches( const NotificationMessage &msg );
00116
00120 void invalidateCache( const Collection &col );
00121
00122 virtual int pipelineSize() const;
00123
00124
00125 void dataAvailable();
00126 void slotSessionDestroyed( QObject* );
00127 void slotStatisticsChangedFinished( KJob* );
00128 void slotFlushRecentlyChangedCollections();
00129
00130 void appendAndCompress( const NotificationMessage &msg );
00131
00132 virtual void slotNotify( const NotificationMessage::List &msgs );
00133
00134 void emitItemNotification( const NotificationMessage &msg, const Item &item = Item(),
00135 const Collection &collection = Collection(), const Collection &collectionDest = Collection() );
00136 void emitCollectionNotification( const NotificationMessage &msg, const Collection &col = Collection(),
00137 const Collection &par = Collection(), const Collection &dest = Collection() );
00138
00139
00152 class PurgeBuffer
00153 {
00154
00155 static const int MAXBUFFERSIZE = 10;
00156 public:
00157 explicit PurgeBuffer()
00158 : m_index( 0 ),
00159 m_bufferSize( MAXBUFFERSIZE )
00160 {
00161 }
00162
00168 Collection::Id buffer( Collection::Id id );
00169
00173 void purge( Collection::Id id );
00174
00175 bool isBuffered( Collection::Id id ) const
00176 {
00177 return m_buffer.contains( id );
00178 }
00179
00180 private:
00181 QList<Collection::Id> m_buffer;
00182 int m_index;
00183 int m_bufferSize;
00184 } m_buffer;
00185
00186
00187 QHash<Collection::Id, int> refCountMap;
00188 bool useRefCounting;
00189 void ref( Collection::Id id );
00190 Collection::Id deref( Collection::Id id );
00191
00192 private:
00193
00194 QSet<Collection::Id> recentlyChangedCollections;
00195
00199 bool isLazilyIgnored( const NotificationMessage & msg ) const;
00200
00201 bool isCollectionMonitored( Collection::Id collection ) const
00202 {
00203 if ( collections.contains( Collection( collection ) ) )
00204 return true;
00205 if ( collections.contains( Collection::root() ) )
00206 return true;
00207 return false;
00208 }
00209
00210 bool isMimeTypeMonitored( const QString& mimetype ) const
00211 {
00212 if ( mimetypes.contains( mimetype ) )
00213 return true;
00214
00215 KMimeType::Ptr mimeType = KMimeType::mimeType( mimetype, KMimeType::ResolveAliases );
00216 if ( mimeType.isNull() )
00217 return false;
00218
00219 foreach ( const QString &mt, mimetypes ) {
00220 if ( mimeType->is( mt ) )
00221 return true;
00222 }
00223
00224 return false;
00225 }
00226
00227 void fetchStatistics( Collection::Id colId )
00228 {
00229 CollectionStatisticsJob *job = new CollectionStatisticsJob( Collection( colId ), session );
00230 QObject::connect( job, SIGNAL( result( KJob* ) ), q_ptr, SLOT( slotStatisticsChangedFinished( KJob* ) ) );
00231 }
00232
00233 void notifyCollectionStatisticsWatchers( Collection::Id collection, const QByteArray &resource )
00234 {
00235 if ( collection > 0 && isCollectionMonitored( collection, resource ) ) {
00236 if (recentlyChangedCollections.empty() )
00237 QTimer::singleShot( 500, q_ptr, SLOT( slotFlushRecentlyChangedCollections() ) );
00238 recentlyChangedCollections.insert( collection );
00239 }
00240 }
00241 };
00242
00243 }
00244
00245 #endif