akonadi
item.h
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 <boost/utility/enable_if.hpp>
00037
00038 #include <typeinfo>
00039 #include <memory>
00040
00041 class KUrl;
00042
00043 template <typename T>
00044 class QVector;
00045
00046 namespace Akonadi {
00047
00048 class ItemPrivate;
00049
00115 class AKONADI_EXPORT Item : public Entity
00116 {
00117 public:
00121 typedef QList<Item> List;
00122
00126 typedef QByteArray Flag;
00127
00131 typedef QSet<QByteArray> Flags;
00132
00137 static const char* FullPayload;
00138
00142 Item();
00143
00147 explicit Item( Id id );
00148
00154 explicit Item( const QString &mimeType );
00155
00159 Item( const Item &other );
00160
00164 ~Item();
00165
00169 static Item fromUrl( const KUrl &url );
00170
00174 Flags flags() const;
00175
00180 QDateTime modificationTime() const;
00181
00189 void setModificationTime( const QDateTime &datetime );
00190
00195 bool hasFlag( const QByteArray &name ) const;
00196
00200 void setFlag( const QByteArray &name );
00201
00205 void clearFlag( const QByteArray &name );
00206
00210 void setFlags( const Flags &flags );
00211
00215 void clearFlags();
00216
00224 void setPayloadFromData( const QByteArray &data );
00225
00232 QByteArray payloadData() const;
00233
00238 QSet<QByteArray> loadedPayloadParts() const;
00239
00249 void clearPayload();
00250
00257 void setRevision( int revision );
00258
00262 int revision() const;
00263
00272 Entity::Id storageCollectionId() const;
00273
00279 void setSize( qint64 size );
00280
00286 qint64 size() const;
00287
00291 void setMimeType( const QString &mimeType );
00292
00296 QString mimeType() const;
00297
00304 QVector<int> availablePayloadMetaTypeIds() const;
00305
00317 template <typename T> void setPayload( const T &p );
00318
00319 template <typename T> void setPayload( T* p );
00320 template <typename T> void setPayload( std::auto_ptr<T> p );
00321
00322
00336 template <typename T> T payload() const;
00337
00341 bool hasPayload() const;
00342
00352 template <typename T> bool hasPayload() const;
00353
00357 enum UrlType
00358 {
00359 UrlShort = 0,
00360 UrlWithMimeType = 1
00361 };
00362
00366 KUrl url( UrlType type = UrlShort ) const;
00367
00376 QSet<QByteArray> availablePayloadParts() const;
00377
00391 void apply( const Item &other );
00392
00402 template <typename T> static void addToLegacyMapping( const QString & mimeType );
00403
00404 private:
00405
00406 friend class ItemCreateJob;
00407 friend class ItemModifyJob;
00408 friend class ItemSync;
00409 friend class ProtocolHelper;
00410 PayloadBase* payloadBase() const;
00411 void setPayloadBase( PayloadBase* );
00412 PayloadBase* payloadBaseV2( int sharedPointerId, int metaTypeId ) const;
00413
00414 void setPayloadBaseV2( int sharedPointerId, int metaTypeId, std::auto_ptr<PayloadBase> p );
00415 void addPayloadBaseVariant( int sharedPointerId, int metaTypeId, std::auto_ptr<PayloadBase> p ) const;
00416 static void addToLegacyMappingImpl( const QString & mimeType, int sharedPointerId, int metaTypeId, std::auto_ptr<PayloadBase> p );
00417
00422 bool ensureMetaTypeId( int mtid ) const;
00423
00424 template <typename T>
00425 typename boost::enable_if_c<Internal::PayloadTrait<T>::isPolymorphic,void>::type
00426 setPayloadImpl( const T &, const int * = 0 );
00427 template <typename T>
00428 typename boost::disable_if_c<Internal::PayloadTrait<T>::isPolymorphic,void>::type
00429 setPayloadImpl( const T & );
00430
00431 template <typename T>
00432 typename boost::enable_if_c<Internal::PayloadTrait<T>::isPolymorphic,T>::type
00433 payloadImpl( const int * = 0 ) const;
00434 template <typename T>
00435 typename boost::disable_if_c<Internal::PayloadTrait<T>::isPolymorphic,T>::type
00436 payloadImpl() const;
00437
00438 template <typename T>
00439 typename boost::enable_if_c<Internal::PayloadTrait<T>::isPolymorphic,bool>::type
00440 hasPayloadImpl( const int * = 0 ) const;
00441 template <typename T>
00442 typename boost::disable_if_c<Internal::PayloadTrait<T>::isPolymorphic,bool>::type
00443 hasPayloadImpl() const;
00444
00445 template <typename T>
00446 typename boost::enable_if<Internal::is_shared_pointer<T>,bool>::type
00447 tryToClone( T *, const int * = 0 ) const;
00448 template <typename T>
00449 typename boost::disable_if<Internal::is_shared_pointer<T>,bool>::type
00450 tryToClone( T * ) const;
00451
00457 void setStorageCollectionId( Entity::Id collectionId);
00458
00459 #if 0
00460
00463 QString payloadExceptionText( int spid, int mtid ) const;
00464
00470 inline void throwPayloadException( int spid, int mtid ) const {
00471 throw PayloadException( payloadExceptionText( spid, mtid ) );
00472 }
00473 #else
00474 void throwPayloadException( int spid, int mtid ) const;
00475 #endif
00476
00477
00478 AKONADI_DECLARE_PRIVATE( Item )
00479 };
00480
00481
00482 template <typename T>
00483 T Item::payload() const
00484 {
00485 BOOST_STATIC_ASSERT( !boost::is_pointer<T>::value );
00486
00487 if ( !hasPayload() )
00488 throwPayloadException( -1, -1 );
00489
00490 return payloadImpl<T>();
00491 }
00492
00493 template <typename T>
00494 typename boost::enable_if_c<Internal::PayloadTrait<T>::isPolymorphic,T>::type
00495 Item::payloadImpl( const int * ) const
00496 {
00497 typedef Internal::PayloadTrait<T> PayloadType;
00498 BOOST_STATIC_ASSERT(( PayloadType::isPolymorphic ));
00499
00500 typedef typename Internal::get_hierarchy_root<T>::type Root_T;
00501 typedef Internal::PayloadTrait<Root_T> RootType;
00502 BOOST_STATIC_ASSERT(( !RootType::isPolymorphic ));
00503
00504 return PayloadType::castFrom( payloadImpl<Root_T>() );
00505 }
00506
00507 template <typename T>
00508 typename boost::disable_if_c<Internal::PayloadTrait<T>::isPolymorphic,T>::type
00509 Item::payloadImpl() const
00510 {
00511 typedef Internal::PayloadTrait<T> PayloadType;
00512 BOOST_STATIC_ASSERT(( !PayloadType::isPolymorphic ));
00513
00514 const int metaTypeId = PayloadType::elementMetaTypeId();
00515
00516
00517 if ( !ensureMetaTypeId( metaTypeId ) )
00518 throwPayloadException( PayloadType::sharedPointerId, metaTypeId );
00519
00520
00521
00522 if ( const Payload<T> * const p = Internal::payload_cast<T>( payloadBaseV2( PayloadType::sharedPointerId, metaTypeId ) ) )
00523 return p->payload;
00524
00525 T ret;
00526 if ( !tryToClone<T>( &ret ) )
00527 throwPayloadException( PayloadType::sharedPointerId, metaTypeId );
00528 return ret;
00529 }
00530
00531 template <typename T>
00532 typename boost::enable_if<Internal::is_shared_pointer<T>,bool>::type
00533 Item::tryToClone( T * ret, const int * ) const
00534 {
00535 typedef Internal::PayloadTrait<T> PayloadType;
00536 BOOST_STATIC_ASSERT(( !PayloadType::isPolymorphic ));
00537
00538 const int metaTypeId = PayloadType::elementMetaTypeId();
00539
00540
00541
00542
00543 typedef typename Internal::shared_pointer_traits<T>::next_shared_ptr NewT;
00544 typedef Internal::PayloadTrait<NewT> NewPayloadType;
00545
00546 if ( const Payload<NewT> * const p = Internal::payload_cast<NewT>( payloadBaseV2( NewPayloadType::sharedPointerId, metaTypeId ) ) ) {
00547
00548 const T nt = PayloadType::clone( p->payload );
00549 if ( !PayloadType::isNull( nt ) ) {
00550
00551 std::auto_ptr<PayloadBase> npb( new Payload<T>( nt ) );
00552 addPayloadBaseVariant( PayloadType::sharedPointerId, metaTypeId, npb );
00553
00554 if ( ret ) *ret = nt;
00555 return true;
00556 }
00557 }
00558
00559 return false;
00560 }
00561
00562 template <typename T>
00563 typename boost::disable_if<Internal::is_shared_pointer<T>, bool>::type
00564 Item::tryToClone( T * ) const
00565 {
00566 typedef Internal::PayloadTrait<T> PayloadType;
00567 BOOST_STATIC_ASSERT(( !PayloadType::isPolymorphic ));
00568
00569 return false;
00570 }
00571
00572 template <typename T>
00573 bool Item::hasPayload() const
00574 {
00575 BOOST_STATIC_ASSERT( !boost::is_pointer<T>::value );
00576 return hasPayload() && hasPayloadImpl<T>();
00577 }
00578
00579 template <typename T>
00580 typename boost::enable_if_c<Internal::PayloadTrait<T>::isPolymorphic,bool>::type
00581 Item::hasPayloadImpl( const int * ) const
00582 {
00583 typedef Internal::PayloadTrait<T> PayloadType;
00584 BOOST_STATIC_ASSERT(( PayloadType::isPolymorphic ));
00585
00586 typedef typename Internal::get_hierarchy_root<T>::type Root_T;
00587 typedef Internal::PayloadTrait<Root_T> RootType;
00588 BOOST_STATIC_ASSERT(( !RootType::isPolymorphic ));
00589
00590 try {
00591 return hasPayloadImpl<Root_T>()
00592 && PayloadType::canCastFrom( payload<Root_T>() );
00593 } catch ( const Akonadi::PayloadException & ) {
00594 return false;
00595 }
00596 }
00597
00598 template <typename T>
00599 typename boost::disable_if_c<Internal::PayloadTrait<T>::isPolymorphic,bool>::type
00600 Item::hasPayloadImpl() const
00601 {
00602 typedef Internal::PayloadTrait<T> PayloadType;
00603 BOOST_STATIC_ASSERT(( !PayloadType::isPolymorphic ));
00604
00605 const int metaTypeId = PayloadType::elementMetaTypeId();
00606
00607
00608 if ( !ensureMetaTypeId( metaTypeId ) )
00609 return false;
00610
00611
00612
00613 if ( const Payload<T> * const p = Internal::payload_cast<T>( payloadBaseV2( PayloadType::sharedPointerId, metaTypeId ) ) )
00614 return true;
00615
00616 return tryToClone<T>( 0 );
00617 }
00618
00619 template <typename T>
00620 void Item::setPayload( const T &p )
00621 {
00622 BOOST_STATIC_ASSERT(( !boost::is_pointer<T>::value ));
00623 setPayloadImpl( p );
00624 }
00625
00626 template <typename T>
00627 typename boost::enable_if_c<Internal::PayloadTrait<T>::isPolymorphic>::type
00628 Item::setPayloadImpl( const T & p, const int * )
00629 {
00630 typedef Internal::PayloadTrait<T> PayloadType;
00631 BOOST_STATIC_ASSERT(( PayloadType::isPolymorphic ));
00632
00633 typedef typename Internal::get_hierarchy_root<T>::type Root_T;
00634 typedef Internal::PayloadTrait<Root_T> RootType;
00635 BOOST_STATIC_ASSERT(( !RootType::isPolymorphic ));
00636
00637 setPayloadImpl<Root_T>( p );
00638 }
00639
00640 template <typename T>
00641 typename boost::disable_if_c<Internal::PayloadTrait<T>::isPolymorphic>::type
00642 Item::setPayloadImpl( const T & p )
00643 {
00644 typedef Internal::PayloadTrait<T> PayloadType;
00645 std::auto_ptr<PayloadBase> pb( new Payload<T>( p ) );
00646 setPayloadBaseV2( PayloadType::sharedPointerId,
00647 PayloadType::elementMetaTypeId(),
00648 pb );
00649 }
00650
00651 template <typename T>
00652 void Item::setPayload( T* p )
00653 {
00654 p->You_MUST_NOT_use_a_pointer_as_payload;
00655 }
00656
00657 template <typename T>
00658 void Item::setPayload( std::auto_ptr<T> p )
00659 {
00660 p.Nice_try_but_a_std_auto_ptr_is_not_allowed_as_payload_either;
00661 }
00662
00663 template <typename T>
00664 void Item::addToLegacyMapping( const QString & mimeType ) {
00665 typedef Internal::PayloadTrait<T> PayloadType;
00666 BOOST_STATIC_ASSERT(( !PayloadType::isPolymorphic ));
00667 std::auto_ptr<PayloadBase> p( new Payload<T> );
00668 addToLegacyMappingImpl( mimeType, PayloadType::sharedPointerId, PayloadType::elementMetaTypeId(), p );
00669 }
00670
00671 }
00672
00673 Q_DECLARE_METATYPE(Akonadi::Item)
00674 Q_DECLARE_METATYPE(Akonadi::Item::List)
00675
00676
00677 #endif