~ubuntu-branches/ubuntu/precise/latexila/precise

« back to all changes in this revision

Viewing changes to src/templates.c

  • Committer: Bazaar Package Importer
  • Author(s): Tanguy Ortolo
  • Date: 2010-04-26 22:13:00 UTC
  • Revision ID: james.westby@ubuntu.com-20100426221300-6pa79a1yk5tino7y
Tags: upstream-0.2.0
ImportĀ upstreamĀ versionĀ 0.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of LaTeXila.
 
3
 *
 
4
 * Copyright Ā© 2009, 2010 SĆ©bastien Wilmet
 
5
 *
 
6
 * LaTeXila is free software: you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation, either version 3 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * LaTeXila is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with LaTeXila.  If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#include <stdlib.h>
 
21
#include <gtk/gtk.h>
 
22
#include <sys/stat.h> // for S_IRWXU
 
23
#include <glib/gstdio.h> // for g_remove()
 
24
 
 
25
#include "main.h"
 
26
#include "config.h"
 
27
#include "print.h"
 
28
#include "callbacks.h"
 
29
#include "templates.h"
 
30
 
 
31
static void add_template_from_string (GtkListStore *store, const gchar *name,
 
32
                const gchar *icon_id, const gchar *contents);
 
33
static void add_template_from_file (GtkListStore *store, const gchar *name,
 
34
                const gchar *icon_id, const gchar *path);
 
35
static GtkWidget * create_icon_view (GtkListStore *store);
 
36
static void cb_icon_view_selection_changed (GtkIconView *icon_view,
 
37
                gpointer other_icon_view);
 
38
static gchar * get_rc_file (void);
 
39
static gchar * get_rc_dir (void);
 
40
static void add_personnal_template (const gchar *contents);
 
41
static void save_rc_file (void);
 
42
static void save_contents (void);
 
43
 
 
44
static GtkListStore *default_store;
 
45
static GtkListStore *personnal_store;
 
46
static gint nb_personnal_templates;
 
47
 
 
48
void
 
49
cb_new (void)
 
50
{
 
51
        GtkWidget *dialog = gtk_dialog_new_with_buttons (_("New File..."),
 
52
                        latexila.main_window,
 
53
                        GTK_DIALOG_NO_SEPARATOR,
 
54
                        GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
 
55
                        GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
 
56
                        NULL);
 
57
 
 
58
        gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 330);
 
59
        
 
60
        GtkWidget *content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
 
61
 
 
62
        /* icon view for the default templates */
 
63
        GtkWidget *icon_view_default_templates = create_icon_view (default_store);
 
64
 
 
65
        // with a scrollbar (without that there is a problem for resizing the
 
66
        // dialog, we can make it bigger but not smaller...)
 
67
        GtkWidget *scrollbar = gtk_scrolled_window_new (NULL, NULL);
 
68
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollbar),
 
69
                        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
70
        gtk_container_add (GTK_CONTAINER (scrollbar), icon_view_default_templates);
 
71
 
 
72
        // with a frame
 
73
        GtkWidget *frame = gtk_frame_new (_("Default templates"));
 
74
        gtk_container_add (GTK_CONTAINER (frame), scrollbar);
 
75
 
 
76
        gtk_box_pack_start (GTK_BOX (content_area), frame, TRUE, TRUE, 10);
 
77
 
 
78
        /* icon view for the personnal templates */
 
79
        GtkWidget *icon_view_personnal_templates = create_icon_view (personnal_store);
 
80
 
 
81
        // with a scrollbar
 
82
        scrollbar = gtk_scrolled_window_new (NULL, NULL);
 
83
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollbar),
 
84
                        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
85
        gtk_container_add (GTK_CONTAINER (scrollbar), icon_view_personnal_templates);
 
86
 
 
87
        // with a frame
 
88
        frame = gtk_frame_new (_("Your personnal templates"));
 
89
        gtk_container_add (GTK_CONTAINER (frame), scrollbar);
 
90
 
 
91
        gtk_box_pack_start (GTK_BOX (content_area), frame, TRUE, TRUE, 10);
 
92
 
 
93
        gtk_widget_show_all (content_area);
 
94
 
 
95
        /* signals */
 
96
        g_signal_connect (G_OBJECT (icon_view_default_templates),
 
97
                        "selection-changed",
 
98
                        G_CALLBACK (cb_icon_view_selection_changed),
 
99
                        GTK_ICON_VIEW (icon_view_personnal_templates));
 
100
 
 
101
        g_signal_connect (G_OBJECT (icon_view_personnal_templates),
 
102
                        "selection-changed",
 
103
                        G_CALLBACK (cb_icon_view_selection_changed),
 
104
                        GTK_ICON_VIEW (icon_view_default_templates));
 
105
 
 
106
        if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
 
107
        {
 
108
                GList *selected_items = gtk_icon_view_get_selected_items (
 
109
                                GTK_ICON_VIEW (icon_view_default_templates));
 
110
                GtkTreeModel *model = GTK_TREE_MODEL (default_store);
 
111
 
 
112
                // if no item is selected in the default templates, maybe one item is
 
113
                // selected in the personnal templates
 
114
                if (g_list_length (selected_items) == 0)
 
115
                {
 
116
                        // free the GList
 
117
                        g_list_foreach (selected_items, (GFunc) gtk_tree_path_free, NULL);
 
118
                        g_list_free (selected_items);
 
119
 
 
120
                        selected_items = gtk_icon_view_get_selected_items (
 
121
                                        GTK_ICON_VIEW (icon_view_personnal_templates));
 
122
                        model = GTK_TREE_MODEL (personnal_store);
 
123
                }
 
124
 
 
125
                GtkTreePath *path = g_list_nth_data (selected_items, 0);
 
126
                GtkTreeIter iter;
 
127
                gchar *contents = NULL;
 
128
 
 
129
                if (path != NULL && gtk_tree_model_get_iter (model, &iter, path))
 
130
                {
 
131
                        gtk_tree_model_get (model, &iter,
 
132
                                        COL_TEMPLATE_CONTENTS, &contents,
 
133
                                        -1);
 
134
                }
 
135
                else
 
136
                        contents = g_strdup ("");
 
137
 
 
138
                create_document_in_new_tab (NULL, contents, _("New document"));
 
139
 
 
140
                g_free (contents);
 
141
 
 
142
                // free the GList
 
143
                g_list_foreach (selected_items, (GFunc) gtk_tree_path_free, NULL);
 
144
                g_list_free (selected_items);
 
145
        }
 
146
 
 
147
        gtk_widget_destroy (dialog);
 
148
}
 
149
 
 
150
void
 
151
cb_create_template (void)
 
152
{
 
153
        if (latexila.active_doc == NULL)
 
154
                return;
 
155
 
 
156
        GtkWidget *dialog = gtk_dialog_new_with_buttons (_("New Template..."),
 
157
                        latexila.main_window, 0,
 
158
                        GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
 
159
                        GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
 
160
                        NULL);
 
161
 
 
162
        gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 330);
 
163
 
 
164
        GtkWidget *content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
 
165
 
 
166
        /* name */
 
167
        GtkWidget *hbox = gtk_hbox_new (FALSE, 5);
 
168
        GtkWidget *label = gtk_label_new (_("Name of the new template:"));
 
169
        GtkWidget *entry = gtk_entry_new ();
 
170
 
 
171
        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
 
172
        gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
 
173
        gtk_box_pack_start (GTK_BOX (content_area), hbox, FALSE, FALSE, 10);
 
174
 
 
175
        /* icon */
 
176
        // we take the default store because it contains all the icons
 
177
        GtkWidget *icon_view = create_icon_view (default_store);
 
178
 
 
179
        // bug, see https://bugzilla.gnome.org/show_bug.cgi?id=608609
 
180
        //gtk_icon_view_set_text_column (GTK_ICON_VIEW (icon_view), -1);
 
181
 
 
182
        // with a scrollbar
 
183
        GtkWidget *scrollbar = gtk_scrolled_window_new (NULL, NULL);
 
184
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollbar),
 
185
                        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
186
        gtk_container_add (GTK_CONTAINER (scrollbar), icon_view);
 
187
 
 
188
        // with a frame
 
189
        GtkWidget *frame = gtk_frame_new (_("Choose an icon:"));
 
190
        gtk_container_add (GTK_CONTAINER (frame), scrollbar);
 
191
        gtk_box_pack_start (GTK_BOX (content_area), frame, TRUE, TRUE, 10);
 
192
 
 
193
        gtk_widget_show_all (content_area);
 
194
 
 
195
        while (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
 
196
        {
 
197
                // if no name specified
 
198
                if (gtk_entry_get_text_length (GTK_ENTRY (entry)) == 0)
 
199
                        continue;
 
200
 
 
201
                GList *selected_items =
 
202
                        gtk_icon_view_get_selected_items (GTK_ICON_VIEW (icon_view));
 
203
 
 
204
                // if no icon selected
 
205
                if (g_list_length (selected_items) == 0)
 
206
                {
 
207
                        g_list_free (selected_items);
 
208
                        continue;
 
209
                }
 
210
 
 
211
                nb_personnal_templates++;
 
212
 
 
213
                // get the contents
 
214
                GtkTextBuffer *buffer =
 
215
                        GTK_TEXT_BUFFER (latexila.active_doc->source_buffer);
 
216
                GtkTextIter start, end;
 
217
                gtk_text_buffer_get_bounds (buffer, &start, &end);
 
218
                gchar *contents = gtk_text_buffer_get_text (buffer, &start, &end,
 
219
                                FALSE);
 
220
 
 
221
                // get the name
 
222
                const gchar *name = gtk_entry_get_text (GTK_ENTRY (entry));
 
223
 
 
224
                // get the icon id
 
225
                GtkTreeModel *model = GTK_TREE_MODEL (default_store);
 
226
                GtkTreePath *path = g_list_nth_data (selected_items, 0);
 
227
                GtkTreeIter iter;
 
228
                gchar *icon_id;
 
229
                gtk_tree_model_get_iter (model, &iter, path);
 
230
                gtk_tree_model_get (model, &iter,
 
231
                                COL_TEMPLATE_ICON_ID, &icon_id,
 
232
                                -1);
 
233
 
 
234
                add_template_from_string (personnal_store, name, icon_id, contents);
 
235
                add_personnal_template (contents);
 
236
 
 
237
                g_free (contents);
 
238
                g_free (icon_id);
 
239
                g_list_foreach (selected_items, (GFunc) gtk_tree_path_free, NULL);
 
240
                g_list_free (selected_items);
 
241
                break;
 
242
        }
 
243
 
 
244
        gtk_widget_destroy (dialog);
 
245
}
 
246
 
 
247
void
 
248
cb_delete_template (void)
 
249
{
 
250
        GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Delete Template(s)..."),
 
251
                        latexila.main_window,
 
252
                        GTK_DIALOG_NO_SEPARATOR,
 
253
                        GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT,
 
254
                        GTK_STOCK_OK, GTK_RESPONSE_REJECT,
 
255
                        NULL);
 
256
 
 
257
        gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 200);
 
258
        
 
259
        GtkWidget *content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
 
260
 
 
261
        /* icon view for the personnal templates */
 
262
        GtkWidget *icon_view = create_icon_view (personnal_store);
 
263
        gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (icon_view),
 
264
                        GTK_SELECTION_MULTIPLE);
 
265
 
 
266
        // with a scrollbar (without that there is a problem for resizing the
 
267
        // dialog, we can make it bigger but not smaller...)
 
268
        GtkWidget *scrollbar = gtk_scrolled_window_new (NULL, NULL);
 
269
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollbar),
 
270
                        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
271
        gtk_container_add (GTK_CONTAINER (scrollbar), icon_view);
 
272
 
 
273
        // with a frame
 
274
        GtkWidget *frame = gtk_frame_new (_("Personnal templates"));
 
275
        gtk_container_add (GTK_CONTAINER (frame), scrollbar);
 
276
 
 
277
        gtk_box_pack_start (GTK_BOX (content_area), frame, TRUE, TRUE, 10);
 
278
 
 
279
        gtk_widget_show_all (content_area);
 
280
 
 
281
        gint nb_personnal_templates_before = nb_personnal_templates;
 
282
 
 
283
        while (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
 
284
        {
 
285
                GList *selected_items = gtk_icon_view_get_selected_items (
 
286
                                GTK_ICON_VIEW (icon_view));
 
287
                GtkTreeModel *model = GTK_TREE_MODEL (personnal_store);
 
288
                
 
289
                guint nb_selected_items = g_list_length (selected_items);
 
290
 
 
291
                for (gint i = 0 ; i < nb_selected_items ; i++)
 
292
                {
 
293
                        GtkTreePath *path = g_list_nth_data (selected_items, i);
 
294
                        GtkTreeIter iter;
 
295
                        gtk_tree_model_get_iter (model, &iter, path);
 
296
                        gtk_list_store_remove (personnal_store, &iter);
 
297
                }
 
298
 
 
299
                nb_personnal_templates -= nb_selected_items;
 
300
 
 
301
                // free the GList
 
302
                g_list_foreach (selected_items, (GFunc) gtk_tree_path_free, NULL);
 
303
                g_list_free (selected_items);
 
304
        }
 
305
 
 
306
        if (nb_personnal_templates != nb_personnal_templates_before)
 
307
        {
 
308
                save_rc_file ();
 
309
                save_contents ();
 
310
        }
 
311
 
 
312
        gtk_widget_destroy (dialog);
 
313
}
 
314
 
 
315
void
 
316
init_templates (void)
 
317
{
 
318
        /* default templates */
 
319
        default_store = gtk_list_store_new (N_COLS_TEMPLATE,
 
320
                        GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
 
321
 
 
322
        add_template_from_string (default_store, _("Empty"), "empty", "");
 
323
 
 
324
        // article
 
325
        gchar *path = g_strdup_printf (DATA_DIR "/templates/%s",
 
326
                        _("article-en.tex"));
 
327
        add_template_from_file (default_store, _("Article"), "article", path);
 
328
        g_free (path);
 
329
 
 
330
        // report
 
331
        path = g_strdup_printf (DATA_DIR "/templates/%s",
 
332
                        _("report-en.tex"));
 
333
        add_template_from_file (default_store, _("Report"), "report", path);
 
334
        g_free (path);
 
335
 
 
336
        // book
 
337
        path = g_strdup_printf (DATA_DIR "/templates/%s",
 
338
                        _("book-en.tex"));
 
339
        add_template_from_file (default_store, _("Book"), "book", path);
 
340
        g_free (path);
 
341
 
 
342
        // letter
 
343
        path = g_strdup_printf (DATA_DIR "/templates/%s",
 
344
                        _("letter-en.tex"));
 
345
        add_template_from_file (default_store, _("Letter"), "letter", path);
 
346
        g_free (path);
 
347
 
 
348
        // presentation (beamer)
 
349
        path = g_strdup_printf (DATA_DIR "/templates/%s",
 
350
                        _("beamer-en.tex"));
 
351
        add_template_from_file (default_store, _("Presentation"), "beamer", path);
 
352
        g_free (path);
 
353
 
 
354
        /* personnal templates */
 
355
        personnal_store = gtk_list_store_new (N_COLS_TEMPLATE,
 
356
                        GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
 
357
        nb_personnal_templates = 0;
 
358
 
 
359
        gchar *rc_file = get_rc_file ();
 
360
        if (! g_file_test (rc_file, G_FILE_TEST_EXISTS))
 
361
        {
 
362
                g_free (rc_file);
 
363
                return;
 
364
        }
 
365
 
 
366
        GKeyFile *key_file = g_key_file_new ();
 
367
        GError *error = NULL;
 
368
        g_key_file_load_from_file (key_file, rc_file, G_KEY_FILE_NONE, &error);
 
369
        g_free (rc_file);
 
370
 
 
371
        if (error != NULL)
 
372
        {
 
373
                print_warning ("load templates failed: %s", error->message);
 
374
                g_error_free (error);
 
375
                return;
 
376
        }
 
377
 
 
378
        gsize length;
 
379
        gchar **names = g_key_file_get_string_list (key_file, PROGRAM_NAME,
 
380
                        "names", &length, &error);
 
381
        if (error != NULL)
 
382
        {
 
383
                print_warning ("load templates failed: %s", error->message);
 
384
                g_error_free (error);
 
385
                g_key_file_free (key_file);
 
386
                return;
 
387
        }
 
388
 
 
389
        gchar **icons = g_key_file_get_string_list (key_file, PROGRAM_NAME,
 
390
                        "icons", NULL, &error);
 
391
        gboolean icons_ok = TRUE;
 
392
        if (error != NULL)
 
393
        {
 
394
                print_warning ("%s", error->message);
 
395
                g_error_free (error);
 
396
                icons_ok = FALSE;
 
397
        }
 
398
 
 
399
        nb_personnal_templates = length;
 
400
 
 
401
        gchar *rc_dir = get_rc_dir ();
 
402
 
 
403
        for (gint i = 0 ; i < length ; i++)
 
404
        {
 
405
                gchar *file = g_strdup_printf ("%s/%d.tex", rc_dir, i);
 
406
                if (! g_file_test (file, G_FILE_TEST_EXISTS))
 
407
                {
 
408
                        g_free (file);
 
409
                        continue;
 
410
                }
 
411
 
 
412
                add_template_from_file (personnal_store, names[i],
 
413
                                icons_ok ? icons[i] : "article", file);
 
414
                g_free (file);
 
415
        }
 
416
 
 
417
        g_strfreev (names);
 
418
        g_strfreev (icons);
 
419
        g_key_file_free (key_file);
 
420
        g_free (rc_dir);
 
421
}
 
422
 
 
423
static void
 
424
add_template_from_string (GtkListStore *store, const gchar *name,
 
425
                const gchar *icon_id, const gchar *contents)
 
426
{
 
427
        if (contents == NULL)
 
428
                return;
 
429
 
 
430
        GError *error = NULL;
 
431
        gchar *icon_path = g_strdup_printf (DATA_DIR "/images/templates/%s.png",
 
432
                        icon_id);
 
433
        GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (icon_path, &error);
 
434
        g_free (icon_path);
 
435
        if (error != NULL)
 
436
        {
 
437
                print_warning ("impossible to load the icon of the template: %s",
 
438
                                error->message);
 
439
                g_error_free (error);
 
440
                return;
 
441
        }
 
442
 
 
443
        GtkTreeIter iter;
 
444
        gtk_list_store_append (store, &iter);
 
445
        gtk_list_store_set (store, &iter,
 
446
                        COL_TEMPLATE_PIXBUF, pixbuf,
 
447
                        COL_TEMPLATE_ICON_ID, icon_id,
 
448
                        COL_TEMPLATE_NAME, name,
 
449
                        COL_TEMPLATE_CONTENTS, contents,
 
450
                        -1);
 
451
 
 
452
        g_object_unref (pixbuf);
 
453
}
 
454
 
 
455
static void
 
456
add_template_from_file (GtkListStore *store, const gchar *name,
 
457
                const gchar *icon_id, const gchar *path)
 
458
{
 
459
        gchar *contents = NULL;
 
460
        GError *error = NULL;
 
461
        g_file_get_contents (path, &contents, NULL, &error);
 
462
 
 
463
        if (error != NULL)
 
464
        {
 
465
                print_warning ("impossible to load the template \"%s\": %s", name,
 
466
                                error->message);
 
467
                g_error_free (error);
 
468
                return;
 
469
        }
 
470
 
 
471
        gchar *text_utf8 = g_locale_to_utf8 (contents, -1, NULL, NULL, NULL);
 
472
        add_template_from_string (store, name, icon_id, text_utf8);
 
473
 
 
474
        g_free (text_utf8);
 
475
        g_free (contents);
 
476
}
 
477
 
 
478
static GtkWidget *
 
479
create_icon_view (GtkListStore *store)
 
480
{
 
481
        GtkWidget *icon_view = gtk_icon_view_new_with_model (
 
482
                        GTK_TREE_MODEL (store));
 
483
        gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (icon_view),
 
484
                        GTK_SELECTION_SINGLE);
 
485
        gtk_icon_view_set_text_column (GTK_ICON_VIEW (icon_view),
 
486
                        COL_TEMPLATE_NAME);
 
487
        gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (icon_view),
 
488
                        COL_TEMPLATE_PIXBUF);
 
489
 
 
490
        return icon_view;
 
491
}
 
492
 
 
493
static void
 
494
cb_icon_view_selection_changed (GtkIconView *icon_view,
 
495
                gpointer other_icon_view)
 
496
{
 
497
        // only one item of the two icon views can be selected at once
 
498
        
 
499
        // we unselect all the items of the other icon view only if the current icon
 
500
        // view have an item selected, because when we unselect all the items the
 
501
        // "selection-changed" signal is emitted for the other icon view, so for the
 
502
        // other icon view this function is also called but no item is selected so
 
503
        // nothing is done and the item selected by the user keeps selected
 
504
 
 
505
        GList *selected_items = gtk_icon_view_get_selected_items (icon_view);
 
506
 
 
507
        if (g_list_length (selected_items) > 0)
 
508
                gtk_icon_view_unselect_all ((GtkIconView *) other_icon_view);
 
509
 
 
510
        // free the GList
 
511
        g_list_foreach (selected_items, (GFunc) gtk_tree_path_free, NULL);
 
512
        g_list_free (selected_items);
 
513
}
 
514
 
 
515
static gchar *
 
516
get_rc_file (void)
 
517
{
 
518
        // rc_file must be freed
 
519
        gchar *rc_file = g_build_filename (g_get_user_data_dir (), "latexila",
 
520
                        "templatesrc", NULL);
 
521
        return rc_file;
 
522
}
 
523
 
 
524
static gchar *
 
525
get_rc_dir (void)
 
526
{
 
527
        // rc_dir must be freed
 
528
        gchar *rc_dir = g_build_filename (g_get_user_data_dir (), "latexila", NULL);
 
529
        return rc_dir;
 
530
}
 
531
 
 
532
static void
 
533
add_personnal_template (const gchar *contents)
 
534
{
 
535
        save_rc_file ();
 
536
 
 
537
        gchar *rc_dir = get_rc_dir ();
 
538
 
 
539
        gchar *file = g_strdup_printf ("%s/%d.tex", rc_dir,
 
540
                        nb_personnal_templates - 1);
 
541
 
 
542
        GError *error = NULL;
 
543
        g_file_set_contents (file, contents, -1, &error);
 
544
 
 
545
        if (error != NULL)
 
546
        {
 
547
                print_warning ("impossible to save templates: %s", error->message);
 
548
                g_error_free (error);
 
549
        }
 
550
 
 
551
        g_free (rc_dir);
 
552
        g_free (file);
 
553
}
 
554
 
 
555
static void
 
556
save_rc_file (void)
 
557
{
 
558
        if (nb_personnal_templates == 0)
 
559
        {
 
560
                gchar *rc_file = get_rc_file ();
 
561
                g_remove (rc_file);
 
562
                g_free (rc_file);
 
563
                return;
 
564
        }
 
565
 
 
566
        // the names of all the personnal templates
 
567
        gchar **names = g_malloc ((nb_personnal_templates + 1) * sizeof (gchar *));
 
568
        gchar **names_i = names;
 
569
 
 
570
        // the icons id of all the personnal templates
 
571
        gchar **icons = g_malloc ((nb_personnal_templates + 1) * sizeof (gchar *));
 
572
        gchar **icons_i = icons;
 
573
        
 
574
        // traverse the list store
 
575
        GtkTreeIter iter;
 
576
        GtkTreeModel *model = GTK_TREE_MODEL (personnal_store);
 
577
        gboolean valid_iter = gtk_tree_model_get_iter_first (model, &iter);
 
578
        while (valid_iter)
 
579
        {
 
580
                gtk_tree_model_get (model, &iter,
 
581
                                COL_TEMPLATE_NAME, names_i,
 
582
                                COL_TEMPLATE_ICON_ID, icons_i,
 
583
                                -1);
 
584
                valid_iter = gtk_tree_model_iter_next (model, &iter);
 
585
                names_i++;
 
586
                icons_i++;
 
587
        }
 
588
 
 
589
        // the last elements are NULL so we can use g_strfreev()
 
590
        *names_i = NULL;
 
591
        *icons_i = NULL;
 
592
 
 
593
        GKeyFile *key_file = g_key_file_new ();
 
594
        g_key_file_set_string_list (key_file, PROGRAM_NAME, "names",
 
595
                        (const gchar * const *) names, nb_personnal_templates);
 
596
        g_key_file_set_string_list (key_file, PROGRAM_NAME, "icons",
 
597
                        (const gchar * const *) icons, nb_personnal_templates);
 
598
 
 
599
        /* save the rc file */
 
600
        gchar *rc_file = get_rc_file ();
 
601
        gchar *rc_dir = get_rc_dir ();
 
602
        g_mkdir_with_parents(rc_dir, S_IRWXU);
 
603
        gchar *key_file_data = g_key_file_to_data (key_file, NULL, NULL);
 
604
 
 
605
        GError *error = NULL;
 
606
        g_file_set_contents (rc_file, key_file_data, -1, &error);
 
607
 
 
608
        if (error != NULL)
 
609
        {
 
610
                print_warning ("impossible to save templates: %s", error->message);
 
611
                g_error_free (error);
 
612
        }
 
613
 
 
614
        g_strfreev (names);
 
615
        g_strfreev (icons);
 
616
        g_free (rc_file);
 
617
        g_free (rc_dir);
 
618
        g_free (key_file_data);
 
619
        g_key_file_free (key_file);
 
620
}
 
621
 
 
622
/* save the contents of the personnal templates
 
623
 * the first personnal template is saved in 0.tex, the second in 1.tex, etc */
 
624
static void
 
625
save_contents (void)
 
626
{
 
627
        gchar *rc_dir = get_rc_dir ();
 
628
 
 
629
        // delete all the *.tex files
 
630
        gchar *command = g_strdup_printf ("rm -f %s/*.tex", rc_dir);
 
631
        system (command);
 
632
        g_free (command);
 
633
 
 
634
        // traverse the list store
 
635
        GtkTreeIter iter;
 
636
        GtkTreeModel *model = GTK_TREE_MODEL (personnal_store);
 
637
        gboolean valid_iter = gtk_tree_model_get_iter_first (model, &iter);
 
638
        gint i = 0;
 
639
        while (valid_iter)
 
640
        {
 
641
                gchar *contents;
 
642
                gtk_tree_model_get (model, &iter, COL_TEMPLATE_CONTENTS, &contents, -1);
 
643
 
 
644
                gchar *file = g_strdup_printf ("%s/%d.tex", rc_dir, i);
 
645
 
 
646
                GError *error = NULL;
 
647
                g_file_set_contents (file, contents, -1, &error);
 
648
 
 
649
                if (error != NULL)
 
650
                {
 
651
                        print_warning ("impossible to save the template: %s", error->message);
 
652
                        g_error_free (error);
 
653
                        error = NULL;
 
654
                }
 
655
 
 
656
                g_free (contents);
 
657
                g_free (file);
 
658
 
 
659
                valid_iter = gtk_tree_model_iter_next (model, &iter);
 
660
                i++;
 
661
        }
 
662
 
 
663
        g_free (rc_dir);
 
664
}