Mercurial > geeqie
annotate src/view_dir_tree.c @ 380:5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
data.
Specific data is now in ViewDirInfoList and ViewDirInfoTree.
Type of directory view can be specified with enum DirViewType.
This is saved to rc file as layout.dir_view_type, which replace
layout.view_as_tree.
Code was modified to reflect these changes.
This is a first to move to merge common code of view_dir_list.c
and view_dir_tree.c and ease the introduction of new types
of directory view.
author | zas_ |
---|---|
date | Wed, 16 Apr 2008 14:45:22 +0000 |
parents | 673d1eb5af73 |
children | eceeced4cbb9 |
rev | line source |
---|---|
9 | 1 /* |
196 | 2 * Geeqie |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
3 * (C) 2006 John Ellis |
9 | 4 * |
5 * Author: John Ellis | |
6 * | |
7 * This software is released under the GNU General Public License (GNU GPL). | |
8 * Please read the included file COPYING for more information. | |
9 * This software comes with no warranty of any kind, use at your own risk! | |
10 */ | |
11 | |
281 | 12 #include "main.h" |
9 | 13 #include "view_dir_tree.h" |
14 | |
15 | |
16 #include "dnd.h" | |
17 #include "dupe.h" | |
18 #include "filelist.h" | |
19 #include "layout.h" | |
20 #include "layout_image.h" | |
21 #include "layout_util.h" | |
22 #include "utilops.h" | |
23 #include "ui_bookmark.h" | |
24 #include "ui_fileops.h" | |
25 #include "ui_menu.h" | |
26 #include "ui_tree_edit.h" | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
27 #include "view_dir.h" |
9 | 28 |
29 #include <gdk/gdkkeysyms.h> /* for keyboard values */ | |
30 | |
31 | |
32 #define VDTREE_INDENT 14 | |
33 #define VDTREE_PAD 4 | |
34 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
35 #define VDTREE_INFO(_vd_, _part_) (((ViewDirInfoTree *)(_vd_->info))->_part_) |
9 | 36 |
37 | |
38 typedef struct _PathData PathData; | |
39 struct _PathData | |
40 { | |
41 gchar *name; | |
42 FileData *node; | |
43 }; | |
44 | |
45 typedef struct _NodeData NodeData; | |
46 struct _NodeData | |
47 { | |
48 FileData *fd; | |
49 gint expanded; | |
50 time_t last_update; | |
51 }; | |
52 | |
53 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
54 static gint vdtree_populate_path_by_iter(ViewDir *vdt, GtkTreeIter *iter, gint force, const gchar *target_path); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
55 static FileData *vdtree_populate_path(ViewDir *vdt, const gchar *path, gint expand, gint force); |
9 | 56 |
57 | |
58 /* | |
59 *---------------------------------------------------------------------------- | |
60 * utils | |
61 *---------------------------------------------------------------------------- | |
62 */ | |
63 | |
64 static void set_cursor(GtkWidget *widget, GdkCursorType cursor_type) | |
65 { | |
66 GdkCursor *cursor = NULL; | |
67 | |
68 if (!widget || !widget->window) return; | |
69 | |
70 if (cursor_type > -1) cursor = gdk_cursor_new (cursor_type); | |
71 gdk_window_set_cursor (widget->window, cursor); | |
72 if (cursor) gdk_cursor_unref(cursor); | |
73 gdk_flush(); | |
74 } | |
75 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
76 static void vdtree_busy_push(ViewDir *vdt) |
9 | 77 { |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
78 if (VDTREE_INFO(vdt, busy_ref) == 0) set_cursor(vdt->view, GDK_WATCH); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
79 VDTREE_INFO(vdt, busy_ref)++; |
9 | 80 } |
81 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
82 static void vdtree_busy_pop(ViewDir *vdt) |
9 | 83 { |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
84 if (VDTREE_INFO(vdt, busy_ref) == 1) set_cursor(vdt->view, -1); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
85 if (VDTREE_INFO(vdt, busy_ref) > 0) VDTREE_INFO(vdt, busy_ref)--; |
9 | 86 } |
87 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
88 static gint vdtree_find_row(ViewDir *vdt, FileData *fd, GtkTreeIter *iter, GtkTreeIter *parent) |
9 | 89 { |
90 GtkTreeModel *store; | |
91 gint valid; | |
92 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
93 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view)); |
9 | 94 if (parent) |
95 { | |
96 valid = gtk_tree_model_iter_children(store, iter, parent); | |
97 } | |
98 else | |
99 { | |
100 valid = gtk_tree_model_get_iter_first(store, iter); | |
101 } | |
102 while (valid) | |
103 { | |
104 NodeData *nd; | |
105 GtkTreeIter found; | |
106 | |
107 gtk_tree_model_get(GTK_TREE_MODEL(store), iter, DIR_COLUMN_POINTER, &nd, -1); | |
108 if (nd->fd == fd) return TRUE; | |
109 | |
110 if (vdtree_find_row(vdt, fd, &found, iter)) | |
111 { | |
112 memcpy(iter, &found, sizeof(found)); | |
113 return TRUE; | |
114 } | |
115 | |
116 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), iter); | |
117 } | |
118 | |
119 return FALSE; | |
120 } | |
121 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
122 static void vdtree_icon_set_by_iter(ViewDir *vdt, GtkTreeIter *iter, GdkPixbuf *pixbuf) |
9 | 123 { |
124 GtkTreeModel *store; | |
125 GdkPixbuf *old; | |
126 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
127 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view)); |
9 | 128 gtk_tree_model_get(store, iter, DIR_COLUMN_ICON, &old, -1); |
129 if (old != vdt->pf->deny) | |
130 { | |
131 gtk_tree_store_set(GTK_TREE_STORE(store), iter, DIR_COLUMN_ICON, pixbuf, -1); | |
132 } | |
133 } | |
134 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
135 static void vdtree_expand_by_iter(ViewDir *vdt, GtkTreeIter *iter, gint expand) |
9 | 136 { |
137 GtkTreeModel *store; | |
138 GtkTreePath *tpath; | |
139 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
140 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view)); |
9 | 141 tpath = gtk_tree_model_get_path(store, iter); |
142 if (expand) | |
143 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
144 gtk_tree_view_expand_row(GTK_TREE_VIEW(vdt->view), tpath, FALSE); |
9 | 145 vdtree_icon_set_by_iter(vdt, iter, vdt->pf->open); |
146 } | |
147 else | |
148 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
149 gtk_tree_view_collapse_row(GTK_TREE_VIEW(vdt->view), tpath); |
9 | 150 } |
151 gtk_tree_path_free(tpath); | |
152 } | |
153 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
154 static void vdtree_expand_by_data(ViewDir *vdt, FileData *fd, gint expand) |
9 | 155 { |
156 GtkTreeIter iter; | |
157 | |
158 if (vdtree_find_row(vdt, fd, &iter, NULL)) | |
159 { | |
160 vdtree_expand_by_iter(vdt, &iter, expand); | |
161 } | |
162 } | |
163 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
164 static void vdtree_color_set(ViewDir *vdt, FileData *fd, gint color_set) |
9 | 165 { |
166 GtkTreeModel *store; | |
167 GtkTreeIter iter; | |
168 | |
169 if (!vdtree_find_row(vdt, fd, &iter, NULL)) return; | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
170 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view)); |
9 | 171 gtk_tree_store_set(GTK_TREE_STORE(store), &iter, DIR_COLUMN_COLOR, color_set, -1); |
172 } | |
173 | |
174 static gint vdtree_rename_row_cb(TreeEditData *td, const gchar *old, const gchar *new, gpointer data) | |
175 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
176 ViewDir *vdt = data; |
9 | 177 GtkTreeModel *store; |
178 GtkTreeIter iter; | |
179 NodeData *nd; | |
180 gchar *old_path; | |
181 gchar *new_path; | |
182 gchar *base; | |
183 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
184 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view)); |
9 | 185 if (!gtk_tree_model_get_iter(store, &iter, td->path)) return FALSE; |
186 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &nd, -1); | |
187 if (!nd) return FALSE; | |
188 | |
189 old_path = g_strdup(nd->fd->path); | |
190 | |
191 base = remove_level_from_path(old_path); | |
192 new_path = concat_dir_and_file(base, new); | |
193 g_free(base); | |
194 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
195 if (file_util_rename_dir(nd->fd, new_path, vdt->view)) |
9 | 196 { |
197 vdtree_populate_path(vdt, new_path, TRUE, TRUE); | |
198 | |
199 if (vdt->layout && strcmp(vdt->path, old_path) == 0) | |
200 { | |
201 layout_set_path(vdt->layout, new_path); | |
202 } | |
203 } | |
204 | |
205 g_free(old_path); | |
206 g_free(new_path); | |
207 | |
208 return FALSE; | |
209 } | |
210 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
211 static void vdtree_rename_by_data(ViewDir *vdt, FileData *fd) |
9 | 212 { |
213 GtkTreeModel *store; | |
214 GtkTreePath *tpath; | |
215 GtkTreeIter iter; | |
216 | |
217 if (!fd || | |
218 !vdtree_find_row(vdt, fd, &iter, NULL)) return; | |
219 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
220 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view)); |
9 | 221 tpath = gtk_tree_model_get_path(store, &iter); |
222 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
223 tree_edit_by_path(GTK_TREE_VIEW(vdt->view), tpath, 0, fd->name, |
9 | 224 vdtree_rename_row_cb, vdt); |
225 gtk_tree_path_free(tpath); | |
226 } | |
227 | |
228 static void vdtree_node_free(NodeData *nd) | |
229 { | |
230 if (!nd) return; | |
231 | |
138 | 232 file_data_unref(nd->fd); |
9 | 233 g_free(nd); |
234 } | |
235 | |
236 static void vdtree_popup_destroy_cb(GtkWidget *widget, gpointer data) | |
237 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
238 ViewDir *vdt = data; |
9 | 239 |
240 vdtree_color_set(vdt, vdt->click_fd, FALSE); | |
241 vdt->click_fd = NULL; | |
242 vdt->popup = NULL; | |
243 | |
244 vdtree_color_set(vdt, vdt->drop_fd, FALSE); | |
138 | 245 filelist_free(vdt->drop_list); |
9 | 246 vdt->drop_list = NULL; |
247 vdt->drop_fd = NULL; | |
248 } | |
249 | |
250 /* | |
251 *----------------------------------------------------------------------------- | |
252 * drop menu (from dnd) | |
253 *----------------------------------------------------------------------------- | |
254 */ | |
255 | |
256 static void vdtree_drop_menu_copy_cb(GtkWidget *widget, gpointer data) | |
257 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
258 ViewDir *vdt = data; |
9 | 259 const gchar *path; |
260 GList *list; | |
261 | |
262 if (!vdt->drop_fd) return; | |
263 | |
264 path = vdt->drop_fd->path; | |
265 list = vdt->drop_list; | |
266 | |
267 vdt->drop_list = NULL; | |
268 | |
269 file_util_copy_simple(list, path); | |
270 } | |
271 | |
272 static void vdtree_drop_menu_move_cb(GtkWidget *widget, gpointer data) | |
273 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
274 ViewDir *vdt = data; |
9 | 275 const gchar *path; |
276 GList *list; | |
277 | |
278 if (!vdt->drop_fd) return; | |
279 | |
280 path = vdt->drop_fd->path; | |
281 list = vdt->drop_list; | |
282 | |
283 vdt->drop_list = NULL; | |
284 | |
285 file_util_move_simple(list, path); | |
286 } | |
287 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
288 static GtkWidget *vdtree_drop_menu(ViewDir *vdt, gint active) |
9 | 289 { |
290 GtkWidget *menu; | |
291 | |
292 menu = popup_menu_short_lived(); | |
293 g_signal_connect(G_OBJECT(menu), "destroy", | |
294 G_CALLBACK(vdtree_popup_destroy_cb), vdt); | |
295 | |
296 menu_item_add_stock_sensitive(menu, _("_Copy"), GTK_STOCK_COPY, active, | |
297 G_CALLBACK(vdtree_drop_menu_copy_cb), vdt); | |
298 menu_item_add_sensitive(menu, _("_Move"), active, G_CALLBACK(vdtree_drop_menu_move_cb), vdt); | |
299 | |
300 menu_item_add_divider(menu); | |
301 menu_item_add_stock(menu, _("Cancel"), GTK_STOCK_CANCEL, NULL, vdt); | |
302 | |
303 return menu; | |
304 } | |
305 | |
306 /* | |
307 *----------------------------------------------------------------------------- | |
308 * pop-up menu | |
309 *----------------------------------------------------------------------------- | |
310 */ | |
311 | |
312 static void vdtree_pop_menu_up_cb(GtkWidget *widget, gpointer data) | |
313 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
314 ViewDir *vdt = data; |
9 | 315 gchar *path; |
316 | |
317 if (!vdt->path || strcmp(vdt->path, "/") == 0) return; | |
318 path = remove_level_from_path(vdt->path); | |
319 | |
320 if (vdt->select_func) | |
321 { | |
322 vdt->select_func(vdt, path, vdt->select_data); | |
323 } | |
324 | |
325 g_free(path); | |
326 } | |
327 | |
328 static void vdtree_pop_menu_slide_cb(GtkWidget *widget, gpointer data) | |
329 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
330 ViewDir *vdt = data; |
9 | 331 gchar *path; |
332 | |
333 if (!vdt->layout) return; | |
334 | |
335 if (!vdt->click_fd) return; | |
138 | 336 path = vdt->click_fd->path; |
9 | 337 |
338 layout_set_path(vdt->layout, path); | |
339 layout_select_none(vdt->layout); | |
340 layout_image_slideshow_stop(vdt->layout); | |
341 layout_image_slideshow_start(vdt->layout); | |
342 } | |
343 | |
344 static void vdtree_pop_menu_slide_rec_cb(GtkWidget *widget, gpointer data) | |
345 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
346 ViewDir *vdt = data; |
9 | 347 gchar *path; |
348 GList *list; | |
349 | |
350 if (!vdt->layout) return; | |
351 | |
352 if (!vdt->click_fd) return; | |
138 | 353 path = vdt->click_fd->path; |
9 | 354 |
138 | 355 list = filelist_recursive(path); |
9 | 356 |
357 layout_image_slideshow_stop(vdt->layout); | |
358 layout_image_slideshow_start_from_list(vdt->layout, list); | |
359 } | |
360 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
361 static void vdtree_pop_menu_dupe(ViewDir *vdt, gint recursive) |
9 | 362 { |
363 DupeWindow *dw; | |
364 GList *list = NULL; | |
365 | |
366 if (!vdt->click_fd) return; | |
367 | |
368 if (recursive) | |
369 { | |
138 | 370 list = g_list_append(list, file_data_ref(vdt->click_fd)); |
9 | 371 } |
372 else | |
373 { | |
138 | 374 filelist_read(vdt->click_fd->path, &list, NULL); |
375 list = filelist_filter(list, FALSE); | |
9 | 376 } |
377 | |
378 dw = dupe_window_new(DUPE_MATCH_NAME); | |
379 dupe_window_add_files(dw, list, recursive); | |
380 | |
138 | 381 filelist_free(list); |
9 | 382 } |
383 | |
384 static void vdtree_pop_menu_dupe_cb(GtkWidget *widget, gpointer data) | |
385 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
386 ViewDir *vdt = data; |
9 | 387 vdtree_pop_menu_dupe(vdt, FALSE); |
388 } | |
389 | |
390 static void vdtree_pop_menu_dupe_rec_cb(GtkWidget *widget, gpointer data) | |
391 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
392 ViewDir *vdt = data; |
9 | 393 vdtree_pop_menu_dupe(vdt, TRUE); |
394 } | |
395 | |
396 static void vdtree_pop_menu_new_cb(GtkWidget *widget, gpointer data) | |
397 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
398 ViewDir *vdt = data; |
9 | 399 const gchar *path; |
400 gchar *new_path; | |
401 gchar *buf; | |
402 | |
403 if (!vdt->click_fd) return; | |
404 path = vdt->click_fd->path; | |
405 | |
406 buf = concat_dir_and_file(path, _("new_folder")); | |
407 new_path = unique_filename(buf, NULL, NULL, FALSE); | |
408 g_free(buf); | |
409 if (!new_path) return; | |
410 | |
411 if (!mkdir_utf8(new_path, 0755)) | |
412 { | |
413 gchar *text; | |
414 | |
415 text = g_strdup_printf(_("Unable to create folder:\n%s"), new_path); | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
416 file_util_warning_dialog(_("Error creating folder"), text, GTK_STOCK_DIALOG_ERROR, vdt->view); |
9 | 417 g_free(text); |
418 } | |
419 else | |
420 { | |
421 FileData *fd; | |
422 | |
423 fd = vdtree_populate_path(vdt, new_path, TRUE, TRUE); | |
424 | |
425 vdtree_rename_by_data(vdt, fd); | |
426 } | |
427 | |
428 g_free(new_path); | |
429 } | |
430 | |
431 static void vdtree_pop_menu_rename_cb(GtkWidget *widget, gpointer data) | |
432 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
433 ViewDir *vdt = data; |
9 | 434 |
435 vdtree_rename_by_data(vdt, vdt->click_fd); | |
436 } | |
437 | |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
438 static void vdtree_pop_menu_delete_cb(GtkWidget *widget, gpointer data) |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
439 { |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
440 ViewDir *vdt = data; |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
441 |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
442 if (!vdt->click_fd) return; |
138 | 443 file_util_delete_dir(vdt->click_fd, vdt->widget); |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
444 } |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
445 |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
446 static void vdtree_pop_menu_dir_view_as_cb(GtkWidget *widget, gpointer data) |
9 | 447 { |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
448 ViewDir *vdt = data; |
9 | 449 |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
450 if (vdt->layout) layout_views_set(vdt->layout, DIRVIEW_LIST, vdt->layout->icon_view); |
9 | 451 } |
452 | |
453 static void vdtree_pop_menu_refresh_cb(GtkWidget *widget, gpointer data) | |
454 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
455 ViewDir *vdt = data; |
9 | 456 |
457 if (vdt->layout) layout_refresh(vdt->layout); | |
458 } | |
459 | |
356 | 460 static void vdtree_toggle_show_hidden_files_cb(GtkWidget *widget, gpointer data) |
355
0b82646e977f
Let toggle the visibility of hidden files from directories list
zas_
parents:
332
diff
changeset
|
461 { |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
462 ViewDir *vdt = data; |
355
0b82646e977f
Let toggle the visibility of hidden files from directories list
zas_
parents:
332
diff
changeset
|
463 |
356 | 464 options->file_filter.show_hidden_files = !options->file_filter.show_hidden_files; |
355
0b82646e977f
Let toggle the visibility of hidden files from directories list
zas_
parents:
332
diff
changeset
|
465 if (vdt->layout) layout_refresh(vdt->layout); |
0b82646e977f
Let toggle the visibility of hidden files from directories list
zas_
parents:
332
diff
changeset
|
466 } |
0b82646e977f
Let toggle the visibility of hidden files from directories list
zas_
parents:
332
diff
changeset
|
467 |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
468 static GtkWidget *vdtree_pop_menu(ViewDir *vdt, FileData *fd) |
9 | 469 { |
470 GtkWidget *menu; | |
471 gint active; | |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
472 gint parent_active = FALSE; |
9 | 473 |
474 active = (fd != NULL); | |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
475 if (fd) |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
476 { |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
477 gchar *parent; |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
478 |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
479 parent = remove_level_from_path(fd->path); |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
480 parent_active = access_file(parent, W_OK | X_OK); |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
481 g_free(parent); |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
482 } |
9 | 483 |
484 menu = popup_menu_short_lived(); | |
485 g_signal_connect(G_OBJECT(menu), "destroy", | |
486 G_CALLBACK(vdtree_popup_destroy_cb), vdt); | |
487 | |
488 menu_item_add_stock_sensitive(menu, _("_Up to parent"), GTK_STOCK_GO_UP, | |
489 (vdt->path && strcmp(vdt->path, "/") != 0), | |
490 G_CALLBACK(vdtree_pop_menu_up_cb), vdt); | |
491 | |
492 menu_item_add_divider(menu); | |
493 menu_item_add_sensitive(menu, _("_Slideshow"), active, | |
494 G_CALLBACK(vdtree_pop_menu_slide_cb), vdt); | |
495 menu_item_add_sensitive(menu, _("Slideshow recursive"), active, | |
496 G_CALLBACK(vdtree_pop_menu_slide_rec_cb), vdt); | |
497 | |
498 menu_item_add_divider(menu); | |
499 menu_item_add_stock_sensitive(menu, _("Find _duplicates..."), GTK_STOCK_FIND, active, | |
500 G_CALLBACK(vdtree_pop_menu_dupe_cb), vdt); | |
501 menu_item_add_stock_sensitive(menu, _("Find duplicates recursive..."), GTK_STOCK_FIND, active, | |
502 G_CALLBACK(vdtree_pop_menu_dupe_rec_cb), vdt); | |
503 | |
504 menu_item_add_divider(menu); | |
505 | |
506 active = (fd && | |
507 access_file(fd->path, W_OK | X_OK)); | |
508 menu_item_add_sensitive(menu, _("_New folder..."), active, | |
509 G_CALLBACK(vdtree_pop_menu_new_cb), vdt); | |
510 | |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
511 menu_item_add_sensitive(menu, _("_Rename..."), parent_active, |
9 | 512 G_CALLBACK(vdtree_pop_menu_rename_cb), vdt); |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
513 menu_item_add_stock_sensitive(menu, _("_Delete..."), GTK_STOCK_DELETE, parent_active, |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
514 G_CALLBACK(vdtree_pop_menu_delete_cb), vdt); |
9 | 515 |
516 menu_item_add_divider(menu); | |
517 menu_item_add_check(menu, _("View as _tree"), TRUE, | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
518 G_CALLBACK(vdtree_pop_menu_dir_view_as_cb), vdt); |
356 | 519 menu_item_add_check(menu, _("Show _hidden files"), options->file_filter.show_hidden_files, |
520 G_CALLBACK(vdtree_toggle_show_hidden_files_cb), vdt); | |
355
0b82646e977f
Let toggle the visibility of hidden files from directories list
zas_
parents:
332
diff
changeset
|
521 |
9 | 522 menu_item_add_stock(menu, _("Re_fresh"), GTK_STOCK_REFRESH, |
523 G_CALLBACK(vdtree_pop_menu_refresh_cb), vdt); | |
524 | |
525 return menu; | |
526 } | |
527 | |
528 /* | |
529 *---------------------------------------------------------------------------- | |
530 * dnd | |
531 *---------------------------------------------------------------------------- | |
532 */ | |
533 | |
534 static GtkTargetEntry vdtree_dnd_drop_types[] = { | |
535 { "text/uri-list", 0, TARGET_URI_LIST } | |
536 }; | |
537 static gint vdtree_dnd_drop_types_count = 1; | |
538 | |
539 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
540 static void vdtree_dest_set(ViewDir *vdt, gint enable) |
9 | 541 { |
542 if (enable) | |
543 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
544 gtk_drag_dest_set(vdt->view, |
9 | 545 GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, |
546 vdtree_dnd_drop_types, vdtree_dnd_drop_types_count, | |
547 GDK_ACTION_MOVE | GDK_ACTION_COPY); | |
548 } | |
549 else | |
550 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
551 gtk_drag_dest_unset(vdt->view); |
9 | 552 } |
553 } | |
554 | |
555 static void vdtree_dnd_get(GtkWidget *widget, GdkDragContext *context, | |
556 GtkSelectionData *selection_data, guint info, | |
557 guint time, gpointer data) | |
558 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
559 ViewDir *vdt = data; |
9 | 560 GList *list; |
561 gchar *uri_text = NULL; | |
562 gint length = 0; | |
563 | |
564 if (!vdt->click_fd) return; | |
565 | |
566 switch (info) | |
567 { | |
568 case TARGET_URI_LIST: | |
569 case TARGET_TEXT_PLAIN: | |
138 | 570 list = g_list_prepend(NULL, vdt->click_fd); |
571 uri_text = uri_text_from_filelist(list, &length, (info == TARGET_TEXT_PLAIN)); | |
9 | 572 g_list_free(list); |
573 break; | |
574 } | |
575 | |
576 if (uri_text) | |
577 { | |
578 gtk_selection_data_set(selection_data, selection_data->target, | |
64
04ff0df3ad2f
Mon Aug 15 17:13:57 2005 John Ellis <johne@verizon.net>
gqview
parents:
63
diff
changeset
|
579 8, (guchar *)uri_text, length); |
9 | 580 g_free(uri_text); |
581 } | |
582 } | |
583 | |
584 static void vdtree_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data) | |
585 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
586 ViewDir *vdt = data; |
9 | 587 |
588 vdtree_color_set(vdt, vdt->click_fd, TRUE); | |
589 vdtree_dest_set(vdt, FALSE); | |
590 } | |
591 | |
592 static void vdtree_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer data) | |
593 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
594 ViewDir *vdt = data; |
9 | 595 |
596 vdtree_color_set(vdt, vdt->click_fd, FALSE); | |
597 vdtree_dest_set(vdt, TRUE); | |
598 } | |
599 | |
600 static void vdtree_dnd_drop_receive(GtkWidget *widget, | |
601 GdkDragContext *context, gint x, gint y, | |
602 GtkSelectionData *selection_data, guint info, | |
603 guint time, gpointer data) | |
604 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
605 ViewDir *vdt = data; |
9 | 606 GtkTreePath *tpath; |
607 GtkTreeIter iter; | |
608 FileData *fd = NULL; | |
609 | |
610 vdt->click_fd = NULL; | |
611 | |
612 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), x, y, | |
613 &tpath, NULL, NULL, NULL)) | |
614 { | |
615 GtkTreeModel *store; | |
616 NodeData *nd; | |
617 | |
618 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
619 gtk_tree_model_get_iter(store, &iter, tpath); | |
620 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &nd, -1); | |
621 gtk_tree_path_free(tpath); | |
622 | |
623 fd = (nd) ? nd->fd : NULL; | |
624 } | |
625 | |
626 if (!fd) return; | |
627 | |
628 if (info == TARGET_URI_LIST) | |
629 { | |
630 GList *list; | |
631 gint active; | |
632 | |
138 | 633 list = uri_filelist_from_text((gchar *)selection_data->data, TRUE); |
9 | 634 if (!list) return; |
635 | |
636 active = access_file(fd->path, W_OK | X_OK); | |
637 | |
638 vdtree_color_set(vdt, fd, TRUE); | |
639 vdt->popup = vdtree_drop_menu(vdt, active); | |
640 gtk_menu_popup(GTK_MENU(vdt->popup), NULL, NULL, NULL, NULL, 0, time); | |
641 | |
642 vdt->drop_fd = fd; | |
643 vdt->drop_list = list; | |
644 } | |
645 } | |
646 | |
647 static gint vdtree_dnd_drop_expand_cb(gpointer data) | |
648 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
649 ViewDir *vdt = data; |
9 | 650 GtkTreeIter iter; |
651 | |
652 if (vdt->drop_fd && | |
653 vdtree_find_row(vdt, vdt->drop_fd, &iter, NULL)) | |
654 { | |
655 vdtree_populate_path_by_iter(vdt, &iter, FALSE, vdt->path); | |
656 vdtree_expand_by_data(vdt, vdt->drop_fd, TRUE); | |
657 } | |
658 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
659 VDTREE_INFO(vdt, drop_expand_id) = -1; |
9 | 660 return FALSE; |
661 } | |
662 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
663 static void vdtree_dnd_drop_expand_cancel(ViewDir *vdt) |
9 | 664 { |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
665 if (VDTREE_INFO(vdt, drop_expand_id) != -1) g_source_remove(VDTREE_INFO(vdt, drop_expand_id)); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
666 VDTREE_INFO(vdt, drop_expand_id) = -1; |
9 | 667 } |
668 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
669 static void vdtree_dnd_drop_expand(ViewDir *vdt) |
9 | 670 { |
671 vdtree_dnd_drop_expand_cancel(vdt); | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
672 VDTREE_INFO(vdt, drop_expand_id) = g_timeout_add(1000, vdtree_dnd_drop_expand_cb, vdt); |
9 | 673 } |
674 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
675 static void vdtree_drop_update(ViewDir *vdt, gint x, gint y) |
9 | 676 { |
677 GtkTreePath *tpath; | |
678 GtkTreeIter iter; | |
679 FileData *fd = NULL; | |
680 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
681 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vdt->view), x, y, |
9 | 682 &tpath, NULL, NULL, NULL)) |
683 { | |
684 GtkTreeModel *store; | |
685 NodeData *nd; | |
686 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
687 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view)); |
9 | 688 gtk_tree_model_get_iter(store, &iter, tpath); |
689 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &nd, -1); | |
690 gtk_tree_path_free(tpath); | |
691 | |
692 fd = (nd) ? nd->fd : NULL; | |
693 } | |
694 | |
695 if (fd != vdt->drop_fd) | |
696 { | |
697 vdtree_color_set(vdt, vdt->drop_fd, FALSE); | |
698 vdtree_color_set(vdt, fd, TRUE); | |
699 if (fd) vdtree_dnd_drop_expand(vdt); | |
700 } | |
701 | |
702 vdt->drop_fd = fd; | |
703 } | |
704 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
705 static void vdtree_dnd_drop_scroll_cancel(ViewDir *vdt) |
9 | 706 { |
707 if (vdt->drop_scroll_id != -1) g_source_remove(vdt->drop_scroll_id); | |
708 vdt->drop_scroll_id = -1; | |
709 } | |
710 | |
711 static gint vdtree_auto_scroll_idle_cb(gpointer data) | |
712 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
713 ViewDir *vdt = data; |
9 | 714 |
715 if (vdt->drop_fd) | |
716 { | |
717 GdkWindow *window; | |
718 gint x, y; | |
719 gint w, h; | |
720 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
721 window = vdt->view->window; |
9 | 722 gdk_window_get_pointer(window, &x, &y, NULL); |
723 gdk_drawable_get_size(window, &w, &h); | |
724 if (x >= 0 && x < w && y >= 0 && y < h) | |
725 { | |
726 vdtree_drop_update(vdt, x, y); | |
727 } | |
728 } | |
729 | |
730 vdt->drop_scroll_id = -1; | |
731 return FALSE; | |
732 } | |
733 | |
734 static gint vdtree_auto_scroll_notify_cb(GtkWidget *widget, gint x, gint y, gpointer data) | |
735 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
736 ViewDir *vdt = data; |
9 | 737 |
738 if (!vdt->drop_fd || vdt->drop_list) return FALSE; | |
739 | |
740 if (vdt->drop_scroll_id == -1) vdt->drop_scroll_id = g_idle_add(vdtree_auto_scroll_idle_cb, vdt); | |
741 | |
742 return TRUE; | |
743 } | |
744 | |
745 static gint vdtree_dnd_drop_motion(GtkWidget *widget, GdkDragContext *context, | |
746 gint x, gint y, guint time, gpointer data) | |
747 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
748 ViewDir *vdt = data; |
9 | 749 |
750 vdt->click_fd = NULL; | |
751 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
752 if (gtk_drag_get_source_widget(context) == vdt->view) |
9 | 753 { |
754 gdk_drag_status(context, 0, time); | |
755 return TRUE; | |
756 } | |
757 else | |
758 { | |
759 gdk_drag_status(context, context->suggested_action, time); | |
760 } | |
761 | |
762 vdtree_drop_update(vdt, x, y); | |
763 | |
764 if (vdt->drop_fd) | |
765 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
766 GtkAdjustment *adj = gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(vdt->view)); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
767 widget_auto_scroll_start(vdt->view, adj, -1, -1, vdtree_auto_scroll_notify_cb, vdt); |
9 | 768 } |
769 | |
770 return FALSE; | |
771 } | |
772 | |
773 static void vdtree_dnd_drop_leave(GtkWidget *widget, GdkDragContext *context, guint time, gpointer data) | |
774 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
775 ViewDir *vdt = data; |
9 | 776 |
777 if (vdt->drop_fd != vdt->click_fd) vdtree_color_set(vdt, vdt->drop_fd, FALSE); | |
778 | |
779 vdt->drop_fd = NULL; | |
780 | |
781 vdtree_dnd_drop_expand_cancel(vdt); | |
782 } | |
783 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
784 static void vdtree_dnd_init(ViewDir *vdt) |
9 | 785 { |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
786 gtk_drag_source_set(vdt->view, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, |
9 | 787 dnd_file_drag_types, dnd_file_drag_types_count, |
788 GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK); | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
789 g_signal_connect(G_OBJECT(vdt->view), "drag_data_get", |
9 | 790 G_CALLBACK(vdtree_dnd_get), vdt); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
791 g_signal_connect(G_OBJECT(vdt->view), "drag_begin", |
9 | 792 G_CALLBACK(vdtree_dnd_begin), vdt); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
793 g_signal_connect(G_OBJECT(vdt->view), "drag_end", |
9 | 794 G_CALLBACK(vdtree_dnd_end), vdt); |
795 | |
796 vdtree_dest_set(vdt, TRUE); | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
797 g_signal_connect(G_OBJECT(vdt->view), "drag_data_received", |
9 | 798 G_CALLBACK(vdtree_dnd_drop_receive), vdt); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
799 g_signal_connect(G_OBJECT(vdt->view), "drag_motion", |
9 | 800 G_CALLBACK(vdtree_dnd_drop_motion), vdt); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
801 g_signal_connect(G_OBJECT(vdt->view), "drag_leave", |
9 | 802 G_CALLBACK(vdtree_dnd_drop_leave), vdt); |
803 } | |
804 | |
805 /* | |
806 *---------------------------------------------------------------------------- | |
807 * parts lists | |
808 *---------------------------------------------------------------------------- | |
809 */ | |
810 | |
811 static GList *parts_list(const gchar *path) | |
812 { | |
813 GList *list = NULL; | |
814 const gchar *strb, *strp; | |
815 gint l; | |
816 | |
817 strp = path; | |
818 | |
819 if (*strp != '/') return NULL; | |
820 | |
821 strp++; | |
822 strb = strp; | |
823 l = 0; | |
824 | |
825 while (*strp != '\0') | |
826 { | |
827 if (*strp == '/') | |
828 { | |
829 if (l > 0) list = g_list_prepend(list, g_strndup(strb, l)); | |
830 strp++; | |
831 strb = strp; | |
832 l = 0; | |
833 } | |
834 else | |
835 { | |
836 strp++; | |
837 l++; | |
838 } | |
839 } | |
840 if (l > 0) list = g_list_prepend(list, g_strndup(strb, l)); | |
841 | |
842 list = g_list_reverse(list); | |
843 | |
844 list = g_list_prepend(list, g_strdup("/")); | |
845 | |
846 return list; | |
847 } | |
848 | |
849 static void parts_list_free(GList *list) | |
850 { | |
851 GList *work = list; | |
852 while (work) | |
853 { | |
854 PathData *pd = work->data; | |
855 g_free(pd->name); | |
856 g_free(pd); | |
857 work = work->next; | |
858 } | |
859 | |
860 g_list_free(list); | |
861 } | |
862 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
863 static GList *parts_list_add_node_points(ViewDir *vdt, GList *list) |
9 | 864 { |
865 GList *work; | |
866 GtkTreeModel *store; | |
867 GtkTreeIter iter; | |
868 gint valid; | |
869 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
870 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view)); |
9 | 871 valid = gtk_tree_model_get_iter_first(store, &iter); |
872 | |
873 work = list; | |
874 while (work) | |
875 { | |
876 PathData *pd; | |
877 FileData *fd = NULL; | |
878 | |
879 pd = g_new0(PathData, 1); | |
880 pd->name = work->data; | |
881 | |
882 while (valid && !fd) | |
883 { | |
884 NodeData *nd; | |
885 | |
886 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &nd, -1); | |
887 if (strcmp(nd->fd->name, pd->name) == 0) | |
888 { | |
889 fd = nd->fd; | |
890 } | |
891 else | |
892 { | |
893 valid = gtk_tree_model_iter_next(store, &iter); | |
894 } | |
895 } | |
896 | |
897 pd->node = fd; | |
898 work->data = pd; | |
899 | |
900 if (fd) | |
901 { | |
902 GtkTreeIter parent; | |
903 memcpy(&parent, &iter, sizeof(parent)); | |
904 valid = gtk_tree_model_iter_children(store, &iter, &parent); | |
905 } | |
906 | |
907 work = work->next; | |
908 } | |
909 | |
910 return list; | |
911 } | |
912 | |
913 /* | |
914 *---------------------------------------------------------------------------- | |
915 * misc | |
916 *---------------------------------------------------------------------------- | |
917 */ | |
918 | |
919 #if 0 | |
920 static void vdtree_row_deleted_cb(GtkTreeModel *tree_model, GtkTreePath *tpath, gpointer data) | |
921 { | |
922 GtkTreeIter iter; | |
923 NodeData *nd; | |
924 | |
925 gtk_tree_model_get_iter(tree_model, &iter, tpath); | |
926 gtk_tree_model_get(tree_model, &iter, DIR_COLUMN_POINTER, &nd, -1); | |
927 | |
928 if (!nd) return; | |
929 | |
138 | 930 file_data_unref(nd->fd); |
9 | 931 g_free(nd); |
932 } | |
933 #endif | |
934 | |
935 /* | |
936 *---------------------------------------------------------------------------- | |
937 * node traversal, management | |
938 *---------------------------------------------------------------------------- | |
939 */ | |
940 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
941 static gint vdtree_find_iter_by_data(ViewDir *vdt, GtkTreeIter *parent, NodeData *nd, GtkTreeIter *iter) |
9 | 942 { |
943 GtkTreeModel *store; | |
944 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
945 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view)); |
9 | 946 if (!nd || !gtk_tree_model_iter_children(store, iter, parent)) return -1; |
947 do { | |
948 NodeData *cnd; | |
949 | |
950 gtk_tree_model_get(store, iter, DIR_COLUMN_POINTER, &cnd, -1); | |
951 if (cnd == nd) return TRUE; | |
952 } while (gtk_tree_model_iter_next(store, iter)); | |
953 | |
954 return FALSE; | |
955 } | |
956 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
957 static NodeData *vdtree_find_iter_by_name(ViewDir *vdt, GtkTreeIter *parent, const gchar *name, GtkTreeIter *iter) |
9 | 958 { |
959 GtkTreeModel *store; | |
960 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
961 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view)); |
9 | 962 if (!name || !gtk_tree_model_iter_children(store, iter, parent)) return NULL; |
963 do { | |
964 NodeData *nd; | |
965 | |
966 gtk_tree_model_get(store, iter, DIR_COLUMN_POINTER, &nd, -1); | |
967 if (nd && strcmp(nd->fd->name, name) == 0) return nd; | |
968 } while (gtk_tree_model_iter_next(store, iter)); | |
969 | |
970 return NULL; | |
971 } | |
972 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
973 static void vdtree_add_by_data(ViewDir *vdt, FileData *fd, GtkTreeIter *parent) |
9 | 974 { |
975 GtkTreeStore *store; | |
976 GtkTreeIter child; | |
977 NodeData *nd; | |
978 GdkPixbuf *pixbuf; | |
979 NodeData *end; | |
980 GtkTreeIter empty; | |
981 | |
982 if (!fd) return; | |
983 | |
984 if (access_file(fd->path, R_OK | X_OK)) | |
985 { | |
986 pixbuf = vdt->pf->close; | |
987 } | |
988 else | |
989 { | |
990 pixbuf = vdt->pf->deny; | |
991 } | |
992 | |
993 nd = g_new0(NodeData, 1); | |
994 nd->fd = fd; | |
995 nd->expanded = FALSE; | |
996 nd->last_update = time(NULL); | |
997 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
998 store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view))); |
9 | 999 gtk_tree_store_append(store, &child, parent); |
1000 gtk_tree_store_set(store, &child, DIR_COLUMN_POINTER, nd, | |
1001 DIR_COLUMN_ICON, pixbuf, | |
1002 DIR_COLUMN_NAME, nd->fd->name, | |
1003 DIR_COLUMN_COLOR, FALSE, -1); | |
1004 | |
1005 /* all nodes are created with an "empty" node, so that the expander is shown | |
1006 * this is removed when the child is populated */ | |
1007 end = g_new0(NodeData, 1); | |
138 | 1008 end->fd = file_data_new_simple(""); |
9 | 1009 end->expanded = TRUE; |
1010 | |
1011 gtk_tree_store_append(store, &empty, &child); | |
1012 gtk_tree_store_set(store, &empty, DIR_COLUMN_POINTER, end, | |
1013 DIR_COLUMN_NAME, "empty", -1); | |
1014 | |
1015 if (parent) | |
1016 { | |
1017 NodeData *pnd; | |
1018 GtkTreePath *tpath; | |
1019 | |
1020 gtk_tree_model_get(GTK_TREE_MODEL(store), parent, DIR_COLUMN_POINTER, &pnd, -1); | |
1021 tpath = gtk_tree_model_get_path(GTK_TREE_MODEL(store), parent); | |
320 | 1022 if (options->tree_descend_subdirs && |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1023 gtk_tree_view_row_expanded(GTK_TREE_VIEW(vdt->view), tpath) && |
9 | 1024 !nd->expanded) |
1025 { | |
1026 vdtree_populate_path_by_iter(vdt, &child, FALSE, vdt->path); | |
1027 } | |
1028 gtk_tree_path_free(tpath); | |
1029 } | |
1030 } | |
1031 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1032 static gint vdtree_populate_path_by_iter(ViewDir *vdt, GtkTreeIter *iter, gint force, const gchar *target_path) |
9 | 1033 { |
1034 GtkTreeModel *store; | |
1035 GList *list; | |
1036 GList *work; | |
1037 GList *old; | |
1038 time_t current_time; | |
1039 GtkTreeIter child; | |
1040 NodeData *nd; | |
1041 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1042 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view)); |
9 | 1043 gtk_tree_model_get(store, iter, DIR_COLUMN_POINTER, &nd, -1); |
1044 | |
1045 if (!nd) return FALSE; | |
1046 | |
1047 current_time = time(NULL); | |
1048 | |
1049 if (nd->expanded) | |
1050 { | |
1051 if (!force && current_time - nd->last_update < 10) return TRUE; | |
1052 if (!isdir(nd->fd->path)) | |
1053 { | |
1054 if (vdt->click_fd == nd->fd) vdt->click_fd = NULL; | |
1055 if (vdt->drop_fd == nd->fd) vdt->drop_fd = NULL; | |
1056 gtk_tree_store_remove(GTK_TREE_STORE(store), iter); | |
1057 vdtree_node_free(nd); | |
1058 return FALSE; | |
1059 } | |
1060 if (!force && filetime(nd->fd->path) == nd->fd->date) return TRUE; | |
1061 } | |
1062 | |
1063 vdtree_busy_push(vdt); | |
1064 | |
1065 list = NULL; | |
1066 filelist_read(nd->fd->path, NULL, &list); | |
1067 | |
1068 /* when hidden files are not enabled, and the user enters a hidden path, | |
1069 * allow the tree to display that path by specifically inserting the hidden entries | |
1070 */ | |
356 | 1071 if (!options->file_filter.show_hidden_files && |
9 | 1072 target_path && |
1073 strncmp(nd->fd->path, target_path, strlen(nd->fd->path)) == 0) | |
1074 { | |
1075 gint n; | |
1076 | |
1077 n = strlen(nd->fd->path); | |
1078 if (target_path[n] == '/' && target_path[n+1] == '.') | |
1079 { | |
1080 gchar *name8; | |
1081 struct stat sbuf; | |
1082 | |
1083 n++; | |
1084 | |
1085 while (target_path[n] != '\0' && target_path[n] != '/') n++; | |
1086 name8 = g_strndup(target_path, n); | |
1087 | |
1088 if (stat_utf8(name8, &sbuf)) | |
1089 { | |
145
8be2cc687304
fixed grouping sidecar files and made it configurable via config file
nadvornik
parents:
138
diff
changeset
|
1090 list = g_list_prepend(list, file_data_new_simple(name8)); |
9 | 1091 } |
1092 | |
1093 g_free(name8); | |
1094 } | |
1095 } | |
1096 | |
1097 old = NULL; | |
1098 if (gtk_tree_model_iter_children(store, &child, iter)) | |
1099 { | |
1100 do { | |
1101 NodeData *cnd; | |
1102 | |
1103 gtk_tree_model_get(store, &child, DIR_COLUMN_POINTER, &cnd, -1); | |
1104 old = g_list_prepend(old, cnd); | |
1105 } while (gtk_tree_model_iter_next(store, &child)); | |
1106 } | |
1107 | |
1108 work = list; | |
1109 while (work) | |
1110 { | |
1111 FileData *fd; | |
1112 | |
1113 fd = work->data; | |
1114 work = work->next; | |
1115 | |
1116 if (strcmp(fd->name, ".") == 0 || strcmp(fd->name, "..") == 0) | |
1117 { | |
138 | 1118 file_data_unref(fd); |
9 | 1119 } |
1120 else | |
1121 { | |
1122 NodeData *cnd; | |
1123 | |
1124 cnd = vdtree_find_iter_by_name(vdt, iter, fd->name, &child); | |
1125 if (cnd) | |
1126 { | |
1127 old = g_list_remove(old, cnd); | |
1128 if (cnd->expanded && cnd->fd->date != fd->date && | |
1129 vdtree_populate_path_by_iter(vdt, &child, FALSE, target_path)) | |
1130 { | |
1131 cnd->fd->size = fd->size; | |
1132 cnd->fd->date = fd->date; | |
1133 } | |
1134 | |
138 | 1135 file_data_unref(fd); |
9 | 1136 } |
1137 else | |
1138 { | |
1139 vdtree_add_by_data(vdt, fd, iter); | |
1140 } | |
1141 } | |
1142 } | |
1143 | |
1144 work = old; | |
1145 while (work) | |
1146 { | |
1147 NodeData *cnd = work->data; | |
1148 work = work->next; | |
1149 | |
1150 if (vdt->click_fd == cnd->fd) vdt->click_fd = NULL; | |
1151 if (vdt->drop_fd == cnd->fd) vdt->drop_fd = NULL; | |
1152 | |
1153 if (vdtree_find_iter_by_data(vdt, iter, cnd, &child)) | |
1154 { | |
1155 gtk_tree_store_remove(GTK_TREE_STORE(store), &child); | |
1156 vdtree_node_free(cnd); | |
1157 } | |
1158 } | |
1159 | |
1160 g_list_free(old); | |
1161 g_list_free(list); | |
1162 | |
1163 vdtree_busy_pop(vdt); | |
1164 | |
1165 nd->expanded = TRUE; | |
1166 nd->last_update = current_time; | |
1167 | |
1168 return TRUE; | |
1169 } | |
1170 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1171 static FileData *vdtree_populate_path(ViewDir *vdt, const gchar *path, gint expand, gint force) |
9 | 1172 { |
1173 GList *list; | |
1174 GList *work; | |
1175 FileData *fd = NULL; | |
1176 | |
1177 if (!path) return NULL; | |
1178 | |
1179 vdtree_busy_push(vdt); | |
1180 | |
1181 list = parts_list(path); | |
1182 list = parts_list_add_node_points(vdt, list); | |
1183 | |
1184 work = list; | |
1185 while (work) | |
1186 { | |
1187 PathData *pd = work->data; | |
1188 if (pd->node == NULL) | |
1189 { | |
1190 PathData *parent_pd; | |
1191 GtkTreeIter parent_iter; | |
1192 GtkTreeIter iter; | |
1193 NodeData *nd; | |
1194 | |
1195 if (work == list) | |
1196 { | |
1197 /* should not happen */ | |
1198 printf("vdtree warning, root node not found\n"); | |
1199 parts_list_free(list); | |
1200 vdtree_busy_pop(vdt); | |
1201 return NULL; | |
1202 } | |
1203 | |
1204 parent_pd = work->prev->data; | |
1205 | |
1206 if (!vdtree_find_row(vdt, parent_pd->node, &parent_iter, NULL) || | |
1207 !vdtree_populate_path_by_iter(vdt, &parent_iter, force, path) || | |
1208 (nd = vdtree_find_iter_by_name(vdt, &parent_iter, pd->name, &iter)) == NULL) | |
1209 { | |
1210 printf("vdtree warning, aborted at %s\n", parent_pd->name); | |
1211 parts_list_free(list); | |
1212 vdtree_busy_pop(vdt); | |
1213 return NULL; | |
1214 } | |
1215 | |
1216 pd->node = nd->fd; | |
1217 | |
1218 if (pd->node) | |
1219 { | |
1220 if (expand) | |
1221 { | |
1222 vdtree_expand_by_iter(vdt, &parent_iter, TRUE); | |
1223 vdtree_expand_by_iter(vdt, &iter, TRUE); | |
1224 } | |
1225 vdtree_populate_path_by_iter(vdt, &iter, force, path); | |
1226 } | |
1227 } | |
1228 else | |
1229 { | |
1230 GtkTreeIter iter; | |
1231 | |
1232 if (vdtree_find_row(vdt, pd->node, &iter, NULL)) | |
1233 { | |
1234 if (expand) vdtree_expand_by_iter(vdt, &iter, TRUE); | |
1235 vdtree_populate_path_by_iter(vdt, &iter, force, path); | |
1236 } | |
1237 } | |
1238 | |
1239 work = work->next; | |
1240 } | |
1241 | |
1242 work = g_list_last(list); | |
1243 if (work) | |
1244 { | |
1245 PathData *pd = work->data; | |
1246 fd = pd->node; | |
1247 } | |
1248 parts_list_free(list); | |
1249 | |
1250 vdtree_busy_pop(vdt); | |
1251 | |
1252 return fd; | |
1253 } | |
1254 | |
1255 /* | |
1256 *---------------------------------------------------------------------------- | |
1257 * access | |
1258 *---------------------------------------------------------------------------- | |
1259 */ | |
1260 | |
1261 static gint selection_is_ok = FALSE; | |
1262 | |
1263 static gboolean vdtree_select_cb(GtkTreeSelection *selection, GtkTreeModel *store, GtkTreePath *tpath, | |
1264 gboolean path_currently_selected, gpointer data) | |
1265 { | |
1266 return selection_is_ok; | |
1267 } | |
1268 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1269 static void vdtree_select_row(ViewDir *vdt, FileData *fd) |
9 | 1270 { |
1271 GtkTreeSelection *selection; | |
1272 GtkTreeIter iter; | |
1273 | |
1274 if (!vdtree_find_row(vdt, fd, &iter, NULL)) return; | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1275 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vdt->view)); |
9 | 1276 |
1277 /* hack, such that selection is only allowed to be changed from here */ | |
1278 selection_is_ok = TRUE; | |
1279 gtk_tree_selection_select_iter(selection, &iter); | |
1280 selection_is_ok = FALSE; | |
1281 | |
1282 if (!vdtree_populate_path_by_iter(vdt, &iter, FALSE, vdt->path)) return; | |
1283 | |
1284 vdtree_expand_by_iter(vdt, &iter, TRUE); | |
1285 | |
1286 if (fd && vdt->select_func) | |
1287 { | |
1288 vdt->select_func(vdt, fd->path, vdt->select_data); | |
1289 } | |
1290 } | |
1291 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1292 gint vdtree_set_path(ViewDir *vdt, const gchar *path) |
9 | 1293 { |
1294 FileData *fd; | |
1295 GtkTreeIter iter; | |
1296 | |
1297 if (!path) return FALSE; | |
1298 if (vdt->path && strcmp(path, vdt->path) == 0) return TRUE; | |
1299 | |
1300 g_free(vdt->path); | |
1301 vdt->path = g_strdup(path); | |
1302 | |
63
e29c291e106b
Mon Aug 15 16:35:15 2005 John Ellis <johne@verizon.net>
gqview
parents:
44
diff
changeset
|
1303 fd = vdtree_populate_path(vdt, vdt->path, TRUE, FALSE); |
9 | 1304 |
1305 if (!fd) return FALSE; | |
1306 | |
1307 if (vdtree_find_row(vdt, fd, &iter, NULL)) | |
1308 { | |
1309 GtkTreeModel *store; | |
1310 GtkTreePath *tpath; | |
1311 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1312 tree_view_row_make_visible(GTK_TREE_VIEW(vdt->view), &iter, TRUE); |
9 | 1313 |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1314 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view)); |
9 | 1315 tpath = gtk_tree_model_get_path(store, &iter); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1316 gtk_tree_view_set_cursor(GTK_TREE_VIEW(vdt->view), tpath, NULL, FALSE); |
9 | 1317 gtk_tree_path_free(tpath); |
1318 | |
1319 vdtree_select_row(vdt, fd); | |
1320 } | |
1321 | |
1322 return TRUE; | |
1323 } | |
1324 | |
1325 #if 0 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1326 const gchar *vdtree_get_path(ViewDir *vdt) |
9 | 1327 { |
1328 return vdt->path; | |
1329 } | |
1330 #endif | |
1331 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1332 void vdtree_refresh(ViewDir *vdt) |
9 | 1333 { |
1334 vdtree_populate_path(vdt, vdt->path, FALSE, TRUE); | |
1335 } | |
1336 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1337 const gchar *vdtree_row_get_path(ViewDir *vdt, gint row) |
9 | 1338 { |
1339 printf("FIXME: no get row path\n"); | |
1340 return NULL; | |
1341 } | |
1342 | |
1343 /* | |
1344 *---------------------------------------------------------------------------- | |
1345 * callbacks | |
1346 *---------------------------------------------------------------------------- | |
1347 */ | |
1348 | |
1349 static void vdtree_menu_position_cb(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data) | |
1350 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1351 ViewDir *vdt = data; |
9 | 1352 GtkTreeModel *store; |
1353 GtkTreeIter iter; | |
1354 GtkTreePath *tpath; | |
1355 gint cw, ch; | |
1356 | |
1357 if (vdtree_find_row(vdt, vdt->click_fd, &iter, NULL) < 0) return; | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1358 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view)); |
9 | 1359 tpath = gtk_tree_model_get_path(store, &iter); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1360 tree_view_get_cell_clamped(GTK_TREE_VIEW(vdt->view), tpath, 0, TRUE, x, y, &cw, &ch); |
9 | 1361 gtk_tree_path_free(tpath); |
1362 *y += ch; | |
1363 popup_menu_position_clamp(menu, x, y, 0); | |
1364 } | |
1365 | |
1366 static gint vdtree_press_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer data) | |
1367 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1368 ViewDir *vdt = data; |
9 | 1369 GtkTreePath *tpath; |
1370 GtkTreeIter iter; | |
1371 FileData *fd = NULL; | |
1372 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1373 gtk_tree_view_get_cursor(GTK_TREE_VIEW(vdt->view), &tpath, NULL); |
9 | 1374 if (tpath) |
1375 { | |
1376 GtkTreeModel *store; | |
1377 NodeData *nd; | |
1378 | |
1379 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
1380 gtk_tree_model_get_iter(store, &iter, tpath); | |
1381 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &nd, -1); | |
1382 | |
1383 gtk_tree_path_free(tpath); | |
1384 | |
1385 fd = (nd) ? nd->fd : NULL; | |
1386 } | |
1387 | |
1388 switch (event->keyval) | |
1389 { | |
1390 case GDK_Menu: | |
1391 vdt->click_fd = fd; | |
1392 vdtree_color_set(vdt, vdt->click_fd, TRUE); | |
1393 | |
1394 vdt->popup = vdtree_pop_menu(vdt, vdt->click_fd); | |
1395 gtk_menu_popup(GTK_MENU(vdt->popup), NULL, NULL, vdtree_menu_position_cb, vdt, 0, GDK_CURRENT_TIME); | |
1396 | |
1397 return TRUE; | |
1398 break; | |
1399 case GDK_plus: | |
1400 case GDK_Right: | |
1401 case GDK_KP_Add: | |
1402 if (fd) | |
1403 { | |
1404 vdtree_populate_path_by_iter(vdt, &iter, FALSE, vdt->path); | |
1405 vdtree_icon_set_by_iter(vdt, &iter, vdt->pf->open); | |
1406 } | |
1407 break; | |
1408 } | |
1409 | |
1410 return FALSE; | |
1411 } | |
1412 | |
1413 static gint vdtree_clicked_on_expander(GtkTreeView *treeview, GtkTreePath *tpath, | |
1414 GtkTreeViewColumn *column, gint x, gint y, gint *left_of_expander) | |
1415 { | |
1416 gint depth; | |
1417 gint size; | |
1418 gint sep; | |
1419 gint exp_width; | |
1420 | |
1421 if (column != gtk_tree_view_get_expander_column(treeview)) return FALSE; | |
1422 | |
1423 gtk_widget_style_get(GTK_WIDGET(treeview), "expander-size", &size, "horizontal-separator", &sep, NULL); | |
1424 depth = gtk_tree_path_get_depth(tpath); | |
1425 | |
1426 exp_width = sep + size + sep; | |
1427 | |
1428 if (x <= depth * exp_width) | |
1429 { | |
1430 if (left_of_expander) *left_of_expander = !(x >= (depth - 1) * exp_width); | |
1431 return TRUE; | |
1432 } | |
1433 | |
1434 return FALSE; | |
1435 } | |
1436 | |
1437 static gint vdtree_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) | |
1438 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1439 ViewDir *vdt = data; |
9 | 1440 GtkTreePath *tpath; |
1441 GtkTreeViewColumn *column; | |
1442 GtkTreeIter iter; | |
1443 NodeData *nd = NULL; | |
1444 | |
1445 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y, | |
1446 &tpath, &column, NULL, NULL)) | |
1447 { | |
1448 GtkTreeModel *store; | |
1449 gint left_of_expander; | |
1450 | |
1451 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
1452 gtk_tree_model_get_iter(store, &iter, tpath); | |
1453 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &nd, -1); | |
1454 gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget), tpath, NULL, FALSE); | |
1455 | |
1456 if (vdtree_clicked_on_expander(GTK_TREE_VIEW(widget), tpath, column, bevent->x, bevent->y, &left_of_expander)) | |
1457 { | |
1458 vdt->click_fd = NULL; | |
1459 | |
1460 /* clicking this region should automatically reveal an expander, if necessary | |
1461 * treeview bug: the expander will not expand until a button_motion_event highlights it. | |
1462 */ | |
1463 if (bevent->button == 1 && | |
1464 !left_of_expander && | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1465 !gtk_tree_view_row_expanded(GTK_TREE_VIEW(vdt->view), tpath)) |
9 | 1466 { |
1467 vdtree_populate_path_by_iter(vdt, &iter, FALSE, vdt->path); | |
1468 vdtree_icon_set_by_iter(vdt, &iter, vdt->pf->open); | |
1469 } | |
1470 | |
1471 gtk_tree_path_free(tpath); | |
1472 return FALSE; | |
1473 } | |
1474 | |
1475 gtk_tree_path_free(tpath); | |
1476 } | |
1477 | |
1478 vdt->click_fd = (nd) ? nd->fd : NULL; | |
1479 vdtree_color_set(vdt, vdt->click_fd, TRUE); | |
1480 | |
1481 if (bevent->button == 3) | |
1482 { | |
1483 vdt->popup = vdtree_pop_menu(vdt, vdt->click_fd); | |
1484 gtk_menu_popup(GTK_MENU(vdt->popup), NULL, NULL, NULL, NULL, | |
1485 bevent->button, bevent->time); | |
1486 } | |
1487 | |
1488 return (bevent->button != 1); | |
1489 } | |
1490 | |
1491 static gint vdtree_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) | |
1492 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1493 ViewDir *vdt = data; |
9 | 1494 GtkTreePath *tpath; |
1495 GtkTreeIter iter; | |
1496 NodeData *nd = NULL; | |
1497 | |
1498 if (!vdt->click_fd) return FALSE; | |
1499 vdtree_color_set(vdt, vdt->click_fd, FALSE); | |
1500 | |
1501 if (bevent->button != 1) return TRUE; | |
1502 | |
1503 if ((bevent->x != 0 || bevent->y != 0) && | |
1504 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y, | |
1505 &tpath, NULL, NULL, NULL)) | |
1506 { | |
1507 GtkTreeModel *store; | |
1508 | |
1509 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
1510 gtk_tree_model_get_iter(store, &iter, tpath); | |
1511 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &nd, -1); | |
1512 gtk_tree_path_free(tpath); | |
1513 } | |
1514 | |
1515 if (nd && vdt->click_fd == nd->fd) | |
1516 { | |
1517 vdtree_select_row(vdt, vdt->click_fd); | |
1518 } | |
1519 | |
1520 return FALSE; | |
1521 } | |
1522 | |
1523 static void vdtree_row_expanded(GtkTreeView *treeview, GtkTreeIter *iter, GtkTreePath *tpath, gpointer data) | |
1524 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1525 ViewDir *vdt = data; |
9 | 1526 |
25
0c3b353b666e
Fri Mar 25 22:39:30 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
1527 vdtree_populate_path_by_iter(vdt, iter, FALSE, NULL); |
9 | 1528 vdtree_icon_set_by_iter(vdt, iter, vdt->pf->open); |
1529 } | |
1530 | |
1531 static void vdtree_row_collapsed(GtkTreeView *treeview, GtkTreeIter *iter, GtkTreePath *tpath, gpointer data) | |
1532 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1533 ViewDir *vdt = data; |
9 | 1534 |
1535 vdtree_icon_set_by_iter(vdt, iter, vdt->pf->close); | |
1536 } | |
1537 | |
1538 static gint vdtree_sort_cb(GtkTreeModel *store, GtkTreeIter *a, GtkTreeIter *b, gpointer data) | |
1539 { | |
1540 NodeData *nda; | |
1541 NodeData *ndb; | |
1542 | |
1543 gtk_tree_model_get(store, a, DIR_COLUMN_POINTER, &nda, -1); | |
1544 gtk_tree_model_get(store, b, DIR_COLUMN_POINTER, &ndb, -1); | |
1545 | |
1546 return CASE_SORT(nda->fd->name, ndb->fd->name); | |
1547 } | |
1548 | |
1549 /* | |
1550 *---------------------------------------------------------------------------- | |
1551 * core | |
1552 *---------------------------------------------------------------------------- | |
1553 */ | |
1554 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1555 static void vdtree_setup_root(ViewDir *vdt) |
9 | 1556 { |
1557 const gchar *path = "/"; | |
1558 FileData *fd; | |
1559 | |
138 | 1560 |
1561 fd = file_data_new_simple(path); | |
9 | 1562 vdtree_add_by_data(vdt, fd, NULL); |
1563 | |
1564 vdtree_expand_by_data(vdt, fd, TRUE); | |
1565 vdtree_populate_path(vdt, path, FALSE, FALSE); | |
1566 } | |
1567 | |
1568 static void vdtree_activate_cb(GtkTreeView *tview, GtkTreePath *tpath, GtkTreeViewColumn *column, gpointer data) | |
1569 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1570 ViewDir *vdt = data; |
9 | 1571 GtkTreeModel *store; |
1572 GtkTreeIter iter; | |
1573 NodeData *nd; | |
1574 | |
1575 store = gtk_tree_view_get_model(tview); | |
1576 gtk_tree_model_get_iter(store, &iter, tpath); | |
1577 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &nd, -1); | |
1578 | |
1579 vdtree_select_row(vdt, nd->fd); | |
1580 } | |
1581 | |
1582 static GdkColor *vdtree_color_shifted(GtkWidget *widget) | |
1583 { | |
1584 static GdkColor color; | |
1585 static GtkWidget *done = NULL; | |
1586 | |
1587 if (done != widget) | |
1588 { | |
1589 GtkStyle *style; | |
1590 | |
1591 style = gtk_widget_get_style(widget); | |
1592 memcpy(&color, &style->base[GTK_STATE_NORMAL], sizeof(color)); | |
1593 shift_color(&color, -1, 0); | |
1594 done = widget; | |
1595 } | |
1596 | |
1597 return &color; | |
1598 } | |
1599 | |
1600 static void vdtree_color_cb(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, | |
1601 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) | |
1602 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1603 ViewDir *vdt = data; |
9 | 1604 gboolean set; |
1605 | |
1606 gtk_tree_model_get(tree_model, iter, DIR_COLUMN_COLOR, &set, -1); | |
1607 g_object_set(G_OBJECT(cell), | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1608 "cell-background-gdk", vdtree_color_shifted(vdt->view), |
9 | 1609 "cell-background-set", set, NULL); |
1610 } | |
1611 | |
1612 static gboolean vdtree_destroy_node_cb(GtkTreeModel *store, GtkTreePath *tpath, GtkTreeIter *iter, gpointer data) | |
1613 { | |
1614 NodeData *nd; | |
1615 | |
1616 gtk_tree_model_get(store, iter, DIR_COLUMN_POINTER, &nd, -1); | |
1617 vdtree_node_free(nd); | |
1618 | |
1619 return FALSE; | |
1620 } | |
1621 | |
1622 static void vdtree_destroy_cb(GtkWidget *widget, gpointer data) | |
1623 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1624 ViewDir *vdt = data; |
9 | 1625 GtkTreeModel *store; |
1626 | |
1627 if (vdt->popup) | |
1628 { | |
1629 g_signal_handlers_disconnect_matched(G_OBJECT(vdt->popup), G_SIGNAL_MATCH_DATA, | |
1630 0, 0, 0, NULL, vdt); | |
1631 gtk_widget_destroy(vdt->popup); | |
1632 } | |
1633 | |
1634 vdtree_dnd_drop_expand_cancel(vdt); | |
1635 vdtree_dnd_drop_scroll_cancel(vdt); | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1636 widget_auto_scroll_stop(vdt->view); |
9 | 1637 |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1638 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->view)); |
9 | 1639 gtk_tree_model_foreach(store, vdtree_destroy_node_cb, vdt); |
1640 | |
138 | 1641 filelist_free(vdt->drop_list); |
9 | 1642 |
1643 folder_icons_free(vdt->pf); | |
1644 | |
1645 g_free(vdt->path); | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1646 g_free(vdt->info); |
9 | 1647 g_free(vdt); |
1648 } | |
1649 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1650 ViewDir *vdtree_new(const gchar *path) |
9 | 1651 { |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1652 ViewDir *vdt; |
9 | 1653 GtkTreeStore *store; |
1654 GtkTreeSelection *selection; | |
1655 GtkTreeViewColumn *column; | |
1656 GtkCellRenderer *renderer; | |
1657 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1658 vdt = g_new0(ViewDir, 1); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1659 vdt->info = g_new0(ViewDirInfoTree, 1); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1660 vdt->type = DIRVIEW_TREE; |
9 | 1661 |
1662 vdt->path = NULL; | |
1663 vdt->click_fd = NULL; | |
1664 | |
1665 vdt->drop_fd = NULL; | |
1666 vdt->drop_list = NULL; | |
1667 vdt->drop_scroll_id = -1; | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1668 VDTREE_INFO(vdt, drop_expand_id) = -1; |
9 | 1669 |
1670 vdt->popup = NULL; | |
1671 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1672 VDTREE_INFO(vdt, busy_ref) = 0; |
9 | 1673 |
1674 vdt->widget = gtk_scrolled_window_new(NULL, NULL); | |
1675 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(vdt->widget), GTK_SHADOW_IN); | |
1676 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(vdt->widget), | |
1677 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); | |
1678 g_signal_connect(G_OBJECT(vdt->widget), "destroy", | |
1679 G_CALLBACK(vdtree_destroy_cb), vdt); | |
1680 | |
1681 store = gtk_tree_store_new(4, G_TYPE_POINTER, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT); | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1682 vdt->view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); |
9 | 1683 g_object_unref(store); |
1684 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1685 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(vdt->view), FALSE); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1686 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(vdt->view), FALSE); |
9 | 1687 gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), vdtree_sort_cb, vdt, NULL); |
1688 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), | |
1689 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING); | |
1690 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1691 g_signal_connect(G_OBJECT(vdt->view), "row_activated", |
9 | 1692 G_CALLBACK(vdtree_activate_cb), vdt); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1693 g_signal_connect(G_OBJECT(vdt->view), "row_expanded", |
9 | 1694 G_CALLBACK(vdtree_row_expanded), vdt); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1695 g_signal_connect(G_OBJECT(vdt->view), "row_collapsed", |
9 | 1696 G_CALLBACK(vdtree_row_collapsed), vdt); |
1697 #if 0 | |
1698 g_signal_connect(G_OBJECT(store), "row_deleted", | |
1699 G_CALLBACK(vdtree_row_deleted_cb), vdt); | |
1700 #endif | |
1701 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1702 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vdt->view)); |
9 | 1703 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); |
1704 gtk_tree_selection_set_select_function(selection, vdtree_select_cb, vdt, NULL); | |
1705 | |
1706 column = gtk_tree_view_column_new(); | |
1707 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY); | |
1708 | |
1709 renderer = gtk_cell_renderer_pixbuf_new(); | |
1710 gtk_tree_view_column_pack_start(column, renderer, FALSE); | |
1711 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", DIR_COLUMN_ICON); | |
1712 gtk_tree_view_column_set_cell_data_func(column, renderer, vdtree_color_cb, vdt, NULL); | |
1713 | |
1714 renderer = gtk_cell_renderer_text_new(); | |
1715 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
1716 gtk_tree_view_column_add_attribute(column, renderer, "text", DIR_COLUMN_NAME); | |
1717 gtk_tree_view_column_set_cell_data_func(column, renderer, vdtree_color_cb, vdt, NULL); | |
1718 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1719 gtk_tree_view_append_column(GTK_TREE_VIEW(vdt->view), column); |
9 | 1720 |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1721 g_signal_connect(G_OBJECT(vdt->view), "key_press_event", |
9 | 1722 G_CALLBACK(vdtree_press_key_cb), vdt); |
1723 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1724 gtk_container_add(GTK_CONTAINER(vdt->widget), vdt->view); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1725 gtk_widget_show(vdt->view); |
9 | 1726 |
1727 vdt->pf = folder_icons_new(); | |
1728 | |
1729 vdtree_setup_root(vdt); | |
1730 | |
1731 vdtree_dnd_init(vdt); | |
1732 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1733 g_signal_connect(G_OBJECT(vdt->view), "button_press_event", |
9 | 1734 G_CALLBACK(vdtree_press_cb), vdt); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1735 g_signal_connect(G_OBJECT(vdt->view), "button_release_event", |
9 | 1736 G_CALLBACK(vdtree_release_cb), vdt); |
1737 | |
1738 vdtree_set_path(vdt, path); | |
1739 | |
1740 return vdt; | |
1741 } | |
1742 | |
1743 #if 0 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1744 void vdtree_set_click_func(ViewDir *vdt, |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
356
diff
changeset
|
1745 void (*func)(ViewDir *vdt, GdkEventButton *event, FileData *fd, gpointer), gpointer data) |
9 | 1746 { |
1747 if (!td) return; | |
1748 vdt->click_func = func; | |
1749 vdt->click_data = data; | |
1750 } | |
1751 #endif | |
1752 | |
1753 |