]>
Commit | Line | Data |
---|---|---|
ad0a8c2d EB |
1 | /* |
2 | * viking -- GPS Data and Topo Analyzer, Explorer, and Manager | |
3 | * | |
4 | * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net> | |
6eb145f6 | 5 | * Copyright (C) 2011, Rob Norris <rw_norris@hotmail.com> |
ad0a8c2d EB |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | * | |
21 | */ | |
22 | ||
4c77d5e0 GB |
23 | #ifdef HAVE_CONFIG_H |
24 | #include "config.h" | |
25 | #endif | |
26 | ||
ad0a8c2d | 27 | #include <gtk/gtk.h> |
4c77d5e0 | 28 | #include <glib/gi18n.h> |
ad0a8c2d EB |
29 | |
30 | #include "vikfilelist.h" | |
ad0a8c2d EB |
31 | |
32 | struct _VikFileList { | |
33 | GtkVBox parent; | |
ad0a8c2d | 34 | GtkWidget *treeview; |
4c85a045 | 35 | GtkWidget *file_selector; |
ad0a8c2d EB |
36 | GtkTreeModel *model; |
37 | }; | |
38 | ||
39 | static void file_list_add ( VikFileList *vfl ) | |
40 | { | |
6e4a49aa MA |
41 | GSList *files = NULL; |
42 | GSList *fiter = NULL; | |
43 | ||
4c85a045 EB |
44 | if ( ! vfl->file_selector ) |
45 | { | |
46 | GtkWidget *win; | |
47 | g_assert ( (win = gtk_widget_get_toplevel(GTK_WIDGET(vfl))) ); | |
6e4a49aa MA |
48 | vfl->file_selector = gtk_file_chooser_dialog_new (_("Choose file(s)"), |
49 | GTK_WINDOW(win), | |
50 | GTK_FILE_CHOOSER_ACTION_OPEN, | |
51 | GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | |
52 | GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, | |
53 | NULL); | |
54 | gtk_file_chooser_set_select_multiple ( GTK_FILE_CHOOSER(vfl->file_selector), TRUE ); | |
4c85a045 EB |
55 | gtk_window_set_transient_for ( GTK_WINDOW(vfl->file_selector), GTK_WINDOW(win) ); |
56 | gtk_window_set_destroy_with_parent ( GTK_WINDOW(vfl->file_selector), TRUE ); | |
57 | } | |
58 | ||
6e4a49aa MA |
59 | if ( gtk_dialog_run ( GTK_DIALOG(vfl->file_selector) ) == GTK_RESPONSE_ACCEPT ) { |
60 | files = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER(vfl->file_selector) ); | |
61 | fiter = files; | |
4c85a045 | 62 | GtkTreeIter iter; |
6e4a49aa MA |
63 | while ( fiter ) { |
64 | gchar *file_name = fiter->data; | |
65 | ||
4c85a045 | 66 | gtk_list_store_append ( GTK_LIST_STORE(vfl->model), &iter ); |
6e4a49aa MA |
67 | gtk_list_store_set ( GTK_LIST_STORE(vfl->model), &iter, 0, file_name, -1 ); |
68 | ||
69 | g_free (file_name); | |
70 | ||
71 | fiter = g_slist_next (fiter); | |
4c85a045 | 72 | } |
6e4a49aa | 73 | g_slist_free (files); |
4c85a045 EB |
74 | } |
75 | gtk_widget_hide ( vfl->file_selector ); | |
ad0a8c2d EB |
76 | } |
77 | ||
6eb145f6 RN |
78 | |
79 | static GtkTreeRowReference** file_list_get_selected_refs (GtkTreeModel *model, | |
80 | GList *list) | |
81 | { | |
82 | GtkTreeRowReference **arr; | |
83 | GList *iter; | |
84 | ||
85 | arr = g_new (GtkTreeRowReference *, g_list_length (list) + 1); | |
86 | ||
87 | gint pos = 0; | |
88 | for (iter = g_list_first (list); iter != NULL; iter = g_list_next (iter)) { | |
89 | GtkTreePath *path = (GtkTreePath *)(iter->data); | |
90 | arr[pos] = gtk_tree_row_reference_new (model, path); | |
91 | pos++; | |
92 | } | |
93 | arr[pos] = NULL; | |
94 | ||
95 | return arr; | |
96 | } | |
97 | ||
98 | static void file_list_store_delete_refs (GtkTreeModel *model, | |
99 | GtkTreeRowReference * const *rrefs) | |
100 | { | |
101 | GtkTreePath *path; | |
102 | GtkTreeIter iter; | |
103 | ||
104 | gint rr; | |
105 | for ( rr = 0; rrefs[rr] != NULL; rr++ ) { | |
106 | path = gtk_tree_row_reference_get_path (rrefs[rr]); | |
107 | gtk_tree_model_get_iter (model, &iter, path); | |
108 | gtk_list_store_remove (GTK_LIST_STORE (model), &iter); | |
109 | } | |
110 | } | |
111 | ||
112 | ||
ad0a8c2d EB |
113 | static void file_list_del ( VikFileList *vfl ) |
114 | { | |
115 | GtkTreeSelection *ts = gtk_tree_view_get_selection (GTK_TREE_VIEW(vfl->treeview)); | |
6eb145f6 RN |
116 | GList *list = gtk_tree_selection_get_selected_rows ( ts, &(vfl->model) ); |
117 | ||
118 | // For multi delete need to store references to selected rows | |
119 | GtkTreeRowReference **rrefs = file_list_get_selected_refs ( vfl->model, list ); | |
120 | // And then delete each one individually as the path will have changed | |
121 | file_list_store_delete_refs ( vfl->model, rrefs ); | |
122 | ||
123 | // Cleanup | |
124 | g_list_foreach ( list, (GFunc) gtk_tree_path_free, NULL ); | |
125 | g_list_free ( list ); | |
126 | g_free (rrefs); | |
ad0a8c2d EB |
127 | } |
128 | ||
129 | GType vik_file_list_get_type (void) | |
130 | { | |
131 | static GType vs_type = 0; | |
132 | ||
133 | if (!vs_type) | |
134 | { | |
135 | static const GTypeInfo vs_info = | |
136 | { | |
137 | sizeof (VikFileListClass), | |
138 | NULL, /* base_init */ | |
139 | NULL, /* base_finalize */ | |
140 | NULL, /* class init */ | |
141 | NULL, /* class_finalize */ | |
142 | NULL, /* class_data */ | |
143 | sizeof (VikFileList), | |
144 | 0, | |
145 | NULL /* instance init */ | |
146 | }; | |
147 | vs_type = g_type_register_static ( GTK_TYPE_VBOX, "VikFileList", &vs_info, 0 ); | |
148 | } | |
149 | ||
150 | return vs_type; | |
151 | } | |
152 | ||
153 | GtkWidget *vik_file_list_new ( const gchar *title ) | |
154 | { | |
155 | GtkWidget *add_btn, *del_btn; | |
156 | GtkWidget *hbox, *scrolledwindow; | |
157 | VikFileList *vfl = VIK_FILE_LIST ( g_object_new ( VIK_FILE_LIST_TYPE, NULL ) ); | |
158 | ||
159 | GtkTreeViewColumn *column; | |
160 | ||
161 | vfl->model = GTK_TREE_MODEL ( gtk_list_store_new(1, G_TYPE_STRING) ); | |
162 | ||
163 | vfl->treeview = gtk_tree_view_new ( ); | |
164 | gtk_tree_view_set_model ( GTK_TREE_VIEW(vfl->treeview), vfl->model ); | |
165 | column = gtk_tree_view_column_new_with_attributes ( title, gtk_cell_renderer_text_new (), "text", 0, NULL); | |
166 | gtk_tree_view_append_column (GTK_TREE_VIEW (vfl->treeview), column); | |
167 | ||
6eb145f6 RN |
168 | gtk_tree_selection_set_mode ( gtk_tree_view_get_selection (GTK_TREE_VIEW(vfl->treeview)), GTK_SELECTION_MULTIPLE ); |
169 | ||
ad0a8c2d EB |
170 | gtk_widget_set_size_request ( vfl->treeview, 200, 100); |
171 | ||
4c77d5e0 GB |
172 | add_btn = gtk_button_new_with_label(_("Add...")); |
173 | del_btn = gtk_button_new_with_label(_("Delete")); | |
ad0a8c2d EB |
174 | |
175 | g_signal_connect_swapped ( G_OBJECT(add_btn), "clicked", G_CALLBACK(file_list_add), vfl ); | |
176 | g_signal_connect_swapped ( G_OBJECT(del_btn), "clicked", G_CALLBACK(file_list_del), vfl ); | |
177 | ||
178 | hbox = gtk_hbox_new(FALSE, 2); | |
179 | ||
180 | scrolledwindow = gtk_scrolled_window_new ( NULL, NULL ); | |
181 | gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); | |
182 | gtk_container_add ( GTK_CONTAINER(scrolledwindow), GTK_WIDGET(vfl->treeview) ); | |
183 | ||
184 | gtk_box_pack_start ( GTK_BOX(vfl), scrolledwindow, TRUE, TRUE, 3 ); | |
185 | ||
186 | ||
ad0a8c2d EB |
187 | gtk_box_pack_start ( GTK_BOX(hbox), add_btn, TRUE, TRUE, 3 ); |
188 | gtk_box_pack_start ( GTK_BOX(hbox), del_btn, TRUE, TRUE, 3 ); | |
189 | gtk_box_pack_start ( GTK_BOX(vfl), hbox, FALSE, FALSE, 3 ); | |
190 | gtk_widget_show_all(GTK_WIDGET(vfl)); | |
191 | ||
4c85a045 | 192 | vfl->file_selector = NULL; |
ad0a8c2d EB |
193 | |
194 | return GTK_WIDGET(vfl); | |
195 | } | |
196 | ||
197 | static gboolean get_file_name(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, GList **list) | |
198 | { | |
199 | gchar *str; | |
200 | gtk_tree_model_get ( model, iter, 0, &str, -1 ); | |
4c77d5e0 | 201 | g_debug ("%s: %s", __FUNCTION__, str); |
ad0a8c2d EB |
202 | (*list) = g_list_append((*list), g_strdup(str)); |
203 | return FALSE; | |
204 | } | |
205 | ||
206 | GList *vik_file_list_get_files ( VikFileList *vfl ) | |
207 | { | |
208 | GList *list = NULL; | |
209 | gtk_tree_model_foreach (vfl->model, (GtkTreeModelForeachFunc) get_file_name, &list); | |
210 | return list; | |
211 | } | |
212 | ||
213 | void vik_file_list_set_files ( VikFileList *vfl, GList *files ) | |
214 | { | |
215 | while (files) { | |
216 | GtkTreeIter iter; | |
217 | gtk_list_store_append ( GTK_LIST_STORE(vfl->model), &iter ); | |
218 | gtk_list_store_set ( GTK_LIST_STORE(vfl->model), &iter, 0, files->data, -1 ); | |
219 | files = files->next; | |
220 | } | |
221 | } |