[gnome-latex: 139/205] Possibility to delete personnal templates



commit 8fa1e3e13d928cd9f851508a8afee841762823d8
Author: Sébastien Wilmet <sebastien wilmet gmail com>
Date:   Wed Dec 16 18:34:41 2009 +0100

    Possibility to delete personnal templates
    
    After the user have deleted templates, we must update the key-value file
    which contains the names, and the files "0.tex", "1.tex", etc.
    The save_contents() function delete all the *.tex files and rewrite them
    by traverse the list store.
    The save_rc_file() function traverse the list store to take all the
    names and save the rc file.

 TODO            |   8 ++-
 src/templates.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++--------
 src/templates.h |   1 +
 src/ui.c        |   2 +
 src/ui.xml      |   1 +
 5 files changed, 177 insertions(+), 30 deletions(-)
---
diff --git a/TODO b/TODO
index a3f8886..6068410 100644
--- a/TODO
+++ b/TODO
@@ -1,10 +1,10 @@
 TODO LaTeXila
 
-[-] Templates
+[x] Templates
        x create a few default templates
        x on the action "new file", possibility to select a template
        x possibility to create new templates
-       - possibility to delete templates (not the defaults)
+       x possibility to delete templates (not the defaults)
 
 [-] BibTeX support
 
@@ -21,3 +21,7 @@ TODO LaTeXila
 [-] documentation
 
 [-] replace the notebook in the side pane by a combo box with a close button
+
+[-] bug correction
+       - if new document, save must save as
+       - when there are too much recent documents, new documents are not visible in File/Open Recent
diff --git a/src/templates.c b/src/templates.c
index 7062df9..ef0920e 100644
--- a/src/templates.c
+++ b/src/templates.c
@@ -24,6 +24,7 @@
 #include <gtk/gtk.h>
 #include <gtksourceview/gtksourceview.h>
 #include <sys/stat.h> // for S_IRWXU
+#include <glib/gstdio.h> // for g_remove()
 
 #include "main.h"
 #include "config.h"
@@ -39,7 +40,10 @@ static GtkWidget * create_icon_view (GtkListStore *store);
 static void cb_icon_view_selection_changed (GtkIconView *icon_view,
                gpointer other_icon_view);
 static gchar * get_rc_file (void);
+static gchar * get_rc_dir (void);
 static void add_personnal_template (const gchar *name, const gchar *contents);
+static void save_rc_file (void);
+static void save_contents (void);
 
 static GtkListStore *default_store;
 static GtkListStore *personnal_store;
@@ -176,6 +180,8 @@ cb_create_template (void)
                if (gtk_entry_get_text_length (GTK_ENTRY (entry)) == 0)
                        continue;
 
+               nb_personnal_templates++;
+
                const gchar *name = gtk_entry_get_text (GTK_ENTRY (entry));
 
                GtkTextBuffer *buffer =
@@ -196,6 +202,69 @@ cb_create_template (void)
        gtk_widget_destroy (dialog);
 }
 
+void
+cb_delete_template (void)
+{
+       GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Delete Template(s)..."),
+                       latexila.main_window,
+                       GTK_DIALOG_NO_SEPARATOR,
+                       GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT,
+                       GTK_STOCK_OK, GTK_RESPONSE_REJECT,
+                       NULL);
+
+       gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 200);
+       
+       GtkWidget *content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+       /* icon view for the personnal templates */
+       GtkWidget *icon_view = create_icon_view (personnal_store);
+       gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (icon_view),
+                       GTK_SELECTION_MULTIPLE);
+
+       // with a scrollbar (without that there is a problem for resizing the
+       // dialog, we can make it bigger but not smaller...)
+       GtkWidget *scrollbar = gtk_scrolled_window_new (NULL, NULL);
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollbar),
+                       GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+       gtk_container_add (GTK_CONTAINER (scrollbar), icon_view);
+
+       // with a frame
+       GtkWidget *frame = gtk_frame_new (_("Personnal templates"));
+       gtk_container_add (GTK_CONTAINER (frame), scrollbar);
+
+       gtk_box_pack_start (GTK_BOX (content_area), frame, TRUE, TRUE, 10);
+
+       gtk_widget_show_all (content_area);
+
+       while (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+       {
+               GList *selected_items = gtk_icon_view_get_selected_items (
+                               GTK_ICON_VIEW (icon_view));
+               GtkTreeModel *model = GTK_TREE_MODEL (personnal_store);
+               
+               guint nb_selected_items = g_list_length (selected_items);
+
+               for (gint i = 0 ; i < nb_selected_items ; i++)
+               {
+                       GtkTreePath *path = g_list_nth_data (selected_items, i);
+                       GtkTreeIter iter;
+                       gtk_tree_model_get_iter (model, &iter, path);
+                       gtk_list_store_remove (personnal_store, &iter);
+               }
+
+               nb_personnal_templates -= nb_selected_items;
+
+               // free the GList
+               g_list_foreach (selected_items, (GFunc) gtk_tree_path_free, NULL);
+               g_list_free (selected_items);
+       }
+
+       save_rc_file ();
+       save_contents ();
+
+       gtk_widget_destroy (dialog);
+}
+
 void
 init_templates (void)
 {
@@ -247,8 +316,6 @@ init_templates (void)
                return;
        }
 
-       gchar *rc_path = g_path_get_dirname (rc_file);
-
        GKeyFile *key_file = g_key_file_new ();
        GError *error = NULL;
        g_key_file_load_from_file (key_file, rc_file, G_KEY_FILE_NONE, &error);
@@ -258,7 +325,6 @@ init_templates (void)
        {
                print_warning ("load templates failed: %s", error->message);
                g_error_free (error);
-               g_free (rc_path);
                return;
        }
 
@@ -270,15 +336,16 @@ init_templates (void)
                print_warning ("load templates failed: %s", error->message);
                g_error_free (error);
                g_key_file_free (key_file);
-               g_free (rc_path);
                return;
        }
 
        nb_personnal_templates = length;
 
+       gchar *rc_dir = get_rc_dir ();
+
        for (gint i = 0 ; i < length ; i++)
        {
-               gchar *file = g_strdup_printf ("%s/%d.tex", rc_path, i);
+               gchar *file = g_strdup_printf ("%s/%d.tex", rc_dir, i);
 
                if (! g_file_test (file, G_FILE_TEST_EXISTS))
                        continue;
@@ -289,6 +356,7 @@ init_templates (void)
 
        g_strfreev (names);
        g_key_file_free (key_file);
+       g_free (rc_dir);
 }
 
 static void
@@ -388,22 +456,64 @@ get_rc_file (void)
        return rc_file;
 }
 
+static gchar *
+get_rc_dir (void)
+{
+       // rc_dir must be freed
+       gchar *rc_dir = g_build_filename (g_get_user_data_dir (), "latexila", NULL);
+       return rc_dir;
+}
+
 static void
 add_personnal_template (const gchar *name, const gchar *contents)
 {
-       nb_personnal_templates++;
+       save_rc_file ();
+
+       gchar *rc_dir = get_rc_dir ();
 
-       gchar **names = g_malloc (nb_personnal_templates * sizeof (gchar *));
+       gchar *file = g_strdup_printf ("%s/%d.tex", rc_dir,
+                       nb_personnal_templates - 1);
+
+       GError *error = NULL;
+       g_file_set_contents (file, contents, -1, &error);
+
+       if (error != NULL)
+       {
+               print_warning ("impossible to save templates: %s", error->message);
+               g_error_free (error);
+       }
+
+       g_free (rc_dir);
+       g_free (file);
+}
+
+static void
+save_rc_file (void)
+{
+       if (nb_personnal_templates == 0)
+       {
+               gchar *rc_file = get_rc_file ();
+               g_remove (rc_file);
+               g_free (rc_file);
+               return;
+       }
+
+       gchar **names = g_malloc ((nb_personnal_templates + 1) * sizeof (gchar *));
        gchar **names_i = names;
        
+       // traverse the list store
        GtkTreeIter iter;
-       gtk_tree_model_get_iter_first (GTK_TREE_MODEL (personnal_store), &iter);
-       do
+       GtkTreeModel *model = GTK_TREE_MODEL (personnal_store);
+       gboolean valid_iter = gtk_tree_model_get_iter_first (model, &iter);
+       while (valid_iter)
        {
-               gtk_tree_model_get (GTK_TREE_MODEL (personnal_store), &iter,
-                               COLUMN_TEMPLATE_NAME, names_i, -1);
+               gtk_tree_model_get (model, &iter, COLUMN_TEMPLATE_NAME, names_i, -1);
+               valid_iter = gtk_tree_model_iter_next (model, &iter);
                names_i++;
-       } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (personnal_store), &iter));
+       }
+
+       // the last element is NULL so we can use g_strfreev()
+       *names_i = NULL;
 
        GKeyFile *key_file = g_key_file_new ();
        g_key_file_set_string_list (key_file, PROGRAM_NAME, "names",
@@ -412,35 +522,64 @@ add_personnal_template (const gchar *name, const gchar *contents)
 
        /* save the rc file */
        gchar *rc_file = get_rc_file ();
-       gchar *rc_path = g_path_get_dirname (rc_file);
-       g_mkdir_with_parents(rc_path, S_IRWXU);
+       gchar *rc_dir = get_rc_dir ();
+       g_mkdir_with_parents(rc_dir, S_IRWXU);
        gchar *key_file_data = g_key_file_to_data (key_file, NULL, NULL);
 
        GError *error = NULL;
        g_file_set_contents (rc_file, key_file_data, -1, &error);
 
-       g_free (rc_file);
-       g_free (key_file_data);
-       g_key_file_free (key_file);
-
        if (error != NULL)
        {
                print_warning ("impossible to save templates: %s", error->message);
                g_error_free (error);
-               g_free (rc_path);
-               return;
        }
 
-       gchar *file = g_strdup_printf ("%s/%d.tex", rc_path,
-                       nb_personnal_templates - 1);
-       g_file_set_contents (file, contents, -1, &error);
+       g_strfreev (names);
+       g_free (rc_file);
+       g_free (rc_dir);
+       g_free (key_file_data);
+       g_key_file_free (key_file);
+}
 
-       if (error != NULL)
+static void
+save_contents (void)
+{
+       gchar *rc_dir = get_rc_dir ();
+
+       // delete all the *.tex files
+       gchar *command = g_strdup_printf ("rm -f %s/*.tex", rc_dir);
+       system (command);
+       g_free (command);
+
+       // traverse the list store
+       GtkTreeIter iter;
+       GtkTreeModel *model = GTK_TREE_MODEL (personnal_store);
+       gboolean valid_iter = gtk_tree_model_get_iter_first (model, &iter);
+       gint i = 0;
+       while (valid_iter)
        {
-               print_warning ("impossible to save templates: %s", error->message);
-               g_error_free (error);
+               gchar *contents;
+               gtk_tree_model_get (model, &iter, COLUMN_TEMPLATE_CONTENTS, &contents, -1);
+
+               gchar *file = g_strdup_printf ("%s/%d.tex", rc_dir, i);
+
+               GError *error = NULL;
+               g_file_set_contents (file, contents, -1, &error);
+
+               if (error != NULL)
+               {
+                       print_warning ("impossible to save the template: %s", error->message);
+                       g_error_free (error);
+                       error = NULL;
+               }
+
+               g_free (contents);
+               g_free (file);
+
+               valid_iter = gtk_tree_model_iter_next (model, &iter);
+               i++;
        }
 
-       g_free (rc_path);
-       g_free (file);
+       g_free (rc_dir);
 }
diff --git a/src/templates.h b/src/templates.h
index 9033218..3df3520 100644
--- a/src/templates.h
+++ b/src/templates.h
@@ -22,6 +22,7 @@
 
 void cb_new (void);
 void cb_create_template (void);
+void cb_delete_template (void);
 void init_templates (void);
 
 enum templates
diff --git a/src/ui.c b/src/ui.c
index dc3400b..32e73e9 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -82,6 +82,8 @@ static GtkActionEntry entries[] = {
                N_("Save the current file with a different name"), G_CALLBACK (cb_save_as)},
        {"FileCreateTemplate", NULL, N_("Create Template From Document..."), NULL,
                N_("Create a new template from the current document"), G_CALLBACK (cb_create_template)},
+       {"FileDeleteTemplate", NULL, N_("Delete Template..."), NULL,
+               N_("Delete personnal template(s)"), G_CALLBACK (cb_delete_template)},
        {"FileClose", GTK_STOCK_CLOSE, N_("Close"), "<Control>W",
                N_("Close the current file"), G_CALLBACK (cb_close)},
        {"FileQuit", GTK_STOCK_QUIT, N_("Quit"), "<Control>Q",
diff --git a/src/ui.xml b/src/ui.xml
index 8ad2ff4..faefd77 100644
--- a/src/ui.xml
+++ b/src/ui.xml
@@ -33,6 +33,7 @@ In the code, GtkUIManager is used to construct them.
       <menuitem action="FileSaveAs" />
       <separator />
       <menuitem action="FileCreateTemplate" />
+      <menuitem action="FileDeleteTemplate" />
       <separator />
       <menuitem action="FileClose" />
       <menuitem action="FileQuit" />


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