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"