1 /*
2 * Copyright (C) 2005 Sasha Vasko <sasha at aftercode.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 */
19
20 #define LOCAL_DEBUG
21 #include "../configure.h"
22
23 #include "../libAfterStep/asapp.h"
24 #include "../libAfterStep/screen.h"
25 #include "../libAfterImage/afterimage.h"
26
27
28 #include "asgtk.h"
29 #include "asgtkai.h"
30 #include "asgtkimagedir.h"
31 #include "asgtkimageview.h"
32 #include "asgtkimagebrowser.h"
33
34 #define DIR_LIST_WIDTH 200
35 #define DIR_LIST_HEIGHT 150
36 #define FILE_LIST_WIDTH 200
37 #define FILE_LIST_HEIGHT 210
38 #define PREVIEW_WIDTH 480
39 #define PREVIEW_HEIGHT 360
40
41
42 /* local function prototypes */
43 static void asgtk_image_browser_class_init (ASGtkImageBrowserClass *
44 klass);
45 static void asgtk_image_browser_init (ASGtkImageBrowser * ib);
46 static void asgtk_image_browser_dispose (GObject * object);
47 static void asgtk_image_browser_finalize (GObject * object);
48 static void asgtk_image_browser_style_set (GtkWidget * widget,
49 GtkStyle * prev_style);
50
51 /* private variables */
52 static GtkWindowClass *parent_class = NULL;
53
asgtk_image_browser_get_type(void)54 GType asgtk_image_browser_get_type (void)
55 {
56 static GType ib_type = 0;
57
58 if (!ib_type) {
59 static const GTypeInfo ib_info = {
60 sizeof (ASGtkImageBrowserClass),
61 (GBaseInitFunc) NULL,
62 (GBaseFinalizeFunc) NULL,
63 (GClassInitFunc) asgtk_image_browser_class_init,
64 NULL, /* class_finalize */
65 NULL, /* class_data */
66 sizeof (ASGtkImageBrowser),
67 0, /* n_preallocs */
68 (GInstanceInitFunc) asgtk_image_browser_init,
69 };
70
71 ib_type =
72 g_type_register_static (GTK_TYPE_WINDOW, "ASGtkImageBrowser",
73 &ib_info, 0);
74 }
75
76 return ib_type;
77 }
78
asgtk_image_browser_class_init(ASGtkImageBrowserClass * klass)79 static void asgtk_image_browser_class_init (ASGtkImageBrowserClass * klass)
80 {
81 GObjectClass *object_class = G_OBJECT_CLASS (klass);
82 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
83
84 parent_class = g_type_class_peek_parent (klass);
85
86 object_class->dispose = asgtk_image_browser_dispose;
87 object_class->finalize = asgtk_image_browser_finalize;
88
89 widget_class->style_set = asgtk_image_browser_style_set;
90
91 }
92
asgtk_image_browser_init(ASGtkImageBrowser * ib)93 static void asgtk_image_browser_init (ASGtkImageBrowser * ib)
94 {
95 }
96
asgtk_image_browser_dispose(GObject * object)97 static void asgtk_image_browser_dispose (GObject * object)
98 {
99 /* ASGtkImageBrowser *ib = ASGTK_IMAGE_BROWSER (object); */
100 G_OBJECT_CLASS (parent_class)->dispose (object);
101 }
102
asgtk_image_browser_finalize(GObject * object)103 static void asgtk_image_browser_finalize (GObject * object)
104 {
105 G_OBJECT_CLASS (parent_class)->finalize (object);
106 }
107
108 static void
asgtk_image_browser_style_set(GtkWidget * widget,GtkStyle * prev_style)109 asgtk_image_browser_style_set (GtkWidget * widget, GtkStyle * prev_style)
110 {
111 /* ASGtkImageBrowser *id = ASGTK_IMAGE_BROWSER (widget); */
112
113 GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style);
114 }
115
asgtk_image_browser_make_fullfilename(ASGtkImageBrowser * ib,const char * filename)116 static char *asgtk_image_browser_make_fullfilename (ASGtkImageBrowser * ib,
117 const char *filename)
118 {
119 if (filename[0] == '.' && filename[1] == '\0')
120 return mystrdup (ib->current_dir);
121
122 if (filename[0] == '.' && filename[1] == '.' && filename[2] == '\0') {
123 char *sep = strrchr (ib->current_dir, '/');
124
125 if (sep > ib->current_dir)
126 return mystrndup (ib->current_dir, sep - ib->current_dir);
127
128 return mystrdup ("/");
129 }
130
131 if (filename[0] == '/')
132 return mystrdup (filename);
133
134 return make_file_name (ib->current_dir, filename);
135 }
136
137 static void
asgtk_image_browser_dir_activate(GtkTreeView * tree_view,GtkTreePath * path,GtkTreeViewColumn * column,gpointer user_data)138 asgtk_image_browser_dir_activate (GtkTreeView * tree_view,
139 GtkTreePath * path,
140 GtkTreeViewColumn * column,
141 gpointer user_data)
142 {
143 ASGtkImageBrowser *ib = ASGTK_IMAGE_BROWSER (user_data);
144 GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
145 GtkTreeIter iter;
146 char *filename;
147
148 gtk_tree_model_get_iter (model, &iter, path);
149 gtk_tree_model_get (model, &iter, 0, &filename, -1);
150 LOCAL_DEBUG_OUT ("filename == \"%s\"", filename);
151 /* TODO : change directory/populate file list */
152 if (filename[0] == '.' && filename[1] == '\0') {
153 /* already in current dir - do nothing */
154 } else {
155 filename = asgtk_image_browser_make_fullfilename (ib, filename);
156 asgtk_image_browser_change_dir (ib, filename);
157 free (filename);
158 }
159 }
160
161 static void
asgtk_image_browser_dir_select(GtkTreeSelection * selection,gpointer user_data)162 asgtk_image_browser_dir_select (GtkTreeSelection * selection,
163 gpointer user_data)
164 {
165 ASGtkImageBrowser *ib = ASGTK_IMAGE_BROWSER (user_data);
166 char *filename;
167 GtkTreeIter iter;
168 GtkTreeModel *model;
169
170 if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
171 gtk_tree_model_get (model, &iter, 0, &filename, -1);
172 LOCAL_DEBUG_OUT ("filename == \"%s\"", filename);
173 /* TODO : change directory/populate file list */
174 if (filename[0] == '.' && filename[1] == '\0')
175 asgtk_image_dir_set_path (ASGTK_IMAGE_DIR (ib->image_dir),
176 ib->current_dir);
177 else {
178 filename = asgtk_image_browser_make_fullfilename (ib, filename);
179 asgtk_image_dir_set_path (ASGTK_IMAGE_DIR (ib->image_dir), filename);
180 free (filename);
181 }
182 }
183 }
184
on_root_clicked(GtkButton * button,gpointer user_data)185 static void on_root_clicked (GtkButton * button, gpointer user_data)
186 {
187 ASGtkImageBrowser *ib = ASGTK_IMAGE_BROWSER (user_data);
188
189 asgtk_image_browser_change_dir (ib, "/");
190 }
191
on_home_clicked(GtkButton * button,gpointer user_data)192 static void on_home_clicked (GtkButton * button, gpointer user_data)
193 {
194 ASGtkImageBrowser *ib = ASGTK_IMAGE_BROWSER (user_data);
195
196 asgtk_image_browser_change_dir (ib, "~/");
197 }
198
199
200 static void
asgtk_image_browser_path_entry(GtkWidget * widget,gpointer data)201 asgtk_image_browser_path_entry (GtkWidget * widget, gpointer data)
202 {
203 ASGtkImageBrowser *ib = ASGTK_IMAGE_BROWSER (data);
204
205 if (ib->path_entry) {
206 const gchar *entry_text =
207 gtk_entry_get_text (GTK_ENTRY (ib->path_entry));
208
209 asgtk_image_browser_change_dir (ib, entry_text);
210 }
211 }
212
213 static void
asgtk_image_browser_path_changed(GtkWidget * widget,gpointer data)214 asgtk_image_browser_path_changed (GtkWidget * widget, gpointer data)
215 {
216 ASGtkImageBrowser *ib = ASGTK_IMAGE_BROWSER (data);
217
218 if (ib) {
219 const gchar *entry_text =
220 asgtk_combo_box_get_active_text (GTK_COMBO_BOX (ib->path_combo));
221
222 asgtk_image_browser_change_dir (ib, entry_text);
223 }
224 }
225
226 static void
asgtk_image_browser_scale_toggle(GtkWidget * checkbutton,gpointer data)227 asgtk_image_browser_scale_toggle (GtkWidget * checkbutton, gpointer data)
228 {
229 ASGtkImageBrowser *ib = ASGTK_IMAGE_BROWSER (data);
230
231 asgtk_image_view_set_resize (ib->preview,
232 GTK_TOGGLE_BUTTON (checkbutton)->active ?
233 ASGTK_IMAGE_VIEW_SCALE_TO_VIEW : 0,
234 ASGTK_IMAGE_VIEW_SCALE_TO_VIEW);
235 }
236
237
238
239 static void
asgtk_image_browser_create_dir_list(ASGtkImageBrowser * ib,GtkWidget * list_vbox)240 asgtk_image_browser_create_dir_list (ASGtkImageBrowser * ib,
241 GtkWidget * list_vbox)
242 {
243 GtkWidget *scrolled_win, *model;
244 GtkTreeViewColumn *column;
245
246 model = GTK_WIDGET (gtk_list_store_new (1, G_TYPE_STRING));
247 ib->dir_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
248 g_object_unref (model);
249
250 column =
251 gtk_tree_view_column_new_with_attributes ("Folders",
252 gtk_cell_renderer_text_new
253 (), "text", 0, NULL);
254 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
255 gtk_tree_view_append_column (GTK_TREE_VIEW (ib->dir_list), column);
256
257 gtk_widget_set_size_request (ib->dir_list, DIR_LIST_WIDTH,
258 DIR_LIST_HEIGHT);
259 g_signal_connect (ib->dir_list, "row_activated",
260 G_CALLBACK (asgtk_image_browser_dir_activate), ib);
261 g_signal_connect (gtk_tree_view_get_selection
262 (GTK_TREE_VIEW (ib->dir_list)), "changed",
263 G_CALLBACK (asgtk_image_browser_dir_select), ib);
264
265 scrolled_win =
266 ASGTK_SCROLLED_WINDOW (GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS,
267 GTK_SHADOW_IN);
268
269 ASGTK_CONTAINER_CONFIG (scrolled_win, DIR_LIST_WIDTH, DIR_LIST_HEIGHT,
270 0);
271 ASGTK_CONTAINER_ADD (scrolled_win, ib->dir_list);
272 if (GTK_IS_PANED (list_vbox))
273 gtk_paned_pack1 (GTK_PANED (list_vbox), GTK_WIDGET (scrolled_win),
274 TRUE, TRUE);
275 else
276 gtk_box_pack_end (GTK_BOX (list_vbox), GTK_WIDGET (scrolled_win), TRUE,
277 TRUE, 0);
278
279 gtk_widget_show (scrolled_win);
280 colorize_gtk_tree_view_window (GTK_WIDGET (scrolled_win));
281 }
282
283 static void
asgtk_image_browser_file_sel_handler(ASGtkImageDir * id,gpointer user_data)284 asgtk_image_browser_file_sel_handler (ASGtkImageDir * id,
285 gpointer user_data)
286 {
287 ASGtkImageBrowser *ib = ASGTK_IMAGE_BROWSER (user_data);
288
289 g_return_if_fail (ASGTK_IS_IMAGE_DIR (id));
290 if (ib) {
291 ASImageListEntry *le = asgtk_image_dir_get_selection (id);
292
293 asgtk_image_view_set_entry (ib->preview, le);
294 if (le)
295 unref_asimage_list_entry (le);
296 }
297 }
298
299
300 /* public functions */
asgtk_image_browser_new()301 GtkWidget *asgtk_image_browser_new ()
302 {
303 ASGtkImageBrowser *ib;
304 GtkWidget *main_vbox;
305 GtkWidget *shortcuts_hbox, *btn;
306 GtkWidget *list_vbox, *preview_vbox;
307
308 ib = g_object_new (ASGTK_TYPE_IMAGE_BROWSER, NULL);
309 colorize_gtk_window (GTK_WIDGET (ib));
310
311 gtk_container_set_border_width (GTK_CONTAINER (ib), 5);
312 main_vbox = gtk_vbox_new (FALSE, 0);
313 gtk_widget_show (main_vbox);
314 gtk_container_add (GTK_CONTAINER (ib), main_vbox);
315 gtk_box_set_spacing (GTK_BOX (main_vbox), 5);
316
317 shortcuts_hbox = gtk_hbox_new (FALSE, 0);
318 gtk_widget_show (shortcuts_hbox);
319 gtk_box_pack_start (GTK_BOX (main_vbox), shortcuts_hbox, FALSE, FALSE,
320 0);
321 gtk_box_set_spacing (GTK_BOX (shortcuts_hbox), 5);
322
323 btn =
324 asgtk_add_button_to_box (GTK_BOX (shortcuts_hbox),
325 GTK_STOCK_GOTO_TOP, "/",
326 G_CALLBACK (on_root_clicked), ib);
327 gtk_widget_set_size_request (btn, 50, -1);
328 btn =
329 asgtk_add_button_to_box (GTK_BOX (shortcuts_hbox), GTK_STOCK_HOME,
330 "~/", G_CALLBACK (on_home_clicked), ib);
331 gtk_widget_set_size_request (btn, 50, -1);
332
333 ib->path_combo = gtk_combo_box_entry_new_text ();
334 //gtk_widget_set_size_request ( ib->path_combo, DIR_LIST_WIDTH+300-105 , -1);
335 gtk_box_pack_end (GTK_BOX (shortcuts_hbox), ib->path_combo, TRUE, TRUE,
336 10);
337 gtk_widget_show (ib->path_combo);
338 colorize_gtk_edit (ib->path_combo);
339 ib->path_entry = NULL;
340 /* path_entry is actually found trough the following discovery process : */
341 if (GTK_IS_CONTAINER (ib->path_combo))
342 gtk_container_forall (GTK_CONTAINER (ib->path_combo),
343 find_combobox_entry, &(ib->path_entry));
344 /* if above succeeded then path_entry should be not NULL here : */
345 if (ib->path_entry)
346 g_signal_connect (G_OBJECT (ib->path_entry), "activate",
347 G_CALLBACK (asgtk_image_browser_path_entry),
348 (gpointer) ib);
349 g_signal_connect (G_OBJECT (ib->path_combo), "changed",
350 G_CALLBACK (asgtk_image_browser_path_changed),
351 (gpointer) ib);
352
353
354 #if 0
355 ib->list_hbox = gtk_hbox_new (FALSE, 0);
356 #else
357 ib->list_hbox = gtk_hpaned_new ();
358 colorize_gtk_widget (ib->list_hbox, get_colorschemed_style_normal ());
359 #endif
360 gtk_widget_show (ib->list_hbox);
361 gtk_box_pack_start (GTK_BOX (main_vbox), ib->list_hbox, TRUE, TRUE, 0);
362
363 ib->main_buttons_hbox = gtk_hbutton_box_new ();
364 gtk_hbutton_box_set_layout_default (GTK_BUTTONBOX_SPREAD);
365 gtk_widget_show (ib->main_buttons_hbox);
366 gtk_box_pack_end (GTK_BOX (main_vbox), ib->main_buttons_hbox, FALSE,
367 FALSE, 5);
368
369
370 /* separator really goes above the buttons box, so it is added second from the end ! */
371 ib->separator = gtk_hseparator_new ();
372 gtk_box_pack_end (GTK_BOX (main_vbox), ib->separator, FALSE, FALSE, 5);
373 colorize_gtk_widget (GTK_WIDGET (ib->separator),
374 get_colorschemed_style_button ());
375
376 /* now designing dirlist controls : */
377 #if 0
378 list_vbox = gtk_vbox_new (FALSE, 0);
379 #else
380 list_vbox = gtk_vpaned_new ();
381 colorize_gtk_widget (list_vbox, get_colorschemed_style_normal ());
382 #endif
383 gtk_widget_show (list_vbox);
384
385 if (GTK_IS_PANED (ib->list_hbox))
386 gtk_paned_pack1 (GTK_PANED (ib->list_hbox), list_vbox, FALSE, FALSE);
387 else
388 gtk_box_pack_start (GTK_BOX (ib->list_hbox), list_vbox, FALSE, FALSE,
389 0);
390
391 /* dir list : */
392 asgtk_image_browser_create_dir_list (ib, list_vbox);
393 /* image file list : */
394 ib->image_dir = ASGTK_IMAGE_DIR (asgtk_image_dir_new ());
395 if (GTK_IS_PANED (list_vbox))
396 gtk_paned_pack2 (GTK_PANED (list_vbox), GTK_WIDGET (ib->image_dir),
397 TRUE, TRUE);
398 else
399 gtk_box_pack_end (GTK_BOX (list_vbox), GTK_WIDGET (ib->image_dir),
400 TRUE, TRUE, 0);
401
402 gtk_widget_set_size_request (GTK_WIDGET (ib->image_dir), FILE_LIST_WIDTH,
403 FILE_LIST_HEIGHT);
404 gtk_widget_show (GTK_WIDGET (ib->image_dir));
405
406 asgtk_image_dir_set_title (ASGTK_IMAGE_DIR (ib->image_dir),
407 "Image files:");
408
409 /* now designing preview controls : */
410 preview_vbox = gtk_vbox_new (FALSE, 0);
411 gtk_widget_show (preview_vbox);
412 if (GTK_IS_PANED (ib->list_hbox))
413 gtk_paned_pack2 (GTK_PANED (ib->list_hbox), preview_vbox, TRUE, TRUE);
414 else
415 gtk_box_pack_end (GTK_BOX (ib->list_hbox), preview_vbox, TRUE, TRUE,
416 5);
417
418 ib->preview = ASGTK_IMAGE_VIEW (asgtk_image_view_new ());
419 gtk_widget_set_size_request (GTK_WIDGET (ib->preview), PREVIEW_WIDTH,
420 PREVIEW_HEIGHT);
421 gtk_box_pack_start (GTK_BOX (preview_vbox), GTK_WIDGET (ib->preview),
422 TRUE, TRUE, 0);
423 gtk_widget_show (GTK_WIDGET (ib->preview));
424 asgtk_image_view_set_resize (ib->preview, ASGTK_IMAGE_VIEW_SCALE_TO_VIEW,
425 ASGTK_IMAGE_VIEW_RESIZE_ALL);
426
427 ib->scale_check_box = gtk_check_button_new_with_label ("Scale to fit");
428 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ib->scale_check_box),
429 TRUE);
430 gtk_widget_show (ib->scale_check_box);
431 colorize_gtk_widget (ib->scale_check_box,
432 get_colorschemed_style_normal ());
433 g_signal_connect (G_OBJECT (ib->scale_check_box), "toggled",
434 G_CALLBACK (asgtk_image_browser_scale_toggle),
435 (gpointer) ib);
436
437 gtk_button_set_alignment (GTK_BUTTON (ib->scale_check_box), 1.0, 0.5);
438 asgtk_image_view_add_detail (ib->preview, ib->scale_check_box, 0);
439 /* changing to default dir : */
440 asgtk_image_dir_set_sel_handler (ASGTK_IMAGE_DIR (ib->image_dir),
441 asgtk_image_browser_file_sel_handler,
442 ib);
443 asgtk_image_browser_change_dir (ib, NULL);
444
445 LOCAL_DEBUG_OUT ("created image ASGtkImageBrowser object %p", ib);
446 return GTK_WIDGET (ib);
447 }
448
asgtk_image_browser_add_main_button(ASGtkImageBrowser * ib,const char * stock,GCallback func,gpointer user_data)449 GtkWidget *asgtk_image_browser_add_main_button (ASGtkImageBrowser * ib,
450 const char *stock,
451 GCallback func,
452 gpointer user_data)
453 {
454 if (!ASGTK_IS_IMAGE_BROWSER (ib))
455 return NULL;
456
457 gtk_widget_show (ib->separator);
458 return asgtk_add_button_to_box (GTK_BOX (ib->main_buttons_hbox), stock,
459 NULL, func, user_data);
460 }
461
asgtk_image_browser_add_selection_button(ASGtkImageBrowser * ib,const char * stock,GCallback func)462 GtkWidget *asgtk_image_browser_add_selection_button (ASGtkImageBrowser *
463 ib, const char *stock,
464 GCallback func)
465 {
466 GtkWidget *btn;
467
468 if (!ASGTK_IS_IMAGE_BROWSER (ib))
469 return NULL;
470
471 btn = asgtk_add_button_to_box (NULL, stock, NULL, func, ib->image_dir);
472 asgtk_image_view_add_tool (ib->preview, btn, 0);
473 return btn;
474 }
475
asgtk_image_browser_refresh(ASGtkImageBrowser * ib)476 void asgtk_image_browser_refresh (ASGtkImageBrowser * ib)
477 {
478 GtkListStore *dir_store;
479 GtkTreeIter iter;
480
481 g_return_if_fail (ASGTK_IS_IMAGE_BROWSER (ib));
482 LOCAL_DEBUG_OUT (" refreshing %p: current dir = \"%s\"", ib,
483 ib->current_dir ? ib->current_dir : "null");
484 asgtk_image_dir_set_path (ASGTK_IMAGE_DIR (ib->image_dir),
485 ib->current_dir);
486 dir_store =
487 GTK_LIST_STORE (gtk_tree_view_get_model
488 (GTK_TREE_VIEW (ib->dir_list)));
489 gtk_list_store_clear (dir_store);
490 if (ib->current_dir != NULL) {
491 /* Add current dir entry as the first item : */
492 gtk_list_store_append (dir_store, &iter);
493 gtk_list_store_set (dir_store, &iter, 0, ".", -1);
494
495 if (strcmp (ib->current_dir, "/") != 0) {
496 gtk_list_store_append (dir_store, &iter);
497 gtk_list_store_set (dir_store, &iter, 0, "..", -1);
498 }
499
500 /* Add subdirs : */
501 {
502 struct direntry **list = NULL;
503 int n = my_scandir (ib->current_dir, &list, NULL, NULL);
504
505 LOCAL_DEBUG_OUT (" scandir indicates %d entries in list", n);
506 if (n > 0) {
507 int i;
508
509 for (i = 0; i < n; i++) {
510 if (S_ISDIR (list[i]->d_mode)) {
511 Bool skip = False;
512
513 if (list[i]->d_name[0] == '.') {
514 skip = (list[i]->d_name[1] == '\0' ||
515 (list[i]->d_name[1] == '.'
516 && list[i]->d_name[2] == '\0'));
517 }
518 if (!skip) {
519 gtk_list_store_append (dir_store, &iter);
520 gtk_list_store_set (dir_store, &iter, 0, list[i]->d_name,
521 -1);
522 }
523 }
524 free (list[i]);
525 }
526 free (list);
527 }
528 }
529
530 /* Add dirs above us : */
531 {
532 char *above_dir = mystrdup (ib->current_dir);
533 int i = strlen (above_dir) - 1;
534
535 while (--i > 0) {
536 if (above_dir[i] == '/') {
537 above_dir[i] = '\0';
538 gtk_list_store_append (dir_store, &iter);
539 gtk_list_store_set (dir_store, &iter, 0, above_dir, -1);
540 }
541 }
542 }
543 }
544 if (ib->current_dir == NULL || strcmp (ib->current_dir, "/") != 0) {
545 gtk_list_store_append (dir_store, &iter);
546 gtk_list_store_set (dir_store, &iter, 0, "/", -1);
547 }
548 /*
549 :sG:
550 The following 3 lines make the file lists sorted by
551 the Directory Name, Ascending.
552
553 For general directory listing (not files)
554 */
555 GtkTreeSortable *sortable;
556
557 sortable = GTK_TREE_SORTABLE (dir_store);
558 gtk_tree_sortable_set_sort_column_id (sortable, 0, GTK_SORT_ASCENDING);
559
560
561 }
562
add_dir_to_history(ASGtkImageBrowser * ib,const char * dir)563 static void add_dir_to_history (ASGtkImageBrowser * ib, const char *dir)
564 {
565 g_signal_handlers_block_by_func (G_OBJECT (ib->path_combo),
566 G_CALLBACK
567 (asgtk_image_browser_path_changed),
568 (gpointer) ib);
569
570 asgtk_combo_box_add_to_history (GTK_COMBO_BOX (ib->path_combo), dir);
571 g_signal_handlers_unblock_by_func (G_OBJECT (ib->path_combo),
572 G_CALLBACK
573 (asgtk_image_browser_path_changed),
574 (gpointer) ib);
575
576 }
577
578 void
asgtk_image_browser_change_dir(ASGtkImageBrowser * ib,const char * dir)579 asgtk_image_browser_change_dir (ASGtkImageBrowser * ib, const char *dir)
580 {
581 char *fullfilename;
582 int fullnamelen;
583
584 g_return_if_fail (ASGTK_IS_IMAGE_BROWSER (ib));
585
586 if (dir == NULL)
587 fullfilename = PutHome ("~/");
588 else if (dir[0] == '/')
589 fullfilename = mystrdup (dir);
590 else
591 fullfilename = PutHome (dir);
592
593 fullnamelen = strlen (fullfilename);
594 while (fullnamelen > 1 && fullfilename[fullnamelen - 1] == '/') {
595 fullfilename[fullnamelen - 1] = '\0';
596 --fullnamelen;
597 }
598
599 LOCAL_DEBUG_OUT
600 (" changing dir for %p: current dir = \"%s\", new dir = \"%s\"", ib,
601 ib->current_dir ? ib->current_dir : "null", fullfilename);
602 if (ib->current_dir == NULL
603 || strcmp (ib->current_dir, fullfilename) != 0) {
604 char *title = safemalloc (128 + fullnamelen + 1);
605
606 if (ib->current_dir)
607 free (ib->current_dir);
608
609 ib->current_dir = fullfilename;
610 sprintf (title, "AfterStep image browser: %s", fullfilename);
611 gtk_window_set_title (GTK_WINDOW (ib), title);
612 free (title);
613 add_dir_to_history (ib, fullfilename);
614 asgtk_image_browser_refresh (ib);
615 }
616
617 }
618