From 32b9cc123c820a023433ef79c2884b7a8c120a9c Mon Sep 17 00:00:00 2001
From: Dale Glass <dale@daleglass.net>
Date: Sun, 4 Jun 2023 14:50:03 +0200
Subject: [PATCH] Fix resetting the settings

Also minor documentation improvements
---
 interface/src/CrashRecoveryHandler.cpp  | 16 ++++-----
 libraries/shared/src/SettingHandle.cpp  |  6 +++-
 libraries/shared/src/SettingHandle.h    |  2 ++
 libraries/shared/src/SettingManager.cpp | 15 +++++++++
 libraries/shared/src/SettingManager.h   | 43 +++++++++++++++++++++++++
 5 files changed, 73 insertions(+), 9 deletions(-)

diff --git a/interface/src/CrashRecoveryHandler.cpp b/interface/src/CrashRecoveryHandler.cpp
index 4bf4d04180..94523333d4 100644
--- a/interface/src/CrashRecoveryHandler.cpp
+++ b/interface/src/CrashRecoveryHandler.cpp
@@ -25,14 +25,16 @@
 #include "Application.h"
 #include "Menu.h"
 
+
 #include <RunningMarker.h>
 #include <SettingHandle.h>
 #include <SettingHelpers.h>
+#include <SettingManager.h>
+#include <DependencyManager.h>
 
 
 bool CrashRecoveryHandler::checkForResetSettings(bool wasLikelyCrash, bool suppressPrompt) {
-    QSettings::setDefaultFormat(JSON_FORMAT);
-    QSettings settings;
+    Settings settings;
     settings.beginGroup("Developer");
     QVariant displayCrashOptions = settings.value(MenuOption::DisplayCrashOptions);
     settings.endGroup();
@@ -111,7 +113,8 @@ void CrashRecoveryHandler::handleCrash(CrashRecoveryHandler::Action action) {
         return;
     }
 
-    QSettings settings;
+    Settings settings;
+
     const QString ADDRESS_MANAGER_GROUP = "AddressManager";
     const QString ADDRESS_KEY = "address";
     const QString AVATAR_GROUP = "Avatar";
@@ -145,11 +148,8 @@ void CrashRecoveryHandler::handleCrash(CrashRecoveryHandler::Action action) {
         tutorialComplete = settings.value(TUTORIAL_COMPLETE_FLAG_KEY).toBool();
     }
 
-    // Delete Interface.ini
-    QFile settingsFile(settings.fileName());
-    if (settingsFile.exists()) {
-        settingsFile.remove();
-    }
+    // Reset everything
+    settings.clear();
 
     if (action == CrashRecoveryHandler::RETAIN_IMPORTANT_INFO) {
         // Write avatar info
diff --git a/libraries/shared/src/SettingHandle.cpp b/libraries/shared/src/SettingHandle.cpp
index bb607b1544..88785e5700 100644
--- a/libraries/shared/src/SettingHandle.cpp
+++ b/libraries/shared/src/SettingHandle.cpp
@@ -199,4 +199,8 @@ QString Settings::getPath(const QString &key) const {
 
     ret.append(key);
     return ret;
-}
\ No newline at end of file
+}
+
+void Settings::clear() {
+    _manager->clearAllSettings();
+}
diff --git a/libraries/shared/src/SettingHandle.h b/libraries/shared/src/SettingHandle.h
index e474ee61de..2390063555 100644
--- a/libraries/shared/src/SettingHandle.h
+++ b/libraries/shared/src/SettingHandle.h
@@ -110,6 +110,8 @@ public:
     void setQuatValue(const QString& name, const glm::quat& quatValue);
     void getQuatValueIfValid(const QString& name, glm::quat& quatValue);
 
+    void clear();
+
 private:
     QString getGroupPrefix() const;
     QString getPath(const QString &value) const;
diff --git a/libraries/shared/src/SettingManager.cpp b/libraries/shared/src/SettingManager.cpp
index 7a98d01232..1376f3138a 100644
--- a/libraries/shared/src/SettingManager.cpp
+++ b/libraries/shared/src/SettingManager.cpp
@@ -45,6 +45,12 @@ namespace Setting {
         _qSettings->remove(key);
     }
 
+    void WriteWorker::clearAllSettings() {
+        init();
+        _qSettings->clear();
+        sync();
+    }
+
     void WriteWorker::sync() {
         //qCDebug(settings_writer) << "Forcing settings sync";
         init();
@@ -81,6 +87,7 @@ namespace Setting {
         connect(this, &Manager::valueChanged, worker, &WriteWorker::setValue, Qt::QueuedConnection);
         connect(this, &Manager::keyRemoved, worker, &WriteWorker::removeKey, Qt::QueuedConnection);
         connect(this, &Manager::syncRequested, worker, &WriteWorker::sync, Qt::QueuedConnection);
+        connect(this, &Manager::clearAllSettingsRequested, worker, &WriteWorker::clearAllSettings, Qt::QueuedConnection);
 
         // This one is blocking because we want to wait until it's actually processed.
         connect(this, &Manager::terminationRequested, worker, &WriteWorker::terminate, Qt::BlockingQueuedConnection);
@@ -209,4 +216,12 @@ namespace Setting {
             return _settings.value(key, defaultValue);
         });
     }
+
+    void Manager::clearAllSettings() {
+        withWriteLock([&] {
+            _settings.clear();
+        });
+
+        emit clearAllSettingsRequested();
+    }
 }
diff --git a/libraries/shared/src/SettingManager.h b/libraries/shared/src/SettingManager.h
index b2e85e4395..5708fa8dbd 100644
--- a/libraries/shared/src/SettingManager.h
+++ b/libraries/shared/src/SettingManager.h
@@ -75,6 +75,12 @@ namespace Setting {
          */
         void removeKey(const QString key);
 
+        /**
+         * @brief Remove all values from the configuration.
+         *
+         */
+        void clearAllSettings();
+
         /**
          * @brief Force writing the config to disk
          *
@@ -172,6 +178,13 @@ namespace Setting {
          */
         QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
 
+        /**
+         * @brief Clear all the settings
+         *
+         * Removes the entire configuration, resetting everything to "factory default"
+         *
+         */
+        void clearAllSettings();
     protected:
         /**
          * @brief How long to wait for writer thread termination
@@ -204,9 +217,39 @@ namespace Setting {
         void terminateThread();
 
     signals:
+        /**
+         * @brief The value of a setting was changed
+         *
+         * @param key Setting key
+         * @param value New value
+         */
         void valueChanged(const QString key, QVariant value);
+
+        /**
+         * @brief A setting was removed
+         *
+         * @param key Setting key
+         */
         void keyRemoved(const QString key);
+
+        /**
+         * @brief A request to synchronize the settings to permanent storage was made
+         *
+         */
         void syncRequested();
+
+        /**
+         * @brief A request to clear all the settings was made
+         *
+         */
+        void clearAllSettingsRequested();
+
+        /**
+         * @brief The termination of the settings system was requested
+         *
+         * This happens on shutdown. All pending changes should be serialized to disk.
+         *
+         */
         void terminationRequested();
 
     private: