[latexila/wip/templates-revamp: 1/5] LatexilaTemplatesDialogs: dialog to create a new template



commit c4948e14a20700a27c0a8b88b10cfb4f90da710b
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sat Apr 18 15:07:24 2015 +0200

    LatexilaTemplatesDialogs: dialog to create a new template

 docs/reference/latexila-sections.txt          |    2 +
 src/liblatexila/latexila-templates-dialogs.c  |  140 ++++++++++++++++++++
 src/liblatexila/latexila-templates-dialogs.h  |    5 +-
 src/liblatexila/latexila-templates-personal.c |  169 +++++++++++++++++++++++++
 src/liblatexila/latexila-templates-personal.h |    6 +
 src/main_window_file.vala                     |   10 ++-
 src/templates_dialogs.vala                    |   73 -----------
 7 files changed, 329 insertions(+), 76 deletions(-)
---
diff --git a/docs/reference/latexila-sections.txt b/docs/reference/latexila-sections.txt
index 0d4a234..70d7b67 100644
--- a/docs/reference/latexila-sections.txt
+++ b/docs/reference/latexila-sections.txt
@@ -233,6 +233,7 @@ latexila_synctex_get_type
 <FILE>templates-dialogs</FILE>
 <TITLE>LatexilaTemplatesDialogs</TITLE>
 latexila_templates_dialogs_open
+latexila_templates_dialogs_create_template
 </SECTION>
 
 <SECTION>
@@ -251,6 +252,7 @@ LATEXILA_TYPE_TEMPLATES_DEFAULT
 LatexilaTemplatesPersonal
 latexila_templates_personal_get_instance
 latexila_templates_personal_get_contents
+latexila_templates_personal_create
 <SUBSECTION Standard>
 LATEXILA_TYPE_TEMPLATES_PERSONAL
 </SECTION>
diff --git a/src/liblatexila/latexila-templates-dialogs.c b/src/liblatexila/latexila-templates-dialogs.c
index 062a684..cc5fde3 100644
--- a/src/liblatexila/latexila-templates-dialogs.c
+++ b/src/liblatexila/latexila-templates-dialogs.c
@@ -201,3 +201,143 @@ latexila_templates_dialogs_open (GtkWindow *parent_window)
   gtk_widget_destroy (GTK_WIDGET (dialog));
   return contents;
 }
+
+/**
+ * latexila_templates_dialogs_create_template:
+ * @parent_window: transient parent window of the dialog.
+ * @template_contents: the template's contents.
+ *
+ * Runs a #GtkDialog to create a new template. The template's contents is given.
+ * The #GtkDialog asks the template's name and icon.
+ */
+void
+latexila_templates_dialogs_create_template (GtkWindow   *parent_window,
+                                            const gchar *template_contents)
+{
+  GtkDialog *dialog;
+  GtkBox *content_area;
+  GtkEntry *entry;
+  GtkWidget *component;
+  LatexilaTemplatesDefault *default_store;
+  GtkTreeView *default_view;
+  GtkWidget *scrolled_window;
+
+  dialog = g_object_new (GTK_TYPE_DIALOG,
+                         "use-header-bar", TRUE,
+                         "title", _("New Template..."),
+                         "destroy-with-parent", TRUE,
+                         "transient-for", parent_window,
+                         NULL);
+
+  gtk_dialog_add_buttons (dialog,
+                          _("_Cancel"), GTK_RESPONSE_CANCEL,
+                          _("Crea_te"), GTK_RESPONSE_OK,
+                          NULL);
+
+  gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK);
+
+  content_area = GTK_BOX (gtk_dialog_get_content_area (dialog));
+
+  /* Name */
+  entry = GTK_ENTRY (gtk_entry_new ());
+  gtk_widget_set_hexpand (GTK_WIDGET (entry), TRUE);
+  component = latexila_utils_get_dialog_component (_("Name of the new template"),
+                                                   GTK_WIDGET (entry));
+  gtk_box_pack_start (content_area, component, FALSE, TRUE, 0);
+
+  /* Icon.
+   * Take the default store because it contains all the icons.
+   */
+  default_store = latexila_templates_default_get_instance ();
+  default_view = latexila_templates_get_view (GTK_LIST_STORE (default_store));
+
+  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_set_size_request (scrolled_window, 250, 200);
+  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
+                                       GTK_SHADOW_IN);
+
+  gtk_container_add (GTK_CONTAINER (scrolled_window),
+                     GTK_WIDGET (default_view));
+
+  component = latexila_utils_get_dialog_component (_("Choose an icon"), scrolled_window);
+  gtk_box_pack_start (content_area, component, TRUE, TRUE, 0);
+
+  gtk_widget_show_all (GTK_WIDGET (content_area));
+
+  while (gtk_dialog_run (dialog) == GTK_RESPONSE_OK)
+    {
+      GtkTreeSelection *selection;
+      GList *selected_rows;
+      GtkTreePath *path;
+      GtkTreeIter iter;
+      gchar *config_icon_name = NULL;
+      const gchar *name = NULL;
+      LatexilaTemplatesPersonal *personal_store;
+      GError *error = NULL;
+
+      /* If no name specified. */
+      if (gtk_entry_get_text_length (entry) == 0)
+        continue;
+
+      selection = gtk_tree_view_get_selection (default_view);
+
+      /* If no icons selected. */
+      if (gtk_tree_selection_count_selected_rows (selection) == 0)
+        continue;
+
+      /* Get config icon name. */
+      selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);
+      g_assert (g_list_length (selected_rows) == 1);
+
+      path = selected_rows->data;
+
+      if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (default_store), &iter, path))
+        {
+          g_warning ("Create template dialog: invalid path");
+          break;
+        }
+
+      gtk_tree_model_get (GTK_TREE_MODEL (default_store), &iter,
+                          LATEXILA_TEMPLATES_COLUMN_CONFIG_ICON_NAME, &config_icon_name,
+                          -1);
+
+      name = gtk_entry_get_text (entry);
+
+      personal_store = latexila_templates_personal_get_instance ();
+
+      latexila_templates_personal_create (personal_store,
+                                          name,
+                                          config_icon_name,
+                                          template_contents,
+                                          &error);
+
+      g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free);
+      g_free (config_icon_name);
+
+      if (error != NULL)
+        {
+          GtkWidget *error_dialog;
+
+          error_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
+                                                 GTK_DIALOG_MODAL |
+                                                 GTK_DIALOG_DESTROY_WITH_PARENT |
+                                                 GTK_DIALOG_USE_HEADER_BAR,
+                                                 GTK_MESSAGE_ERROR,
+                                                 GTK_BUTTONS_OK,
+                                                 "%s", _("Impossible to create the personal template."));
+
+          gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (error_dialog),
+                                                    "%s", error->message);
+
+          gtk_dialog_run (GTK_DIALOG (error_dialog));
+          gtk_widget_destroy (error_dialog);
+
+          g_error_free (error);
+          continue;
+        }
+
+      break;
+    }
+
+  gtk_widget_destroy (GTK_WIDGET (dialog));
+}
diff --git a/src/liblatexila/latexila-templates-dialogs.h b/src/liblatexila/latexila-templates-dialogs.h
index 950b218..9dc0102 100644
--- a/src/liblatexila/latexila-templates-dialogs.h
+++ b/src/liblatexila/latexila-templates-dialogs.h
@@ -24,7 +24,10 @@
 
 G_BEGIN_DECLS
 
-gchar *         latexila_templates_dialogs_open             (GtkWindow *parent_window);
+gchar *         latexila_templates_dialogs_open               (GtkWindow *parent_window);
+
+void            latexila_templates_dialogs_create_template    (GtkWindow   *parent_window,
+                                                               const gchar *template_contents);
 
 G_END_DECLS
 
diff --git a/src/liblatexila/latexila-templates-personal.c b/src/liblatexila/latexila-templates-personal.c
index c168c41..da47f47 100644
--- a/src/liblatexila/latexila-templates-personal.c
+++ b/src/liblatexila/latexila-templates-personal.c
@@ -34,7 +34,9 @@
 
 #include "config.h"
 #include "latexila-templates-personal.h"
+#include <string.h>
 #include "latexila-templates-common.h"
+#include "latexila-utils.h"
 
 struct _LatexilaTemplatesPersonal
 {
@@ -216,6 +218,7 @@ latexila_templates_personal_get_contents (LatexilaTemplatesPersonal *templates,
   GError *error = NULL;
 
   g_return_val_if_fail (LATEXILA_IS_TEMPLATES_PERSONAL (templates), NULL);
+  g_return_val_if_fail (path != NULL, NULL);
 
   gtk_tree_model_get_iter (GTK_TREE_MODEL (templates),
                            &iter,
@@ -239,3 +242,169 @@ latexila_templates_personal_get_contents (LatexilaTemplatesPersonal *templates,
   g_object_unref (file);
   return contents;
 }
+
+static gboolean
+save_rc_file (LatexilaTemplatesPersonal  *templates,
+              GError                    **error)
+{
+  GFile *rc_file;
+  gchar *rc_path = NULL;
+  gint personal_templates_count;
+  gchar **names = NULL;
+  gchar **icons = NULL;
+  GtkTreeIter iter;
+  gint template_num;
+  GKeyFile *key_file = NULL;
+  gboolean ret = TRUE;
+
+  rc_file = get_rc_file ();
+  personal_templates_count = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (templates), NULL);
+
+  if (personal_templates_count == 0)
+    {
+      GError *my_error = NULL;
+
+      g_file_delete (rc_file, NULL, &my_error);
+
+      if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+        {
+          g_error_free (my_error);
+          my_error = NULL;
+        }
+      else if (my_error != NULL)
+        {
+          ret = FALSE;
+          g_propagate_error (error, my_error);
+        }
+
+      goto out;
+    }
+
+  names = g_new0 (gchar *, personal_templates_count + 1);
+  icons = g_new0 (gchar *, personal_templates_count + 1);
+
+  if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (templates), &iter))
+    g_assert_not_reached ();
+
+  template_num = 0;
+  do
+    {
+      gchar *name;
+      gchar *icon;
+
+      gtk_tree_model_get (GTK_TREE_MODEL (templates), &iter,
+                          LATEXILA_TEMPLATES_COLUMN_NAME, &name,
+                          LATEXILA_TEMPLATES_COLUMN_CONFIG_ICON_NAME, &icon,
+                          -1);
+
+      g_assert_cmpint (template_num, <, personal_templates_count);
+      names[template_num] = name;
+      icons[template_num] = icon;
+      template_num++;
+    }
+  while (gtk_tree_model_iter_next (GTK_TREE_MODEL (templates), &iter));
+
+  g_assert_cmpint (template_num, ==, personal_templates_count);
+
+  key_file = g_key_file_new ();
+
+  g_key_file_set_string_list (key_file,
+                              PACKAGE_NAME,
+                              "names",
+                              (const gchar * const *) names,
+                              personal_templates_count);
+
+  g_key_file_set_string_list (key_file,
+                              PACKAGE_NAME,
+                              "icons",
+                              (const gchar * const *) icons,
+                              personal_templates_count);
+
+  rc_path = g_file_get_path (rc_file);
+  if (!g_key_file_save_to_file (key_file, rc_path, error))
+    ret = FALSE;
+
+out:
+  g_object_unref (rc_file);
+  g_free (rc_path);
+  g_strfreev (names);
+  g_strfreev (icons);
+
+  if (key_file != NULL)
+    g_key_file_unref (key_file);
+
+  return ret;
+}
+
+/**
+ * latexila_templates_personal_create:
+ * @templates: the #LatexilaTemplatesPersonal instance.
+ * @name: the template's name.
+ * @config_icon_name: the icon name that will be stored in the config file.
+ * @contents: the template's contents.
+ * @error: (out) (optional): a location to a %NULL #GError, or %NULL.
+ *
+ * Creates a new personal template. The new template is added at the end of the
+ * list.
+ *
+ * Returns: %TRUE on success, %FALSE on error.
+ */
+gboolean
+latexila_templates_personal_create (LatexilaTemplatesPersonal  *templates,
+                                    const gchar                *name,
+                                    const gchar                *config_icon_name,
+                                    const gchar                *contents,
+                                    GError                    **error)
+{
+  gint template_num;
+  GFile *template_file = NULL;
+  GFileOutputStream *stream = NULL;
+  gboolean ret = TRUE;
+
+  g_return_val_if_fail (LATEXILA_IS_TEMPLATES_PERSONAL (templates), FALSE);
+  g_return_val_if_fail (name != NULL && name[0] != '\0', FALSE);
+  g_return_val_if_fail (config_icon_name != NULL && config_icon_name[0] != '\0', FALSE);
+  g_return_val_if_fail (contents != NULL, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  template_num = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (templates), NULL);
+  template_file = get_personal_template_file (template_num);
+
+  if (!latexila_utils_create_parent_directories (template_file, error))
+    {
+      ret = FALSE;
+      goto out;
+    }
+
+  stream = g_file_create (template_file, G_FILE_CREATE_NONE, NULL, error);
+
+  if (stream == NULL)
+    {
+      ret = FALSE;
+      goto out;
+    }
+
+  if (!g_output_stream_write_all (G_OUTPUT_STREAM (stream),
+                                  contents,
+                                  strlen (contents),
+                                  NULL,
+                                  NULL,
+                                  error))
+    {
+      ret = FALSE;
+      goto out;
+    }
+
+  latexila_templates_add_template (GTK_LIST_STORE (templates),
+                                   name,
+                                   config_icon_name,
+                                   template_file);
+
+  if (!save_rc_file (templates, error))
+    ret = FALSE;
+
+out:
+  g_clear_object (&template_file);
+  g_clear_object (&stream);
+  return ret;
+}
diff --git a/src/liblatexila/latexila-templates-personal.h b/src/liblatexila/latexila-templates-personal.h
index 2bc0a51..1f3ba1a 100644
--- a/src/liblatexila/latexila-templates-personal.h
+++ b/src/liblatexila/latexila-templates-personal.h
@@ -33,6 +33,12 @@ LatexilaTemplatesPersonal *
 gchar *       latexila_templates_personal_get_contents          (LatexilaTemplatesPersonal *templates,
                                                                  GtkTreePath               *path);
 
+gboolean      latexila_templates_personal_create                (LatexilaTemplatesPersonal *templates,
+                                                                 const gchar               *name,
+                                                                 const gchar               *config_icon_name,
+                                                                 const gchar               *contents,
+                                                                 GError                   **error);
+
 G_END_DECLS
 
 #endif /* __LATEXILA_TEMPLATES_PERSONAL_H__ */
diff --git a/src/main_window_file.vala b/src/main_window_file.vala
index eb511f6..106b711 100644
--- a/src/main_window_file.vala
+++ b/src/main_window_file.vala
@@ -213,8 +213,14 @@ public class MainWindowFile
     {
         return_if_fail (_main_window.active_tab != null);
 
-        CreateTemplateDialog dialog = new CreateTemplateDialog (_main_window);
-        dialog.destroy ();
+        // get the template's contents
+        TextIter start;
+        TextIter end;
+        Document doc = _main_window.active_document;
+        doc.get_bounds (out start, out end);
+        string template_contents = doc.get_text (start, end, false);
+
+        Latexila.templates_dialogs_create_template (_main_window, template_contents);
     }
 
     public void on_delete_template ()
diff --git a/src/templates_dialogs.vala b/src/templates_dialogs.vala
index 766ef07..e5547db 100644
--- a/src/templates_dialogs.vala
+++ b/src/templates_dialogs.vala
@@ -19,79 +19,6 @@
 
 using Gtk;
 
-public class CreateTemplateDialog : Dialog
-{
-    public CreateTemplateDialog (MainWindow parent)
-    {
-        Object (use_header_bar: 1);
-        return_val_if_fail (parent.active_tab != null, null);
-
-        title = _("New Template...");
-        set_transient_for (parent);
-        destroy_with_parent = true;
-        add_button (_("_Cancel"), ResponseType.CANCEL);
-        add_button (_("Crea_te"), ResponseType.OK);
-        set_default_response (ResponseType.OK);
-
-        Box content_area = get_content_area () as Box;
-        content_area.homogeneous = false;
-
-        /* name */
-        Entry entry = new Entry ();
-        entry.hexpand = true;
-        Widget component = Latexila.utils_get_dialog_component (_("Name of the new template"),
-            entry);
-        content_area.pack_start (component, false);
-
-        /* icon */
-        Templates templates = Templates.get_default ();
-
-        // Take the default store because it contains all the icons.
-        TreeView templates_list = templates.get_default_templates_list ();
-
-        ScrolledWindow scrollbar = Utils.add_scrollbar (templates_list);
-        scrollbar.set_shadow_type (ShadowType.IN);
-        scrollbar.set_size_request (250, 200);
-        component = Latexila.utils_get_dialog_component (_("Choose an icon"), scrollbar);
-        content_area.pack_start (component);
-
-        content_area.show_all ();
-
-        run_me (parent, entry, templates_list);
-    }
-
-    private void run_me (MainWindow parent, Entry entry, TreeView templates_list)
-    {
-        Templates templates = Templates.get_default ();
-
-        while (run () == ResponseType.OK)
-        {
-            // if no name specified
-            if (entry.text_length == 0)
-                continue;
-
-            TreeSelection select = templates_list.get_selection ();
-            List<TreePath> selected_items = select.get_selected_rows (null);
-
-            // if no icon selected
-            if (selected_items.length () == 0)
-                continue;
-
-            // get the contents
-            TextIter start, end;
-            parent.active_document.get_bounds (out start, out end);
-            string contents = parent.active_document.get_text (start, end, false);
-
-            // get the icon id
-            TreePath path = selected_items.nth_data (0);
-            string icon_id = templates.get_icon_id (path);
-
-            templates.create_personal_template (entry.text, icon_id, contents);
-            break;
-        }
-    }
-}
-
 public class DeleteTemplateDialog : Dialog
 {
     public DeleteTemplateDialog (MainWindow parent)


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