akonadi
item.h
00001 /* 00002 Copyright (c) 2006 Volker Krause <vkrause@kde.org> 00003 2007 Till Adam <adam@kde.org> 00004 00005 This library is free software; you can redistribute it and/or modify it 00006 under the terms of the GNU Library General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or (at your 00008 option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, but WITHOUT 00011 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to the 00017 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00018 02110-1301, USA. 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 //@cond PRIVATE 00319 template <typename T> void setPayload( T* p ); 00320 template <typename T> void setPayload( std::auto_ptr<T> p ); 00321 //@endcond 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 //@cond PRIVATE 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 //std::auto_ptr<PayloadBase> takePayloadBase( int sharedPointerId, int metaTypeId ); 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 * /*disambiguate*/ = 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 * /*disambiguate*/ = 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 * /*disambiguate*/ = 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 * /*disambiguate*/ = 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 //@endcond 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 )); // prevent endless recursion 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 // make sure that we have a payload format represented by 'metaTypeId': 00517 if ( !ensureMetaTypeId( metaTypeId ) ) 00518 throwPayloadException( PayloadType::sharedPointerId, metaTypeId ); 00519 00520 // Check whether we have the exact payload 00521 // (metatype id and shared pointer type match) 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 // Check whether we have the same payload in 'the other 00541 // shared pointer' (### make it recurse, trying to find one, but 00542 // don't introduce infinite recursion): 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 // If found, attempt to make a clone (required the payload to provide virtual T * T::clone() const) 00548 const T nt = PayloadType::clone( p->payload ); 00549 if ( !PayloadType::isNull( nt ) ) { 00550 // if clone succeeded, add the clone to the Item: 00551 std::auto_ptr<PayloadBase> npb( new Payload<T>( nt ) ); 00552 addPayloadBaseVariant( PayloadType::sharedPointerId, metaTypeId, npb ); 00553 // and return it 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 )); // prevent endless recursion 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 // make sure that we have a payload format represented by 'metaTypeId': 00608 if ( !ensureMetaTypeId( metaTypeId ) ) 00609 return false; 00610 00611 // Check whether we have the exact payload 00612 // (metatype id and shared pointer type match) 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 )); // prevent endless recursion 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
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon May 14 2012 04:52:56 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon May 14 2012 04:52:56 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.