File indexing completed on 2024-11-10 04:40:39
0001 /* 0002 SPDX-FileCopyrightText: 2010 KDAB 0003 SPDX-FileContributor: Tobias Koenig <tokoe@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "conflicthandler_p.h" 0009 0010 #include "itemcreatejob.h" 0011 #include "itemfetchjob.h" 0012 #include "itemfetchscope.h" 0013 #include "itemmodifyjob.h" 0014 #include "session.h" 0015 #include <KLocalizedString> 0016 0017 using namespace Akonadi; 0018 0019 ConflictHandler::ConflictHandler(ConflictType type, QObject *parent) 0020 : QObject(parent) 0021 , mConflictType(type) 0022 , mSession(new Session("conflict handling session", this)) 0023 { 0024 } 0025 0026 void ConflictHandler::setConflictingItems(const Akonadi::Item &changedItem, const Akonadi::Item &conflictingItem) 0027 { 0028 mChangedItem = changedItem; 0029 mConflictingItem = conflictingItem; 0030 } 0031 0032 void ConflictHandler::start() 0033 { 0034 if (mConflictType == LocalLocalConflict || mConflictType == LocalRemoteConflict) { 0035 auto job = new ItemFetchJob(mConflictingItem, mSession); 0036 job->fetchScope().fetchFullPayload(); 0037 job->fetchScope().setAncestorRetrieval(ItemFetchScope::Parent); 0038 connect(job, &ItemFetchJob::result, this, &ConflictHandler::slotOtherItemFetched); 0039 } else { 0040 resolve(); 0041 } 0042 } 0043 0044 void ConflictHandler::slotOtherItemFetched(KJob *job) 0045 { 0046 if (job->error()) { 0047 Q_EMIT error(job->errorText()); // TODO: extend error message 0048 return; 0049 } 0050 0051 auto fetchJob = qobject_cast<ItemFetchJob *>(job); 0052 if (fetchJob->items().isEmpty()) { 0053 Q_EMIT error(i18n("Did not find other item for conflict handling")); 0054 return; 0055 } 0056 0057 mConflictingItem = fetchJob->items().at(0); 0058 QMetaObject::invokeMethod(this, &ConflictHandler::resolve, Qt::QueuedConnection); 0059 } 0060 0061 void ConflictHandler::resolve() 0062 { 0063 #pragma message("warning KF6 Port me!") 0064 #if 0 0065 ConflictResolveDialog dlg; 0066 dlg.setConflictingItems(mChangedItem, mConflictingItem); 0067 dlg.exec(); 0068 0069 const ResolveStrategy strategy = dlg.resolveStrategy(); 0070 switch (strategy) { 0071 case UseLocalItem: 0072 useLocalItem(); 0073 break; 0074 case UseOtherItem: 0075 useOtherItem(); 0076 break; 0077 case UseBothItems: 0078 useBothItems(); 0079 break; 0080 } 0081 #endif 0082 } 0083 0084 void ConflictHandler::useLocalItem() 0085 { 0086 // We have to overwrite the other item inside the Akonadi storage with the local 0087 // item. To make this happen, we have to set the revision of the local item to 0088 // the one of the other item to let the Akonadi server accept it. 0089 0090 Item newItem(mChangedItem); 0091 newItem.setRevision(mConflictingItem.revision()); 0092 0093 auto job = new ItemModifyJob(newItem, mSession); 0094 connect(job, &ItemModifyJob::result, this, &ConflictHandler::slotUseLocalItemFinished); 0095 } 0096 0097 void ConflictHandler::slotUseLocalItemFinished(KJob *job) 0098 { 0099 if (job->error()) { 0100 Q_EMIT error(job->errorText()); // TODO: extend error message 0101 } else { 0102 Q_EMIT conflictResolved(); 0103 } 0104 } 0105 0106 void ConflictHandler::useOtherItem() 0107 { 0108 // We can just ignore the local item here and leave everything as it is. 0109 Q_EMIT conflictResolved(); 0110 } 0111 0112 void ConflictHandler::useBothItems() 0113 { 0114 // We have to create a new item for the local item under the collection that has 0115 // been retrieved when we fetched the other item. 0116 auto job = new ItemCreateJob(mChangedItem, mConflictingItem.parentCollection(), mSession); 0117 connect(job, &ItemCreateJob::result, this, &ConflictHandler::slotUseBothItemsFinished); 0118 } 0119 0120 void ConflictHandler::slotUseBothItemsFinished(KJob *job) 0121 { 0122 if (job->error()) { 0123 Q_EMIT error(job->errorText()); // TODO: extend error message 0124 } else { 0125 Q_EMIT conflictResolved(); 0126 } 0127 } 0128 0129 #include "moc_conflicthandler_p.cpp"