4 * Copyright (C) 2008 The Geeqie Team
8 * This software is released under the GNU General Public License (GNU GPL).
9 * Please read the included file COPYING for more information.
10 * This software comes with no warranty of any kind, use at your own risk!
17 #include "color-man.h"
18 #include "layout_config.h"
19 #include "layout_image.h"
20 #include "layout_util.h"
22 #include "pixbuf-renderer.h"
23 #include "pixbuf_util.h"
26 #include "view_file_list.h"
27 #include "view_file_icon.h"
28 #include "ui_bookmark.h"
29 #include "ui_fileops.h"
32 #include "ui_tabcomp.h"
33 #include "histogram.h"
36 #define MAINWINDOW_DEF_WIDTH 700
37 #define MAINWINDOW_DEF_HEIGHT 500
39 #define MAIN_WINDOW_DIV_HPOS 270
40 #define MAIN_WINDOW_DIV_VPOS 200
42 #define TOOLWINDOW_DEF_WIDTH 260
43 #define TOOLWINDOW_DEF_HEIGHT 450
44 #define PROGRESS_WIDTH 150
45 #define ZOOM_LABEL_WIDTH 64
47 #define PANE_DIVIDER_SIZE 10
50 GList *layout_window_list = NULL;
53 static void layout_list_scroll_to_subpart(LayoutWindow *lw, const gchar *needle);
57 *-----------------------------------------------------------------------------
59 *-----------------------------------------------------------------------------
62 gint layout_valid(LayoutWindow **lw)
66 if (layout_window_list) *lw = layout_window_list->data;
70 return (g_list_find(layout_window_list, *lw) != NULL);
73 LayoutWindow *layout_find_by_image(ImageWindow *imd)
77 work = layout_window_list;
80 LayoutWindow *lw = work->data;
83 if (lw->image == imd) return lw;
89 LayoutWindow *layout_find_by_image_fd(ImageWindow *imd)
93 work = layout_window_list;
96 LayoutWindow *lw = work->data;
98 if (lw->image->image_fd == imd->image_fd)
107 *-----------------------------------------------------------------------------
108 * menu, toolbar, and dir view
109 *-----------------------------------------------------------------------------
112 static void layout_path_entry_changed_cb(GtkWidget *widget, gpointer data)
114 LayoutWindow *lw = data;
117 if (gtk_combo_box_get_active(GTK_COMBO_BOX(widget)) < 0) return;
119 buf = g_strdup(gtk_entry_get_text(GTK_ENTRY(lw->path_entry)));
120 if (!buf || (lw->path && strcmp(buf, lw->path) == 0))
126 layout_set_path(lw, buf);
131 static void layout_path_entry_tab_cb(const gchar *path, gpointer data)
133 LayoutWindow *lw = data;
137 buf = g_strdup(path);
138 parse_out_relatives(buf);
139 base = remove_level_from_path(buf);
143 if ((!lw->path || strcmp(lw->path, buf) != 0) && layout_set_path(lw, buf))
146 /* put the '/' back, if we are in tab completion for a dir and result was path change */
147 gtk_editable_insert_text(GTK_EDITABLE(lw->path_entry), "/", -1, &pos);
148 gtk_editable_set_position(GTK_EDITABLE(lw->path_entry),
149 strlen(gtk_entry_get_text(GTK_ENTRY(lw->path_entry))));
152 else if (lw->path && strcmp(lw->path, base) == 0)
154 layout_list_scroll_to_subpart(lw, filename_from_path(buf));
161 static void layout_path_entry_cb(const gchar *path, gpointer data)
163 LayoutWindow *lw = data;
166 buf = g_strdup(path);
167 parse_out_relatives(buf);
169 layout_set_path(lw, buf);
174 static void layout_vd_select_cb(ViewDir *vd, const gchar *path, gpointer data)
176 LayoutWindow *lw = data;
178 layout_set_path(lw, path);
181 static GtkWidget *layout_tool_setup(LayoutWindow *lw)
187 box = gtk_vbox_new(FALSE, 0);
189 menu_bar = layout_actions_menu_bar(lw);
190 gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, FALSE, 0);
191 gtk_widget_show(menu_bar);
193 lw->toolbar = layout_button_bar(lw);
194 gtk_box_pack_start(GTK_BOX(box), lw->toolbar, FALSE, FALSE, 0);
195 if (!lw->toolbar_hidden) gtk_widget_show(lw->toolbar);
197 tabcomp = tab_completion_new_with_history(&lw->path_entry, NULL, "path_list", -1,
198 layout_path_entry_cb, lw);
199 tab_completion_add_tab_func(lw->path_entry, layout_path_entry_tab_cb, lw);
200 gtk_box_pack_start(GTK_BOX(box), tabcomp, FALSE, FALSE, 0);
201 gtk_widget_show(tabcomp);
203 g_signal_connect(G_OBJECT(lw->path_entry->parent), "changed",
204 G_CALLBACK(layout_path_entry_changed_cb), lw);
206 lw->vd = vd_new(lw->dir_view_type, lw->path);
207 vd_set_layout(lw->vd, lw);
208 vd_set_select_func(lw->vd, layout_vd_select_cb, lw);
210 lw->dir_view = lw->vd->widget;
212 gtk_box_pack_start(GTK_BOX(box), lw->dir_view, TRUE, TRUE, 0);
213 gtk_widget_show(lw->dir_view);
215 gtk_widget_show(box);
221 *-----------------------------------------------------------------------------
222 * sort button (and menu)
223 *-----------------------------------------------------------------------------
226 static void layout_sort_menu_cb(GtkWidget *widget, gpointer data)
231 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) return;
233 lw = submenu_item_get_data(widget);
236 type = (SortType)GPOINTER_TO_INT(data);
238 layout_sort_set(lw, type, lw->sort_ascend);
241 static void layout_sort_menu_ascend_cb(GtkWidget *widget, gpointer data)
243 LayoutWindow *lw = data;
245 layout_sort_set(lw, lw->sort_method, !lw->sort_ascend);
248 static void layout_sort_menu_hide_cb(GtkWidget *widget, gpointer data)
250 /* destroy the menu */
251 gtk_widget_unref(GTK_WIDGET(widget));
254 static void layout_sort_button_press_cb(GtkWidget *widget, gpointer data)
256 LayoutWindow *lw = data;
261 menu = submenu_add_sort(NULL, G_CALLBACK(layout_sort_menu_cb), lw, FALSE, FALSE, TRUE, lw->sort_method);
263 /* take ownership of menu */
264 #ifdef GTK_OBJECT_FLOATING
266 g_object_ref(G_OBJECT(menu));
267 gtk_object_sink(GTK_OBJECT(menu));
270 g_object_ref_sink(G_OBJECT(menu));
273 /* ascending option */
274 menu_item_add_divider(menu);
275 menu_item_add_check(menu, _("Ascending"), lw->sort_ascend, G_CALLBACK(layout_sort_menu_ascend_cb), lw);
277 g_signal_connect(G_OBJECT(menu), "selection_done",
278 G_CALLBACK(layout_sort_menu_hide_cb), NULL);
280 event = gtk_get_current_event();
283 etime = gdk_event_get_time(event);
284 gdk_event_free(event);
291 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, etime);
294 static GtkWidget *layout_sort_button(LayoutWindow *lw)
298 button = gtk_button_new_with_label(sort_type_get_text(lw->sort_method));
299 g_signal_connect(G_OBJECT(button), "clicked",
300 G_CALLBACK(layout_sort_button_press_cb), lw);
301 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
307 *-----------------------------------------------------------------------------
308 * color profile button (and menu)
309 *-----------------------------------------------------------------------------
312 static void layout_color_menu_enable_cb(GtkWidget *widget, gpointer data)
314 LayoutWindow *lw = data;
316 layout_image_color_profile_set_use(lw, (!layout_image_color_profile_get_use(lw)));
317 layout_image_refresh(lw);
320 static void layout_color_menu_use_image_cb(GtkWidget *widget, gpointer data)
322 LayoutWindow *lw = data;
323 gint input, screen, use_image;
325 if (!layout_image_color_profile_get(lw, &input, &screen, &use_image)) return;
326 layout_image_color_profile_set(lw, input, screen, !use_image);
327 layout_image_refresh(lw);
330 #define COLOR_MENU_KEY "color_menu_key"
332 static void layout_color_menu_input_cb(GtkWidget *widget, gpointer data)
334 LayoutWindow *lw = data;
336 gint input, screen, use_image;
338 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) return;
340 type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), COLOR_MENU_KEY));
341 if (type < 0 || type >= COLOR_PROFILE_FILE + COLOR_PROFILE_INPUTS) return;
343 if (!layout_image_color_profile_get(lw, &input, &screen, &use_image)) return;
344 if (type == input) return;
346 layout_image_color_profile_set(lw, type, screen, use_image);
347 layout_image_refresh(lw);
350 static void layout_color_menu_screen_cb(GtkWidget *widget, gpointer data)
352 LayoutWindow *lw = data;
354 gint input, screen, use_image;
356 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) return;
358 type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), COLOR_MENU_KEY));
359 if (type < 0 || type > 1) return;
361 if (!layout_image_color_profile_get(lw, &input, &screen, &use_image)) return;
362 if (type == screen) return;
364 layout_image_color_profile_set(lw, input, type, use_image);
365 layout_image_refresh(lw);
368 static gchar *layout_color_name_parse(const gchar *name)
370 if (!name) return g_strdup(_("Empty"));
371 return g_strdelimit(g_strdup(name), "_", '-');
374 static void layout_color_button_press_cb(GtkWidget *widget, gpointer data)
377 gchar *msg = g_strdup_printf(_("This installation of %s was not built with support for color profiles."), GQ_APPNAME);
378 file_util_warning_dialog(_("Color profiles not supported"),
380 GTK_STOCK_DIALOG_INFO, widget);
384 LayoutWindow *lw = data;
397 if (!layout_image_color_profile_get(lw, &input, &screen, &use_image)) return;
399 from_image = use_image && (layout_image_color_profile_get_from_image(lw) != COLOR_PROFILE_NONE);
400 menu = popup_menu_short_lived();
402 active = layout_image_color_profile_get_use(lw);
403 menu_item_add_check(menu, _("Use _color profiles"), active,
404 G_CALLBACK(layout_color_menu_enable_cb), lw);
406 menu_item_add_divider(menu);
408 item = menu_item_add_check(menu, _("Use profile from _image"), use_image,
409 G_CALLBACK(layout_color_menu_use_image_cb), lw);
410 gtk_widget_set_sensitive(item, active);
412 for (i = COLOR_PROFILE_SRGB; i < COLOR_PROFILE_FILE; i++)
414 front = g_strdup_printf(_("Input _%d:"), i);
415 buf = g_strdup_printf("%s %s", front, i == COLOR_PROFILE_SRGB ? _("sRGB") : _("AdobeRGB compatible"));
417 item = menu_item_add_radio(menu, (i == 0) ? NULL : item,
419 G_CALLBACK(layout_color_menu_input_cb), lw);
421 g_object_set_data(G_OBJECT(item), COLOR_MENU_KEY, GINT_TO_POINTER(i));
422 gtk_widget_set_sensitive(item, active && !from_image);
425 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
429 name = options->color_profile.input_name[i];
430 if (!name) name = filename_from_path(options->color_profile.input_file[i]);
432 front = g_strdup_printf(_("Input _%d:"), i + COLOR_PROFILE_FILE);
433 end = layout_color_name_parse(name);
434 buf = g_strdup_printf("%s %s", front, end);
438 item = menu_item_add_radio(menu, item,
439 buf, (i + COLOR_PROFILE_FILE == input),
440 G_CALLBACK(layout_color_menu_input_cb), lw);
442 g_object_set_data(G_OBJECT(item), COLOR_MENU_KEY, GINT_TO_POINTER(i + COLOR_PROFILE_FILE));
443 gtk_widget_set_sensitive(item, active && options->color_profile.input_file[i] && !from_image);
446 menu_item_add_divider(menu);
448 buf = g_strdup_printf("%s sRGB", _("Screen"));
449 item = menu_item_add_radio(menu, NULL,
451 G_CALLBACK(layout_color_menu_screen_cb), lw);
453 g_object_set_data(G_OBJECT(item), COLOR_MENU_KEY, GINT_TO_POINTER(0));
454 gtk_widget_set_sensitive(item, active);
456 item = menu_item_add_radio(menu, item,
457 _("_Screen profile"), (screen == 1),
458 G_CALLBACK(layout_color_menu_screen_cb), lw);
459 g_object_set_data(G_OBJECT(item), COLOR_MENU_KEY, GINT_TO_POINTER(1));
460 gtk_widget_set_sensitive(item, active && options->color_profile.screen_file);
462 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, GDK_CURRENT_TIME);
463 #endif /* HAVE_LCMS */
466 static GtkWidget *layout_color_button(LayoutWindow *lw)
472 button = gtk_button_new();
473 image = gtk_image_new_from_stock(GTK_STOCK_SELECT_COLOR, GTK_ICON_SIZE_MENU);
474 gtk_container_add(GTK_CONTAINER(button), image);
475 gtk_widget_show(image);
476 g_signal_connect(G_OBJECT(button), "clicked",
477 G_CALLBACK(layout_color_button_press_cb), lw);
478 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
481 enable = (lw->image) ? lw->image->color_profile_enable : FALSE;
485 gtk_widget_set_sensitive(image, enable);
492 *-----------------------------------------------------------------------------
494 *-----------------------------------------------------------------------------
497 void layout_status_update_progress(LayoutWindow *lw, gdouble val, const gchar *text)
499 if (!layout_valid(&lw)) return;
500 if (!lw->info_progress_bar) return;
502 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(lw->info_progress_bar), val);
503 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(lw->info_progress_bar), (text) ? text : " ");
506 void layout_status_update_info(LayoutWindow *lw, const gchar *text)
510 if (!layout_valid(&lw)) return;
520 if (layout_image_slideshow_active(lw))
522 if (!layout_image_slideshow_paused(lw))
524 ss = _(" Slideshow");
536 n = layout_list_count(lw, &n_bytes);
537 s = layout_selection_count(lw, &s_bytes);
539 layout_bars_new_selection(lw, s);
543 gchar *b = text_from_size_abrev(n_bytes);
544 gchar *sb = text_from_size_abrev(s_bytes);
545 buf = g_strdup_printf(_("%s, %d files (%s, %d)%s"), b, n, sb, s, ss);
551 gchar *b = text_from_size_abrev(n_bytes);
552 buf = g_strdup_printf(_("%s, %d files%s"), b, n, ss);
557 buf = g_strdup_printf(_("%d files%s"), n, ss);
562 layout_image_overlay_update(lw);
565 gtk_label_set_text(GTK_LABEL(lw->info_status), text);
569 void layout_status_update_image(LayoutWindow *lw)
574 if (!layout_valid(&lw) || !lw->image) return;
576 text = image_zoom_get_as_text(lw->image);
577 gtk_label_set_text(GTK_LABEL(lw->info_zoom), text);
580 b = text_from_size(lw->image->size);
582 if (lw->image->unknown)
584 if (image_get_path(lw->image) && !access_file(image_get_path(lw->image), R_OK))
586 text = g_strdup_printf(_("(no read permission) %s bytes"), b);
590 text = g_strdup_printf(_("( ? x ? ) %s bytes"), b);
597 pixbuf_renderer_get_image_size(PIXBUF_RENDERER(lw->image->pr), &width, &height);
598 text = g_strdup_printf(_("( %d x %d ) %s bytes"),
602 gtk_label_set_text(GTK_LABEL(lw->info_details), text);
608 void layout_status_update_all(LayoutWindow *lw)
610 layout_status_update_progress(lw, 0.0, NULL);
611 layout_status_update_info(lw, NULL);
612 layout_status_update_image(lw);
615 static GtkWidget *layout_status_label(gchar *text, GtkWidget *box, gint start, gint size, gint expand)
620 frame = gtk_frame_new(NULL);
621 if (size) gtk_widget_set_size_request(frame, size, -1);
622 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
625 gtk_box_pack_start(GTK_BOX(box), frame, expand, expand, 0);
629 gtk_box_pack_end(GTK_BOX(box), frame, expand, expand, 0);
631 gtk_widget_show(frame);
633 label = gtk_label_new(text ? text : "");
634 gtk_container_add(GTK_CONTAINER(frame), label);
635 gtk_widget_show(label);
640 static void layout_status_setup(LayoutWindow *lw, GtkWidget *box, gint small_format)
644 if (lw->info_box) return;
648 lw->info_box = gtk_vbox_new(FALSE, 0);
652 lw->info_box = gtk_hbox_new(FALSE, 0);
654 gtk_box_pack_end(GTK_BOX(box), lw->info_box, FALSE, FALSE, 0);
655 gtk_widget_show(lw->info_box);
659 hbox = gtk_hbox_new(FALSE, 0);
660 gtk_box_pack_start(GTK_BOX(lw->info_box), hbox, FALSE, FALSE, 0);
661 gtk_widget_show(hbox);
667 lw->info_progress_bar = gtk_progress_bar_new();
668 gtk_widget_set_size_request(lw->info_progress_bar, PROGRESS_WIDTH, -1);
669 gtk_box_pack_start(GTK_BOX(hbox), lw->info_progress_bar, FALSE, FALSE, 0);
670 gtk_widget_show(lw->info_progress_bar);
672 lw->info_sort = layout_sort_button(lw);
673 gtk_box_pack_start(GTK_BOX(hbox), lw->info_sort, FALSE, FALSE, 0);
674 gtk_widget_show(lw->info_sort);
676 lw->info_color = layout_color_button(lw);
677 gtk_widget_show(lw->info_color);
679 if (small_format) gtk_box_pack_end(GTK_BOX(hbox), lw->info_color, FALSE, FALSE, 0);
681 lw->info_status = layout_status_label(NULL, lw->info_box, TRUE, 0, (!small_format));
685 hbox = gtk_hbox_new(FALSE, 0);
686 gtk_box_pack_start(GTK_BOX(lw->info_box), hbox, FALSE, FALSE, 0);
687 gtk_widget_show(hbox);
693 lw->info_details = layout_status_label(NULL, hbox, TRUE, 0, TRUE);
694 if (!small_format) gtk_box_pack_start(GTK_BOX(hbox), lw->info_color, FALSE, FALSE, 0);
695 lw->info_zoom = layout_status_label(NULL, hbox, FALSE, ZOOM_LABEL_WIDTH, FALSE);
699 *-----------------------------------------------------------------------------
701 *-----------------------------------------------------------------------------
704 static GtkWidget *layout_tools_new(LayoutWindow *lw)
706 lw->dir_view = layout_tool_setup(lw);
710 static void layout_list_status_cb(ViewFileList *vfl, gpointer data)
712 LayoutWindow *lw = data;
714 layout_status_update_info(lw, NULL);
717 static void layout_list_thumb_cb(ViewFileList *vfl, gdouble val, const gchar *text, gpointer data)
719 LayoutWindow *lw = data;
721 layout_status_update_progress(lw, val, text);
724 static void layout_icon_status_cb(ViewFileIcon *vfi, gpointer data)
726 LayoutWindow *lw = data;
728 layout_status_update_info(lw, NULL);
731 static void layout_icon_thumb_cb(ViewFileIcon *vfi, gdouble val, const gchar *text, gpointer data)
733 LayoutWindow *lw = data;
735 layout_status_update_progress(lw, val, text);
738 static GtkWidget *layout_list_new(LayoutWindow *lw)
742 lw->vfi = vficon_new(NULL);
743 vficon_set_layout(lw->vfi, lw);
745 vficon_set_status_func(lw->vfi, layout_icon_status_cb, lw);
746 vficon_set_thumb_status_func(lw->vfi, layout_icon_thumb_cb, lw);
747 /* FIXME vficon_marks_set(lw->vfi, lw->marks_enabled); */
749 return lw->vfi->widget;
752 lw->vfl = vflist_new(NULL, lw->thumbs_enabled);
753 vflist_set_layout(lw->vfl, lw);
755 vflist_set_status_func(lw->vfl, layout_list_status_cb, lw);
756 vflist_set_thumb_status_func(lw->vfl, layout_list_thumb_cb, lw);
758 vflist_marks_set(lw->vfl, lw->marks_enabled);
760 return lw->vfl->widget;
763 static void layout_list_sync_thumb(LayoutWindow *lw)
765 if (lw->vfl) vflist_thumb_set(lw->vfl, lw->thumbs_enabled);
768 static void layout_list_sync_marks(LayoutWindow *lw)
770 if (lw->vfl) vflist_marks_set(lw->vfl, lw->marks_enabled);
773 static void layout_list_scroll_to_subpart(LayoutWindow *lw, const gchar *needle)
777 if (lw->vfl) vflist_scroll_to_subpart(lw->vfl, needle);
778 if (lw->vfi) vficon_scroll_to_subpart(lw->vfi, needle);
782 GList *layout_list(LayoutWindow *lw)
784 if (!layout_valid(&lw)) return NULL;
786 if (lw->vfl) return vflist_get_list(lw->vfl);
787 if (lw->vfi) return vficon_get_list(lw->vfi);
792 gint layout_list_count(LayoutWindow *lw, gint64 *bytes)
794 if (!layout_valid(&lw)) return 0;
796 if (lw->vfl) return vflist_count(lw->vfl, bytes);
797 if (lw->vfi) return vficon_count(lw->vfi, bytes);
802 const gchar *layout_list_get_path(LayoutWindow *lw, gint index)
804 if (!layout_valid(&lw)) return NULL;
806 if (lw->vfl) return vflist_index_get_path(lw->vfl, index);
807 if (lw->vfi) return vficon_index_get_path(lw->vfi, index);
812 FileData *layout_list_get_fd(LayoutWindow *lw, gint index)
814 if (!layout_valid(&lw)) return NULL;
816 if (lw->vfl) return vflist_index_get_data(lw->vfl, index);
817 if (lw->vfi) return vficon_index_get_data(lw->vfi, index);
822 gint layout_list_get_index(LayoutWindow *lw, const gchar *path)
824 if (!layout_valid(&lw)) return -1;
826 if (lw->vfl) return vflist_index_by_path(lw->vfl, path);
827 if (lw->vfi) return vficon_index_by_path(lw->vfi, path);
832 void layout_list_sync_fd(LayoutWindow *lw, FileData *fd)
834 if (!layout_valid(&lw)) return;
836 if (lw->vfl) vflist_select_by_fd(lw->vfl, fd);
837 if (lw->vfi) vficon_select_by_fd(lw->vfi, fd);
840 static void layout_list_sync_sort(LayoutWindow *lw)
842 if (!layout_valid(&lw)) return;
844 if (lw->vfl) vflist_sort_set(lw->vfl, lw->sort_method, lw->sort_ascend);
845 if (lw->vfi) vficon_sort_set(lw->vfi, lw->sort_method, lw->sort_ascend);
848 GList *layout_selection_list(LayoutWindow *lw)
850 if (!layout_valid(&lw)) return NULL;
852 if (layout_image_get_collection(lw, NULL))
856 fd = layout_image_get_fd(lw);
857 if (fd) return g_list_append(NULL, file_data_ref(fd));
861 if (lw->vfl) return vflist_selection_get_list(lw->vfl);
862 if (lw->vfi) return vficon_selection_get_list(lw->vfi);
867 GList *layout_selection_list_by_index(LayoutWindow *lw)
869 if (!layout_valid(&lw)) return NULL;
871 if (lw->vfl) return vflist_selection_get_list_by_index(lw->vfl);
872 if (lw->vfi) return vficon_selection_get_list_by_index(lw->vfi);
877 gint layout_selection_count(LayoutWindow *lw, gint64 *bytes)
879 if (!layout_valid(&lw)) return 0;
881 if (lw->vfl) return vflist_selection_count(lw->vfl, bytes);
882 if (lw->vfi) return vficon_selection_count(lw->vfi, bytes);
887 void layout_select_all(LayoutWindow *lw)
889 if (!layout_valid(&lw)) return;
891 if (lw->vfl) vflist_select_all(lw->vfl);
892 if (lw->vfi) vficon_select_all(lw->vfi);
895 void layout_select_none(LayoutWindow *lw)
897 if (!layout_valid(&lw)) return;
899 if (lw->vfl) vflist_select_none(lw->vfl);
900 if (lw->vfi) vficon_select_none(lw->vfi);
903 void layout_mark_to_selection(LayoutWindow *lw, gint mark, MarkToSelectionMode mode)
905 if (!layout_valid(&lw)) return;
907 if (lw->vfl) vflist_mark_to_selection(lw->vfl, mark, mode);
908 if (lw->vfi) vficon_mark_to_selection(lw->vfi, mark, mode);
911 void layout_selection_to_mark(LayoutWindow *lw, gint mark, SelectionToMarkMode mode)
913 if (!layout_valid(&lw)) return;
915 if (lw->vfl) vflist_selection_to_mark(lw->vfl, mark, mode);
916 if (lw->vfi) vficon_selection_to_mark(lw->vfi, mark, mode);
918 layout_status_update_info(lw, NULL); /* osd in fullscreen mode */
922 *-----------------------------------------------------------------------------
924 *-----------------------------------------------------------------------------
927 const gchar *layout_get_path(LayoutWindow *lw)
929 if (!layout_valid(&lw)) return NULL;
933 static void layout_sync_path(LayoutWindow *lw)
935 if (!lw->path) return;
937 lw->last_time = filetime(lw->path);
939 gtk_entry_set_text(GTK_ENTRY(lw->path_entry), lw->path);
940 if (lw->vd) vd_set_path(lw->vd, lw->path);
942 if (lw->vfl) vflist_set_path(lw->vfl, lw->path);
943 if (lw->vfi) vficon_set_path(lw->vfi, lw->path);
946 gint layout_set_path(LayoutWindow *lw, const gchar *path)
948 gint have_file = FALSE;
950 if (!layout_valid(&lw)) return FALSE;
952 if (!path || !isname(path)) return FALSE;
953 if (lw->path && path && strcmp(path, lw->path) == 0)
961 lw->path = g_strdup(path);
967 base = remove_level_from_path(path);
968 if (lw->path && strcmp(lw->path, base) == 0)
972 else if (isdir(base))
982 if (isfile(path)) have_file = TRUE;
985 if (lw->path_entry) tab_completion_append_to_history(lw->path_entry, lw->path);
986 layout_sync_path(lw);
992 row = layout_list_get_index(lw, path);
995 layout_image_set_index(lw, row);
999 layout_image_set_fd(lw, file_data_new_simple(path));
1002 else if (!options->lazy_image_sync)
1004 layout_image_set_index(lw, 0);
1010 static void layout_refresh_lists(LayoutWindow *lw)
1012 if (lw->path) lw->last_time = filetime(lw->path);
1014 if (lw->vd) vd_refresh(lw->vd);
1016 if (lw->vfl) vflist_refresh(lw->vfl);
1017 if (lw->vfi) vficon_refresh(lw->vfi);
1020 static void layout_refresh_by_time(LayoutWindow *lw)
1022 layout_refresh_lists(lw);
1024 if (lw->image && filetime(layout_image_get_path(lw)) >= lw->last_time)
1026 layout_image_refresh(lw);
1030 void layout_refresh(LayoutWindow *lw)
1032 if (!layout_valid(&lw)) return;
1034 if (debug) printf("layout refresh\n");
1036 layout_refresh_lists(lw);
1038 if (lw->image) layout_image_refresh(lw);
1041 static gint layout_check_for_update_cb(gpointer data)
1043 LayoutWindow *lw = data;
1045 if (!options->update_on_time_change) return TRUE;
1051 new_time = filetime(lw->path);
1053 if (new_time > 0 && new_time > lw->last_time)
1055 if (debug) printf("layout path time changed, refreshing...\n");
1056 layout_refresh_by_time(lw);
1063 void layout_thumb_set(LayoutWindow *lw, gint enable)
1065 if (!layout_valid(&lw)) return;
1067 if (lw->thumbs_enabled == enable) return;
1069 lw->thumbs_enabled = enable;
1071 layout_util_sync_thumb(lw);
1072 layout_list_sync_thumb(lw);
1075 void layout_marks_set(LayoutWindow *lw, gint enable)
1077 if (!layout_valid(&lw)) return;
1079 if (lw->marks_enabled == enable) return;
1081 lw->marks_enabled = enable;
1083 // layout_util_sync_marks(lw);
1084 layout_list_sync_marks(lw);
1087 gint layout_thumb_get(LayoutWindow *lw)
1089 if (!layout_valid(&lw)) return FALSE;
1091 return lw->thumbs_enabled;
1094 gint layout_marks_get(LayoutWindow *lw)
1096 if (!layout_valid(&lw)) return FALSE;
1098 return lw->marks_enabled;
1101 void layout_sort_set(LayoutWindow *lw, SortType type, gint ascend)
1103 if (!layout_valid(&lw)) return;
1104 if (lw->sort_method == type && lw->sort_ascend == ascend) return;
1106 lw->sort_method = type;
1107 lw->sort_ascend = ascend;
1109 if (lw->info_sort) gtk_label_set_text(GTK_LABEL(GTK_BIN(lw->info_sort)->child),
1110 sort_type_get_text(type));
1111 layout_list_sync_sort(lw);
1114 gint layout_sort_get(LayoutWindow *lw, SortType *type, gint *ascend)
1116 if (!layout_valid(&lw)) return FALSE;
1118 if (type) *type = lw->sort_method;
1119 if (ascend) *ascend = lw->sort_ascend;
1124 gint layout_geometry_get(LayoutWindow *lw, gint *x, gint *y, gint *w, gint *h)
1126 if (!layout_valid(&lw)) return FALSE;
1128 gdk_window_get_root_origin(lw->window->window, x, y);
1129 gdk_drawable_get_size(lw->window->window, w, h);
1134 gint layout_geometry_get_dividers(LayoutWindow *lw, gint *h, gint *v)
1136 if (!layout_valid(&lw)) return FALSE;
1138 if (lw->h_pane && GTK_PANED(lw->h_pane)->child1->allocation.x >= 0)
1140 *h = GTK_PANED(lw->h_pane)->child1->allocation.width;
1142 else if (h != &lw->div_h)
1147 if (lw->v_pane && GTK_PANED(lw->v_pane)->child1->allocation.x >= 0)
1149 *v = GTK_PANED(lw->v_pane)->child1->allocation.height;
1151 else if (v != &lw->div_v)
1159 void layout_views_set(LayoutWindow *lw, DirViewType type, gint icons)
1161 if (!layout_valid(&lw)) return;
1163 if (lw->dir_view_type == type && lw->icon_view == icons) return;
1165 lw->dir_view_type = type;
1166 lw->icon_view = icons;
1168 layout_style_set(lw, -1, NULL);
1171 gint layout_views_get(LayoutWindow *lw, DirViewType *type, gint *icons)
1173 if (!layout_valid(&lw)) return FALSE;
1175 *type = lw->dir_view_type;
1176 *icons = lw->icon_view;
1182 *-----------------------------------------------------------------------------
1184 *-----------------------------------------------------------------------------
1187 static gint layout_location_single(LayoutLocation l)
1189 return (l == LAYOUT_LEFT ||
1190 l == LAYOUT_RIGHT ||
1192 l == LAYOUT_BOTTOM);
1195 static gint layout_location_vertical(LayoutLocation l)
1197 return (l & LAYOUT_TOP ||
1201 static gint layout_location_first(LayoutLocation l)
1203 return (l & LAYOUT_TOP ||
1207 static LayoutLocation layout_grid_compass(LayoutWindow *lw)
1209 if (layout_location_single(lw->dir_location)) return lw->dir_location;
1210 if (layout_location_single(lw->file_location)) return lw->file_location;
1211 return lw->image_location;
1214 static void layout_location_compute(LayoutLocation l1, LayoutLocation l2,
1215 GtkWidget *s1, GtkWidget *s2,
1216 GtkWidget **d1, GtkWidget **d2)
1220 l = l1 & l2; /* get common compass direction */
1221 l = l1 - l; /* remove it */
1223 if (layout_location_first(l))
1236 *-----------------------------------------------------------------------------
1237 * tools window (for floating/hidden)
1238 *-----------------------------------------------------------------------------
1241 gint layout_geometry_get_tools(LayoutWindow *lw, gint *x, gint *y, gint *w, gint *h, gint *divider_pos)
1243 if (!layout_valid(&lw)) return FALSE;
1245 if (!lw->tools || !GTK_WIDGET_VISIBLE(lw->tools))
1247 /* use the stored values (sort of breaks success return value) */
1249 *divider_pos = lw->div_float;
1254 gdk_window_get_root_origin(lw->tools->window, x, y);
1255 gdk_drawable_get_size(lw->tools->window, w, h);
1257 if (GTK_IS_VPANED(lw->tools_pane))
1259 *divider_pos = GTK_PANED(lw->tools_pane)->child1->allocation.height;
1263 *divider_pos = GTK_PANED(lw->tools_pane)->child1->allocation.width;
1269 static void layout_tools_geometry_sync(LayoutWindow *lw)
1271 layout_geometry_get_tools(lw, &options->layout.float_window.x, &options->layout.float_window.x,
1272 &options->layout.float_window.w, &options->layout.float_window.h, &lw->div_float);
1275 static void layout_tools_hide(LayoutWindow *lw, gint hide)
1277 if (!lw->tools) return;
1281 if (GTK_WIDGET_VISIBLE(lw->tools))
1283 layout_tools_geometry_sync(lw);
1284 gtk_widget_hide(lw->tools);
1289 if (!GTK_WIDGET_VISIBLE(lw->tools))
1291 gtk_widget_show(lw->tools);
1292 if (lw->vfi) vficon_refresh(lw->vfi);
1296 lw->tools_hidden = hide;
1299 static gint layout_tools_delete_cb(GtkWidget *widget, GdkEventAny *event, gpointer data)
1301 LayoutWindow *lw = data;
1303 layout_tools_float_toggle(lw);
1308 static void layout_tools_setup(LayoutWindow *lw, GtkWidget *tools, GtkWidget *files)
1313 gint new_window = FALSE;
1315 vertical = (layout_location_single(lw->image_location) && !layout_location_vertical(lw->image_location)) ||
1316 (!layout_location_single(lw->image_location) && layout_location_vertical(layout_grid_compass(lw)));
1318 layout_location_compute(lw->dir_location, lw->file_location,
1319 tools, files, &w1, &w2);
1321 /* for now, tools/dir are always first in order */
1327 GdkGeometry geometry;
1328 GdkWindowHints hints;
1330 lw->tools = window_new(GTK_WINDOW_TOPLEVEL, "tools", PIXBUF_INLINE_ICON_TOOLS, NULL, _("Tools"));
1331 g_signal_connect(G_OBJECT(lw->tools), "delete_event",
1332 G_CALLBACK(layout_tools_delete_cb), lw);
1333 layout_keyboard_init(lw, lw->tools);
1335 if (options->layout.save_window_positions)
1337 hints = GDK_HINT_USER_POS;
1344 geometry.min_width = 32;
1345 geometry.min_height = 32;
1346 geometry.base_width = TOOLWINDOW_DEF_WIDTH;
1347 geometry.base_height = TOOLWINDOW_DEF_HEIGHT;
1348 gtk_window_set_geometry_hints(GTK_WINDOW(lw->tools), NULL, &geometry,
1349 GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE | hints);
1352 gtk_window_set_resizable(GTK_WINDOW(lw->tools), TRUE);
1353 gtk_container_set_border_width(GTK_CONTAINER(lw->tools), 0);
1359 layout_tools_geometry_sync(lw);
1360 /* dump the contents */
1361 gtk_widget_destroy(GTK_BIN(lw->tools)->child);
1364 layout_actions_add_window(lw, lw->tools);
1366 vbox = gtk_vbox_new(FALSE, 0);
1367 gtk_container_add(GTK_CONTAINER(lw->tools), vbox);
1368 gtk_widget_show(vbox);
1370 layout_status_setup(lw, vbox, TRUE);
1374 lw->tools_pane = gtk_vpaned_new();
1378 lw->tools_pane = gtk_hpaned_new();
1380 gtk_box_pack_start(GTK_BOX(vbox), lw->tools_pane, TRUE, TRUE, 0);
1381 gtk_widget_show(lw->tools_pane);
1383 gtk_paned_pack1(GTK_PANED(lw->tools_pane), w1, FALSE, TRUE);
1384 gtk_paned_pack2(GTK_PANED(lw->tools_pane), w2, TRUE, TRUE);
1386 gtk_widget_show(tools);
1387 gtk_widget_show(files);
1391 if (options->layout.save_window_positions)
1393 gtk_window_set_default_size(GTK_WINDOW(lw->tools), options->layout.float_window.w, options->layout.float_window.h);
1394 gtk_window_move(GTK_WINDOW(lw->tools), options->layout.float_window.x, options->layout.float_window.y);
1400 gtk_window_set_default_size(GTK_WINDOW(lw->tools),
1401 TOOLWINDOW_DEF_WIDTH, TOOLWINDOW_DEF_HEIGHT);
1405 gtk_window_set_default_size(GTK_WINDOW(lw->tools),
1406 TOOLWINDOW_DEF_HEIGHT, TOOLWINDOW_DEF_WIDTH);
1411 if (!options->layout.save_window_positions)
1415 lw->div_float = MAIN_WINDOW_DIV_VPOS;
1419 lw->div_float = MAIN_WINDOW_DIV_HPOS;
1423 gtk_paned_set_position(GTK_PANED(lw->tools_pane), lw->div_float);
1427 *-----------------------------------------------------------------------------
1428 * glue (layout arrangement)
1429 *-----------------------------------------------------------------------------
1432 static void layout_grid_compute(LayoutWindow *lw,
1433 GtkWidget *image, GtkWidget *tools, GtkWidget *files,
1434 GtkWidget **w1, GtkWidget **w2, GtkWidget **w3)
1436 /* heh, this was fun */
1438 if (layout_location_single(lw->dir_location))
1440 if (layout_location_first(lw->dir_location))
1443 layout_location_compute(lw->file_location, lw->image_location, files, image, w2, w3);
1448 layout_location_compute(lw->file_location, lw->image_location, files, image, w1, w2);
1451 else if (layout_location_single(lw->file_location))
1453 if (layout_location_first(lw->file_location))
1456 layout_location_compute(lw->dir_location, lw->image_location, tools, image, w2, w3);
1461 layout_location_compute(lw->dir_location, lw->image_location, tools, image, w1, w2);
1467 if (layout_location_first(lw->image_location))
1470 layout_location_compute(lw->file_location, lw->dir_location, files, tools, w2, w3);
1475 layout_location_compute(lw->file_location, lw->dir_location, files, tools, w1, w2);
1480 void layout_split_change(LayoutWindow *lw, ImageSplitMode mode)
1485 for (i = 0; i < MAX_SPLIT_IMAGES; i++)
1487 if (lw->split_images[i])
1489 gtk_widget_hide(lw->split_images[i]->widget);
1490 if (lw->split_images[i]->widget->parent != lw->utility_box)
1491 gtk_container_remove(GTK_CONTAINER(lw->split_images[i]->widget->parent), lw->split_images[i]->widget);
1494 gtk_container_remove(GTK_CONTAINER(lw->utility_box), lw->split_image_widget);
1496 image = layout_image_setup_split(lw, mode);
1498 gtk_box_pack_start(GTK_BOX(lw->utility_box), image, TRUE, TRUE, 0);
1499 gtk_box_reorder_child(GTK_BOX(lw->utility_box), image, 0);
1500 gtk_widget_show(image);
1503 static void layout_grid_setup(LayoutWindow *lw)
1505 gint priority_location;
1508 GtkWidget *w1, *w2, *w3;
1514 layout_actions_setup(lw);
1515 layout_actions_add_window(lw, lw->window);
1517 lw->group_box = gtk_vbox_new(FALSE, 0);
1518 gtk_box_pack_start(GTK_BOX(lw->main_box), lw->group_box, TRUE, TRUE, 0);
1519 gtk_widget_show(lw->group_box);
1521 priority_location = layout_grid_compass(lw);
1523 image = layout_image_setup_split(lw, lw->split_mode);
1525 tools = layout_tools_new(lw);
1526 files = layout_list_new(lw);
1528 image = layout_bars_prepare(lw, image);
1530 if (lw->tools_float || lw->tools_hidden)
1532 gtk_box_pack_start(GTK_BOX(lw->group_box), image, TRUE, TRUE, 0);
1533 gtk_widget_show(image);
1535 layout_tools_setup(lw, tools, files);
1537 gtk_widget_grab_focus(lw->image->widget);
1543 layout_tools_geometry_sync(lw);
1544 gtk_widget_destroy(lw->tools);
1546 lw->tools_pane = NULL;
1549 layout_status_setup(lw, lw->group_box, FALSE);
1551 layout_grid_compute(lw, image, tools, files, &w1, &w2, &w3);
1553 v = lw->v_pane = gtk_vpaned_new();
1555 h = lw->h_pane = gtk_hpaned_new();
1557 if (!layout_location_vertical(priority_location))
1566 gtk_box_pack_start(GTK_BOX(lw->group_box), v, TRUE, TRUE, 0);
1568 if (!layout_location_first(priority_location))
1570 gtk_paned_pack1(GTK_PANED(v), h, FALSE, TRUE);
1571 gtk_paned_pack2(GTK_PANED(v), w3, TRUE, TRUE);
1573 gtk_paned_pack1(GTK_PANED(h), w1, FALSE, TRUE);
1574 gtk_paned_pack2(GTK_PANED(h), w2, TRUE, TRUE);
1578 gtk_paned_pack1(GTK_PANED(v), w1, FALSE, TRUE);
1579 gtk_paned_pack2(GTK_PANED(v), h, TRUE, TRUE);
1581 gtk_paned_pack1(GTK_PANED(h), w2, FALSE, TRUE);
1582 gtk_paned_pack2(GTK_PANED(h), w3, TRUE, TRUE);
1585 gtk_widget_show(image);
1586 gtk_widget_show(tools);
1587 gtk_widget_show(files);
1592 /* fix to have image pane visible when it is left and priority widget */
1593 if (lw->div_h == -1 &&
1595 !layout_location_vertical(priority_location) &&
1596 layout_location_first(priority_location))
1598 gtk_widget_set_size_request(image, 200, -1);
1601 gtk_paned_set_position(GTK_PANED(lw->h_pane), lw->div_h);
1602 gtk_paned_set_position(GTK_PANED(lw->v_pane), lw->div_v);
1604 gtk_widget_grab_focus(lw->image->widget);
1607 void layout_style_set(LayoutWindow *lw, gint style, const gchar *order)
1612 if (!layout_valid(&lw)) return;
1616 LayoutLocation d, f, i;
1618 layout_config_parse(style, order, &d, &f, &i);
1620 if (lw->dir_location == d &&
1621 lw->file_location == f &&
1622 lw->image_location == i) return;
1624 lw->dir_location = d;
1625 lw->file_location = f;
1626 lw->image_location = i;
1629 /* remember state */
1631 layout_image_slideshow_stop(lw);
1632 layout_image_full_screen_stop(lw);
1637 lw->utility_box = NULL;
1639 layout_geometry_get_dividers(lw, &lw->div_h, &lw->div_v);
1643 for (i = 0; i < MAX_SPLIT_IMAGES; i++)
1645 if (lw->split_images[i])
1647 gtk_widget_hide(lw->split_images[i]->widget);
1648 gtk_container_remove(GTK_CONTAINER(lw->split_images[i]->widget->parent), lw->split_images[i]->widget);
1656 lw->thumb_button = NULL;
1657 lw->path_entry = NULL;
1658 lw->dir_view = NULL;
1661 lw->file_view = NULL;
1665 lw->info_box = NULL;
1666 lw->info_progress_bar = NULL;
1667 lw->info_sort = NULL;
1668 lw->info_color = NULL;
1669 lw->info_status = NULL;
1670 lw->info_details = NULL;
1671 lw->info_zoom = NULL;
1673 if (lw->ui_manager) g_object_unref(lw->ui_manager);
1674 lw->ui_manager = NULL;
1675 lw->action_group = NULL;
1677 gtk_container_remove(GTK_CONTAINER(lw->main_box), lw->group_box);
1678 lw->group_box = NULL;
1682 layout_grid_setup(lw);
1683 layout_tools_hide(lw, lw->tools_hidden);
1685 layout_list_sync_sort(lw);
1686 layout_util_sync(lw);
1687 layout_status_update_all(lw);
1691 if (image_get_path(lw->image))
1693 layout_set_path(lw, image_get_path(lw->image));
1697 layout_set_path(lw, path);
1699 image_top_window_set_sync(lw->image, (lw->tools_float || lw->tools_hidden));
1706 void layout_styles_update(void)
1710 work = layout_window_list;
1713 LayoutWindow *lw = work->data;
1716 layout_style_set(lw, options->layout.style, options->layout.order);
1720 void layout_colors_update(void)
1724 work = layout_window_list;
1727 LayoutWindow *lw = work->data;
1730 if (!lw->image) continue;
1731 image_background_set_color(lw->image, options->image.use_custom_border_color ? &options->image.border_color : NULL);
1735 void layout_tools_float_toggle(LayoutWindow *lw)
1741 if (!lw->tools_hidden)
1743 popped = !lw->tools_float;
1750 if (lw->tools_float == popped)
1752 if (popped && lw->tools_hidden)
1754 layout_tools_float_set(lw, popped, FALSE);
1759 if (lw->tools_float)
1761 layout_tools_float_set(lw, FALSE, FALSE);
1765 layout_tools_float_set(lw, TRUE, FALSE);
1770 void layout_tools_hide_toggle(LayoutWindow *lw)
1774 layout_tools_float_set(lw, lw->tools_float, !lw->tools_hidden);
1777 void layout_tools_float_set(LayoutWindow *lw, gint popped, gint hidden)
1779 if (!layout_valid(&lw)) return;
1781 if (lw->tools_float == popped && lw->tools_hidden == hidden) return;
1783 if (lw->tools_float == popped && lw->tools_float && lw->tools)
1785 layout_tools_hide(lw, hidden);
1789 lw->tools_float = popped;
1790 lw->tools_hidden = hidden;
1792 layout_style_set(lw, -1, NULL);
1795 gint layout_tools_float_get(LayoutWindow *lw, gint *popped, gint *hidden)
1797 if (!layout_valid(&lw)) return FALSE;
1799 *popped = lw->tools_float;
1800 *hidden = lw->tools_hidden;
1805 void layout_toolbar_toggle(LayoutWindow *lw)
1807 if (!layout_valid(&lw)) return;
1808 if (!lw->toolbar) return;
1810 lw->toolbar_hidden = !lw->toolbar_hidden;
1812 if (lw->toolbar_hidden)
1814 if (GTK_WIDGET_VISIBLE(lw->toolbar)) gtk_widget_hide(lw->toolbar);
1818 if (!GTK_WIDGET_VISIBLE(lw->toolbar)) gtk_widget_show(lw->toolbar);
1822 gint layout_toolbar_hidden(LayoutWindow *lw)
1824 if (!layout_valid(&lw)) return TRUE;
1826 return lw->toolbar_hidden;
1830 *-----------------------------------------------------------------------------
1832 *-----------------------------------------------------------------------------
1835 void layout_close(LayoutWindow *lw)
1837 if (layout_window_list && layout_window_list->next)
1847 void layout_free(LayoutWindow *lw)
1851 layout_window_list = g_list_remove(layout_window_list, lw);
1853 if (lw->last_time_id != -1)
1855 g_source_remove(lw->last_time_id);
1858 layout_bars_close(lw);
1860 gtk_widget_destroy(lw->window);
1862 histogram_free(lw->histogram);
1869 static gint layout_delete_cb(GtkWidget *widget, GdkEventAny *event, gpointer data)
1871 LayoutWindow *lw = data;
1877 LayoutWindow *layout_new(const gchar *path, gint popped, gint hidden)
1879 return layout_new_with_geometry(path, popped, hidden, NULL);
1882 LayoutWindow *layout_new_with_geometry(const gchar *path, gint popped, gint hidden,
1883 const gchar *geometry)
1887 GdkWindowHints hint_mask;
1889 lw = g_new0(LayoutWindow, 1);
1891 lw->thumbs_enabled = options->layout.show_thumbnails;
1892 lw->marks_enabled = options->layout.show_marks;
1893 lw->sort_method = SORT_NAME;
1894 lw->sort_ascend = TRUE;
1896 lw->tools_float = popped;
1897 lw->tools_hidden = hidden;
1899 lw->toolbar_hidden = options->layout.toolbar_hidden;
1901 lw->utility_box = NULL;
1902 lw->bar_sort = NULL;
1903 lw->bar_sort_enabled = FALSE;
1904 lw->bar_exif = NULL;
1905 lw->bar_exif_enabled = FALSE;
1906 lw->bar_exif_size = -1;
1907 lw->bar_exif_advanced = FALSE;
1909 lw->histogram_enabled = FALSE;
1911 /* default layout */
1913 layout_config_parse(options->layout.style, options->layout.order,
1914 &lw->dir_location, &lw->file_location, &lw->image_location);
1915 lw->dir_view_type = options->layout.dir_view_type;
1916 lw->icon_view = options->layout.view_as_icons;
1918 /* divider positions */
1920 if (options->layout.save_window_positions)
1922 lw->div_h = options->layout.main_window.hdivider_pos;
1923 lw->div_v = options->layout.main_window.vdivider_pos;
1924 lw->div_float = options->layout.float_window.vdivider_pos;
1928 lw->div_h = MAIN_WINDOW_DIV_HPOS;
1929 lw->div_v = MAIN_WINDOW_DIV_VPOS;
1930 lw->div_float = MAIN_WINDOW_DIV_VPOS;
1935 lw->window = window_new(GTK_WINDOW_TOPLEVEL, GQ_WMCLASS, NULL, NULL, NULL);
1936 gtk_window_set_resizable(GTK_WINDOW(lw->window), TRUE);
1937 gtk_container_set_border_width(GTK_CONTAINER(lw->window), 0);
1939 if (options->layout.save_window_positions)
1941 hint_mask = GDK_HINT_USER_POS;
1948 hint.min_width = 32;
1949 hint.min_height = 32;
1950 hint.base_width = 0;
1951 hint.base_height = 0;
1952 gtk_window_set_geometry_hints(GTK_WINDOW(lw->window), NULL, &hint,
1953 GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE | hint_mask);
1955 if (options->layout.save_window_positions)
1957 gtk_window_set_default_size(GTK_WINDOW(lw->window), options->layout.main_window.w, options->layout.main_window.h);
1958 if (!layout_window_list)
1960 gtk_window_move(GTK_WINDOW(lw->window), options->layout.main_window.x, options->layout.main_window.y);
1961 if (options->layout.main_window.maximized) gtk_window_maximize(GTK_WINDOW(lw->window));
1966 gtk_window_set_default_size(GTK_WINDOW(lw->window), MAINWINDOW_DEF_WIDTH, MAINWINDOW_DEF_HEIGHT);
1969 g_signal_connect(G_OBJECT(lw->window), "delete_event",
1970 G_CALLBACK(layout_delete_cb), lw);
1972 layout_keyboard_init(lw, lw->window);
1974 lw->main_box = gtk_vbox_new(FALSE, 0);
1975 gtk_container_add(GTK_CONTAINER(lw->window), lw->main_box);
1976 gtk_widget_show(lw->main_box);
1978 layout_grid_setup(lw);
1979 image_top_window_set_sync(lw->image, (lw->tools_float || lw->tools_hidden));
1981 layout_util_sync(lw);
1982 layout_status_update_all(lw);
1986 layout_set_path(lw, path);
1992 pixbuf = pixbuf_inline(PIXBUF_INLINE_LOGO);
1993 image_change_pixbuf(lw->image, pixbuf, 1.0);
1994 gdk_pixbuf_unref(pixbuf);
1997 /* set up the time stat timeout */
1999 lw->last_time_id = g_timeout_add(5000, layout_check_for_update_cb, lw);
2003 if (!gtk_window_parse_geometry(GTK_WINDOW(lw->window), geometry))
2005 print_term(_("Invalid geometry\n"));
2009 gtk_widget_show(lw->window);
2010 layout_tools_hide(lw, lw->tools_hidden);
2012 layout_window_list = g_list_append(layout_window_list, lw);
2018 *-----------------------------------------------------------------------------
2019 * maintenance (for rename, move, remove)
2020 *-----------------------------------------------------------------------------
2023 static void layout_real_time_update(LayoutWindow *lw)
2025 /* this resets the last time stamp of path so that a refresh does not occur
2026 * from an internal file operation.
2029 if (lw->path) lw->last_time = filetime(lw->path);
2032 static void layout_real_renamed(LayoutWindow *lw, FileData *fd)
2034 gint update = FALSE;
2036 if (lw->image) layout_image_maint_renamed(lw, fd);
2038 if (lw->vfl) update |= vflist_maint_renamed(lw->vfl, fd);
2039 if (lw->vfi) update |= vficon_maint_renamed(lw->vfi, fd);
2041 if (update) layout_real_time_update(lw);
2044 static void layout_real_removed(LayoutWindow *lw, FileData *fd, GList *ignore_list)
2046 gint update = FALSE;
2048 if (lw->image) layout_image_maint_removed(lw, fd);
2050 if (lw->vfl) update |= vflist_maint_removed(lw->vfl, fd, ignore_list);
2051 if (lw->vfi) update |= vficon_maint_removed(lw->vfi, fd, ignore_list);
2053 if (update) layout_real_time_update(lw);
2056 static void layout_real_moved(LayoutWindow *lw, FileData *fd, GList *ignore_list)
2058 gint update = FALSE;
2060 if (lw->image) layout_image_maint_moved(lw, fd);
2062 if (lw->vfl) update |= vflist_maint_moved(lw->vfl, fd, ignore_list);
2063 if (lw->vfi) update |= vficon_maint_moved(lw->vfi, fd, ignore_list);
2065 if (update) layout_real_time_update(lw);
2068 void layout_maint_renamed(FileData *fd)
2070 GList *work = layout_window_list;
2073 LayoutWindow *lw = work->data;
2076 layout_real_renamed(lw, fd);
2080 void layout_maint_removed(FileData *fd, GList *ignore_list)
2082 GList *work = layout_window_list;
2085 LayoutWindow *lw = work->data;
2088 layout_real_removed(lw, fd, ignore_list);
2092 void layout_maint_moved(FileData *fd, GList *ignore_list)
2094 GList *work = layout_window_list;
2097 LayoutWindow *lw = work->data;
2100 layout_real_moved(lw, fd, ignore_list);