Add KeepBothVersions as a possible solution to ConflictSolver
authorKevin Ottens <kevin.ottens@nextcloud.com>
Thu, 8 Oct 2020 13:54:32 +0000 (15:54 +0200)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Thu, 22 Oct 2020 14:40:46 +0000 (16:40 +0200)
Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
src/gui/conflictsolver.cpp
src/gui/conflictsolver.h

index 578d15a54b14f248541e5109408147e62957e281..6a1de573c1e735742a4c606896f7e9f9b8cfa0a6 100644 (file)
@@ -17,6 +17,7 @@
 #include <QFileDialog>
 #include <QMessageBox>
 
+#include "common/utility.h"
 #include "filesystem.h"
 
 namespace OCC {
@@ -46,6 +47,8 @@ bool ConflictSolver::exec(ConflictSolver::Solution solution)
         return overwriteRemoteVersion();
     case KeepRemoteVersion:
         return deleteLocalVersion();
+    case KeepBothVersions:
+        return renameLocalVersion();
     }
     Q_UNREACHABLE();
     return false;
@@ -95,6 +98,44 @@ bool ConflictSolver::deleteLocalVersion()
     }
 }
 
+bool ConflictSolver::renameLocalVersion()
+{
+    if (_localVersionFilename.isEmpty()) {
+        return false;
+    }
+
+    QFileInfo info(_localVersionFilename);
+    if (!info.exists()) {
+        return false;
+    }
+
+    const auto renamePattern = [=] {
+        auto result = QString::fromUtf8(OCC::Utility::conflictFileBaseNameFromPattern(_localVersionFilename.toUtf8()));
+        const auto dotIndex = result.lastIndexOf('.');
+        return QString(result.left(dotIndex) + "_%1" + result.mid(dotIndex));
+    }();
+
+    const auto targetFilename = [=] {
+        uint i = 1;
+        auto result = renamePattern.arg(i);
+        while (QFileInfo::exists(result)) {
+            Q_ASSERT(i > 0);
+            i++;
+            result = renamePattern.arg(i);
+        }
+        return result;
+    }();
+
+    QString error;
+    if (FileSystem::uncheckedRenameReplace(_localVersionFilename, targetFilename, &error)) {
+        return true;
+    } else {
+        qCWarning(lcConflict) << "Rename error:" << error;
+        QMessageBox::warning(_parentWidget, tr("Error"), tr("Moving file failed:\n\n%1").arg(error));
+        return false;
+    }
+}
+
 bool ConflictSolver::overwriteRemoteVersion()
 {
     if (_localVersionFilename.isEmpty()) {
index e31e6eb0ace0cbb80ce9f5de5dcf36f86a296f84..caf4f2286742ce93fae408932add8fcc138b531e 100644 (file)
@@ -29,7 +29,8 @@ class ConflictSolver : public QObject
 public:
     enum Solution {
         KeepLocalVersion,
-        KeepRemoteVersion
+        KeepRemoteVersion,
+        KeepBothVersions
     };
 
     explicit ConflictSolver(QWidget *parent = nullptr);
@@ -49,6 +50,7 @@ signals:
 
 private:
     bool deleteLocalVersion();
+    bool renameLocalVersion();
     bool overwriteRemoteVersion();
 
     QWidget *_parentWidget;