[gnome-font-viewer] font-view: account for font files with same basename



commit 58dd17da55c807c94e109682f969e1f729c1f7ad
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Thu Jul 4 15:45:24 2019 -0700

    font-view: account for font files with same basename
    
    We make sure the font we're trying to install doesn't already
    exist on the system by matching its metadata, but we copy the font file
    keeping its original basename.
    
    In case a font file with the same basename already exists in the user
    directory, but for another font than the one we're trying to install,
    we'll thus fail the installation, because the file already exists.
    
    Account for that possibility by adding a number as a prefix to the
    font file name, when that happens.
    
    https://gitlab.gnome.org/GNOME/gnome-font-viewer/issues/10
    https://gitlab.gnome.org/GNOME/gnome-font-viewer/issues/11

 src/font-view.c | 100 ++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 71 insertions(+), 29 deletions(-)
---
diff --git a/src/font-view.c b/src/font-view.c
index 7a2ae25..2d514b1 100644
--- a/src/font-view.c
+++ b/src/font-view.c
@@ -548,16 +548,27 @@ install_button_refresh_appearance (FontViewApplication *self,
 }
 
 static void
-font_install_finished_cb (GObject      *source_object,
-                          GAsyncResult *res,
-                          gpointer      user_data)
+font_model_config_changed_cb (FontViewModel *model,
+                              gpointer user_data)
+{
+    FontViewApplication *self = user_data;
+
+    if (self->font_file != NULL)
+        install_button_refresh_appearance (self, NULL);
+}
+
+static void
+font_install_finished (GObject      *source_object,
+                       GAsyncResult *res,
+                       gpointer      user_data)
 {
     FontViewApplication *self = user_data;
     GError *err = NULL;
 
-    g_file_copy_finish (G_FILE (source_object), res, &err);
+    g_task_propagate_boolean (G_TASK (res), &err);
 
     if (err != NULL) {
+        /* TODO: show error dialog */
         install_button_refresh_appearance (self, err);
 
         g_debug ("Install failed: %s", err->message);
@@ -568,13 +579,62 @@ font_install_finished_cb (GObject      *source_object,
 }
 
 static void
-font_model_config_changed_cb (FontViewModel *model,
-                              gpointer user_data)
+install_font_job (GTask *task,
+                  gpointer source_object,
+                  gpointer user_data,
+                  GCancellable *cancellable)
 {
-    FontViewApplication *self = user_data;
+    GFile *dest_location = user_data;
+    FontViewApplication *self = FONT_VIEW_APPLICATION (source_object);
+    gchar *dest_basename = g_file_get_basename (self->font_file);
+    gboolean created = FALSE;
+    GError *error = NULL;
+    gint i = 0;
+
+    while (!created) {
+        gchar *dest_filename = (i == 0) ?
+            g_strdup (dest_basename) : g_strdup_printf ("%d%s", i, dest_basename);
+        GFile *dest_file = g_file_get_child (dest_location, dest_filename);
+        g_free (dest_filename);
+
+        created = g_file_copy (self->font_file,
+                               dest_file,
+                               G_FILE_COPY_NONE,
+                               cancellable,
+                               NULL, NULL,
+                               &error);
+        g_object_unref (dest_file);
+
+        if (error != NULL) {
+            if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
+                g_clear_error (&error);
+                i++;
+                continue;
+            }
+            break;
+        }
+    }
 
-    if (self->font_file != NULL)
-        install_button_refresh_appearance (self, NULL);
+    if (error != NULL)
+        g_task_return_error (task, error);
+    else
+        g_task_return_boolean (task, TRUE);
+
+    g_free (dest_basename);
+}
+
+static void
+font_view_install_font (FontViewApplication *self,
+                        GFile *dest_location)
+{
+    GTask *task;
+
+    self->cancellable = g_cancellable_new ();
+
+    task = g_task_new (self, self->cancellable, font_install_finished, self);
+    g_task_set_task_data (task, g_object_ref (dest_location), g_object_unref);
+    g_task_run_in_thread (task, install_font_job);
+    g_object_unref (task);
 }
 
 static void
@@ -582,14 +642,13 @@ install_button_clicked_cb (GtkButton *button,
                            gpointer user_data)
 {
     FontViewApplication *self = user_data;
-    gchar *dest_filename;
     GError *err = NULL;
     FcConfig *config;
     FcStrList *str_list;
     FcChar8 *path;
     GFile *xdg_prefix, *home_prefix, *file;
     GFile *xdg_location = NULL, *home_location = NULL;
-    GFile *dest_location = NULL, *dest_file;
+    GFile *dest_location = NULL;
 
     config = FcConfigGetCurrent ();
     str_list = FcConfigGetFontDirs (config);
@@ -645,27 +704,10 @@ install_button_clicked_cb (GtkButton *button,
         }
     }
 
-    /* create destination filename */
-    dest_filename = g_file_get_basename (self->font_file);
-    dest_file = g_file_get_child (dest_location, dest_filename);
-    g_free (dest_filename);
-
-    self->cancellable = g_cancellable_new ();
-
-    /* TODO: show error dialog if file exists */
-    g_file_copy_async (self->font_file,
-                       dest_file,
-                       G_FILE_COPY_NONE,
-                       G_PRIORITY_DEFAULT,
-                       self->cancellable,
-                       NULL,
-                       NULL,
-                       font_install_finished_cb,
-                       self);
+    font_view_install_font (self, dest_location);
 
     install_button_refresh_appearance (self, NULL);
 
-    g_object_unref (dest_file);
     g_object_unref (dest_location);
 }
 


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