00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "conflicthandler_p.h"
00022
00023 #include "conflictresolvedialog_p.h"
00024
00025 #include <akonadi/itemcreatejob.h>
00026 #include <akonadi/itemfetchjob.h>
00027 #include <akonadi/itemfetchscope.h>
00028 #include <akonadi/itemmodifyjob.h>
00029 #include <akonadi/session.h>
00030 #include <klocale.h>
00031
00032 using namespace Akonadi;
00033
00034 ConflictHandler::ConflictHandler( ConflictType type, QObject *parent )
00035 : QObject( parent ),
00036 mConflictType( type ),
00037 mSession( new Session( "conflict handling session", this ) )
00038 {
00039 }
00040
00041 void ConflictHandler::setConflictingItems( const Akonadi::Item &changedItem, const Akonadi::Item &conflictingItem )
00042 {
00043 mChangedItem = changedItem;
00044 mConflictingItem = conflictingItem;
00045 }
00046
00047 void ConflictHandler::start()
00048 {
00049 if ( mConflictType == LocalLocalConflict || mConflictType == LocalRemoteConflict ) {
00050 ItemFetchJob *job = new ItemFetchJob( mConflictingItem, mSession );
00051 job->fetchScope().fetchFullPayload();
00052 job->fetchScope().setAncestorRetrieval( ItemFetchScope::Parent );
00053 connect( job, SIGNAL( result( KJob* ) ), SLOT( slotOtherItemFetched( KJob* ) ) );
00054 } else {
00055 resolve();
00056 }
00057 }
00058
00059 void ConflictHandler::slotOtherItemFetched( KJob *job )
00060 {
00061 if ( job->error() ) {
00062 emit error( job->errorText() );
00063 return;
00064 }
00065
00066 ItemFetchJob *fetchJob = qobject_cast<ItemFetchJob*>( job );
00067 if ( fetchJob->items().isEmpty() ) {
00068 emit error( i18n( "Did not find other item for conflict handling" ) );
00069 return;
00070 }
00071
00072 mConflictingItem = fetchJob->items().first();
00073 QMetaObject::invokeMethod( this, "resolve", Qt::QueuedConnection );
00074 }
00075
00076 void ConflictHandler::resolve()
00077 {
00078 ConflictResolveDialog dlg;
00079 dlg.setConflictingItems( mChangedItem, mConflictingItem );
00080 dlg.exec();
00081
00082 const ResolveStrategy strategy = dlg.resolveStrategy();
00083 switch( strategy ) {
00084 case UseLocalItem:
00085 useLocalItem();
00086 break;
00087 case UseOtherItem:
00088 useOtherItem();
00089 break;
00090 case UseBothItems:
00091 useBothItems();
00092 break;
00093 }
00094 }
00095
00096 void ConflictHandler::useLocalItem()
00097 {
00098
00099
00100
00101
00102 Item newItem( mChangedItem );
00103 newItem.setRevision( mConflictingItem.revision() );
00104
00105 ItemModifyJob *job = new ItemModifyJob( newItem, mSession );
00106 connect( job, SIGNAL( result( KJob* ) ), SLOT( slotUseLocalItemFinished( KJob* ) ) );
00107 }
00108
00109 void ConflictHandler::slotUseLocalItemFinished( KJob *job )
00110 {
00111 if ( job->error() ) {
00112 emit error( job->errorText() );
00113 } else {
00114 emit conflictResolved();
00115 }
00116 }
00117
00118 void ConflictHandler::useOtherItem()
00119 {
00120
00121 emit conflictResolved();
00122 }
00123
00124 void ConflictHandler::useBothItems()
00125 {
00126
00127
00128 ItemCreateJob *job = new ItemCreateJob( mChangedItem, mConflictingItem.parentCollection(), mSession );
00129 connect( job, SIGNAL( result( KJob* ) ), SLOT( slotUseBothItemsFinished( KJob* ) ) );
00130 }
00131
00132 void ConflictHandler::slotUseBothItemsFinished( KJob *job )
00133 {
00134 if ( job->error() ) {
00135 emit error( job->errorText() );
00136 } else {
00137 emit conflictResolved();
00138 }
00139 }
00140
00141 #include "conflicthandler_p.moc"