From 564d52c65b2ae7656de7d177b880b77432a8c6da Mon Sep 17 00:00:00 2001
From: Antoine Fontaine <antoine.fontaine@epfl.ch>
Date: Thu, 30 May 2019 12:30:38 +0200
Subject: [PATCH] Add a new Settings object

It is implemented using GSettings' bind. Other parts of the code are to
be adapted to use it.
---
 meson.build      |   1 +
 src/gui-window.c |  44 +++++++-------
 src/settings.c   | 155 +++++++++++++++++++++++++++++++++++++++++++++++
 src/settings.h   |  31 ++++++++++
 4 files changed, 208 insertions(+), 23 deletions(-)
 create mode 100644 src/settings.c
 create mode 100644 src/settings.h

diff --git a/meson.build b/meson.build
index bc398e1..7977027 100644
--- a/meson.build
+++ b/meson.build
@@ -129,6 +129,7 @@ moody_sources = [
   'src/gui-week.c',
   'src/gui-resource.c',
   'src/password.c',
+  'src/settings.c',
   'src/utils.c',
 ]
 
diff --git a/src/gui-window.c b/src/gui-window.c
index 4ade00a..6b31697 100644
--- a/src/gui-window.c
+++ b/src/gui-window.c
@@ -20,8 +20,8 @@
 #include "gui-pass-dialog.h"
 #include "gui-course.h"
 #include "data-struct.h"
+#include "settings.h"
 #include "moodle-provider.h"
-#include "password.h"
 #include "config.h"
 
 #include <glib/gi18n.h>
@@ -32,7 +32,9 @@ struct _GuiWindow
 {
   GtkApplicationWindow parent_instance;
 
-  GSettings *settings;
+  MoodSettings *settings;
+  struct Course* courses;
+  guint course_count;
 
   HdyLeaflet *header_box;
   HdyLeaflet *content_box;
@@ -41,8 +43,6 @@ struct _GuiWindow
   //GtkToggleButton *search_button;
   GtkStackSidebar *sidebar;
   GtkStack *stack;
-  struct Course* courses;
-  guint course_count;
   //HdySearchBar *search_bar;
   //GtkEntry *search_entry;
   HdyHeaderGroup *header_group;
@@ -55,28 +55,24 @@ G_DEFINE_TYPE (GuiWindow, gui_window, GTK_TYPE_APPLICATION_WINDOW)
 static void update_moodle_index (GuiWindow *self);
 
 static void
-initialize_moodle_provider (GuiWindow *self)
+initialize_moodle_provider (MoodSettings *settings)
 {
-  gchar *username, *password;
-  username = g_settings_get_string (self->settings, "username");
-  if (!moodle_password_get (username, &password))
-    g_error ("Could not get password\n");
+  const gchar *username, *password;
+  g_object_get (settings, "username", &username,
+                          "password", &password, NULL);
   moodle_provider_init (MOODLE_MODE_ONLINE, username, password);
 }
 
 static void
 pass_changed_cb (gpointer ptr, const gchar *username, const gchar *password)
 {
-  GuiWindow *self = HDY_GUI_WINDOW (ptr);
-
-  g_settings_set_string (self->settings, "username", username);
+  GuiWindow *self = ptr;
 
-  if (!moodle_password_set (username, password)) {
-    g_warning ("Could not set password\n");
-  }
+  g_object_set (self->settings, "username", username,
+                                "password", password, NULL);
 
   moodle_provider_disconnect ();
-  initialize_moodle_provider (self);
+  initialize_moodle_provider (self->settings);
   update_moodle_index (self);
 }
 
@@ -86,8 +82,9 @@ activate_ask_pass (GSimpleAction *simple,
                    gpointer       ptr)
 {
   GuiWindow *self = ptr;
-  const gchar *current_username = g_settings_get_string (self->settings, "username");
-  self->dialog = gui_pass_dialog_new (GTK_WINDOW (self), current_username, pass_changed_cb, ptr);
+  const gchar *username;
+  g_object_get (self->settings, "username", &username, NULL);
+  self->dialog = gui_pass_dialog_new (GTK_WINDOW (self), username, pass_changed_cb, ptr);
   gtk_widget_show (GTK_WIDGET (self->dialog));
 }
 
@@ -289,6 +286,7 @@ gui_window_new (GtkApplication *application)
   return g_object_new (HDY_TYPE_GUI_WINDOW, "application", application, NULL);
 }
 
+
 static void
 gui_window_finalize (GObject *object)
 {
@@ -297,6 +295,7 @@ gui_window_finalize (GObject *object)
   G_OBJECT_CLASS (gui_window_parent_class)->finalize (object);
 }
 
+
 static void
 gui_window_class_init (GuiWindowClass *class)
 {
@@ -324,7 +323,6 @@ gui_window_class_init (GuiWindowClass *class)
 }
 
 
-
 static void
 update_moodle_index (GuiWindow *self)
 {
@@ -350,10 +348,6 @@ gui_window_init (GuiWindow *self)
   self->dialog = NULL;
   gtk_widget_init_template (GTK_WIDGET (self));
 
-  self->settings = g_settings_new (APP_NAME);
-
-  initialize_moodle_provider (self);
-
   const GActionEntry entries[] = {
     { "ask-pass",     activate_ask_pass          },
     //{ "print-string", activate_print_string, "s" }
@@ -362,6 +356,10 @@ gui_window_init (GuiWindow *self)
                                    entries, G_N_ELEMENTS (entries),
                                    self);
 
+  self->settings = mood_settings_new ();
+
+  initialize_moodle_provider (self->settings);
+
   hdy_leaflet_set_visible_child_name (self->content_box, "content");
   update_header_bar (self);
 
diff --git a/src/settings.c b/src/settings.c
new file mode 100644
index 0000000..1977ca4
--- /dev/null
+++ b/src/settings.c
@@ -0,0 +1,155 @@
+/*
+ *  Copyright 2019, Antoine Fontaine <antoine.fontaine@epfl.ch>
+ *  I release this program under GNU GPLv3+.
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+
+#include "settings.h"
+#include "password.h"
+#include "config.h"
+
+enum {
+  PROP_0,
+  PROP_SETTING_USERNAME,
+  PROP_SETTING_PASSWORD,
+  PROP_SETTING_USE_CACHE,
+  N_SETTINGS
+};
+
+GParamSpec *mood_settings_properties[N_SETTINGS] = { NULL, };
+
+struct _MoodSettings
+{
+  GObject parent_instance;
+
+  const gchar *username;
+  gboolean use_cache;
+};
+
+G_DEFINE_TYPE (MoodSettings, mood_settings, G_TYPE_OBJECT)
+
+MoodSettings *
+mood_settings_new (void)
+{
+  return g_object_new (MOOD_TYPE_SETTINGS, NULL);
+}
+
+
+static void
+mood_settings_set_property (GObject      *object,
+                            guint         property_id,
+                            const GValue *value,
+                            GParamSpec   *pspec)
+{
+  MoodSettings *self = MOOD_MOOD_SETTINGS (object);
+  switch (property_id) {
+  case PROP_SETTING_USERNAME:
+    self->username = g_strdup(g_value_get_string (value));
+    break;
+  case PROP_SETTING_PASSWORD:
+    moodle_password_set (self->username, g_value_get_string (value));
+    break;
+  case PROP_SETTING_USE_CACHE:
+    self->use_cache = g_value_get_boolean (value);
+    break;
+  default:
+    // We don't have any other property...
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+    break;
+  }
+}
+
+static void
+mood_settings_get_property (GObject    *object,
+                            guint       property_id,
+                            GValue     *value,
+                            GParamSpec *pspec)
+{
+  MoodSettings *self = MOOD_MOOD_SETTINGS (object);
+  switch (property_id) {
+  case PROP_SETTING_USERNAME:
+    if (!self->username)
+      g_warning ("That read isn't going well\n");
+    g_value_set_string (value, self->username);
+    break;
+  case PROP_SETTING_PASSWORD: {
+    gchar *password;
+    if (!moodle_password_get (self->username, &password))
+      g_error ("impossible to get saved password\n");
+    g_value_set_string (value, password);
+    // TODO: ensure password is freed out of memory
+    break;
+  }
+  case PROP_SETTING_USE_CACHE:
+    g_value_set_boolean (value, self->use_cache);
+    break;
+  default:
+    // We don't have any other property...
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+    break;
+  }
+}
+
+
+static void
+mood_settings_class_init (MoodSettingsClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  //object_class->finalize = &mood_settings_finalize;
+  mood_settings_properties[PROP_SETTING_USERNAME] =
+    g_param_spec_string ("username", "username",
+                         "The username we use to connect to moodle. At EPFL, this is your gaspard account.",
+                         NULL,
+                         G_PARAM_WRITABLE|G_PARAM_READABLE);
+
+  mood_settings_properties[PROP_SETTING_PASSWORD] =
+    g_param_spec_string ("password", "password",
+                         "Your account's password",
+                         NULL,
+                         G_PARAM_WRITABLE|G_PARAM_READABLE);
+
+  mood_settings_properties[PROP_SETTING_USE_CACHE] =
+    g_param_spec_boolean ("use_cache", "use_cache",
+                          "Whether to save to disk the responses the moodle provider gets",
+                          TRUE,
+                          G_PARAM_WRITABLE|G_PARAM_READABLE);
+
+  object_class->set_property = &mood_settings_set_property;
+  object_class->get_property = &mood_settings_get_property;
+  g_object_class_install_properties (object_class,
+                                     N_SETTINGS,
+                                     mood_settings_properties);
+}
+
+
+static void
+mood_settings_init (MoodSettings *self)
+{
+  //self->settings = g_settings_new (APP_NAME);
+  GSettings *settings = g_settings_new (APP_NAME);
+
+  self->username = NULL;
+  self->use_cache = -1;
+
+  g_settings_bind (settings, "username",
+                   self, "username",
+                   G_SETTINGS_BIND_DEFAULT);
+  g_settings_bind (settings, "use-cache",
+                   self, "use-cache",
+                   G_SETTINGS_BIND_DEFAULT);
+
+}
\ No newline at end of file
diff --git a/src/settings.h b/src/settings.h
new file mode 100644
index 0000000..a12ee38
--- /dev/null
+++ b/src/settings.h
@@ -0,0 +1,31 @@
+/*
+ *  Copyright 2019, Antoine Fontaine <antoine.fontaine@epfl.ch>
+ *  I release this program under GNU GPLv3+.
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define MOOD_TYPE_SETTINGS (mood_settings_get_type())
+
+G_DECLARE_FINAL_TYPE (MoodSettings, mood_settings, MOOD, MOOD_SETTINGS, GObject)
+
+MoodSettings *mood_settings_new (void);
+
+G_END_DECLS
-- 
GitLab