1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 
3 /*
4  *  Engrampa
5  *
6  *  Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #include <config.h>
24 #include <string.h>
25 #include <unistd.h>
26 
27 #include <glib/gi18n.h>
28 #include <gtk/gtk.h>
29 #include <gio/gio.h>
30 #include "dlg-add-folder.h"
31 #include "file-utils.h"
32 #include "fr-window.h"
33 #include "gtk-utils.h"
34 #include "preferences.h"
35 
36 #ifdef __GNUC__
37 #define UNUSED_VARIABLE __attribute__ ((unused))
38 #else
39 #define UNUSED_VARIABLE
40 #endif
41 
42 #define GET_WIDGET(x) (GTK_WIDGET (gtk_builder_get_object (builder, (x))))
43 
44 typedef struct {
45 	FrWindow    *window;
46 	GSettings   *settings;
47 	GtkWidget   *dialog;
48 	GtkWidget   *include_subfold_checkbutton;
49 	GtkWidget   *exclude_symlinks;
50 	GtkWidget   *add_if_newer_checkbutton;
51 	GtkWidget   *include_files_entry;
52 	GtkWidget   *exclude_files_entry;
53 	GtkWidget   *exclude_folders_entry;
54 	char        *last_options;
55 } DialogData;
56 
57 
58 static void
open_file_destroy_cb(GtkWidget * widget,DialogData * data)59 open_file_destroy_cb (GtkWidget  *widget,
60 		      DialogData *data)
61 {
62 	g_object_unref (data->settings);
63 	g_free (data->last_options);
64 	g_free (data);
65 }
66 
67 
68 static gboolean
utf8_only_spaces(const char * text)69 utf8_only_spaces (const char *text)
70 {
71 	const char *scan;
72 
73 	if (text == NULL)
74 		return TRUE;
75 
76 	for (scan = text; *scan != 0; scan = g_utf8_next_char (scan)) {
77 		gunichar c = g_utf8_get_char (scan);
78 		if (! g_unichar_isspace (c))
79 			return FALSE;
80 	}
81 
82 	return TRUE;
83 }
84 
85 
86 static void dlg_add_folder_save_last_options (DialogData *data);
87 
88 
89 static int
file_sel_response_cb(GtkWidget * widget,int response,DialogData * data)90 file_sel_response_cb (GtkWidget    *widget,
91 		      int           response,
92 		      DialogData   *data)
93 {
94 	GtkFileChooser *file_sel = GTK_FILE_CHOOSER (widget);
95 	FrWindow       *window = data->window;
96 	char           *selected_folder;
97 	gboolean        update, UNUSED_VARIABLE recursive, follow_links;
98 	const char     *include_files;
99 	const char     *exclude_files;
100 	const char     *exclude_folders;
101 	char           *dest_dir;
102 	char           *local_filename;
103 
104 
105 	dlg_add_folder_save_last_options (data);
106 
107 	if ((response == GTK_RESPONSE_CANCEL) || (response == GTK_RESPONSE_DELETE_EVENT)) {
108 		gtk_widget_destroy (data->dialog);
109 		return TRUE;
110 	}
111 
112 	if (response == GTK_RESPONSE_HELP) {
113 		show_help_dialog (GTK_WINDOW (data->dialog), "engrampa-add-options");
114 		return TRUE;
115 	}
116 
117 	selected_folder = gtk_file_chooser_get_uri (file_sel);
118 
119 	/* check folder permissions. */
120 
121 	if (! check_permissions (selected_folder, R_OK)) {
122 		GtkWidget *d;
123 		char      *utf8_path;
124 
125 		utf8_path = g_filename_display_name (selected_folder);
126 
127 		d = _gtk_error_dialog_new (GTK_WINDOW (window),
128 					   GTK_DIALOG_MODAL,
129 					   NULL,
130 					   _("Could not add the files to the archive"),
131 					   _("You don't have the right permissions to read files from folder \"%s\""),
132 					   utf8_path);
133 		gtk_dialog_run (GTK_DIALOG (d));
134 		gtk_widget_destroy (GTK_WIDGET (d));
135 
136 		g_free (utf8_path);
137 		g_free (selected_folder);
138 
139 		return FALSE;
140 	}
141 
142 	update = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->add_if_newer_checkbutton));
143 	recursive = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->include_subfold_checkbutton));
144 	follow_links = ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->exclude_symlinks));
145 
146 	include_files = gtk_entry_get_text (GTK_ENTRY (data->include_files_entry));
147 	if (utf8_only_spaces (include_files))
148 		include_files = "*";
149 
150 	exclude_files = gtk_entry_get_text (GTK_ENTRY (data->exclude_files_entry));
151 	if (utf8_only_spaces (exclude_files))
152 		exclude_files = NULL;
153 
154 	exclude_folders = gtk_entry_get_text (GTK_ENTRY (data->exclude_folders_entry));
155 	if (utf8_only_spaces (exclude_folders))
156 		exclude_folders = NULL;
157 
158 	local_filename = g_filename_from_uri (selected_folder, NULL, NULL);
159 	dest_dir = build_uri (fr_window_get_current_location (window),
160 			      file_name_from_path (local_filename),
161 			      NULL);
162 
163 	fr_window_archive_add_with_wildcard (window,
164 					     include_files,
165 					     exclude_files,
166 					     exclude_folders,
167 					     selected_folder,
168 					     dest_dir,
169 					     update,
170 					     follow_links);
171 
172 	g_free (local_filename);
173 	g_free (dest_dir);
174 	g_free (selected_folder);
175 
176 	gtk_widget_destroy (data->dialog);
177 
178 	return TRUE;
179 }
180 
181 
182 static int
include_subfold_toggled_cb(GtkWidget * widget,gpointer callback_data)183 include_subfold_toggled_cb (GtkWidget *widget,
184 			    gpointer   callback_data)
185 {
186 	DialogData *data = callback_data;
187 
188 	gtk_widget_set_sensitive (data->exclude_symlinks,
189 	                          gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
190 
191 	return FALSE;
192 }
193 
194 
195 static void load_options_cb (GtkWidget *w, DialogData *data);
196 static void save_options_cb (GtkWidget *w, DialogData *data);
197 static void clear_options_cb (GtkWidget *w, DialogData *data);
198 static void dlg_add_folder_load_last_options (DialogData *data);
199 
200 
201 /* create the "add" dialog. */
202 void
add_folder_cb(GtkWidget * widget,void * callback_data)203 add_folder_cb (GtkWidget *widget,
204 	       void      *callback_data)
205 {
206 	GtkBuilder  *builder;
207 	DialogData  *data;
208 
209 	builder = gtk_builder_new_from_resource (ENGRAMPA_RESOURCE_UI_PATH G_DIR_SEPARATOR_S "dlg-add-folder.ui");
210 
211 	data = g_new0 (DialogData, 1);
212 	data->window = callback_data;
213 	data->settings = g_settings_new (ENGRAMPA_SCHEMA_ADD);
214 	data->dialog = GET_WIDGET ("dialog_add_folder");
215 	data->add_if_newer_checkbutton = GET_WIDGET ("add_if_newer_checkbutton");
216 	data->exclude_symlinks = GET_WIDGET ("exclude_symlinks");
217 	data->include_subfold_checkbutton = GET_WIDGET ("include_subfold_checkbutton");
218 	data->include_files_entry = GET_WIDGET ("include_files_entry");
219 	data->exclude_files_entry = GET_WIDGET ("exclude_files_entry");
220 	data->exclude_folders_entry = GET_WIDGET ("exclude_folders_entry");
221 
222 	/* set data */
223 	dlg_add_folder_load_last_options (data);
224 
225 	/* signals */
226 	gtk_builder_add_callback_symbols (builder,
227 	                                  "on_dialog_add_folder_destroy",		G_CALLBACK (open_file_destroy_cb),
228 	                                  "on_dialog_add_folder_response",		G_CALLBACK (file_sel_response_cb),
229 	                                  "on_include_subfold_checkbutton_toggled",	G_CALLBACK (include_subfold_toggled_cb),
230 	                                  "on_load_button_clicked",			G_CALLBACK (load_options_cb),
231 	                                  "on_save_button_clicked",			G_CALLBACK (save_options_cb),
232 	                                  "on_clear_button_clicked",			G_CALLBACK (clear_options_cb),
233 	                                  NULL);
234 	gtk_builder_connect_signals (builder, data);
235 
236 	g_object_unref (builder);
237 
238 	gtk_window_set_modal (GTK_WINDOW (data->dialog), TRUE);
239 	gtk_widget_show (data->dialog);
240 }
241 
242 
243 /* load/save the dialog options */
244 
245 
246 static void
dlg_add_folder_save_last_used_options(DialogData * data,const char * options_path)247 dlg_add_folder_save_last_used_options (DialogData *data,
248 			               const char *options_path)
249 {
250 	g_free (data->last_options);
251 	data->last_options = g_strdup (file_name_from_path (options_path));
252 }
253 
254 
255 static void
sync_widgets_with_options(DialogData * data,const char * base_dir,const char * filename,const char * include_files,const char * exclude_files,const char * exclude_folders,gboolean update,gboolean recursive,gboolean no_symlinks)256 sync_widgets_with_options (DialogData *data,
257 			   const char *base_dir,
258 			   const char *filename,
259 			   const char *include_files,
260 			   const char *exclude_files,
261 			   const char *exclude_folders,
262 			   gboolean    update,
263 			   gboolean    recursive,
264 			   gboolean    no_symlinks)
265 {
266 	if ((base_dir == NULL) || (strcmp (base_dir, "") == 0))
267 		base_dir = fr_window_get_add_default_dir (data->window);
268 
269 	if ((filename != NULL) && (strcmp (filename, base_dir) != 0))
270 		gtk_file_chooser_select_uri (GTK_FILE_CHOOSER (data->dialog), filename);
271 	else
272 		gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (data->dialog), base_dir);
273 
274 	if (include_files != NULL)
275 		gtk_entry_set_text (GTK_ENTRY (data->include_files_entry), include_files);
276 	if (exclude_files != NULL)
277 		gtk_entry_set_text (GTK_ENTRY (data->exclude_files_entry), exclude_files);
278 	if (exclude_folders != NULL)
279 		gtk_entry_set_text (GTK_ENTRY (data->exclude_folders_entry), exclude_folders);
280 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->add_if_newer_checkbutton), update);
281 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->include_subfold_checkbutton), recursive);
282 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->exclude_symlinks), no_symlinks);
283 }
284 
285 
286 static void
clear_options_cb(GtkWidget * w,DialogData * data)287 clear_options_cb (GtkWidget  *w,
288 		  DialogData *data)
289 {
290 	sync_widgets_with_options (data,
291 				   gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (data->dialog)),
292 				   gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (data->dialog)),
293 				   "",
294 				   "",
295 				   "",
296 				   FALSE,
297 				   TRUE,
298 				   FALSE);
299 }
300 
301 
302 static gboolean
dlg_add_folder_load_options(DialogData * data,const char * name)303 dlg_add_folder_load_options (DialogData *data,
304 			     const char *name)
305 {
306 	GFile     *options_dir;
307 	GFile     *options_file;
308 	char      *file_path;
309 	GKeyFile  *key_file;
310 	GError    *error = NULL;
311 	char      *base_dir = NULL;
312 	char      *filename = NULL;
313 	char      *include_files = NULL;
314 	char      *exclude_files = NULL;
315 	char      *exclude_folders = NULL;
316 	gboolean   update;
317 	gboolean   recursive;
318 	gboolean   no_symlinks;
319 
320 	options_dir = get_user_config_subdirectory (ADD_FOLDER_OPTIONS_DIR, TRUE);
321 	options_file = g_file_get_child (options_dir, name);
322 	file_path = g_file_get_path (options_file);
323 	key_file = g_key_file_new ();
324 	if (! g_key_file_load_from_file (key_file, file_path, G_KEY_FILE_KEEP_COMMENTS, &error)) {
325 		if (error->code != G_IO_ERROR_NOT_FOUND)
326 			g_warning ("Could not load options file: %s\n", error->message);
327 		g_clear_error (&error);
328 		g_object_unref (options_file);
329 		g_object_unref (options_dir);
330 		g_key_file_free (key_file);
331 		return FALSE;
332 	}
333 
334 	base_dir = g_key_file_get_string (key_file, "Options", "base_dir", NULL);
335 	filename = g_key_file_get_string (key_file, "Options", "filename", NULL);
336 	include_files = g_key_file_get_string (key_file, "Options", "include_files", NULL);
337 	exclude_files = g_key_file_get_string (key_file, "Options", "exclude_files", NULL);
338 	exclude_folders = g_key_file_get_string (key_file, "Options", "exclude_folders", NULL);
339 	update = g_key_file_get_boolean (key_file, "Options", "update", NULL);
340 	recursive = g_key_file_get_boolean (key_file, "Options", "recursive", NULL);
341 	no_symlinks = g_key_file_get_boolean (key_file, "Options", "no_symlinks", NULL);
342 
343 	sync_widgets_with_options (data,
344 			   	   base_dir,
345 			   	   filename,
346 			   	   include_files,
347 			   	   exclude_files,
348 			   	   exclude_folders,
349 			   	   update,
350 			   	   recursive,
351 			   	   no_symlinks);
352 
353 	dlg_add_folder_save_last_used_options (data, file_path);
354 
355 	g_free (base_dir);
356 	g_free (filename);
357 	g_free (include_files);
358 	g_free (exclude_files);
359 	g_free (exclude_folders);
360 	g_key_file_free (key_file);
361 	g_free (file_path);
362 	g_object_unref (options_file);
363 	g_object_unref (options_dir);
364 
365 	return TRUE;
366 }
367 
368 
369 static void
dlg_add_folder_load_last_options(DialogData * data)370 dlg_add_folder_load_last_options (DialogData *data)
371 {
372 	char     *base_dir = NULL;
373 	char     *filename = NULL;
374 	char     *include_files = NULL;
375 	char     *exclude_files = NULL;
376 	char     *exclude_folders = NULL;
377 	gboolean  update;
378 	gboolean  recursive;
379 	gboolean  no_symlinks;
380 
381 	base_dir = g_settings_get_string (data->settings, PREF_ADD_CURRENT_FOLDER);
382 	filename = g_settings_get_string (data->settings, PREF_ADD_FILENAME);
383 	include_files = g_settings_get_string (data->settings, PREF_ADD_INCLUDE_FILES);
384 	exclude_files = g_settings_get_string (data->settings, PREF_ADD_EXCLUDE_FILES);
385 	exclude_folders = g_settings_get_string (data->settings, PREF_ADD_EXCLUDE_FOLDERS);
386 	update = g_settings_get_boolean (data->settings, PREF_ADD_UPDATE);
387 	recursive = g_settings_get_boolean (data->settings, PREF_ADD_RECURSIVE);
388 	no_symlinks = g_settings_get_boolean (data->settings, PREF_ADD_NO_SYMLINKS);
389 
390 	sync_widgets_with_options (data,
391 			   	   base_dir,
392 			   	   filename,
393 			   	   include_files,
394 			   	   exclude_files,
395 			   	   exclude_folders,
396 			   	   update,
397 			   	   recursive,
398 			   	   no_symlinks);
399 
400 	g_free (base_dir);
401 	g_free (filename);
402 	g_free (include_files);
403 	g_free (exclude_files);
404 	g_free (exclude_folders);
405 }
406 
407 
408 static void
get_options_from_widgets(DialogData * data,char ** base_dir,char ** filename,const char ** include_files,const char ** exclude_files,const char ** exclude_folders,gboolean * update,gboolean * recursive,gboolean * no_symlinks)409 get_options_from_widgets (DialogData  *data,
410 			  char       **base_dir,
411 			  char       **filename,
412 			  const char **include_files,
413 			  const char **exclude_files,
414 			  const char **exclude_folders,
415 			  gboolean    *update,
416 			  gboolean    *recursive,
417 			  gboolean    *no_symlinks)
418 {
419 	*base_dir = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (data->dialog));
420 	*filename = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (data->dialog));
421 	*update = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->add_if_newer_checkbutton));
422 	*recursive = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->include_subfold_checkbutton));
423 	*no_symlinks = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->exclude_symlinks));
424 
425 	*include_files = gtk_entry_get_text (GTK_ENTRY (data->include_files_entry));
426 	if (utf8_only_spaces (*include_files))
427 		*include_files = "";
428 
429 	*exclude_files = gtk_entry_get_text (GTK_ENTRY (data->exclude_files_entry));
430 	if (utf8_only_spaces (*exclude_files))
431 		*exclude_files = "";
432 
433 	*exclude_folders = gtk_entry_get_text (GTK_ENTRY (data->exclude_folders_entry));
434 	if (utf8_only_spaces (*exclude_folders))
435 		*exclude_folders = "";
436 }
437 
438 
439 static void
dlg_add_folder_save_current_options(DialogData * data,GFile * options_file)440 dlg_add_folder_save_current_options (DialogData *data,
441 				     GFile      *options_file)
442 {
443 	char       *base_dir;
444 	char       *filename;
445 	const char *include_files;
446 	const char *exclude_files;
447 	const char *exclude_folders;
448 	gboolean    update;
449 	gboolean    recursive;
450 	gboolean    no_symlinks;
451 	GKeyFile   *key_file;
452 
453 	get_options_from_widgets (data,
454 				  &base_dir,
455 				  &filename,
456 				  &include_files,
457 				  &exclude_files,
458 				  &exclude_folders,
459 				  &update,
460 				  &recursive,
461 				  &no_symlinks);
462 
463 	fr_window_set_add_default_dir (data->window, base_dir);
464 
465 	key_file = g_key_file_new ();
466 	g_key_file_set_string (key_file, "Options", "base_dir", base_dir);
467 	g_key_file_set_string (key_file, "Options", "filename", filename);
468 	g_key_file_set_string (key_file, "Options", "include_files", include_files);
469 	g_key_file_set_string (key_file, "Options", "exclude_files", exclude_files);
470 	g_key_file_set_string (key_file, "Options", "exclude_folders", exclude_folders);
471 	g_key_file_set_boolean (key_file, "Options", "update", update);
472 	g_key_file_set_boolean (key_file, "Options", "recursive", recursive);
473 	g_key_file_set_boolean (key_file, "Options", "no_symlinks", no_symlinks);
474 
475 	g_key_file_save (key_file, options_file);
476 
477 	g_key_file_free (key_file);
478 	g_free (base_dir);
479 	g_free (filename);
480 }
481 
482 
483 static void
dlg_add_folder_save_last_options(DialogData * data)484 dlg_add_folder_save_last_options (DialogData *data)
485 {
486 	char       *base_dir;
487 	char       *filename;
488 	const char *include_files;
489 	const char *exclude_files;
490 	const char *exclude_folders;
491 	gboolean    update;
492 	gboolean    recursive;
493 	gboolean    no_symlinks;
494 
495 	get_options_from_widgets (data,
496 				  &base_dir,
497 				  &filename,
498 				  &include_files,
499 				  &exclude_files,
500 				  &exclude_folders,
501 				  &update,
502 				  &recursive,
503 				  &no_symlinks);
504 
505 	g_settings_set_string (data->settings, PREF_ADD_CURRENT_FOLDER, base_dir);
506 	g_settings_set_string (data->settings, PREF_ADD_FILENAME, filename);
507 	g_settings_set_string (data->settings, PREF_ADD_INCLUDE_FILES, include_files);
508 	g_settings_set_string (data->settings, PREF_ADD_EXCLUDE_FILES, exclude_files);
509 	g_settings_set_string (data->settings, PREF_ADD_EXCLUDE_FOLDERS, exclude_folders);
510 	g_settings_set_boolean (data->settings, PREF_ADD_UPDATE, update);
511 	g_settings_set_boolean (data->settings, PREF_ADD_RECURSIVE, recursive);
512 	g_settings_set_boolean (data->settings, PREF_ADD_NO_SYMLINKS, no_symlinks);
513 
514 	g_free (base_dir);
515 	g_free (filename);
516 }
517 
518 
519 typedef struct {
520 	DialogData   *data;
521 	GtkWidget    *dialog;
522 	GtkWidget    *aod_treeview;
523 	GtkTreeModel *aod_model;
524 } LoadOptionsDialogData;
525 
526 
527 static void
aod_destroy_cb(GtkWidget * widget,LoadOptionsDialogData * aod_data)528 aod_destroy_cb (GtkWidget             *widget,
529 		LoadOptionsDialogData *aod_data)
530 {
531 	g_free (aod_data);
532 }
533 
534 
535 static void
aod_apply_cb(GtkWidget * widget,gpointer callback_data)536 aod_apply_cb (GtkWidget *widget,
537 	      gpointer   callback_data)
538 {
539 	LoadOptionsDialogData *aod_data = callback_data;
540 	DialogData            *data = aod_data->data;
541 	GtkTreeSelection      *selection;
542 	GtkTreeIter            iter;
543 	char                  *options_name;
544 
545 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (aod_data->aod_treeview));
546 	if (! gtk_tree_selection_get_selected (selection, NULL, &iter))
547 		return;
548 
549 	gtk_tree_model_get (aod_data->aod_model, &iter, 1, &options_name, -1);
550 
551 	dlg_add_folder_load_options (data, options_name);
552 	g_free (options_name);
553 
554 	gtk_widget_destroy (aod_data->dialog);
555 }
556 
557 
558 static void
aod_activated_cb(GtkTreeView * tree_view,GtkTreePath * path,GtkTreeViewColumn * column,gpointer callback_data)559 aod_activated_cb (GtkTreeView       *tree_view,
560 		  GtkTreePath       *path,
561 		  GtkTreeViewColumn *column,
562 		  gpointer           callback_data)
563 {
564 	aod_apply_cb (NULL, callback_data);
565 }
566 
567 
568 static void
aod_update_option_list(LoadOptionsDialogData * aod_data)569 aod_update_option_list (LoadOptionsDialogData *aod_data)
570 {
571 	GtkListStore    *list_store = GTK_LIST_STORE (aod_data->aod_model);
572 	GFile           *options_dir;
573 	GFileEnumerator *file_enum;
574 	GFileInfo       *info;
575 	GError          *err = NULL;
576 
577 	gtk_list_store_clear (list_store);
578 
579 	options_dir = get_user_config_subdirectory (ADD_FOLDER_OPTIONS_DIR, TRUE);
580 	make_directory_tree (options_dir, 0700, NULL);
581 
582 	file_enum = g_file_enumerate_children (options_dir, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, &err);
583 	if (err != NULL) {
584 		g_warning ("Failed to enumerate children: %s", err->message);
585 		g_clear_error (&err);
586 		g_object_unref (options_dir);
587 		return;
588 	}
589 
590 	while ((info = g_file_enumerator_next_file (file_enum, NULL, &err)) != NULL) {
591 		const char  *name;
592 		char        *display_name;
593 		GtkTreeIter  iter;
594 
595 		if (err != NULL) {
596 			g_warning ("Failed to get info while enumerating: %s", err->message);
597 			g_clear_error (&err);
598 			continue;
599 		}
600 
601 		name = g_file_info_get_name (info);
602 		display_name = g_filename_display_name (name);
603 
604 		gtk_list_store_append (GTK_LIST_STORE (aod_data->aod_model), &iter);
605 		gtk_list_store_set (GTK_LIST_STORE (aod_data->aod_model), &iter,
606 				    0, name,
607 				    1, display_name,
608 				    -1);
609 
610 		g_free (display_name);
611 		g_object_unref (info);
612 	}
613 
614 	if (err != NULL) {
615 		g_warning ("Failed to get info after enumeration: %s", err->message);
616 		g_clear_error (&err);
617 	}
618 
619 	g_object_unref (options_dir);
620 }
621 
622 
623 static void
aod_remove_cb(GtkWidget * widget,LoadOptionsDialogData * aod_data)624 aod_remove_cb (GtkWidget             *widget,
625 	       LoadOptionsDialogData *aod_data)
626 {
627 	GtkTreeSelection *selection;
628 	GtkTreeIter       iter;
629 	char             *filename;
630 	GFile            *options_dir;
631 	GFile            *options_file;
632 	GError           *error = NULL;
633 
634 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (aod_data->aod_treeview));
635 	if (! gtk_tree_selection_get_selected (selection, NULL, &iter))
636 		return;
637 
638 	gtk_tree_model_get (aod_data->aod_model, &iter, 1, &filename, -1);
639 	gtk_list_store_remove (GTK_LIST_STORE (aod_data->aod_model), &iter);
640 
641 	options_dir = get_user_config_subdirectory (ADD_FOLDER_OPTIONS_DIR, TRUE);
642 	options_file = g_file_get_child (options_dir, filename);
643 	if (! g_file_delete (options_file, NULL, &error)) {
644 		g_warning ("could not delete the options: %s", error->message);
645 		g_clear_error (&error);
646 	}
647 
648 	g_object_unref (options_file);
649 	g_object_unref (options_dir);
650 	g_free (filename);
651 }
652 
653 
654 static void
load_options_cb(GtkWidget * w,DialogData * data)655 load_options_cb (GtkWidget  *w,
656 		 DialogData *data)
657 {
658 	LoadOptionsDialogData *aod_data;
659 	GtkBuilder            *builder;
660 	GtkCellRenderer       *renderer;
661 	GtkTreeViewColumn     *column;
662 
663 	aod_data = g_new0 (LoadOptionsDialogData, 1);
664 
665 	aod_data->data = data;
666 	builder = gtk_builder_new_from_resource (ENGRAMPA_RESOURCE_UI_PATH G_DIR_SEPARATOR_S "add-options.ui");
667 
668 	/* Get the widgets. */
669 
670 	aod_data->dialog = GET_WIDGET ("add_options_dialog");
671 	aod_data->aod_treeview = GET_WIDGET ("aod_treeview");
672 
673 	/* Set the signals handlers. */
674 	gtk_builder_add_callback_symbols (builder,
675 	                                  "on_add_options_dialog_destroy",	G_CALLBACK (aod_destroy_cb),
676 	                                  "on_aod_treeview_row_activated",	G_CALLBACK (aod_activated_cb),
677 	                                  "on_aod_ok_button_clicked",		G_CALLBACK (aod_apply_cb),
678 	                                  "on_aod_cancel_button_clicked",	G_CALLBACK (aod_remove_cb),
679 	                                  NULL);
680 	gtk_builder_connect_signals (builder, aod_data);
681 
682 	g_signal_connect_swapped (gtk_builder_get_object (builder, "aod_cancelbutton"),
683 				  "clicked",
684 				  G_CALLBACK (gtk_widget_destroy),
685 				  G_OBJECT (aod_data->dialog));
686 
687 	g_object_unref (builder);
688 
689 	/* Set data. */
690 
691 	aod_data->aod_model = GTK_TREE_MODEL (gtk_list_store_new (2,
692 								  G_TYPE_STRING,
693 								  G_TYPE_STRING));
694 	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (aod_data->aod_model),
695 					      0,
696 					      GTK_SORT_ASCENDING);
697 	gtk_tree_view_set_model (GTK_TREE_VIEW (aod_data->aod_treeview),
698 				 aod_data->aod_model);
699 	g_object_unref (aod_data->aod_model);
700 
701 	/**/
702 
703 	renderer = gtk_cell_renderer_text_new ();
704 	column = gtk_tree_view_column_new_with_attributes (NULL,
705 							   renderer,
706 							   "text", 0,
707 							   NULL);
708 	gtk_tree_view_column_set_sort_column_id (column, 0);
709 	gtk_tree_view_append_column (GTK_TREE_VIEW (aod_data->aod_treeview),
710 				     column);
711 
712 	aod_update_option_list (aod_data);
713 
714 	/* Run */
715 
716 	gtk_window_set_transient_for (GTK_WINDOW (aod_data->dialog),
717 				      GTK_WINDOW (data->dialog));
718 	gtk_window_set_modal (GTK_WINDOW (aod_data->dialog), TRUE);
719 	gtk_widget_show (aod_data->dialog);
720 }
721 
722 
723 static void
save_options_cb(GtkWidget * w,DialogData * data)724 save_options_cb (GtkWidget  *w,
725 		 DialogData *data)
726 {
727 	GFile *options_dir;
728 	GFile *options_file;
729 	char  *opt_filename;
730 
731 	options_dir = get_user_config_subdirectory (ADD_FOLDER_OPTIONS_DIR, TRUE);
732 	make_directory_tree (options_dir, 0700, NULL);
733 
734 	opt_filename = _gtk_request_dialog_run (
735 				GTK_WINDOW (data->dialog),
736 				GTK_DIALOG_MODAL,
737 				_("Save Options"),
738 				_("_Options Name:"),
739 				(data->last_options != NULL) ? data->last_options : "",
740 				1024,
741 				_("_Cancel"),
742 				_("_Save"));
743 	if (opt_filename == NULL)
744 		return;
745 
746 	options_file = g_file_get_child_for_display_name (options_dir, opt_filename, NULL);
747 	dlg_add_folder_save_current_options (data, options_file);
748 	dlg_add_folder_save_last_used_options (data, opt_filename);
749 
750 	g_free (opt_filename);
751 	g_object_unref (options_file);
752 	g_object_unref (options_dir);
753 }
754