[gnome-applets/wip/muktupavels/per-applet-notes-file: 22/24] sticky-notes: create per-applet notes file




commit 06d91ca3aa2a2d858b0e0a7a061b8d94bcadc902
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Tue Apr 7 23:03:26 2020 +0300

    sticky-notes: create per-applet notes file

 ....gnome.gnome-applets.stickynotes.gschema.xml.in |   5 +
 gnome-applets/sticky-notes/gsettings.h             |   1 +
 gnome-applets/sticky-notes/sticky-notes-applet.c   |  44 ++++++
 gnome-applets/sticky-notes/sticky-notes-applet.h   |   2 +
 gnome-applets/sticky-notes/sticky-notes.c          | 156 ++++++++++++++++-----
 5 files changed, 176 insertions(+), 32 deletions(-)
---
diff --git a/data/schemas/org.gnome.gnome-applets.stickynotes.gschema.xml.in 
b/data/schemas/org.gnome.gnome-applets.stickynotes.gschema.xml.in
index 853aa6f43..9c8801451 100644
--- a/data/schemas/org.gnome.gnome-applets.stickynotes.gschema.xml.in
+++ b/data/schemas/org.gnome.gnome-applets.stickynotes.gschema.xml.in
@@ -1,5 +1,10 @@
 <schemalist gettext-domain="@GETTEXT_PACKAGE@">
        <schema id="org.gnome.gnome-applets.stickynotes">
+               <key name="filename" type="s">
+                       <default>""</default>
+                       <summary></summary>
+                       <description></description>
+               </key>
                <key name="default-width" type="i">
                        <default>100</default>
                        <summary>Default width for new notes</summary>
diff --git a/gnome-applets/sticky-notes/gsettings.h b/gnome-applets/sticky-notes/gsettings.h
index fc0199d5c..bcfa77046 100644
--- a/gnome-applets/sticky-notes/gsettings.h
+++ b/gnome-applets/sticky-notes/gsettings.h
@@ -19,6 +19,7 @@
 #define STICKYNOTES_GSETTINGS_H
 
 #define STICKYNOTES_SCHEMA "org.gnome.gnome-applets.stickynotes"
+#define KEY_FILENAME "filename"
 
 #define KEY_DEFAULT_WIDTH      "default-width"
 #define KEY_DEFAULT_HEIGHT     "default-height"
diff --git a/gnome-applets/sticky-notes/sticky-notes-applet.c 
b/gnome-applets/sticky-notes/sticky-notes-applet.c
index 0b31ad530..fe5cc65ed 100644
--- a/gnome-applets/sticky-notes/sticky-notes-applet.c
+++ b/gnome-applets/sticky-notes/sticky-notes-applet.c
@@ -261,6 +261,18 @@ sticky_notes_applet_dispose (GObject *object)
   G_OBJECT_CLASS (sticky_notes_applet_parent_class)->dispose (object);
 }
 
+static void
+sticky_notes_applet_finalize (GObject *object)
+{
+  StickyNotesApplet *self;
+
+  self = STICKY_NOTES_APPLET (object);
+
+  g_clear_pointer (&self->filename, g_free);
+
+  G_OBJECT_CLASS (sticky_notes_applet_parent_class)->finalize (object);
+}
+
 static void
 sticky_notes_applet_class_init (StickyNotesAppletClass *self_class)
 {
@@ -270,6 +282,7 @@ sticky_notes_applet_class_init (StickyNotesAppletClass *self_class)
 
   object_class->constructed = sticky_notes_applet_constructed;
   object_class->dispose = sticky_notes_applet_dispose;
+  object_class->finalize = sticky_notes_applet_finalize;
 }
 
 static void
@@ -318,6 +331,32 @@ stickynotes_make_prelight_icon (GdkPixbuf *dest, GdkPixbuf *src, int shift)
        }
 }
 
+static void
+filename_changed_cb (GSettings         *settings,
+                     const gchar       *key,
+                     StickyNotesApplet *self)
+{
+  char *filename;
+
+  filename = g_settings_get_string (settings, key);
+
+  if (g_strcmp0 (self->filename, filename) == 0)
+    {
+      g_free (filename);
+      return;
+    }
+
+  g_free (filename);
+
+  /* Save and remove existing notes */
+  stickynotes_save_now (self);
+  g_list_free_full (self->notes, (GDestroyNotify) stickynote_free);
+  self->notes = NULL;
+
+  /* Reload notes from new file */
+  stickynotes_load (self);
+}
+
 static void
 preferences_apply_cb (GSettings         *settings,
                       const gchar       *key,
@@ -494,6 +533,11 @@ sticky_notes_init (StickyNotesApplet *self)
 {
   self->settings = gp_applet_settings_new (GP_APPLET (self), STICKYNOTES_SCHEMA);
 
+  g_signal_connect (self->settings,
+                    "changed::" KEY_FILENAME,
+                    G_CALLBACK (filename_changed_cb),
+                    self);
+
   g_signal_connect (self->settings,
                     "changed",
                     G_CALLBACK (preferences_apply_cb),
diff --git a/gnome-applets/sticky-notes/sticky-notes-applet.h 
b/gnome-applets/sticky-notes/sticky-notes-applet.h
index e53163a06..d838f6c59 100644
--- a/gnome-applets/sticky-notes/sticky-notes-applet.h
+++ b/gnome-applets/sticky-notes/sticky-notes-applet.h
@@ -35,6 +35,8 @@ struct _StickyNotesApplet
 
        GSettings *settings;
 
+       char *filename;
+
        GtkWidget *w_image;             /* The applet icon */
 
        GdkPixbuf *icon_normal;         /* Normal applet icon */
diff --git a/gnome-applets/sticky-notes/sticky-notes.c b/gnome-applets/sticky-notes/sticky-notes.c
index d953a7e8e..70f1710f7 100644
--- a/gnome-applets/sticky-notes/sticky-notes.c
+++ b/gnome-applets/sticky-notes/sticky-notes.c
@@ -22,6 +22,7 @@
 #include <X11/Xatom.h>
 #include <gdk/gdkx.h>
 #include <glib/gi18n-lib.h>
+#include <glib/gstdio.h>
 #define WNCK_I_KNOW_THIS_IS_UNSTABLE 1
 #include <libwnck/libwnck.h>
 #include <string.h>
@@ -1118,6 +1119,10 @@ void stickynotes_remove(StickyNote *note)
 void
 stickynotes_save_now (StickyNotesApplet *applet)
 {
+       char *path;
+       char *notes_file;
+       xmlDocPtr doc;
+       xmlNodePtr root;
        WnckScreen *wnck_screen;
        const gchar *title;
        GtkTextBuffer *buffer;
@@ -1125,9 +1130,26 @@ stickynotes_save_now (StickyNotesApplet *applet)
        gchar *body;
        guint i;
 
+       path = g_build_filename (g_get_user_config_dir (),
+                                "gnome-applets",
+                                "sticky-notes",
+                                NULL);
+
+       g_mkdir_with_parents (path, 0700);
+       notes_file = g_build_filename (path, applet->filename, NULL);
+       g_free (path);
+
+       if (applet->notes == NULL) {
+               g_unlink (notes_file);
+               g_free (notes_file);
+
+               applet->save_scheduled = FALSE;
+               return;
+       }
+
        /* Create a new XML document */
-       xmlDocPtr doc = xmlNewDoc(XML_CHAR ("1.0"));
-       xmlNodePtr root = xmlNewDocNode(doc, NULL, XML_CHAR ("stickynotes"), NULL);
+       doc = xmlNewDoc(XML_CHAR ("1.0"));
+       root = xmlNewDocNode(doc, NULL, XML_CHAR ("stickynotes"), NULL);
 
        xmlDocSetRootElement(doc, root);
        xmlNewProp(root, XML_CHAR("version"), XML_CHAR (VERSION));
@@ -1211,21 +1233,19 @@ stickynotes_save_now (StickyNotesApplet *applet)
        }
 
        {
-               const gchar *dir;
-               gchar *path;
-               gchar *file;
-
-               dir = g_get_user_config_dir ();
-               path = g_build_filename (dir, "gnome-applets", "sticky-notes", NULL);
-               file = g_build_filename (path, "sticky-notes.xml", NULL);
+               char *tmp_file;
 
-               g_mkdir_with_parents (path, 0700);
-               g_free (path);
+               tmp_file = g_strdup_printf ("%s.tmp", notes_file);
+               if (xmlSaveFormatFile (tmp_file, doc, 1) == -1 ||
+                       g_rename (tmp_file, notes_file) == -1) {
+                       g_warning ("Failed to save notes");
+                       g_unlink (tmp_file);
+               }
 
-               xmlSaveFormatFile (file, doc, 1);
-               g_free (file);
+               g_free (tmp_file);
        }
 
+       g_free (notes_file);
        xmlFreeDoc(doc);
 
        applet->save_scheduled = FALSE;
@@ -1253,10 +1273,43 @@ stickynotes_save (StickyNotesApplet *applet)
   }
 }
 
+static char *
+get_unique_filename (void)
+{
+  int number;
+  char *filename;
+  char *path;
+
+  number = 1;
+  filename = NULL;
+  path = NULL;
+
+  do
+    {
+      g_free (filename);
+      filename = g_strdup_printf ("sticky-notes-%d.xml", number++);
+
+      g_free (path);
+      path = g_build_filename (g_get_user_config_dir (),
+                               "gnome-applets",
+                               "sticky-notes",
+                               filename,
+                               NULL);
+    }
+  while (g_file_test (path, G_FILE_TEST_EXISTS));
+
+  g_free (path);
+
+  return filename;
+}
+
 /* Load all sticky notes from an XML configuration file */
 void
 stickynotes_load (StickyNotesApplet *applet)
 {
+       const char *dir;
+       char *filename;
+       char *notes_file;
        xmlDocPtr doc;
        xmlNodePtr root;
        xmlNodePtr node;
@@ -1265,32 +1318,71 @@ stickynotes_load (StickyNotesApplet *applet)
        GList *new_nodes; /* Lists of xmlNodePtr's */
        int x, y, w, h;
 
-       {
-               const gchar *dir;
-               gchar *file;
-
-               dir = g_get_user_config_dir ();
-               file = g_build_filename (dir, "gnome-applets", "sticky-notes",
-                                        "sticky-notes.xml", NULL);
-
-               if (!g_file_test (file, G_FILE_TEST_EXISTS))
-               {
-                       g_free (file);
-                       file = g_build_filename (dir, "gnome-applets",
-                                                "stickynotes", NULL);
+       dir = g_get_user_config_dir ();
+       filename = g_settings_get_string (applet->settings, KEY_FILENAME);
+       g_free (applet->filename);
+
+       if (*filename == '\0') {
+               char *old_file;
+
+               g_free (filename);
+               filename = get_unique_filename ();
+
+               notes_file = g_build_filename (dir,
+                                              "gnome-applets",
+                                              "sticky-notes",
+                                              filename,
+                                              NULL);
+
+               old_file = g_build_filename (dir,
+                                            "gnome-applets",
+                                            "sticky-notes",
+                                            "sticky-notes.xml",
+                                            NULL);
+
+               if (g_file_test (old_file, G_FILE_TEST_EXISTS)) {
+                       g_rename (old_file, notes_file);
+
+                       g_free (old_file);
+                       old_file = g_build_filename (dir,
+                                                    "gnome-applets",
+                                                    "stickynotes",
+                                                    NULL);
+
+                       if (g_file_test (old_file, G_FILE_TEST_EXISTS))
+                               g_unlink (old_file);
+               } else {
+                       g_free (old_file);
+                       old_file = g_build_filename (dir,
+                                                    "gnome-applets",
+                                                    "stickynotes",
+                                                    NULL);
+
+                       if (g_file_test (old_file, G_FILE_TEST_EXISTS))
+                               g_rename (old_file, notes_file);
                }
 
-               doc = xmlParseFile (file);
-               g_free (file);
+               applet->filename = filename;
+               g_settings_set_string (applet->settings, KEY_FILENAME, filename);
+
+               g_free (old_file);
+       } else {
+               applet->filename = filename;
+               notes_file = g_build_filename (dir,
+                                              "gnome-applets",
+                                              "sticky-notes",
+                                              filename,
+                                              NULL);
        }
 
-       /* If the XML file does not exist, create a blank one */
-       if (!doc)
-       {
-               stickynotes_save (applet);
+       if (!g_file_test (notes_file, G_FILE_TEST_EXISTS)) {
+               g_free (notes_file);
                return;
        }
 
+       doc = xmlParseFile (notes_file);
+       g_free (notes_file);
+
        /* If the XML file is corrupted/incorrect, create a blank one */
        root = xmlDocGetRootElement(doc);
        if (!root || xmlStrcmp(root->name, XML_CHAR ("stickynotes")))


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]