Mercurial > geeqie.yaz
annotate src/view_dir_list.c @ 388:5186f8e38cb8
Make directory view popup menu common and move it to view_dir.{c,h}.
author | zas_ |
---|---|
date | Wed, 16 Apr 2008 20:36:10 +0000 |
parents | 2c06e06f4236 |
children | b78077f65eff |
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 gint vdlist_auto_scroll_notify_cb(GtkWidget *widget, gint x, gint y, gpointer data); | |
37 | |
38 /* | |
39 *----------------------------------------------------------------------------- | |
40 * misc | |
41 *----------------------------------------------------------------------------- | |
42 */ | |
43 | |
383
499d7ba62261
Move some dnd common code from view_dir_list.c and view_dir_tree.c
zas_
parents:
381
diff
changeset
|
44 gint vdlist_find_row(ViewDir *vd, FileData *fd, GtkTreeIter *iter) |
9 | 45 { |
46 GtkTreeModel *store; | |
47 gint valid; | |
48 gint row = 0; | |
49 | |
381 | 50 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view)); |
9 | 51 valid = gtk_tree_model_get_iter_first(store, iter); |
52 while (valid) | |
53 { | |
54 FileData *fd_n; | |
55 gtk_tree_model_get(GTK_TREE_MODEL(store), iter, DIR_COLUMN_POINTER, &fd_n, -1); | |
56 if (fd_n == fd) return row; | |
57 | |
58 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), iter); | |
59 row++; | |
60 } | |
61 | |
62 return -1; | |
63 } | |
64 | |
65 static gint vdlist_rename_row_cb(TreeEditData *td, const gchar *old, const gchar *new, gpointer data) | |
66 { | |
381 | 67 ViewDir *vd = data; |
9 | 68 GtkTreeModel *store; |
69 GtkTreeIter iter; | |
70 FileData *fd; | |
71 gchar *old_path; | |
72 gchar *new_path; | |
73 gchar *base; | |
74 | |
381 | 75 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view)); |
9 | 76 if (!gtk_tree_model_get_iter(store, &iter, td->path)) return FALSE; |
77 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1); | |
78 if (!fd) return FALSE; | |
79 | |
80 old_path = g_strdup(fd->path); | |
81 | |
82 base = remove_level_from_path(old_path); | |
83 new_path = concat_dir_and_file(base, new); | |
84 g_free(base); | |
85 | |
381 | 86 if (file_util_rename_dir(fd, new_path, vd->view)) |
9 | 87 { |
381 | 88 if (vd->layout && strcmp(vd->path, old_path) == 0) |
9 | 89 { |
381 | 90 layout_set_path(vd->layout, new_path); |
9 | 91 } |
92 else | |
93 { | |
381 | 94 vdlist_refresh(vd); |
9 | 95 } |
96 } | |
97 | |
98 g_free(old_path); | |
99 g_free(new_path); | |
100 return FALSE; | |
101 } | |
102 | |
388
5186f8e38cb8
Make directory view popup menu common and move it to view_dir.{c,h}.
zas_
parents:
385
diff
changeset
|
103 void vdlist_rename_by_row(ViewDir *vd, FileData *fd) |
9 | 104 { |
105 GtkTreeModel *store; | |
106 GtkTreePath *tpath; | |
107 GtkTreeIter iter; | |
108 | |
381 | 109 if (vdlist_find_row(vd, fd, &iter) < 0) return; |
110 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view)); | |
9 | 111 tpath = gtk_tree_model_get_path(store, &iter); |
112 | |
381 | 113 tree_edit_by_path(GTK_TREE_VIEW(vd->view), tpath, 0, fd->name, |
114 vdlist_rename_row_cb, vd); | |
9 | 115 gtk_tree_path_free(tpath); |
116 } | |
117 | |
388
5186f8e38cb8
Make directory view popup menu common and move it to view_dir.{c,h}.
zas_
parents:
385
diff
changeset
|
118 FileData *vdlist_row_by_path(ViewDir *vd, const gchar *path, gint *row) |
9 | 119 { |
120 GList *work; | |
121 gint n; | |
122 | |
123 if (!path) | |
124 { | |
125 if (row) *row = -1; | |
126 return NULL; | |
127 } | |
128 | |
129 n = 0; | |
381 | 130 work = VDLIST_INFO(vd, list); |
9 | 131 while (work) |
132 { | |
133 FileData *fd = work->data; | |
134 if (strcmp(fd->path, path) == 0) | |
135 { | |
136 if (row) *row = n; | |
137 return fd; | |
138 } | |
139 work = work->next; | |
140 n++; | |
141 } | |
142 | |
143 if (row) *row = -1; | |
144 return NULL; | |
145 } | |
146 | |
147 /* | |
148 *----------------------------------------------------------------------------- | |
149 * dnd | |
150 *----------------------------------------------------------------------------- | |
151 */ | |
152 | |
153 static GtkTargetEntry vdlist_dnd_drop_types[] = { | |
154 { "text/uri-list", 0, TARGET_URI_LIST } | |
155 }; | |
156 static gint vdlist_dnd_drop_types_count = 1; | |
157 | |
381 | 158 static void vdlist_dest_set(ViewDir *vd, gint enable) |
9 | 159 { |
160 if (enable) | |
161 { | |
381 | 162 gtk_drag_dest_set(vd->view, |
9 | 163 GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, |
164 vdlist_dnd_drop_types, vdlist_dnd_drop_types_count, | |
165 GDK_ACTION_MOVE | GDK_ACTION_COPY); | |
166 } | |
167 else | |
168 { | |
381 | 169 gtk_drag_dest_unset(vd->view); |
9 | 170 } |
171 } | |
172 | |
173 static void vdlist_dnd_get(GtkWidget *widget, GdkDragContext *context, | |
174 GtkSelectionData *selection_data, guint info, | |
175 guint time, gpointer data) | |
176 { | |
381 | 177 ViewDir *vd = data; |
9 | 178 GList *list; |
179 gchar *text = NULL; | |
180 gint length = 0; | |
181 | |
381 | 182 if (!vd->click_fd) return; |
9 | 183 |
184 switch (info) | |
185 { | |
186 case TARGET_URI_LIST: | |
187 case TARGET_TEXT_PLAIN: | |
381 | 188 list = g_list_prepend(NULL, vd->click_fd); |
138 | 189 text = uri_text_from_filelist(list, &length, (info == TARGET_TEXT_PLAIN)); |
9 | 190 g_list_free(list); |
191 break; | |
192 } | |
193 if (text) | |
194 { | |
195 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
|
196 8, (guchar *)text, length); |
9 | 197 g_free(text); |
198 } | |
199 } | |
200 | |
201 static void vdlist_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data) | |
202 { | |
381 | 203 ViewDir *vd = data; |
9 | 204 |
383
499d7ba62261
Move some dnd common code from view_dir_list.c and view_dir_tree.c
zas_
parents:
381
diff
changeset
|
205 vd_color_set(vd, vd->click_fd, TRUE); |
381 | 206 vdlist_dest_set(vd, FALSE); |
9 | 207 } |
208 | |
209 static void vdlist_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer data) | |
210 { | |
381 | 211 ViewDir *vd = data; |
9 | 212 |
383
499d7ba62261
Move some dnd common code from view_dir_list.c and view_dir_tree.c
zas_
parents:
381
diff
changeset
|
213 vd_color_set(vd, vd->click_fd, FALSE); |
9 | 214 |
215 if (context->action == GDK_ACTION_MOVE) | |
216 { | |
381 | 217 vdlist_refresh(vd); |
9 | 218 } |
381 | 219 vdlist_dest_set(vd, TRUE); |
9 | 220 } |
221 | |
222 static void vdlist_dnd_drop_receive(GtkWidget *widget, | |
223 GdkDragContext *context, gint x, gint y, | |
224 GtkSelectionData *selection_data, guint info, | |
225 guint time, gpointer data) | |
226 { | |
381 | 227 ViewDir *vd = data; |
9 | 228 GtkTreePath *tpath; |
229 GtkTreeIter iter; | |
230 FileData *fd = NULL; | |
231 | |
381 | 232 vd->click_fd = NULL; |
9 | 233 |
234 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), x, y, | |
235 &tpath, NULL, NULL, NULL)) | |
236 { | |
237 GtkTreeModel *store; | |
238 | |
239 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
240 gtk_tree_model_get_iter(store, &iter, tpath); | |
241 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1); | |
242 gtk_tree_path_free(tpath); | |
243 } | |
244 | |
245 if (!fd) return; | |
246 | |
247 if (info == TARGET_URI_LIST) | |
248 { | |
249 GList *list; | |
250 gint active; | |
251 | |
138 | 252 list = uri_filelist_from_text((gchar *)selection_data->data, TRUE); |
9 | 253 if (!list) return; |
254 | |
255 active = access_file(fd->path, W_OK | X_OK); | |
256 | |
383
499d7ba62261
Move some dnd common code from view_dir_list.c and view_dir_tree.c
zas_
parents:
381
diff
changeset
|
257 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
|
258 vd->popup = vd_drop_menu(vd, active); |
381 | 259 gtk_menu_popup(GTK_MENU(vd->popup), NULL, NULL, NULL, NULL, 0, time); |
9 | 260 |
381 | 261 vd->drop_fd = fd; |
262 vd->drop_list = list; | |
9 | 263 } |
264 } | |
265 | |
266 #if 0 | |
381 | 267 static gint vdlist_get_row_visibility(ViewDir *vd, FileData *fd) |
9 | 268 { |
269 GtkTreeModel *store; | |
270 GtkTreeViewColumn *column; | |
271 GtkTreePath *tpath; | |
272 GtkTreeIter iter; | |
273 | |
274 GdkRectangle vrect; | |
275 GdkRectangle crect; | |
276 | |
381 | 277 if (!fd || vdlist_find_row(vd, fd, &iter) < 0) return 0; |
9 | 278 |
381 | 279 column = gtk_tree_view_get_column(GTK_TREE_VIEW(vd->view), 0); |
280 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view)); | |
9 | 281 tpath = gtk_tree_model_get_path(store, &iter); |
282 | |
381 | 283 gtk_tree_view_get_visible_rect(GTK_TREE_VIEW(vd->view), &vrect); |
284 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(vd->view), tpath, column, &crect); | |
9 | 285 printf("window: %d + %d; cell: %d + %d\n", vrect.y, vrect.height, crect.y, crect.height); |
286 gtk_tree_path_free(tpath); | |
287 | |
288 if (crect.y + crect.height < vrect.y) return -1; | |
289 if (crect.y > vrect.y + vrect.height) return 1; | |
290 return 0; | |
291 } | |
292 #endif | |
293 | |
381 | 294 static void vdlist_scroll_to_row(ViewDir *vd, FileData *fd, gfloat y_align) |
9 | 295 { |
296 GtkTreeIter iter; | |
297 | |
381 | 298 if (GTK_WIDGET_REALIZED(vd->view) && |
299 vdlist_find_row(vd, fd, &iter) >= 0) | |
9 | 300 { |
301 GtkTreeModel *store; | |
302 GtkTreePath *tpath; | |
303 | |
381 | 304 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view)); |
9 | 305 tpath = gtk_tree_model_get_path(store, &iter); |
381 | 306 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(vd->view), tpath, NULL, TRUE, y_align, 0.0); |
307 gtk_tree_view_set_cursor(GTK_TREE_VIEW(vd->view), tpath, NULL, FALSE); | |
9 | 308 gtk_tree_path_free(tpath); |
309 | |
381 | 310 if (!GTK_WIDGET_HAS_FOCUS(vd->view)) gtk_widget_grab_focus(vd->view); |
9 | 311 } |
312 } | |
313 | |
381 | 314 static void vdlist_drop_update(ViewDir *vd, gint x, gint y) |
9 | 315 { |
316 GtkTreePath *tpath; | |
317 GtkTreeIter iter; | |
318 FileData *fd = NULL; | |
319 | |
381 | 320 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vd->view), x, y, |
9 | 321 &tpath, NULL, NULL, NULL)) |
322 { | |
323 GtkTreeModel *store; | |
324 | |
381 | 325 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view)); |
9 | 326 gtk_tree_model_get_iter(store, &iter, tpath); |
327 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1); | |
328 gtk_tree_path_free(tpath); | |
329 } | |
330 | |
381 | 331 if (fd != vd->drop_fd) |
9 | 332 { |
383
499d7ba62261
Move some dnd common code from view_dir_list.c and view_dir_tree.c
zas_
parents:
381
diff
changeset
|
333 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
|
334 vd_color_set(vd, fd, TRUE); |
9 | 335 } |
336 | |
381 | 337 vd->drop_fd = fd; |
9 | 338 } |
339 | |
381 | 340 static void vdlist_dnd_drop_scroll_cancel(ViewDir *vd) |
9 | 341 { |
381 | 342 if (vd->drop_scroll_id != -1) g_source_remove(vd->drop_scroll_id); |
343 vd->drop_scroll_id = -1; | |
9 | 344 } |
345 | |
346 static gint vdlist_auto_scroll_idle_cb(gpointer data) | |
347 { | |
381 | 348 ViewDir *vd = data; |
9 | 349 |
381 | 350 if (vd->drop_fd) |
9 | 351 { |
352 GdkWindow *window; | |
353 gint x, y; | |
354 gint w, h; | |
355 | |
381 | 356 window = vd->view->window; |
9 | 357 gdk_window_get_pointer(window, &x, &y, NULL); |
358 gdk_drawable_get_size(window, &w, &h); | |
359 if (x >= 0 && x < w && y >= 0 && y < h) | |
360 { | |
381 | 361 vdlist_drop_update(vd, x, y); |
9 | 362 } |
363 } | |
364 | |
381 | 365 vd->drop_scroll_id = -1; |
9 | 366 return FALSE; |
367 } | |
368 | |
369 static gint vdlist_auto_scroll_notify_cb(GtkWidget *widget, gint x, gint y, gpointer data) | |
370 { | |
381 | 371 ViewDir *vd = data; |
9 | 372 |
381 | 373 if (!vd->drop_fd || vd->drop_list) return FALSE; |
9 | 374 |
381 | 375 if (vd->drop_scroll_id == -1) vd->drop_scroll_id = g_idle_add(vdlist_auto_scroll_idle_cb, vd); |
9 | 376 |
377 return TRUE; | |
378 } | |
379 | |
380 static gint vdlist_dnd_drop_motion(GtkWidget *widget, GdkDragContext *context, | |
381 gint x, gint y, guint time, gpointer data) | |
382 { | |
381 | 383 ViewDir *vd = data; |
9 | 384 |
381 | 385 vd->click_fd = NULL; |
9 | 386 |
381 | 387 if (gtk_drag_get_source_widget(context) == vd->view) |
9 | 388 { |
389 /* from same window */ | |
390 gdk_drag_status(context, 0, time); | |
391 return TRUE; | |
392 } | |
393 else | |
394 { | |
395 gdk_drag_status(context, context->suggested_action, time); | |
396 } | |
397 | |
381 | 398 vdlist_drop_update(vd, x, y); |
9 | 399 |
381 | 400 if (vd->drop_fd) |
9 | 401 { |
381 | 402 GtkAdjustment *adj = gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(vd->view)); |
403 widget_auto_scroll_start(vd->view, adj, -1, -1, vdlist_auto_scroll_notify_cb, vd); | |
9 | 404 } |
405 | |
406 return FALSE; | |
407 } | |
408 | |
409 static void vdlist_dnd_drop_leave(GtkWidget *widget, GdkDragContext *context, guint time, gpointer data) | |
410 { | |
381 | 411 ViewDir *vd = data; |
9 | 412 |
383
499d7ba62261
Move some dnd common code from view_dir_list.c and view_dir_tree.c
zas_
parents:
381
diff
changeset
|
413 if (vd->drop_fd != vd->click_fd) vd_color_set(vd, vd->drop_fd, FALSE); |
9 | 414 |
381 | 415 vd->drop_fd = NULL; |
9 | 416 } |
417 | |
381 | 418 static void vdlist_dnd_init(ViewDir *vd) |
9 | 419 { |
381 | 420 gtk_drag_source_set(vd->view, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, |
9 | 421 dnd_file_drag_types, dnd_file_drag_types_count, |
422 GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); | |
381 | 423 g_signal_connect(G_OBJECT(vd->view), "drag_data_get", |
424 G_CALLBACK(vdlist_dnd_get), vd); | |
425 g_signal_connect(G_OBJECT(vd->view), "drag_begin", | |
426 G_CALLBACK(vdlist_dnd_begin), vd); | |
427 g_signal_connect(G_OBJECT(vd->view), "drag_end", | |
428 G_CALLBACK(vdlist_dnd_end), vd); | |
9 | 429 |
381 | 430 vdlist_dest_set(vd, TRUE); |
431 g_signal_connect(G_OBJECT(vd->view), "drag_data_received", | |
432 G_CALLBACK(vdlist_dnd_drop_receive), vd); | |
433 g_signal_connect(G_OBJECT(vd->view), "drag_motion", | |
434 G_CALLBACK(vdlist_dnd_drop_motion), vd); | |
435 g_signal_connect(G_OBJECT(vd->view), "drag_leave", | |
436 G_CALLBACK(vdlist_dnd_drop_leave), vd); | |
9 | 437 } |
438 | |
439 /* | |
440 *----------------------------------------------------------------------------- | |
441 * main | |
442 *----------------------------------------------------------------------------- | |
443 */ | |
444 | |
381 | 445 static void vdlist_select_row(ViewDir *vd, FileData *fd) |
9 | 446 { |
381 | 447 if (fd && vd->select_func) |
9 | 448 { |
449 gchar *path; | |
450 | |
451 path = g_strdup(fd->path); | |
381 | 452 vd->select_func(vd, path, vd->select_data); |
9 | 453 g_free(path); |
454 } | |
455 } | |
456 | |
381 | 457 const gchar *vdlist_row_get_path(ViewDir *vd, gint row) |
9 | 458 { |
459 FileData *fd; | |
460 | |
381 | 461 fd = g_list_nth_data(VDLIST_INFO(vd, list), row); |
9 | 462 |
463 if (fd) return fd->path; | |
464 | |
465 return NULL; | |
466 } | |
467 | |
381 | 468 static void vdlist_populate(ViewDir *vd) |
9 | 469 { |
470 GtkListStore *store; | |
471 GList *work; | |
472 | |
381 | 473 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view))); |
9 | 474 gtk_list_store_clear(store); |
475 | |
381 | 476 work = VDLIST_INFO(vd, list); |
9 | 477 while (work) |
478 { | |
479 FileData *fd; | |
480 GtkTreeIter iter; | |
481 GdkPixbuf *pixbuf; | |
482 | |
483 fd = work->data; | |
484 | |
485 if (access_file(fd->path, R_OK | X_OK) && fd->name) | |
486 { | |
487 if (fd->name[0] == '.' && fd->name[1] == '\0') | |
488 { | |
381 | 489 pixbuf = vd->pf->open; |
9 | 490 } |
491 else if (fd->name[0] == '.' && fd->name[1] == '.' && fd->name[2] == '\0') | |
492 { | |
381 | 493 pixbuf = vd->pf->parent; |
9 | 494 } |
495 else | |
496 { | |
381 | 497 pixbuf = vd->pf->close; |
9 | 498 } |
499 } | |
500 else | |
501 { | |
381 | 502 pixbuf = vd->pf->deny; |
9 | 503 } |
504 | |
505 gtk_list_store_append(store, &iter); | |
506 gtk_list_store_set(store, &iter, | |
507 DIR_COLUMN_POINTER, fd, | |
508 DIR_COLUMN_ICON, pixbuf, | |
509 DIR_COLUMN_NAME, fd->name, -1); | |
510 | |
511 work = work->next; | |
512 } | |
513 | |
381 | 514 vd->click_fd = NULL; |
515 vd->drop_fd = NULL; | |
9 | 516 } |
517 | |
381 | 518 gint vdlist_set_path(ViewDir *vd, const gchar *path) |
9 | 519 { |
520 gint ret; | |
521 FileData *fd; | |
522 gchar *old_path = NULL; | |
138 | 523 gchar *filepath; |
9 | 524 |
525 if (!path) return FALSE; | |
381 | 526 if (vd->path && strcmp(path, vd->path) == 0) return TRUE; |
9 | 527 |
381 | 528 if (vd->path) |
9 | 529 { |
530 gchar *base; | |
531 | |
381 | 532 base = remove_level_from_path(vd->path); |
9 | 533 if (strcmp(base, path) == 0) |
534 { | |
381 | 535 old_path = g_strdup(filename_from_path(vd->path)); |
9 | 536 } |
537 g_free(base); | |
538 } | |
539 | |
381 | 540 g_free(vd->path); |
541 vd->path = g_strdup(path); | |
9 | 542 |
381 | 543 filelist_free(VDLIST_INFO(vd, list)); |
544 VDLIST_INFO(vd, list) = NULL; | |
9 | 545 |
381 | 546 ret = filelist_read(vd->path, NULL, &VDLIST_INFO(vd, list)); |
9 | 547 |
381 | 548 VDLIST_INFO(vd, list) = filelist_sort(VDLIST_INFO(vd, list), SORT_NAME, TRUE); |
9 | 549 |
550 /* add . and .. */ | |
551 | |
381 | 552 if (strcmp(vd->path, "/") != 0) |
9 | 553 { |
381 | 554 filepath = g_strconcat(vd->path, "/", "..", NULL); |
138 | 555 fd = file_data_new_simple(filepath); |
381 | 556 VDLIST_INFO(vd, list) = g_list_prepend(VDLIST_INFO(vd, list), fd); |
138 | 557 g_free(filepath); |
9 | 558 } |
373
61a3c8b05b24
Add a new option in Preferences > Filtering to allow the
zas_
parents:
356
diff
changeset
|
559 |
61a3c8b05b24
Add a new option in Preferences > Filtering to allow the
zas_
parents:
356
diff
changeset
|
560 if (options->file_filter.show_dot_directory) |
61a3c8b05b24
Add a new option in Preferences > Filtering to allow the
zas_
parents:
356
diff
changeset
|
561 { |
381 | 562 filepath = g_strconcat(vd->path, "/", ".", NULL); |
373
61a3c8b05b24
Add a new option in Preferences > Filtering to allow the
zas_
parents:
356
diff
changeset
|
563 fd = file_data_new_simple(filepath); |
381 | 564 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
|
565 g_free(filepath); |
61a3c8b05b24
Add a new option in Preferences > Filtering to allow the
zas_
parents:
356
diff
changeset
|
566 } |
9 | 567 |
381 | 568 vdlist_populate(vd); |
9 | 569 |
570 if (old_path) | |
571 { | |
572 /* scroll to make last path visible */ | |
573 FileData *found = NULL; | |
574 GList *work; | |
575 | |
381 | 576 work = VDLIST_INFO(vd, list); |
9 | 577 while (work && !found) |
578 { | |
579 FileData *fd = work->data; | |
580 if (strcmp(old_path, fd->name) == 0) found = fd; | |
581 work = work->next; | |
582 } | |
583 | |
381 | 584 if (found) vdlist_scroll_to_row(vd, found, 0.5); |
9 | 585 |
586 g_free(old_path); | |
587 return ret; | |
588 } | |
589 | |
381 | 590 if (GTK_WIDGET_REALIZED(vd->view)) |
9 | 591 { |
381 | 592 gtk_tree_view_scroll_to_point(GTK_TREE_VIEW(vd->view), 0, 0); |
9 | 593 } |
594 | |
595 return ret; | |
596 } | |
597 | |
381 | 598 void vdlist_refresh(ViewDir *vd) |
9 | 599 { |
600 gchar *path; | |
601 | |
381 | 602 path = g_strdup(vd->path); |
603 vd->path = NULL; | |
604 vdlist_set_path(vd, path); | |
9 | 605 g_free(path); |
606 } | |
607 | |
608 static void vdlist_menu_position_cb(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data) | |
609 { | |
381 | 610 ViewDir *vd = data; |
9 | 611 GtkTreeModel *store; |
612 GtkTreeIter iter; | |
613 GtkTreePath *tpath; | |
614 gint cw, ch; | |
615 | |
381 | 616 if (vdlist_find_row(vd, vd->click_fd, &iter) < 0) return; |
617 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view)); | |
9 | 618 tpath = gtk_tree_model_get_path(store, &iter); |
381 | 619 tree_view_get_cell_clamped(GTK_TREE_VIEW(vd->view), tpath, 0, TRUE, x, y, &cw, &ch); |
9 | 620 gtk_tree_path_free(tpath); |
621 *y += ch; | |
622 popup_menu_position_clamp(menu, x, y, 0); | |
623 } | |
624 | |
625 static gint vdlist_press_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer data) | |
626 { | |
381 | 627 ViewDir *vd = data; |
9 | 628 GtkTreePath *tpath; |
629 | |
630 if (event->keyval != GDK_Menu) return FALSE; | |
631 | |
381 | 632 gtk_tree_view_get_cursor(GTK_TREE_VIEW(vd->view), &tpath, NULL); |
9 | 633 if (tpath) |
634 { | |
635 GtkTreeModel *store; | |
636 GtkTreeIter iter; | |
637 | |
638 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
639 gtk_tree_model_get_iter(store, &iter, tpath); | |
381 | 640 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &vd->click_fd, -1); |
9 | 641 |
642 gtk_tree_path_free(tpath); | |
643 } | |
644 else | |
645 { | |
381 | 646 vd->click_fd = NULL; |
9 | 647 } |
648 | |
383
499d7ba62261
Move some dnd common code from view_dir_list.c and view_dir_tree.c
zas_
parents:
381
diff
changeset
|
649 vd_color_set(vd, vd->click_fd, TRUE); |
9 | 650 |
388
5186f8e38cb8
Make directory view popup menu common and move it to view_dir.{c,h}.
zas_
parents:
385
diff
changeset
|
651 vd->popup = vd_pop_menu(vd, vd->click_fd); |
9 | 652 |
381 | 653 gtk_menu_popup(GTK_MENU(vd->popup), NULL, NULL, vdlist_menu_position_cb, vd, 0, GDK_CURRENT_TIME); |
9 | 654 |
655 return TRUE; | |
656 } | |
657 | |
658 static gint vdlist_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) | |
659 { | |
381 | 660 ViewDir *vd = data; |
9 | 661 GtkTreePath *tpath; |
662 GtkTreeIter iter; | |
663 FileData *fd = NULL; | |
664 | |
665 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y, | |
666 &tpath, NULL, NULL, NULL)) | |
667 { | |
668 GtkTreeModel *store; | |
669 | |
670 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
671 gtk_tree_model_get_iter(store, &iter, tpath); | |
672 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1); | |
673 gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget), tpath, NULL, FALSE); | |
674 gtk_tree_path_free(tpath); | |
675 } | |
676 | |
381 | 677 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
|
678 vd_color_set(vd, vd->click_fd, TRUE); |
9 | 679 |
680 if (bevent->button == 3) | |
681 { | |
388
5186f8e38cb8
Make directory view popup menu common and move it to view_dir.{c,h}.
zas_
parents:
385
diff
changeset
|
682 vd->popup = vd_pop_menu(vd, vd->click_fd); |
381 | 683 gtk_menu_popup(GTK_MENU(vd->popup), NULL, NULL, NULL, NULL, |
9 | 684 bevent->button, bevent->time); |
685 } | |
686 | |
687 return TRUE; | |
688 } | |
689 | |
690 static gint vdlist_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) | |
691 { | |
381 | 692 ViewDir *vd = data; |
9 | 693 GtkTreePath *tpath; |
694 GtkTreeIter iter; | |
695 FileData *fd = NULL; | |
696 | |
383
499d7ba62261
Move some dnd common code from view_dir_list.c and view_dir_tree.c
zas_
parents:
381
diff
changeset
|
697 vd_color_set(vd, vd->click_fd, FALSE); |
9 | 698 |
699 if (bevent->button != 1) return TRUE; | |
700 | |
701 if ((bevent->x != 0 || bevent->y != 0) && | |
702 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y, | |
703 &tpath, NULL, NULL, NULL)) | |
704 { | |
705 GtkTreeModel *store; | |
706 | |
707 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
708 gtk_tree_model_get_iter(store, &iter, tpath); | |
709 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1); | |
710 gtk_tree_path_free(tpath); | |
711 } | |
712 | |
381 | 713 if (fd && vd->click_fd == fd) |
9 | 714 { |
381 | 715 vdlist_select_row(vd, vd->click_fd); |
9 | 716 } |
717 | |
718 return TRUE; | |
719 } | |
720 | |
721 static void vdlist_select_cb(GtkTreeView *tview, GtkTreePath *tpath, GtkTreeViewColumn *column, gpointer data) | |
722 { | |
381 | 723 ViewDir *vd = data; |
9 | 724 GtkTreeModel *store; |
725 GtkTreeIter iter; | |
726 FileData *fd; | |
727 | |
728 store = gtk_tree_view_get_model(tview); | |
729 gtk_tree_model_get_iter(store, &iter, tpath); | |
730 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1); | |
731 | |
381 | 732 vdlist_select_row(vd, fd); |
9 | 733 } |
734 | |
735 static GdkColor *vdlist_color_shifted(GtkWidget *widget) | |
736 { | |
737 static GdkColor color; | |
738 static GtkWidget *done = NULL; | |
739 | |
740 if (done != widget) | |
741 { | |
742 GtkStyle *style; | |
384
392dd6541d51
Merge parts of view_dir_list/tree constructors/destructors to
zas_
parents:
383
diff
changeset
|
743 |
9 | 744 style = gtk_widget_get_style(widget); |
745 memcpy(&color, &style->base[GTK_STATE_NORMAL], sizeof(color)); | |
746 shift_color(&color, -1, 0); | |
747 done = widget; | |
748 } | |
749 | |
750 return &color; | |
751 } | |
752 | |
753 static void vdlist_color_cb(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, | |
754 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) | |
755 { | |
381 | 756 ViewDir *vd = data; |
9 | 757 gboolean set; |
758 | |
759 gtk_tree_model_get(tree_model, iter, DIR_COLUMN_COLOR, &set, -1); | |
760 g_object_set(G_OBJECT(cell), | |
381 | 761 "cell-background-gdk", vdlist_color_shifted(vd->view), |
9 | 762 "cell-background-set", set, NULL); |
763 } | |
764 | |
765 static void vdlist_destroy_cb(GtkWidget *widget, gpointer data) | |
766 { | |
381 | 767 ViewDir *vd = data; |
9 | 768 |
381 | 769 vdlist_dnd_drop_scroll_cancel(vd); |
770 widget_auto_scroll_stop(vd->view); | |
9 | 771 |
381 | 772 filelist_free(VDLIST_INFO(vd, list)); |
9 | 773 } |
774 | |
384
392dd6541d51
Merge parts of view_dir_list/tree constructors/destructors to
zas_
parents:
383
diff
changeset
|
775 ViewDir *vdlist_new(ViewDir *vd, const gchar *path) |
9 | 776 { |
777 GtkListStore *store; | |
778 GtkTreeSelection *selection; | |
779 GtkTreeViewColumn *column; | |
780 GtkCellRenderer *renderer; | |
781 | |
381 | 782 vd->info = g_new0(ViewDirInfoList, 1); |
783 vd->type = DIRVIEW_LIST; | |
384
392dd6541d51
Merge parts of view_dir_list/tree constructors/destructors to
zas_
parents:
383
diff
changeset
|
784 vd->widget_destroy_cb = vdlist_destroy_cb; |
9 | 785 |
384
392dd6541d51
Merge parts of view_dir_list/tree constructors/destructors to
zas_
parents:
383
diff
changeset
|
786 VDLIST_INFO(vd, list) = NULL; |
9 | 787 |
788 store = gtk_list_store_new(4, G_TYPE_POINTER, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_BOOLEAN); | |
381 | 789 vd->view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); |
9 | 790 g_object_unref(store); |
791 | |
381 | 792 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(vd->view), FALSE); |
793 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(vd->view), FALSE); | |
794 g_signal_connect(G_OBJECT(vd->view), "row_activated", | |
9 | 795 |
381 | 796 G_CALLBACK(vdlist_select_cb), vd); |
9 | 797 |
381 | 798 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vd->view)); |
9 | 799 gtk_tree_selection_set_mode(selection, GTK_SELECTION_NONE); |
800 | |
801 column = gtk_tree_view_column_new(); | |
802 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); | |
803 | |
804 renderer = gtk_cell_renderer_pixbuf_new(); | |
805 gtk_tree_view_column_pack_start(column, renderer, FALSE); | |
806 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", DIR_COLUMN_ICON); | |
381 | 807 gtk_tree_view_column_set_cell_data_func(column, renderer, vdlist_color_cb, vd, NULL); |
9 | 808 |
809 renderer = gtk_cell_renderer_text_new(); | |
810 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
811 gtk_tree_view_column_add_attribute(column, renderer, "text", DIR_COLUMN_NAME); | |
381 | 812 gtk_tree_view_column_set_cell_data_func(column, renderer, vdlist_color_cb, vd, NULL); |
9 | 813 |
381 | 814 gtk_tree_view_append_column(GTK_TREE_VIEW(vd->view), column); |
9 | 815 |
381 | 816 g_signal_connect(G_OBJECT(vd->view), "key_press_event", |
817 G_CALLBACK(vdlist_press_key_cb), vd); | |
818 gtk_container_add(GTK_CONTAINER(vd->widget), vd->view); | |
819 gtk_widget_show(vd->view); | |
9 | 820 |
381 | 821 vdlist_dnd_init(vd); |
9 | 822 |
381 | 823 g_signal_connect(G_OBJECT(vd->view), "button_press_event", |
824 G_CALLBACK(vdlist_press_cb), vd); | |
825 g_signal_connect(G_OBJECT(vd->view), "button_release_event", | |
826 G_CALLBACK(vdlist_release_cb), vd); | |
9 | 827 |
381 | 828 if (path) vdlist_set_path(vd, path); |
9 | 829 |
381 | 830 return vd; |
9 | 831 } |