00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef AKONADI_ITEM_H
00022 #define AKONADI_ITEM_H
00023
00024 #include "akonadi_export.h"
00025
00026 #include <akonadi/entity.h>
00027 #include <akonadi/exception.h>
00028 #include "itempayloadinternals_p.h"
00029
00030 #include <QtCore/QByteArray>
00031 #include <QtCore/QMetaType>
00032 #include <QtCore/QSet>
00033
00034 #include <boost/static_assert.hpp>
00035 #include <boost/type_traits/is_pointer.hpp>
00036 #include <typeinfo>
00037
00038 class KUrl;
00039
00040 namespace std {
00041 template <typename T> class auto_ptr;
00042 }
00043
00044 namespace Akonadi {
00045
00046 class ItemPrivate;
00047
00086 class AKONADI_EXPORT Item : public Entity
00087 {
00088 public:
00092 typedef QList<Item> List;
00093
00097 typedef QByteArray Flag;
00098
00102 typedef QSet<QByteArray> Flags;
00103
00108 static const char* FullPayload;
00109
00113 Item();
00114
00118 explicit Item( Id id );
00119
00125 explicit Item( const QString &mimeType );
00126
00130 Item( const Item &other );
00131
00135 ~Item();
00136
00140 static Item fromUrl( const KUrl &url );
00141
00145 Flags flags() const;
00146
00151 QDateTime modificationTime() const;
00152
00160 void setModificationTime( const QDateTime &datetime );
00161
00166 bool hasFlag( const QByteArray &name ) const;
00167
00171 void setFlag( const QByteArray &name );
00172
00176 void clearFlag( const QByteArray &name );
00177
00181 void setFlags( const Flags &flags );
00182
00186 void clearFlags();
00187
00195 void setPayloadFromData( const QByteArray &data );
00196
00203 QByteArray payloadData() const;
00204
00209 QSet<QByteArray> loadedPayloadParts() const;
00210
00220 void clearPayload();
00221
00228 void setRevision( int revision );
00229
00233 int revision() const;
00234
00243 Entity::Id storageCollectionId() const;
00244
00250 void setSize( qint64 size );
00251
00257 qint64 size() const;
00258
00262 void setMimeType( const QString &mimeType );
00263
00267 QString mimeType() const;
00268
00280 template <typename T> void setPayload( const T &p );
00281
00282 template <typename T> void setPayload( T* p );
00283 template <typename T> void setPayload( std::auto_ptr<T> p );
00284
00285
00299 template <typename T> T payload() const;
00300
00304 bool hasPayload() const;
00305
00315 template <typename T> bool hasPayload() const;
00316
00320 enum UrlType
00321 {
00322 UrlShort = 0,
00323 UrlWithMimeType = 1
00324 };
00325
00329 KUrl url( UrlType type = UrlShort ) const;
00330
00339 QSet<QByteArray> availablePayloadParts() const;
00340
00354 void apply( const Item &other );
00355
00356 private:
00357
00358 friend class ItemCreateJob;
00359 friend class ItemModifyJob;
00360 friend class ProtocolHelper;
00361 PayloadBase* payloadBase() const;
00362 void setPayloadBase( PayloadBase* );
00368 void setStorageCollectionId( Entity::Id collectionId);
00369
00370
00371
00372 AKONADI_DECLARE_PRIVATE( Item )
00373 };
00374
00375
00376 template <typename T>
00377 T Item::payload() const
00378 {
00379 BOOST_STATIC_ASSERT( !boost::is_pointer<T>::value );
00380
00381 if ( !payloadBase() )
00382 throw PayloadException( "No payload set" );
00383
00384 typedef Internal::PayloadTrait<T> PayloadType;
00385 if ( PayloadType::isPolymorphic ) {
00386 try {
00387 const typename PayloadType::SuperType sp = payload<typename PayloadType::SuperType>();
00388 return PayloadType::castFrom( sp );
00389 } catch ( const Akonadi::PayloadException& ) {}
00390 }
00391
00392 Payload<T> *p = Internal::payload_cast<T>( payloadBase() );
00393 if ( !p ) {
00394 throw PayloadException( QString::fromLatin1( "Wrong payload type (is '%1', requested '%2')" )
00395 .arg( QLatin1String( payloadBase()->typeName() ) )
00396 .arg( QLatin1String( typeid(p).name() ) ) );
00397 }
00398 return p->payload;
00399 }
00400
00401 template <typename T>
00402 bool Item::hasPayload() const
00403 {
00404 BOOST_STATIC_ASSERT( !boost::is_pointer<T>::value );
00405
00406 if ( !hasPayload() )
00407 return false;
00408
00409 typedef Internal::PayloadTrait<T> PayloadType;
00410 if ( PayloadType::isPolymorphic ) {
00411 try {
00412 const typename PayloadType::SuperType sp = payload<typename PayloadType::SuperType>();
00413 return PayloadType::canCastFrom( sp );
00414 } catch ( const Akonadi::PayloadException& ) {}
00415 }
00416
00417 return Internal::payload_cast<T>( payloadBase() );
00418 }
00419
00420 template <typename T>
00421 void Item::setPayload( const T &p )
00422 {
00423 typedef Internal::PayloadTrait<T> PayloadType;
00424 if ( PayloadType::isPolymorphic ) {
00425 const typename PayloadType::SuperType sp
00426 = PayloadType::template castTo<typename PayloadType::SuperElementType>( p );
00427 if ( !Internal::PayloadTrait<typename PayloadType::SuperType>::isNull( sp )
00428 || PayloadType::isNull( p ) )
00429 {
00430 setPayload( sp );
00431 return;
00432 }
00433 }
00434 setPayloadBase( new Payload<T>( p ) );
00435 }
00436
00437 template <typename T>
00438 void Item::setPayload( T* p )
00439 {
00440 p.You_MUST_NOT_use_a_pointer_as_payload;
00441 }
00442
00443 template <typename T>
00444 void Item::setPayload( std::auto_ptr<T> p )
00445 {
00446 p.Nice_try_but_a_std_auto_ptr_is_not_allowed_as_payload_either;
00447 }
00448
00449 }
00450
00451 Q_DECLARE_METATYPE(Akonadi::Item)
00452 Q_DECLARE_METATYPE(Akonadi::Item::List)
00453
00454 #endif