Mercurial > geeqie
annotate src/view_dir_list.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 | 61a3c8b05b24 |
children | ff63dcb0425c |
rev | line source |
---|---|
9 | 1 /* |
196 | 2 * Geeqie |
9 | 3 * (C) 2004 John Ellis |
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_list.h" |
14 | |
15 #include "dnd.h" | |
16 #include "dupe.h" | |
17 #include "filelist.h" | |
18 #include "layout.h" | |
19 #include "layout_image.h" | |
20 #include "layout_util.h" | |
21 #include "utilops.h" | |
22 #include "ui_bookmark.h" | |
23 #include "ui_fileops.h" | |
24 #include "ui_menu.h" | |
25 #include "ui_tree_edit.h" | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
26 #include "view_dir.h" |
9 | 27 |
28 #include <gdk/gdkkeysyms.h> /* for keyboard values */ | |
29 | |
30 | |
31 #define VDLIST_PAD 4 | |
32 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
33 #define VDLIST_INFO(_vd_, _part_) (((ViewDirInfoList *)(_vd_->info))->_part_) |
9 | 34 |
35 | |
36 static void vdlist_popup_destroy_cb(GtkWidget *widget, gpointer data); | |
37 static gint vdlist_auto_scroll_notify_cb(GtkWidget *widget, gint x, gint y, gpointer data); | |
38 | |
39 /* | |
40 *----------------------------------------------------------------------------- | |
41 * misc | |
42 *----------------------------------------------------------------------------- | |
43 */ | |
44 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
45 static gint vdlist_find_row(ViewDir *vdl, FileData *fd, GtkTreeIter *iter) |
9 | 46 { |
47 GtkTreeModel *store; | |
48 gint valid; | |
49 gint row = 0; | |
50 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
51 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdl->view)); |
9 | 52 valid = gtk_tree_model_get_iter_first(store, iter); |
53 while (valid) | |
54 { | |
55 FileData *fd_n; | |
56 gtk_tree_model_get(GTK_TREE_MODEL(store), iter, DIR_COLUMN_POINTER, &fd_n, -1); | |
57 if (fd_n == fd) return row; | |
58 | |
59 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), iter); | |
60 row++; | |
61 } | |
62 | |
63 return -1; | |
64 } | |
65 | |
66 static gint vdlist_rename_row_cb(TreeEditData *td, const gchar *old, const gchar *new, gpointer data) | |
67 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
68 ViewDir *vdl = data; |
9 | 69 GtkTreeModel *store; |
70 GtkTreeIter iter; | |
71 FileData *fd; | |
72 gchar *old_path; | |
73 gchar *new_path; | |
74 gchar *base; | |
75 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
76 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdl->view)); |
9 | 77 if (!gtk_tree_model_get_iter(store, &iter, td->path)) return FALSE; |
78 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1); | |
79 if (!fd) return FALSE; | |
80 | |
81 old_path = g_strdup(fd->path); | |
82 | |
83 base = remove_level_from_path(old_path); | |
84 new_path = concat_dir_and_file(base, new); | |
85 g_free(base); | |
86 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
87 if (file_util_rename_dir(fd, new_path, vdl->view)) |
9 | 88 { |
89 if (vdl->layout && strcmp(vdl->path, old_path) == 0) | |
90 { | |
91 layout_set_path(vdl->layout, new_path); | |
92 } | |
93 else | |
94 { | |
95 vdlist_refresh(vdl); | |
96 } | |
97 } | |
98 | |
99 g_free(old_path); | |
100 g_free(new_path); | |
101 return FALSE; | |
102 } | |
103 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
104 static void vdlist_rename_by_row(ViewDir *vdl, FileData *fd) |
9 | 105 { |
106 GtkTreeModel *store; | |
107 GtkTreePath *tpath; | |
108 GtkTreeIter iter; | |
109 | |
110 if (vdlist_find_row(vdl, fd, &iter) < 0) return; | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
111 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdl->view)); |
9 | 112 tpath = gtk_tree_model_get_path(store, &iter); |
113 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
114 tree_edit_by_path(GTK_TREE_VIEW(vdl->view), tpath, 0, fd->name, |
9 | 115 vdlist_rename_row_cb, vdl); |
116 gtk_tree_path_free(tpath); | |
117 } | |
118 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
119 static FileData *vdlist_row_by_path(ViewDir *vdl, const gchar *path, gint *row) |
9 | 120 { |
121 GList *work; | |
122 gint n; | |
123 | |
124 if (!path) | |
125 { | |
126 if (row) *row = -1; | |
127 return NULL; | |
128 } | |
129 | |
130 n = 0; | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
131 work = VDLIST_INFO(vdl, list); |
9 | 132 while (work) |
133 { | |
134 FileData *fd = work->data; | |
135 if (strcmp(fd->path, path) == 0) | |
136 { | |
137 if (row) *row = n; | |
138 return fd; | |
139 } | |
140 work = work->next; | |
141 n++; | |
142 } | |
143 | |
144 if (row) *row = -1; | |
145 return NULL; | |
146 } | |
147 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
148 static void vdlist_color_set(ViewDir *vdl, FileData *fd, gint color_set) |
9 | 149 { |
150 GtkTreeModel *store; | |
151 GtkTreeIter iter; | |
152 | |
153 if (vdlist_find_row(vdl, fd, &iter) < 0) return; | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
154 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdl->view)); |
9 | 155 gtk_list_store_set(GTK_LIST_STORE(store), &iter, DIR_COLUMN_COLOR, color_set, -1); |
156 } | |
157 | |
158 /* | |
159 *----------------------------------------------------------------------------- | |
160 * drop menu (from dnd) | |
161 *----------------------------------------------------------------------------- | |
162 */ | |
163 | |
164 static void vdlist_drop_menu_copy_cb(GtkWidget *widget, gpointer data) | |
165 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
166 ViewDir *vdl = data; |
9 | 167 const gchar *path; |
168 GList *list; | |
169 | |
170 if (!vdl->drop_fd) return; | |
171 | |
172 path = vdl->drop_fd->path; | |
173 list = vdl->drop_list; | |
174 vdl->drop_list = NULL; | |
175 | |
176 file_util_copy_simple(list, path); | |
177 } | |
178 | |
179 static void vdlist_drop_menu_move_cb(GtkWidget *widget, gpointer data) | |
180 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
181 ViewDir *vdl = data; |
9 | 182 const gchar *path; |
183 GList *list; | |
184 | |
185 if (!vdl->drop_fd) return; | |
186 | |
187 path = vdl->drop_fd->path; | |
188 list = vdl->drop_list; | |
189 | |
190 vdl->drop_list = NULL; | |
191 | |
192 file_util_move_simple(list, path); | |
193 } | |
194 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
195 static GtkWidget *vdlist_drop_menu(ViewDir *vdl, gint active) |
9 | 196 { |
197 GtkWidget *menu; | |
198 | |
199 menu = popup_menu_short_lived(); | |
200 g_signal_connect(G_OBJECT(menu), "destroy", | |
201 G_CALLBACK(vdlist_popup_destroy_cb), vdl); | |
202 | |
203 menu_item_add_stock_sensitive(menu, _("_Copy"), GTK_STOCK_COPY, active, | |
204 G_CALLBACK(vdlist_drop_menu_copy_cb), vdl); | |
205 menu_item_add_sensitive(menu, _("_Move"), active, G_CALLBACK(vdlist_drop_menu_move_cb), vdl); | |
206 | |
207 menu_item_add_divider(menu); | |
208 menu_item_add_stock(menu, _("Cancel"), GTK_STOCK_CANCEL, NULL, vdl); | |
209 | |
210 return menu; | |
211 } | |
212 | |
213 /* | |
214 *----------------------------------------------------------------------------- | |
215 * pop-up menu | |
216 *----------------------------------------------------------------------------- | |
217 */ | |
218 | |
219 static void vdlist_pop_menu_up_cb(GtkWidget *widget, gpointer data) | |
220 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
221 ViewDir *vdl = data; |
9 | 222 gchar *path; |
223 | |
224 if (!vdl->path || strcmp(vdl->path, "/") == 0) return; | |
225 path = remove_level_from_path(vdl->path); | |
226 | |
227 if (vdl->select_func) | |
228 { | |
229 vdl->select_func(vdl, path, vdl->select_data); | |
230 } | |
231 | |
232 g_free(path); | |
233 } | |
234 | |
235 static void vdlist_pop_menu_slide_cb(GtkWidget *widget, gpointer data) | |
236 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
237 ViewDir *vdl = data; |
9 | 238 gchar *path; |
239 | |
240 if (!vdl->layout || !vdl->click_fd) return; | |
241 | |
242 path = g_strdup(vdl->click_fd->path); | |
243 | |
244 layout_set_path(vdl->layout, path); | |
245 layout_select_none(vdl->layout); | |
246 layout_image_slideshow_stop(vdl->layout); | |
247 layout_image_slideshow_start(vdl->layout); | |
248 | |
249 g_free(path); | |
250 } | |
251 | |
252 static void vdlist_pop_menu_slide_rec_cb(GtkWidget *widget, gpointer data) | |
253 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
254 ViewDir *vdl = data; |
9 | 255 gchar *path; |
256 GList *list; | |
257 | |
258 if (!vdl->layout || !vdl->click_fd) return; | |
259 | |
260 path = g_strdup(vdl->click_fd->path); | |
261 | |
138 | 262 list = filelist_recursive(path); |
9 | 263 |
264 layout_image_slideshow_stop(vdl->layout); | |
265 layout_image_slideshow_start_from_list(vdl->layout, list); | |
266 | |
267 g_free(path); | |
268 } | |
269 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
270 static void vdlist_pop_menu_dupe(ViewDir *vdl, gint recursive) |
9 | 271 { |
272 DupeWindow *dw; | |
273 GList *list = NULL; | |
274 | |
275 if (!vdl->click_fd) return; | |
276 | |
277 if (recursive) | |
278 { | |
138 | 279 list = g_list_append(list, file_data_ref(vdl->click_fd)); |
9 | 280 } |
281 else | |
282 { | |
138 | 283 filelist_read(vdl->click_fd->path, &list, NULL); |
284 list = filelist_filter(list, FALSE); | |
9 | 285 } |
286 | |
287 dw = dupe_window_new(DUPE_MATCH_NAME); | |
288 dupe_window_add_files(dw, list, recursive); | |
289 | |
138 | 290 filelist_free(list); |
9 | 291 } |
292 | |
293 static void vdlist_pop_menu_dupe_cb(GtkWidget *widget, gpointer data) | |
294 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
295 ViewDir *vdl = data; |
9 | 296 vdlist_pop_menu_dupe(vdl, FALSE); |
297 } | |
298 | |
299 static void vdlist_pop_menu_dupe_rec_cb(GtkWidget *widget, gpointer data) | |
300 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
301 ViewDir *vdl = data; |
9 | 302 vdlist_pop_menu_dupe(vdl, TRUE); |
303 } | |
304 | |
305 static void vdlist_pop_menu_new_cb(GtkWidget *widget, gpointer data) | |
306 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
307 ViewDir *vdl = data; |
9 | 308 gchar *new_path; |
309 gchar *buf; | |
310 | |
311 if (!vdl->path) return; | |
312 | |
313 buf = concat_dir_and_file(vdl->path, _("new_folder")); | |
314 new_path = unique_filename(buf, NULL, NULL, FALSE); | |
315 g_free(buf); | |
316 if (!new_path) return; | |
317 | |
318 if (!mkdir_utf8(new_path, 0755)) | |
319 { | |
320 gchar *text; | |
321 | |
322 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:
373
diff
changeset
|
323 file_util_warning_dialog(_("Error creating folder"), text, GTK_STOCK_DIALOG_ERROR, vdl->view); |
9 | 324 g_free(text); |
325 } | |
326 else | |
327 { | |
328 FileData *fd; | |
329 | |
330 vdlist_refresh(vdl); | |
331 fd = vdlist_row_by_path(vdl, new_path, NULL); | |
332 | |
333 vdlist_rename_by_row(vdl, fd); | |
334 } | |
335 | |
336 g_free(new_path); | |
337 } | |
338 | |
339 static void vdlist_pop_menu_rename_cb(GtkWidget *widget, gpointer data) | |
340 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
341 ViewDir *vdl = data; |
9 | 342 |
343 vdlist_rename_by_row(vdl, vdl->click_fd); | |
344 } | |
345 | |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
346 static void vdlist_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
|
347 { |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
348 ViewDir *vdl = data; |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
349 |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
350 if (!vdl->click_fd) return; |
138 | 351 file_util_delete_dir(vdl->click_fd, vdl->widget); |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
352 } |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
353 |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
354 static void vdlist_pop_menu_dir_view_as_cb(GtkWidget *widget, gpointer data) |
9 | 355 { |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
356 ViewDir *vdl = data; |
9 | 357 |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
358 if (vdl->layout) layout_views_set(vdl->layout, DIRVIEW_TREE, vdl->layout->icon_view); |
9 | 359 } |
360 | |
361 static void vdlist_pop_menu_refresh_cb(GtkWidget *widget, gpointer data) | |
362 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
363 ViewDir *vdl = data; |
9 | 364 |
365 if (vdl->layout) layout_refresh(vdl->layout); | |
366 } | |
367 | |
356 | 368 static void vdlist_toggle_show_hidden_files_cb(GtkWidget *widget, gpointer data) |
355
0b82646e977f
Let toggle the visibility of hidden files from directories list
zas_
parents:
281
diff
changeset
|
369 { |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
370 ViewDir *vdl = data; |
355
0b82646e977f
Let toggle the visibility of hidden files from directories list
zas_
parents:
281
diff
changeset
|
371 |
356 | 372 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:
281
diff
changeset
|
373 if (vdl->layout) layout_refresh(vdl->layout); |
0b82646e977f
Let toggle the visibility of hidden files from directories list
zas_
parents:
281
diff
changeset
|
374 } |
0b82646e977f
Let toggle the visibility of hidden files from directories list
zas_
parents:
281
diff
changeset
|
375 |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
376 static GtkWidget *vdlist_pop_menu(ViewDir *vdl, FileData *fd) |
9 | 377 { |
378 GtkWidget *menu; | |
379 gint active; | |
380 | |
381 active = (fd != NULL); | |
382 | |
383 menu = popup_menu_short_lived(); | |
384 g_signal_connect(G_OBJECT(menu), "destroy", | |
385 G_CALLBACK(vdlist_popup_destroy_cb), vdl); | |
386 | |
387 menu_item_add_stock_sensitive(menu, _("_Up to parent"), GTK_STOCK_GO_UP, | |
388 (vdl->path && strcmp(vdl->path, "/") != 0), | |
389 G_CALLBACK(vdlist_pop_menu_up_cb), vdl); | |
390 | |
391 menu_item_add_divider(menu); | |
392 menu_item_add_sensitive(menu, _("_Slideshow"), active, | |
393 G_CALLBACK(vdlist_pop_menu_slide_cb), vdl); | |
394 menu_item_add_sensitive(menu, _("Slideshow recursive"), active, | |
395 G_CALLBACK(vdlist_pop_menu_slide_rec_cb), vdl); | |
396 | |
397 menu_item_add_divider(menu); | |
398 menu_item_add_stock_sensitive(menu, _("Find _duplicates..."), GTK_STOCK_FIND, active, | |
399 G_CALLBACK(vdlist_pop_menu_dupe_cb), vdl); | |
400 menu_item_add_stock_sensitive(menu, _("Find duplicates recursive..."), GTK_STOCK_FIND, active, | |
401 G_CALLBACK(vdlist_pop_menu_dupe_rec_cb), vdl); | |
402 | |
403 menu_item_add_divider(menu); | |
404 | |
405 /* check using . (always row 0) */ | |
406 active = (vdl->path && access_file(vdl->path , W_OK | X_OK)); | |
407 menu_item_add_sensitive(menu, _("_New folder..."), active, | |
408 G_CALLBACK(vdlist_pop_menu_new_cb), vdl); | |
409 | |
410 /* ignore .. and . */ | |
411 active = (active && fd && | |
412 strcmp(fd->name, ".") != 0 && | |
413 strcmp(fd->name, "..") != 0 && | |
414 access_file(fd->path, W_OK | X_OK)); | |
415 menu_item_add_sensitive(menu, _("_Rename..."), active, | |
416 G_CALLBACK(vdlist_pop_menu_rename_cb), vdl); | |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
417 menu_item_add_stock_sensitive(menu, _("_Delete..."), GTK_STOCK_DELETE, active, |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
418 G_CALLBACK(vdlist_pop_menu_delete_cb), vdl); |
9 | 419 |
420 menu_item_add_divider(menu); | |
421 menu_item_add_check(menu, _("View as _tree"), FALSE, | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
422 G_CALLBACK(vdlist_pop_menu_dir_view_as_cb), vdl); |
356 | 423 menu_item_add_check(menu, _("Show _hidden files"), options->file_filter.show_hidden_files, |
424 G_CALLBACK(vdlist_toggle_show_hidden_files_cb), vdl); | |
355
0b82646e977f
Let toggle the visibility of hidden files from directories list
zas_
parents:
281
diff
changeset
|
425 |
9 | 426 menu_item_add_stock(menu, _("Re_fresh"), GTK_STOCK_REFRESH, |
427 G_CALLBACK(vdlist_pop_menu_refresh_cb), vdl); | |
428 | |
429 return menu; | |
430 } | |
431 | |
432 static void vdlist_popup_destroy_cb(GtkWidget *widget, gpointer data) | |
433 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
434 ViewDir *vdl = data; |
9 | 435 |
436 vdlist_color_set(vdl, vdl->click_fd, FALSE); | |
437 vdl->click_fd = NULL; | |
438 vdl->popup = NULL; | |
439 | |
440 vdlist_color_set(vdl, vdl->drop_fd, FALSE); | |
138 | 441 filelist_free(vdl->drop_list); |
9 | 442 vdl->drop_list = NULL; |
443 vdl->drop_fd = NULL; | |
444 } | |
445 | |
446 /* | |
447 *----------------------------------------------------------------------------- | |
448 * dnd | |
449 *----------------------------------------------------------------------------- | |
450 */ | |
451 | |
452 static GtkTargetEntry vdlist_dnd_drop_types[] = { | |
453 { "text/uri-list", 0, TARGET_URI_LIST } | |
454 }; | |
455 static gint vdlist_dnd_drop_types_count = 1; | |
456 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
457 static void vdlist_dest_set(ViewDir *vdl, gint enable) |
9 | 458 { |
459 if (enable) | |
460 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
461 gtk_drag_dest_set(vdl->view, |
9 | 462 GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, |
463 vdlist_dnd_drop_types, vdlist_dnd_drop_types_count, | |
464 GDK_ACTION_MOVE | GDK_ACTION_COPY); | |
465 } | |
466 else | |
467 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
468 gtk_drag_dest_unset(vdl->view); |
9 | 469 } |
470 } | |
471 | |
472 static void vdlist_dnd_get(GtkWidget *widget, GdkDragContext *context, | |
473 GtkSelectionData *selection_data, guint info, | |
474 guint time, gpointer data) | |
475 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
476 ViewDir *vdl = data; |
9 | 477 GList *list; |
478 gchar *text = NULL; | |
479 gint length = 0; | |
480 | |
481 if (!vdl->click_fd) return; | |
482 | |
483 switch (info) | |
484 { | |
485 case TARGET_URI_LIST: | |
486 case TARGET_TEXT_PLAIN: | |
138 | 487 list = g_list_prepend(NULL, vdl->click_fd); |
488 text = uri_text_from_filelist(list, &length, (info == TARGET_TEXT_PLAIN)); | |
9 | 489 g_list_free(list); |
490 break; | |
491 } | |
492 if (text) | |
493 { | |
494 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:
44
diff
changeset
|
495 8, (guchar *)text, length); |
9 | 496 g_free(text); |
497 } | |
498 } | |
499 | |
500 static void vdlist_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data) | |
501 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
502 ViewDir *vdl = data; |
9 | 503 |
504 vdlist_color_set(vdl, vdl->click_fd, TRUE); | |
505 vdlist_dest_set(vdl, FALSE); | |
506 } | |
507 | |
508 static void vdlist_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer data) | |
509 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
510 ViewDir *vdl = data; |
9 | 511 |
512 vdlist_color_set(vdl, vdl->click_fd, FALSE); | |
513 | |
514 if (context->action == GDK_ACTION_MOVE) | |
515 { | |
516 vdlist_refresh(vdl); | |
517 } | |
518 vdlist_dest_set(vdl, TRUE); | |
519 } | |
520 | |
521 static void vdlist_dnd_drop_receive(GtkWidget *widget, | |
522 GdkDragContext *context, gint x, gint y, | |
523 GtkSelectionData *selection_data, guint info, | |
524 guint time, gpointer data) | |
525 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
526 ViewDir *vdl = data; |
9 | 527 GtkTreePath *tpath; |
528 GtkTreeIter iter; | |
529 FileData *fd = NULL; | |
530 | |
531 vdl->click_fd = NULL; | |
532 | |
533 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), x, y, | |
534 &tpath, NULL, NULL, NULL)) | |
535 { | |
536 GtkTreeModel *store; | |
537 | |
538 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
539 gtk_tree_model_get_iter(store, &iter, tpath); | |
540 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1); | |
541 gtk_tree_path_free(tpath); | |
542 } | |
543 | |
544 if (!fd) return; | |
545 | |
546 if (info == TARGET_URI_LIST) | |
547 { | |
548 GList *list; | |
549 gint active; | |
550 | |
138 | 551 list = uri_filelist_from_text((gchar *)selection_data->data, TRUE); |
9 | 552 if (!list) return; |
553 | |
554 active = access_file(fd->path, W_OK | X_OK); | |
555 | |
556 vdlist_color_set(vdl, fd, TRUE); | |
557 vdl->popup = vdlist_drop_menu(vdl, active); | |
558 gtk_menu_popup(GTK_MENU(vdl->popup), NULL, NULL, NULL, NULL, 0, time); | |
559 | |
560 vdl->drop_fd = fd; | |
561 vdl->drop_list = list; | |
562 } | |
563 } | |
564 | |
565 #if 0 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
566 static gint vdlist_get_row_visibility(ViewDir *vdl, FileData *fd) |
9 | 567 { |
568 GtkTreeModel *store; | |
569 GtkTreeViewColumn *column; | |
570 GtkTreePath *tpath; | |
571 GtkTreeIter iter; | |
572 | |
573 GdkRectangle vrect; | |
574 GdkRectangle crect; | |
575 | |
576 if (!fd || vdlist_find_row(vdl, fd, &iter) < 0) return 0; | |
577 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
578 column = gtk_tree_view_get_column(GTK_TREE_VIEW(vdl->view), 0); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
579 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdl->view)); |
9 | 580 tpath = gtk_tree_model_get_path(store, &iter); |
581 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
582 gtk_tree_view_get_visible_rect(GTK_TREE_VIEW(vdl->view), &vrect); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
583 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(vdl->view), tpath, column, &crect); |
9 | 584 printf("window: %d + %d; cell: %d + %d\n", vrect.y, vrect.height, crect.y, crect.height); |
585 gtk_tree_path_free(tpath); | |
586 | |
587 if (crect.y + crect.height < vrect.y) return -1; | |
588 if (crect.y > vrect.y + vrect.height) return 1; | |
589 return 0; | |
590 } | |
591 #endif | |
592 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
593 static void vdlist_scroll_to_row(ViewDir *vdl, FileData *fd, gfloat y_align) |
9 | 594 { |
595 GtkTreeIter iter; | |
596 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
597 if (GTK_WIDGET_REALIZED(vdl->view) && |
9 | 598 vdlist_find_row(vdl, fd, &iter) >= 0) |
599 { | |
600 GtkTreeModel *store; | |
601 GtkTreePath *tpath; | |
602 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
603 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdl->view)); |
9 | 604 tpath = gtk_tree_model_get_path(store, &iter); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
605 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(vdl->view), tpath, NULL, TRUE, y_align, 0.0); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
606 gtk_tree_view_set_cursor(GTK_TREE_VIEW(vdl->view), tpath, NULL, FALSE); |
9 | 607 gtk_tree_path_free(tpath); |
608 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
609 if (!GTK_WIDGET_HAS_FOCUS(vdl->view)) gtk_widget_grab_focus(vdl->view); |
9 | 610 } |
611 } | |
612 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
613 static void vdlist_drop_update(ViewDir *vdl, gint x, gint y) |
9 | 614 { |
615 GtkTreePath *tpath; | |
616 GtkTreeIter iter; | |
617 FileData *fd = NULL; | |
618 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
619 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vdl->view), x, y, |
9 | 620 &tpath, NULL, NULL, NULL)) |
621 { | |
622 GtkTreeModel *store; | |
623 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
624 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdl->view)); |
9 | 625 gtk_tree_model_get_iter(store, &iter, tpath); |
626 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1); | |
627 gtk_tree_path_free(tpath); | |
628 } | |
629 | |
630 if (fd != vdl->drop_fd) | |
631 { | |
632 vdlist_color_set(vdl, vdl->drop_fd, FALSE); | |
633 vdlist_color_set(vdl, fd, TRUE); | |
634 } | |
635 | |
636 vdl->drop_fd = fd; | |
637 } | |
638 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
639 static void vdlist_dnd_drop_scroll_cancel(ViewDir *vdl) |
9 | 640 { |
641 if (vdl->drop_scroll_id != -1) g_source_remove(vdl->drop_scroll_id); | |
642 vdl->drop_scroll_id = -1; | |
643 } | |
644 | |
645 static gint vdlist_auto_scroll_idle_cb(gpointer data) | |
646 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
647 ViewDir *vdl = data; |
9 | 648 |
649 if (vdl->drop_fd) | |
650 { | |
651 GdkWindow *window; | |
652 gint x, y; | |
653 gint w, h; | |
654 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
655 window = vdl->view->window; |
9 | 656 gdk_window_get_pointer(window, &x, &y, NULL); |
657 gdk_drawable_get_size(window, &w, &h); | |
658 if (x >= 0 && x < w && y >= 0 && y < h) | |
659 { | |
660 vdlist_drop_update(vdl, x, y); | |
661 } | |
662 } | |
663 | |
664 vdl->drop_scroll_id = -1; | |
665 return FALSE; | |
666 } | |
667 | |
668 static gint vdlist_auto_scroll_notify_cb(GtkWidget *widget, gint x, gint y, gpointer data) | |
669 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
670 ViewDir *vdl = data; |
9 | 671 |
672 if (!vdl->drop_fd || vdl->drop_list) return FALSE; | |
673 | |
674 if (vdl->drop_scroll_id == -1) vdl->drop_scroll_id = g_idle_add(vdlist_auto_scroll_idle_cb, vdl); | |
675 | |
676 return TRUE; | |
677 } | |
678 | |
679 static gint vdlist_dnd_drop_motion(GtkWidget *widget, GdkDragContext *context, | |
680 gint x, gint y, guint time, gpointer data) | |
681 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
682 ViewDir *vdl = data; |
9 | 683 |
684 vdl->click_fd = NULL; | |
685 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
686 if (gtk_drag_get_source_widget(context) == vdl->view) |
9 | 687 { |
688 /* from same window */ | |
689 gdk_drag_status(context, 0, time); | |
690 return TRUE; | |
691 } | |
692 else | |
693 { | |
694 gdk_drag_status(context, context->suggested_action, time); | |
695 } | |
696 | |
697 vdlist_drop_update(vdl, x, y); | |
698 | |
699 if (vdl->drop_fd) | |
700 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
701 GtkAdjustment *adj = gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(vdl->view)); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
702 widget_auto_scroll_start(vdl->view, adj, -1, -1, vdlist_auto_scroll_notify_cb, vdl); |
9 | 703 } |
704 | |
705 return FALSE; | |
706 } | |
707 | |
708 static void vdlist_dnd_drop_leave(GtkWidget *widget, GdkDragContext *context, guint time, gpointer data) | |
709 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
710 ViewDir *vdl = data; |
9 | 711 |
712 if (vdl->drop_fd != vdl->click_fd) vdlist_color_set(vdl, vdl->drop_fd, FALSE); | |
713 | |
714 vdl->drop_fd = NULL; | |
715 } | |
716 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
717 static void vdlist_dnd_init(ViewDir *vdl) |
9 | 718 { |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
719 gtk_drag_source_set(vdl->view, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, |
9 | 720 dnd_file_drag_types, dnd_file_drag_types_count, |
721 GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
722 g_signal_connect(G_OBJECT(vdl->view), "drag_data_get", |
9 | 723 G_CALLBACK(vdlist_dnd_get), vdl); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
724 g_signal_connect(G_OBJECT(vdl->view), "drag_begin", |
9 | 725 G_CALLBACK(vdlist_dnd_begin), vdl); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
726 g_signal_connect(G_OBJECT(vdl->view), "drag_end", |
9 | 727 G_CALLBACK(vdlist_dnd_end), vdl); |
728 | |
729 vdlist_dest_set(vdl, TRUE); | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
730 g_signal_connect(G_OBJECT(vdl->view), "drag_data_received", |
9 | 731 G_CALLBACK(vdlist_dnd_drop_receive), vdl); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
732 g_signal_connect(G_OBJECT(vdl->view), "drag_motion", |
9 | 733 G_CALLBACK(vdlist_dnd_drop_motion), vdl); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
734 g_signal_connect(G_OBJECT(vdl->view), "drag_leave", |
9 | 735 G_CALLBACK(vdlist_dnd_drop_leave), vdl); |
736 } | |
737 | |
738 /* | |
739 *----------------------------------------------------------------------------- | |
740 * main | |
741 *----------------------------------------------------------------------------- | |
742 */ | |
743 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
744 static void vdlist_select_row(ViewDir *vdl, FileData *fd) |
9 | 745 { |
746 if (fd && vdl->select_func) | |
747 { | |
748 gchar *path; | |
749 | |
750 path = g_strdup(fd->path); | |
751 vdl->select_func(vdl, path, vdl->select_data); | |
752 g_free(path); | |
753 } | |
754 } | |
755 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
756 const gchar *vdlist_row_get_path(ViewDir *vdl, gint row) |
9 | 757 { |
758 FileData *fd; | |
759 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
760 fd = g_list_nth_data(VDLIST_INFO(vdl, list), row); |
9 | 761 |
762 if (fd) return fd->path; | |
763 | |
764 return NULL; | |
765 } | |
766 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
767 static void vdlist_populate(ViewDir *vdl) |
9 | 768 { |
769 GtkListStore *store; | |
770 GList *work; | |
771 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
772 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vdl->view))); |
9 | 773 gtk_list_store_clear(store); |
774 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
775 work = VDLIST_INFO(vdl, list); |
9 | 776 while (work) |
777 { | |
778 FileData *fd; | |
779 GtkTreeIter iter; | |
780 GdkPixbuf *pixbuf; | |
781 | |
782 fd = work->data; | |
783 | |
784 if (access_file(fd->path, R_OK | X_OK) && fd->name) | |
785 { | |
786 if (fd->name[0] == '.' && fd->name[1] == '\0') | |
787 { | |
788 pixbuf = vdl->pf->open; | |
789 } | |
790 else if (fd->name[0] == '.' && fd->name[1] == '.' && fd->name[2] == '\0') | |
791 { | |
792 pixbuf = vdl->pf->parent; | |
793 } | |
794 else | |
795 { | |
796 pixbuf = vdl->pf->close; | |
797 } | |
798 } | |
799 else | |
800 { | |
801 pixbuf = vdl->pf->deny; | |
802 } | |
803 | |
804 gtk_list_store_append(store, &iter); | |
805 gtk_list_store_set(store, &iter, | |
806 DIR_COLUMN_POINTER, fd, | |
807 DIR_COLUMN_ICON, pixbuf, | |
808 DIR_COLUMN_NAME, fd->name, -1); | |
809 | |
810 work = work->next; | |
811 } | |
812 | |
813 vdl->click_fd = NULL; | |
814 vdl->drop_fd = NULL; | |
815 } | |
816 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
817 gint vdlist_set_path(ViewDir *vdl, const gchar *path) |
9 | 818 { |
819 gint ret; | |
820 FileData *fd; | |
821 gchar *old_path = NULL; | |
138 | 822 gchar *filepath; |
9 | 823 |
824 if (!path) return FALSE; | |
825 if (vdl->path && strcmp(path, vdl->path) == 0) return TRUE; | |
826 | |
827 if (vdl->path) | |
828 { | |
829 gchar *base; | |
830 | |
831 base = remove_level_from_path(vdl->path); | |
832 if (strcmp(base, path) == 0) | |
833 { | |
834 old_path = g_strdup(filename_from_path(vdl->path)); | |
835 } | |
836 g_free(base); | |
837 } | |
838 | |
839 g_free(vdl->path); | |
840 vdl->path = g_strdup(path); | |
841 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
842 filelist_free(VDLIST_INFO(vdl, list)); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
843 VDLIST_INFO(vdl, list) = NULL; |
9 | 844 |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
845 ret = filelist_read(vdl->path, NULL, &VDLIST_INFO(vdl, list)); |
9 | 846 |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
847 VDLIST_INFO(vdl, list) = filelist_sort(VDLIST_INFO(vdl, list), SORT_NAME, TRUE); |
9 | 848 |
849 /* add . and .. */ | |
850 | |
851 if (strcmp(vdl->path, "/") != 0) | |
852 { | |
138 | 853 filepath = g_strconcat(vdl->path, "/", "..", NULL); |
854 fd = file_data_new_simple(filepath); | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
855 VDLIST_INFO(vdl, list) = g_list_prepend(VDLIST_INFO(vdl, list), fd); |
138 | 856 g_free(filepath); |
9 | 857 } |
373
61a3c8b05b24
Add a new option in Preferences > Filtering to allow the
zas_
parents:
356
diff
changeset
|
858 |
61a3c8b05b24
Add a new option in Preferences > Filtering to allow the
zas_
parents:
356
diff
changeset
|
859 if (options->file_filter.show_dot_directory) |
61a3c8b05b24
Add a new option in Preferences > Filtering to allow the
zas_
parents:
356
diff
changeset
|
860 { |
61a3c8b05b24
Add a new option in Preferences > Filtering to allow the
zas_
parents:
356
diff
changeset
|
861 filepath = g_strconcat(vdl->path, "/", ".", NULL); |
61a3c8b05b24
Add a new option in Preferences > Filtering to allow the
zas_
parents:
356
diff
changeset
|
862 fd = file_data_new_simple(filepath); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
863 VDLIST_INFO(vdl, list) = g_list_prepend(VDLIST_INFO(vdl, list), fd); |
373
61a3c8b05b24
Add a new option in Preferences > Filtering to allow the
zas_
parents:
356
diff
changeset
|
864 g_free(filepath); |
61a3c8b05b24
Add a new option in Preferences > Filtering to allow the
zas_
parents:
356
diff
changeset
|
865 } |
9 | 866 |
867 vdlist_populate(vdl); | |
868 | |
869 if (old_path) | |
870 { | |
871 /* scroll to make last path visible */ | |
872 FileData *found = NULL; | |
873 GList *work; | |
874 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
875 work = VDLIST_INFO(vdl, list); |
9 | 876 while (work && !found) |
877 { | |
878 FileData *fd = work->data; | |
879 if (strcmp(old_path, fd->name) == 0) found = fd; | |
880 work = work->next; | |
881 } | |
882 | |
883 if (found) vdlist_scroll_to_row(vdl, found, 0.5); | |
884 | |
885 g_free(old_path); | |
886 return ret; | |
887 } | |
888 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
889 if (GTK_WIDGET_REALIZED(vdl->view)) |
9 | 890 { |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
891 gtk_tree_view_scroll_to_point(GTK_TREE_VIEW(vdl->view), 0, 0); |
9 | 892 } |
893 | |
894 return ret; | |
895 } | |
896 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
897 void vdlist_refresh(ViewDir *vdl) |
9 | 898 { |
899 gchar *path; | |
900 | |
901 path = g_strdup(vdl->path); | |
902 vdl->path = NULL; | |
903 vdlist_set_path(vdl, path); | |
904 g_free(path); | |
905 } | |
906 | |
907 static void vdlist_menu_position_cb(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data) | |
908 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
909 ViewDir *vdl = data; |
9 | 910 GtkTreeModel *store; |
911 GtkTreeIter iter; | |
912 GtkTreePath *tpath; | |
913 gint cw, ch; | |
914 | |
915 if (vdlist_find_row(vdl, vdl->click_fd, &iter) < 0) return; | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
916 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdl->view)); |
9 | 917 tpath = gtk_tree_model_get_path(store, &iter); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
918 tree_view_get_cell_clamped(GTK_TREE_VIEW(vdl->view), tpath, 0, TRUE, x, y, &cw, &ch); |
9 | 919 gtk_tree_path_free(tpath); |
920 *y += ch; | |
921 popup_menu_position_clamp(menu, x, y, 0); | |
922 } | |
923 | |
924 static gint vdlist_press_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer data) | |
925 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
926 ViewDir *vdl = data; |
9 | 927 GtkTreePath *tpath; |
928 | |
929 if (event->keyval != GDK_Menu) return FALSE; | |
930 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
931 gtk_tree_view_get_cursor(GTK_TREE_VIEW(vdl->view), &tpath, NULL); |
9 | 932 if (tpath) |
933 { | |
934 GtkTreeModel *store; | |
935 GtkTreeIter iter; | |
936 | |
937 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
938 gtk_tree_model_get_iter(store, &iter, tpath); | |
939 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &vdl->click_fd, -1); | |
940 | |
941 gtk_tree_path_free(tpath); | |
942 } | |
943 else | |
944 { | |
945 vdl->click_fd = NULL; | |
946 } | |
947 | |
948 vdlist_color_set(vdl, vdl->click_fd, TRUE); | |
949 | |
950 vdl->popup = vdlist_pop_menu(vdl, vdl->click_fd); | |
951 | |
952 gtk_menu_popup(GTK_MENU(vdl->popup), NULL, NULL, vdlist_menu_position_cb, vdl, 0, GDK_CURRENT_TIME); | |
953 | |
954 return TRUE; | |
955 } | |
956 | |
957 static gint vdlist_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) | |
958 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
959 ViewDir *vdl = data; |
9 | 960 GtkTreePath *tpath; |
961 GtkTreeIter iter; | |
962 FileData *fd = NULL; | |
963 | |
964 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y, | |
965 &tpath, NULL, NULL, NULL)) | |
966 { | |
967 GtkTreeModel *store; | |
968 | |
969 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
970 gtk_tree_model_get_iter(store, &iter, tpath); | |
971 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1); | |
972 gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget), tpath, NULL, FALSE); | |
973 gtk_tree_path_free(tpath); | |
974 } | |
975 | |
976 vdl->click_fd = fd; | |
977 vdlist_color_set(vdl, vdl->click_fd, TRUE); | |
978 | |
979 if (bevent->button == 3) | |
980 { | |
981 vdl->popup = vdlist_pop_menu(vdl, vdl->click_fd); | |
982 gtk_menu_popup(GTK_MENU(vdl->popup), NULL, NULL, NULL, NULL, | |
983 bevent->button, bevent->time); | |
984 } | |
985 | |
986 return TRUE; | |
987 } | |
988 | |
989 static gint vdlist_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) | |
990 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
991 ViewDir *vdl = data; |
9 | 992 GtkTreePath *tpath; |
993 GtkTreeIter iter; | |
994 FileData *fd = NULL; | |
995 | |
996 vdlist_color_set(vdl, vdl->click_fd, FALSE); | |
997 | |
998 if (bevent->button != 1) return TRUE; | |
999 | |
1000 if ((bevent->x != 0 || bevent->y != 0) && | |
1001 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y, | |
1002 &tpath, NULL, NULL, NULL)) | |
1003 { | |
1004 GtkTreeModel *store; | |
1005 | |
1006 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
1007 gtk_tree_model_get_iter(store, &iter, tpath); | |
1008 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1); | |
1009 gtk_tree_path_free(tpath); | |
1010 } | |
1011 | |
1012 if (fd && vdl->click_fd == fd) | |
1013 { | |
1014 vdlist_select_row(vdl, vdl->click_fd); | |
1015 } | |
1016 | |
1017 return TRUE; | |
1018 } | |
1019 | |
1020 static void vdlist_select_cb(GtkTreeView *tview, GtkTreePath *tpath, GtkTreeViewColumn *column, gpointer data) | |
1021 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1022 ViewDir *vdl = data; |
9 | 1023 GtkTreeModel *store; |
1024 GtkTreeIter iter; | |
1025 FileData *fd; | |
1026 | |
1027 store = gtk_tree_view_get_model(tview); | |
1028 gtk_tree_model_get_iter(store, &iter, tpath); | |
1029 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1); | |
1030 | |
1031 vdlist_select_row(vdl, fd); | |
1032 } | |
1033 | |
1034 static GdkColor *vdlist_color_shifted(GtkWidget *widget) | |
1035 { | |
1036 static GdkColor color; | |
1037 static GtkWidget *done = NULL; | |
1038 | |
1039 if (done != widget) | |
1040 { | |
1041 GtkStyle *style; | |
1042 | |
1043 style = gtk_widget_get_style(widget); | |
1044 memcpy(&color, &style->base[GTK_STATE_NORMAL], sizeof(color)); | |
1045 shift_color(&color, -1, 0); | |
1046 done = widget; | |
1047 } | |
1048 | |
1049 return &color; | |
1050 } | |
1051 | |
1052 static void vdlist_color_cb(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, | |
1053 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) | |
1054 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1055 ViewDir *vdl = data; |
9 | 1056 gboolean set; |
1057 | |
1058 gtk_tree_model_get(tree_model, iter, DIR_COLUMN_COLOR, &set, -1); | |
1059 g_object_set(G_OBJECT(cell), | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1060 "cell-background-gdk", vdlist_color_shifted(vdl->view), |
9 | 1061 "cell-background-set", set, NULL); |
1062 } | |
1063 | |
1064 static void vdlist_destroy_cb(GtkWidget *widget, gpointer data) | |
1065 { | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1066 ViewDir *vdl = data; |
9 | 1067 |
1068 if (vdl->popup) | |
1069 { | |
1070 g_signal_handlers_disconnect_matched(G_OBJECT(vdl->popup), G_SIGNAL_MATCH_DATA, | |
1071 0, 0, 0, NULL, vdl); | |
1072 gtk_widget_destroy(vdl->popup); | |
1073 } | |
1074 | |
1075 vdlist_dnd_drop_scroll_cancel(vdl); | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1076 widget_auto_scroll_stop(vdl->view); |
9 | 1077 |
138 | 1078 filelist_free(vdl->drop_list); |
9 | 1079 |
1080 folder_icons_free(vdl->pf); | |
1081 | |
1082 g_free(vdl->path); | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1083 filelist_free(VDLIST_INFO(vdl, list)); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1084 g_free(vdl->info); |
9 | 1085 g_free(vdl); |
1086 } | |
1087 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1088 ViewDir *vdlist_new(const gchar *path) |
9 | 1089 { |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1090 ViewDir *vdl; |
9 | 1091 GtkListStore *store; |
1092 GtkTreeSelection *selection; | |
1093 GtkTreeViewColumn *column; | |
1094 GtkCellRenderer *renderer; | |
1095 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1096 vdl = g_new0(ViewDir, 1); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1097 vdl->info = g_new0(ViewDirInfoList, 1); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1098 vdl->type = DIRVIEW_LIST; |
9 | 1099 |
1100 vdl->path = NULL; | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1101 VDLIST_INFO(vdl, list) = NULL; |
9 | 1102 vdl->click_fd = NULL; |
1103 | |
1104 vdl->drop_fd = NULL; | |
1105 vdl->drop_list = NULL; | |
1106 | |
1107 vdl->drop_scroll_id = -1; | |
1108 | |
1109 vdl->popup = NULL; | |
1110 | |
1111 vdl->widget = gtk_scrolled_window_new(NULL, NULL); | |
1112 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(vdl->widget), GTK_SHADOW_IN); | |
1113 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(vdl->widget), | |
1114 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); | |
1115 g_signal_connect(G_OBJECT(vdl->widget), "destroy", | |
1116 G_CALLBACK(vdlist_destroy_cb), vdl); | |
1117 | |
1118 store = gtk_list_store_new(4, G_TYPE_POINTER, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_BOOLEAN); | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1119 vdl->view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); |
9 | 1120 g_object_unref(store); |
1121 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1122 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(vdl->view), FALSE); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1123 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(vdl->view), FALSE); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1124 g_signal_connect(G_OBJECT(vdl->view), "row_activated", |
9 | 1125 |
1126 G_CALLBACK(vdlist_select_cb), vdl); | |
1127 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1128 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vdl->view)); |
9 | 1129 gtk_tree_selection_set_mode(selection, GTK_SELECTION_NONE); |
1130 | |
1131 column = gtk_tree_view_column_new(); | |
1132 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); | |
1133 | |
1134 renderer = gtk_cell_renderer_pixbuf_new(); | |
1135 gtk_tree_view_column_pack_start(column, renderer, FALSE); | |
1136 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", DIR_COLUMN_ICON); | |
1137 gtk_tree_view_column_set_cell_data_func(column, renderer, vdlist_color_cb, vdl, NULL); | |
1138 | |
1139 renderer = gtk_cell_renderer_text_new(); | |
1140 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
1141 gtk_tree_view_column_add_attribute(column, renderer, "text", DIR_COLUMN_NAME); | |
1142 gtk_tree_view_column_set_cell_data_func(column, renderer, vdlist_color_cb, vdl, NULL); | |
1143 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1144 gtk_tree_view_append_column(GTK_TREE_VIEW(vdl->view), column); |
9 | 1145 |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1146 g_signal_connect(G_OBJECT(vdl->view), "key_press_event", |
9 | 1147 G_CALLBACK(vdlist_press_key_cb), vdl); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1148 gtk_container_add(GTK_CONTAINER(vdl->widget), vdl->view); |
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1149 gtk_widget_show(vdl->view); |
9 | 1150 |
1151 vdl->pf = folder_icons_new(); | |
1152 | |
1153 vdlist_dnd_init(vdl); | |
1154 | |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1155 g_signal_connect(G_OBJECT(vdl->view), "button_press_event", |
9 | 1156 G_CALLBACK(vdlist_press_cb), vdl); |
380
5afe77bb563a
Introduce a new struct ViewDir to handle directory views common
zas_
parents:
373
diff
changeset
|
1157 g_signal_connect(G_OBJECT(vdl->view), "button_release_event", |
9 | 1158 G_CALLBACK(vdlist_release_cb), vdl); |
1159 | |
1160 if (path) vdlist_set_path(vdl, path); | |
1161 | |
1162 return vdl; | |
1163 } |