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