From e0a14cac5b03ea41303e1602b79b51fec1f5c1de Mon Sep 17 00:00:00 2001
From: Olivier Goffart <ogoffart@woboq.com>
Date: Wed, 6 Dec 2017 15:29:07 +0100
Subject: [PATCH] ConfigFile: use QStandardPaths::AppConfigLocation for the
 config file

Also use appName instead of appNameGui in order to compute the path

Issue: #2245

The reason is to respect the XDG spec on Unix (#1601) and might help
on windows roaming profiles (#684)
---
 doc/autoupdate.rst         |  2 +-
 doc/conffile.rst           |  6 +++---
 src/gui/application.cpp    | 21 ++++++++++++++++++++-
 src/libsync/configfile.cpp | 16 ++++------------
 src/libsync/configfile.h   |  1 -
 5 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/doc/autoupdate.rst b/doc/autoupdate.rst
index ad0ff0340..e581a70ae 100644
--- a/doc/autoupdate.rst
+++ b/doc/autoupdate.rst
@@ -119,7 +119,7 @@ Preventing Automatic Updates in Linux Environments
 
 Because the Linux client does not provide automatic updating functionality, there is no
 need to remove the automatic-update check.  However, if you want to disable it edit your desktop
-client configuration file, ``$HOME/.local/share/data/ownCloud/owncloud.cfg``. 
+client configuration file, ``$HOME/.config/ownCloud/owncloud.cfg``.
 Add this line to the [General] section::
 
     skipUpdateCheck=true
diff --git a/doc/conffile.rst b/doc/conffile.rst
index 3fdcc179b..dda2bd68b 100644
--- a/doc/conffile.rst
+++ b/doc/conffile.rst
@@ -1,13 +1,13 @@
 The ownCloud Client reads a configuration file.  You can locate this configuration file as follows:
 
 On Linux distributions:
-        ``$HOME/.local/share/data/ownCloud/owncloud.cfg``
+        ``$HOME/.config/ownCloud/owncloud.cfg``
 
 On Microsoft Windows systems:
-        ``%LOCALAPPDATA%\ownCloud\owncloud.cfg``
+        ``%APPDATA%\ownCloud\owncloud.cfg``
 
 On MAC OS X systems:
-        ``$HOME/Library/Application Support/ownCloud/owncloud.cfg``
+        ``$HOME/Library/Preferences/ownCloud/owncloud.cfg``
 
 
 The configuration file contains settings using the Microsoft Windows .ini file
diff --git a/src/gui/application.cpp b/src/gui/application.cpp
index 1f8b53be8..715e81e9a 100644
--- a/src/gui/application.cpp
+++ b/src/gui/application.cpp
@@ -119,10 +119,29 @@ Application::Application(int &argc, char **argv)
     // TODO: Can't set this without breaking current config paths
     //    setOrganizationName(QLatin1String(APPLICATION_VENDOR));
     setOrganizationDomain(QLatin1String(APPLICATION_REV_DOMAIN));
-    setApplicationName(_theme->appNameGUI());
+    setApplicationName(_theme->appName());
     setWindowIcon(_theme->applicationIcon());
     setAttribute(Qt::AA_UseHighDpiPixmaps, true);
 
+    auto confDir = ConfigFile().configPath();
+    if (!QFileInfo(confDir).exists()) {
+        // Migrate from version <= 2.4
+        setApplicationName(_theme->appNameGUI());
+        QString oldDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
+        setApplicationName(_theme->appName());
+        if (QFileInfo(oldDir).isDir()) {
+            qCInfo(lcApplication) << "Migrating old config from" << oldDir << "to" << confDir;
+            if (!QFile::rename(oldDir, confDir)) {
+                qCWarning(lcApplication) << "Failed to move the old config file to its new location (" << oldDir << "to" << confDir << ")";
+            } else {
+#ifndef Q_OS_WIN
+                // Create a symbolic link so a downgrade of the client would still find the config.
+                QFile::link(confDir, oldDir);
+#endif
+            }
+        }
+    }
+
     parseOptions(arguments());
     //no need to waste time;
     if (_helpOnly || _versionOnly)
diff --git a/src/libsync/configfile.cpp b/src/libsync/configfile.cpp
index d98815920..a564bff25 100644
--- a/src/libsync/configfile.cpp
+++ b/src/libsync/configfile.cpp
@@ -26,7 +26,6 @@
 #ifndef TOKEN_AUTH_ONLY
 #include <QWidget>
 #include <QHeaderView>
-#include <QDesktopServices>
 #endif
 
 #include <QCoreApplication>
@@ -36,6 +35,7 @@
 #include <QLoggingCategory>
 #include <QSettings>
 #include <QNetworkProxy>
+#include <QStandardPaths>
 
 #define DEFAULT_REMOTE_POLL_INTERVAL 30000 // default remote poll time in milliseconds
 #define DEFAULT_FULL_LOCAL_DISCOVERY_INTERVAL (60 * 60 * 1000) // 1 hour
@@ -252,13 +252,11 @@ QVariant ConfigFile::getPolicySetting(const QString &setting, const QVariant &de
 
 QString ConfigFile::configPath() const
 {
-#ifndef TOKEN_AUTH_ONLY
     if (_confDir.isEmpty()) {
-        //  Qt 5's QStandardPaths::writableLocation gives us wrong results (without /data/),
-        //  so we'll have to use the deprecated version for now
-        _confDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
+        // On Unix, use the AppConfigLocation for the settings, that's configurable with the XDG_CONFIG_HOME env variable.
+        // On Windows, use AppDataLocation, that's where the roaming data is and where we should store the config file
+        _confDir = QStandardPaths::writableLocation(Utility::isWindows() ? QStandardPaths::AppDataLocation : QStandardPaths::AppConfigLocation);
     }
-#endif
     QString dir = _confDir;
 
     if (!dir.endsWith(QLatin1Char('/')))
@@ -266,12 +264,6 @@ QString ConfigFile::configPath() const
     return dir;
 }
 
-QString ConfigFile::configPathWithAppName() const
-{
-    //HACK
-    return QFileInfo(configFile()).dir().absolutePath().append("/");
-}
-
 static const QLatin1String exclFile("sync-exclude.lst");
 
 QString ConfigFile::excludeFile(Scope scope) const
diff --git a/src/libsync/configfile.h b/src/libsync/configfile.h
index f1bcf7492..bd33fdc04 100644
--- a/src/libsync/configfile.h
+++ b/src/libsync/configfile.h
@@ -43,7 +43,6 @@ public:
         SystemScope };
 
     QString configPath() const;
-    QString configPathWithAppName() const;
     QString configFile() const;
     QString excludeFile(Scope scope) const;
     static QString excludeFileFromSystem(); // doesn't access config dir