akonadi
itemmodifyjob.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "itemmodifyjob.h"
00021 #include "itemmodifyjob_p.h"
00022
00023 #include "collection.h"
00024 #include "entity_p.h"
00025 #include "imapparser_p.h"
00026 #include "itemserializer.h"
00027 #include "job_p.h"
00028 #include "item_p.h"
00029 #include "protocolhelper.h"
00030
00031 #include <kdebug.h>
00032
00033 using namespace Akonadi;
00034
00035 ItemModifyJobPrivate::ItemModifyJobPrivate( ItemModifyJob *parent, const Item &item )
00036 : JobPrivate( parent ),
00037 mItem( item ),
00038 mRevCheck( true ),
00039 mIgnorePayload( false )
00040 {
00041 mParts = mItem.loadedPayloadParts();
00042 }
00043
00044 void ItemModifyJobPrivate::setClean()
00045 {
00046 mOperations.insert( Dirty );
00047 }
00048
00049 QByteArray ItemModifyJobPrivate::nextPartHeader()
00050 {
00051 QByteArray command;
00052 if ( !mParts.isEmpty() ) {
00053 QSetIterator<QByteArray> it( mParts );
00054 const QByteArray label = it.next();
00055 mParts.remove( label );
00056
00057 mPendingData.clear();
00058 int version = 0;
00059 ItemSerializer::serialize( mItem, label, mPendingData, version );
00060 command += ' ' + ProtocolHelper::encodePartIdentifier( ProtocolHelper::PartPayload, label, version );
00061 command += ".SILENT {" + QByteArray::number( mPendingData.size() ) + '}';
00062 if ( mPendingData.size() > 0 )
00063 command += '\n';
00064 else
00065 command += nextPartHeader();
00066 } else {
00067 command += ")\n";
00068 }
00069 return command;
00070 }
00071
00072
00073 ItemModifyJob::ItemModifyJob( const Item &item, QObject * parent )
00074 : Job( new ItemModifyJobPrivate( this, item ), parent )
00075 {
00076 Q_D( ItemModifyJob );
00077
00078 d->mOperations.insert( ItemModifyJobPrivate::RemoteId );
00079 }
00080
00081 ItemModifyJob::~ItemModifyJob()
00082 {
00083 }
00084
00085 void ItemModifyJob::doStart()
00086 {
00087 Q_D( ItemModifyJob );
00088
00089 QList<QByteArray> changes;
00090 foreach ( int op, d->mOperations ) {
00091 switch ( op ) {
00092 case ItemModifyJobPrivate::RemoteId:
00093 if ( !d->mItem.remoteId().isNull() ) {
00094 changes << "REMOTEID.SILENT";
00095 changes << ImapParser::quote( d->mItem.remoteId().toLatin1() );
00096 }
00097 break;
00098 case ItemModifyJobPrivate::Dirty:
00099 changes << "DIRTY.SILENT";
00100 changes << "false";
00101 break;
00102 }
00103 }
00104
00105 if ( d->mItem.d_func()->mFlagsOverwritten ) {
00106 changes << "FLAGS.SILENT";
00107 changes << '(' + ImapParser::join( d->mItem.flags(), " " ) + ')';
00108 } else {
00109 if ( !d->mItem.d_func()->mAddedFlags.isEmpty() ) {
00110 changes << "+FLAGS.SILENT";
00111 changes << '(' + ImapParser::join( d->mItem.d_func()->mAddedFlags, " " ) + ')';
00112 }
00113 if ( !d->mItem.d_func()->mDeletedFlags.isEmpty() ) {
00114 changes << "-FLAGS.SILENT";
00115 changes << '(' + ImapParser::join( d->mItem.d_func()->mDeletedFlags, " " ) + ')';
00116 }
00117 }
00118
00119 if ( !d->mItem.d_func()->mDeletedAttributes.isEmpty() ) {
00120 changes << "-PARTS.SILENT";
00121 QList<QByteArray> attrs;
00122 foreach ( const QByteArray &attr, d->mItem.d_func()->mDeletedAttributes )
00123 attrs << ProtocolHelper::encodePartIdentifier( ProtocolHelper::PartAttribute, attr );
00124 changes << '(' + ImapParser::join( attrs, " " ) + ')';
00125 }
00126
00127
00128 if ( changes.isEmpty() && d->mParts.isEmpty() ) {
00129 emitResult();
00130 return;
00131 }
00132
00133 d->mTag = d->newTag();
00134 QByteArray command = d->mTag;
00135 command += " UID STORE " + QByteArray::number( d->mItem.id() ) + ' ';
00136 if ( !d->mRevCheck ) {
00137 command += "NOREV ";
00138 } else {
00139 command += "REV " + QByteArray::number( d->mItem.revision() );
00140 }
00141
00142 command += " (" + ImapParser::join( changes, " " );
00143 const QByteArray attrs = ProtocolHelper::attributesToByteArray( d->mItem, true );
00144 if ( !attrs.isEmpty() )
00145 command += ' ' + attrs;
00146 command += d->nextPartHeader();
00147 d->writeData( command );
00148 d->newTag();
00149 }
00150
00151 void ItemModifyJob::doHandleResponse(const QByteArray &_tag, const QByteArray & data)
00152 {
00153 Q_D( ItemModifyJob );
00154
00155 if ( _tag == "+" ) {
00156 d->writeData( d->mPendingData );
00157 d->writeData( d->nextPartHeader() );
00158 return;
00159 }
00160 if ( _tag == d->mTag ) {
00161 if ( data.startsWith( "OK" ) ) {
00162
00163 d->mItem.setRevision( d->mItem.revision() + 1 );
00164 d->mItem.d_ptr->resetChangeLog();
00165 } else {
00166 setError( Unknown );
00167 setErrorText( QString::fromUtf8( data ) );
00168 }
00169 emitResult();
00170 return;
00171 }
00172 kDebug( 5250 ) << "Unhandled response: " << _tag << data;
00173 }
00174
00175 void ItemModifyJob::setIgnorePayload( bool ignore )
00176 {
00177 Q_D( ItemModifyJob );
00178
00179 if ( d->mIgnorePayload == ignore )
00180 return;
00181
00182 d->mIgnorePayload = ignore;
00183 if ( d->mIgnorePayload )
00184 d->mParts = QSet<QByteArray>();
00185 else {
00186 Q_ASSERT( !d->mItem.mimeType().isEmpty() );
00187 d->mParts = d->mItem.loadedPayloadParts();
00188 }
00189 }
00190
00191 bool ItemModifyJob::ignorePayload() const
00192 {
00193 Q_D( const ItemModifyJob );
00194
00195 return d->mIgnorePayload;
00196 }
00197
00198 void ItemModifyJob::disableRevisionCheck()
00199 {
00200 Q_D( ItemModifyJob );
00201
00202 d->mRevCheck = false;
00203 }
00204
00205 Item ItemModifyJob::item() const
00206 {
00207 Q_D( const ItemModifyJob );
00208
00209 return d->mItem;
00210 }
00211
00212 #include "itemmodifyjob.moc"