X-Git-Url: http://geeqie.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flayout.c;h=692a2ae60aacd06844d7873ed8cbbf2becee7e0e;hb=324129463b17052472ce473df3e253bee6476837;hp=95229208343230bcf331b86a46a65bab6912ed82;hpb=d5b911cd3eca6de811ef53f8cac6a3f84ced1062;p=geeqie.git diff --git a/src/layout.c b/src/layout.c index 95229208..692a2ae6 100644 --- a/src/layout.c +++ b/src/layout.c @@ -1,13 +1,22 @@ /* - * Geeqie - * (C) 2006 John Ellis - * Copyright (C) 2008 - 2009 The Geeqie Team + * Copyright (C) 2006 John Ellis + * Copyright (C) 2008 - 2016 The Geeqie Team * * Author: John Ellis * - * This software is released under the GNU General Public License (GNU GPL). - * Please read the included file COPYING for more information. - * This software comes with no warranty of any kind, use at your own risk! + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "main.h" @@ -21,6 +30,7 @@ #include "layout_config.h" #include "layout_image.h" #include "layout_util.h" +#include "logwindow.h" #include "menu.h" #include "pixbuf-renderer.h" #include "pixbuf_util.h" @@ -36,7 +46,8 @@ #include "rcfile.h" #include "bar.h" #include "bar_sort.h" - +#include "preferences.h" +#include "shortcuts.h" #ifdef HAVE_LIRC #include "lirc.h" #endif @@ -57,7 +68,7 @@ GList *layout_window_list = NULL; - +LayoutWindow *current_lw = NULL; static void layout_list_scroll_to_subpart(LayoutWindow *lw, const gchar *needle); @@ -68,14 +79,14 @@ static void layout_list_scroll_to_subpart(LayoutWindow *lw, const gchar *needle) *----------------------------------------------------------------------------- */ -gint layout_valid(LayoutWindow **lw) +gboolean layout_valid(LayoutWindow **lw) { if (*lw == NULL) { - if (layout_window_list) *lw = layout_window_list->data; + if (current_lw) *lw = current_lw; + else if (layout_window_list) *lw = layout_window_list->data; return (*lw != NULL); } - return (g_list_find(layout_window_list, *lw) != NULL); } @@ -104,14 +115,90 @@ LayoutWindow *layout_find_by_image_fd(ImageWindow *imd) { LayoutWindow *lw = work->data; work = work->next; + if (lw->image->image_fd == imd->image_fd) return lw; + } + + return NULL; +} + +LayoutWindow *layout_find_by_layout_id(const gchar *id) +{ + GList *work; + + if (!id || !id[0]) return NULL; + if (strcmp(id, LAYOUT_ID_CURRENT) == 0) + { + if (current_lw) return current_lw; + if (layout_window_list) return layout_window_list->data; + return NULL; + } + + work = layout_window_list; + while (work) + { + LayoutWindow *lw = work->data; + work = work->next; + + if (lw->options.id && strcmp(id, lw->options.id) == 0) + return lw; } return NULL; } +static void layout_set_unique_id(LayoutWindow *lw) +{ + char id[10]; + gint i; + if (lw->options.id && lw->options.id[0]) return; /* id is already set */ + + g_free(lw->options.id); + lw->options.id = NULL; + + if (!layout_find_by_layout_id("main")) + { + lw->options.id = g_strdup("main"); + return; + } + + i = 1; + while (TRUE) + { + g_snprintf(id, sizeof(id), "lw%d", i); + if (!layout_find_by_layout_id(id)) + { + lw->options.id = g_strdup(id); + return; + } + i++; + } +} + +static gboolean layout_set_current_cb(GtkWidget *widget, GdkEventFocus *event, gpointer data) +{ + LayoutWindow *lw = data; + current_lw = lw; + return FALSE; +} + +static void layout_box_folders_changed_cb(GtkWidget *widget, gpointer data) +{ + LayoutWindow *lw; + GList *work; + +/* FIXME: this is probably not the correct way to implement this */ + work = layout_window_list; + while (work) + { + lw = work->data; + lw->options.folder_window.vdivider_pos = gtk_paned_get_position(GTK_PANED(widget)); + work = work->next; + } +} + /* *----------------------------------------------------------------------------- * menu, toolbar, and dir view @@ -126,14 +213,11 @@ static void layout_path_entry_changed_cb(GtkWidget *widget, gpointer data) if (gtk_combo_box_get_active(GTK_COMBO_BOX(widget)) < 0) return; buf = g_strdup(gtk_entry_get_text(GTK_ENTRY(lw->path_entry))); - if (!buf || (lw->dir_fd && strcmp(buf, lw->dir_fd->path) == 0)) + if (!lw->dir_fd || strcmp(buf, lw->dir_fd->path) != 0) { - g_free(buf); - return; + layout_set_path(lw, buf); } - layout_set_path(lw, buf); - g_free(buf); } @@ -141,11 +225,9 @@ static void layout_path_entry_tab_cb(const gchar *path, gpointer data) { LayoutWindow *lw = data; gchar *buf; - gchar *base; buf = g_strdup(path); parse_out_relatives(buf); - base = remove_level_from_path(buf); if (isdir(buf)) { @@ -158,12 +240,17 @@ static void layout_path_entry_tab_cb(const gchar *path, gpointer data) strlen(gtk_entry_get_text(GTK_ENTRY(lw->path_entry)))); } } - else if (lw->dir_fd && strcmp(lw->dir_fd->path, base) == 0) + else if (lw->dir_fd) { - layout_list_scroll_to_subpart(lw, filename_from_path(buf)); + gchar *base = remove_level_from_path(buf); + + if (strcmp(lw->dir_fd->path, base) == 0) + { + layout_list_scroll_to_subpart(lw, filename_from_path(buf)); + } + g_free(base); } - g_free(base); g_free(buf); } @@ -180,11 +267,11 @@ static void layout_path_entry_cb(const gchar *path, gpointer data) g_free(buf); } -static void layout_vd_select_cb(ViewDir *vd, const gchar *path, gpointer data) +static void layout_vd_select_cb(ViewDir *vd, FileData *fd, gpointer data) { LayoutWindow *lw = data; - layout_set_path(lw, path); + layout_set_fd(lw, fd); } static void layout_path_entry_tab_append_cb(const gchar *path, gpointer data, gint n) @@ -194,33 +281,27 @@ static void layout_path_entry_tab_append_cb(const gchar *path, gpointer data, gi if (!lw || !lw->back_button) return; if (!layout_valid(&lw)) return; - if (n >= 2) - { - /* Enable back button */ - gtk_widget_set_sensitive(lw->back_button, TRUE); - } - else - { - /* Disable back button */ - gtk_widget_set_sensitive(lw->back_button, FALSE); - } + /* Enable back button if it makes sense */ + gtk_widget_set_sensitive(lw->back_button, (n > 1)); } static GtkWidget *layout_tool_setup(LayoutWindow *lw) { GtkWidget *box; + GtkWidget *box_folders; + GtkWidget *scd; GtkWidget *menu_bar; GtkWidget *tabcomp; + GtkWidget *toolbar; box = gtk_vbox_new(FALSE, 0); menu_bar = layout_actions_menu_bar(lw); gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, FALSE, 0); - gtk_widget_show(menu_bar); - lw->toolbar = layout_actions_toolbar(lw); - gtk_box_pack_start(GTK_BOX(box), lw->toolbar, FALSE, FALSE, 0); - if (!lw->options.toolbar_hidden) gtk_widget_show(lw->toolbar); + toolbar = layout_actions_toolbar(lw, TOOLBAR_MAIN); + gtk_box_pack_start(GTK_BOX(box), toolbar, FALSE, FALSE, 0); + if (lw->options.toolbar_hidden) gtk_widget_hide(toolbar); tabcomp = tab_completion_new_with_history(&lw->path_entry, NULL, "path_list", -1, layout_path_entry_cb, lw); @@ -229,18 +310,34 @@ static GtkWidget *layout_tool_setup(LayoutWindow *lw) gtk_box_pack_start(GTK_BOX(box), tabcomp, FALSE, FALSE, 0); gtk_widget_show(tabcomp); - g_signal_connect(G_OBJECT(lw->path_entry->parent), "changed", +#if GTK_CHECK_VERSION(3,20,0) + g_signal_connect(G_OBJECT(gtk_widget_get_parent(gtk_widget_get_parent(lw->path_entry))), "changed", G_CALLBACK(layout_path_entry_changed_cb), lw); +#else + g_signal_connect(G_OBJECT(gtk_widget_get_parent(lw->path_entry)), "changed", + G_CALLBACK(layout_path_entry_changed_cb), lw); +#endif + + box_folders = GTK_WIDGET(gtk_hpaned_new()); + gtk_box_pack_start(GTK_BOX(box), box_folders, TRUE, TRUE, 0); lw->vd = vd_new(lw->options.dir_view_type, lw->dir_fd); vd_set_layout(lw->vd, lw); vd_set_select_func(lw->vd, layout_vd_select_cb, lw); lw->dir_view = lw->vd->widget; - - gtk_box_pack_start(GTK_BOX(box), lw->dir_view, TRUE, TRUE, 0); + gtk_paned_add2(GTK_PANED(box_folders), lw->dir_view); gtk_widget_show(lw->dir_view); + scd = shortcuts_new_default(lw); + gtk_paned_add1(GTK_PANED(box_folders), scd); + gtk_paned_set_position(GTK_PANED(box_folders), lw->options.folder_window.vdivider_pos); + + gtk_widget_show(box_folders); + + g_signal_connect(G_OBJECT(box_folders), "notify::position", + G_CALLBACK(layout_box_folders_changed_cb), lw); + gtk_widget_show(box); return box; @@ -277,11 +374,7 @@ static void layout_sort_menu_ascend_cb(GtkWidget *widget, gpointer data) static void layout_sort_menu_hide_cb(GtkWidget *widget, gpointer data) { /* destroy the menu */ -#if GTK_CHECK_VERSION(2,12,0) g_object_unref(widget); -#else - gtk_widget_unref(GTK_WIDGET(widget)); -#endif } static void layout_sort_button_press_cb(GtkWidget *widget, gpointer data) @@ -336,257 +429,119 @@ static GtkWidget *layout_sort_button(LayoutWindow *lw) return button; } -/* - *----------------------------------------------------------------------------- - * color profile button (and menu) - *----------------------------------------------------------------------------- - */ - -#ifdef HAVE_LCMS - -static void layout_color_menu_enable_cb(GtkWidget *widget, gpointer data) +static void layout_zoom_menu_cb(GtkWidget *widget, gpointer data) { - LayoutWindow *lw = data; - - layout_image_color_profile_set_use(lw, (!layout_image_color_profile_get_use(lw))); - layout_image_refresh(lw); -} - -static void layout_color_menu_use_image_cb(GtkWidget *widget, gpointer data) -{ - LayoutWindow *lw = data; - gint input, screen, use_image; - - if (!layout_image_color_profile_get(lw, &input, &screen, &use_image)) return; - layout_image_color_profile_set(lw, input, screen, !use_image); - layout_image_refresh(lw); -} - -#define COLOR_MENU_KEY "color_menu_key" - -static void layout_color_menu_input_cb(GtkWidget *widget, gpointer data) -{ - LayoutWindow *lw = data; - gint type; - gint input, screen, use_image; + ZoomMode mode; if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) return; - type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), COLOR_MENU_KEY)); - if (type < 0 || type >= COLOR_PROFILE_FILE + COLOR_PROFILE_INPUTS) return; - - if (!layout_image_color_profile_get(lw, &input, &screen, &use_image)) return; - if (type == input) return; - - layout_image_color_profile_set(lw, type, screen, use_image); - layout_image_refresh(lw); + mode = (ZoomMode)GPOINTER_TO_INT(data); + options->image.zoom_mode = mode; } -static void layout_color_menu_screen_cb(GtkWidget *widget, gpointer data) +static void layout_scroll_menu_cb(GtkWidget *widget, gpointer data) { - LayoutWindow *lw = data; - gint type; - gint input, screen, use_image; + guint scroll_type; if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) return; - type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), COLOR_MENU_KEY)); - if (type < 0 || type > 1) return; - - if (!layout_image_color_profile_get(lw, &input, &screen, &use_image)) return; - if (type == screen) return; - - layout_image_color_profile_set(lw, input, type, use_image); - layout_image_refresh(lw); + scroll_type = GPOINTER_TO_UINT(data); + options->image.scroll_reset_method = scroll_type; + image_options_sync(); } -static gchar *layout_color_name_parse(const gchar *name) +static void layout_zoom_menu_hide_cb(GtkWidget *widget, gpointer data) { - if (!name || !*name) return g_strdup(_("Empty")); - return g_strdelimit(g_strdup(name), "_", '-'); + /* destroy the menu */ + g_object_unref(widget); } -#endif /* HAVE_LCMS */ - -static void layout_color_button_press_cb(GtkWidget *widget, gpointer data) +static void layout_zoom_button_press_cb(GtkWidget *widget, gpointer data) { -#ifndef HAVE_LCMS - gchar *msg = g_strdup_printf(_("This installation of %s was not built with support for color profiles."), GQ_APPNAME); - file_util_warning_dialog(_("Color profiles not supported"), - msg, - GTK_STOCK_DIALOG_INFO, widget); - g_free(msg); - return; -#else LayoutWindow *lw = data; GtkWidget *menu; - GtkWidget *item; - gchar *buf; - gint active; - gint input = 0; - gint screen = 0; - gint use_image = 0; - gint from_image = 0; - gint image_profile; - gint i; - - if (!layout_image_color_profile_get(lw, &input, &screen, &use_image)) return; + GdkEvent *event; + guint32 etime; - image_profile = layout_image_color_profile_get_from_image(lw); - from_image = use_image && (image_profile != COLOR_PROFILE_NONE); - menu = popup_menu_short_lived(); + menu = submenu_add_zoom(NULL, G_CALLBACK(layout_zoom_menu_cb), + lw, FALSE, FALSE, TRUE, options->image.zoom_mode); - active = layout_image_color_profile_get_use(lw); - menu_item_add_check(menu, _("Use _color profiles"), active, - G_CALLBACK(layout_color_menu_enable_cb), lw); + /* take ownership of menu */ +#ifdef GTK_OBJECT_FLOATING + /* GTK+ < 2.10 */ + g_object_ref(G_OBJECT(menu)); + gtk_object_sink(GTK_OBJECT(menu)); +#else + /* GTK+ >= 2.10 */ + g_object_ref_sink(G_OBJECT(menu)); +#endif menu_item_add_divider(menu); - item = menu_item_add_check(menu, _("Use profile from _image"), use_image, - G_CALLBACK(layout_color_menu_use_image_cb), lw); - gtk_widget_set_sensitive(item, active); + menu_item_add_radio(menu, _("Scroll to top left corner"), + GUINT_TO_POINTER(SCROLL_RESET_TOPLEFT), + options->image.scroll_reset_method == SCROLL_RESET_TOPLEFT, + G_CALLBACK(layout_scroll_menu_cb), + GUINT_TO_POINTER(SCROLL_RESET_TOPLEFT)); + menu_item_add_radio(menu, _("Scroll to image center"), + GUINT_TO_POINTER(SCROLL_RESET_CENTER), + options->image.scroll_reset_method == SCROLL_RESET_CENTER, + G_CALLBACK(layout_scroll_menu_cb), + GUINT_TO_POINTER(SCROLL_RESET_CENTER)); + menu_item_add_radio(menu, _("Keep the region from previous image"), + GUINT_TO_POINTER(SCROLL_RESET_NOCHANGE), + options->image.scroll_reset_method == SCROLL_RESET_NOCHANGE, + G_CALLBACK(layout_scroll_menu_cb), + GUINT_TO_POINTER(SCROLL_RESET_NOCHANGE)); - for (i = COLOR_PROFILE_SRGB; i < COLOR_PROFILE_FILE; i++) - { - const gchar *label; + g_signal_connect(G_OBJECT(menu), "selection_done", + G_CALLBACK(layout_zoom_menu_hide_cb), NULL); - switch (i) - { - case COLOR_PROFILE_SRGB: label = _("sRGB"); break; - case COLOR_PROFILE_ADOBERGB: label = _("AdobeRGB compatible"); break; - default: label = "fixme"; break; - } - buf = g_strdup_printf(_("Input _%d: %s%s"), i, label, (i == image_profile) ? " *" : ""); - item = menu_item_add_radio(menu, (i == COLOR_PROFILE_SRGB) ? NULL : item, - buf, (input == i), - G_CALLBACK(layout_color_menu_input_cb), lw); - g_free(buf); - g_object_set_data(G_OBJECT(item), COLOR_MENU_KEY, GINT_TO_POINTER(i)); - gtk_widget_set_sensitive(item, active && !from_image); + event = gtk_get_current_event(); + if (event) + { + etime = gdk_event_get_time(event); + gdk_event_free(event); } - - for (i = 0; i < COLOR_PROFILE_INPUTS; i++) + else { - const gchar *name; - gchar *end; - - name = options->color_profile.input_name[i]; - if (!name || !name[0]) name = filename_from_path(options->color_profile.input_file[i]); - - end = layout_color_name_parse(name); - buf = g_strdup_printf(_("Input _%d: %s"), i + COLOR_PROFILE_FILE, end); - g_free(end); - - item = menu_item_add_radio(menu, item, - buf, (i + COLOR_PROFILE_FILE == input), - G_CALLBACK(layout_color_menu_input_cb), lw); - g_free(buf); - g_object_set_data(G_OBJECT(item), COLOR_MENU_KEY, GINT_TO_POINTER(i + COLOR_PROFILE_FILE)); - gtk_widget_set_sensitive(item, active && !from_image && options->color_profile.input_file[i] && options->color_profile.input_file[i][0]); + etime = 0; } - menu_item_add_divider(menu); - - item = menu_item_add_radio(menu, NULL, - _("Screen sRGB"), (screen == 0), - G_CALLBACK(layout_color_menu_screen_cb), lw); - - g_object_set_data(G_OBJECT(item), COLOR_MENU_KEY, GINT_TO_POINTER(0)); - gtk_widget_set_sensitive(item, active); - - item = menu_item_add_radio(menu, item, - _("_Screen profile"), (screen == 1), - G_CALLBACK(layout_color_menu_screen_cb), lw); - g_object_set_data(G_OBJECT(item), COLOR_MENU_KEY, GINT_TO_POINTER(1)); - gtk_widget_set_sensitive(item, active && options->color_profile.screen_file && options->color_profile.screen_file[0]); - - gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, GDK_CURRENT_TIME); -#endif /* HAVE_LCMS */ + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, etime); } -static GtkWidget *layout_color_button(LayoutWindow *lw) +static GtkWidget *layout_zoom_button(LayoutWindow *lw, GtkWidget *box, gint size, gboolean expand) { GtkWidget *button; - GtkWidget *image; - gint enable; - - button = gtk_button_new(); - image = gtk_image_new_from_stock(GTK_STOCK_SELECT_COLOR, GTK_ICON_SIZE_MENU); - gtk_container_add(GTK_CONTAINER(button), image); - gtk_widget_show(image); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(layout_color_button_press_cb), lw); - gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); - -#ifdef HAVE_LCMS - enable = (lw->image) ? lw->image->color_profile_enable : FALSE; -#else - enable = FALSE; -#endif - gtk_widget_set_sensitive(image, enable); + GtkWidget *frame; - return button; -} -/* - *----------------------------------------------------------------------------- - * write button - *----------------------------------------------------------------------------- - */ + frame = gtk_frame_new(NULL); + if (size) gtk_widget_set_size_request(frame, size, -1); + gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); -static void layout_write_button_press_cb(GtkWidget *widget, gpointer data) -{ - metadata_write_queue_confirm(NULL, NULL); -} + gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 0); -static GtkWidget *layout_write_button(LayoutWindow *lw) -{ - GtkWidget *button; - GtkWidget *image; + gtk_widget_show(frame); - button = gtk_button_new(); - image = gtk_image_new_from_stock(GTK_STOCK_SAVE, GTK_ICON_SIZE_MENU); - gtk_container_add(GTK_CONTAINER(button), image); - gtk_widget_show(image); + button = gtk_button_new_with_label("1:1"); g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(layout_write_button_press_cb), lw); + G_CALLBACK(layout_zoom_button_press_cb), lw); gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); - - gtk_widget_set_sensitive(button, metadata_queue_length() > 0); - + + gtk_container_add(GTK_CONTAINER(frame), button); + gtk_widget_show(button); + return button; } - /* *----------------------------------------------------------------------------- * status bar *----------------------------------------------------------------------------- */ -void layout_status_update_write(LayoutWindow *lw) -{ - if (!layout_valid(&lw)) return; - if (!lw->info_write) return; - - gtk_widget_set_sensitive(lw->info_write, metadata_queue_length() > 0); - /* FIXME: maybe show also the number of files */ -} - -void layout_status_update_write_all(void) -{ - GList *work; - - work = layout_window_list; - while (work) - { - LayoutWindow *lw = work->data; - work = work->next; - - layout_status_update_write(lw); - } -} - void layout_status_update_progress(LayoutWindow *lw, gdouble val, const gchar *text) { @@ -607,9 +562,9 @@ void layout_status_update_info(LayoutWindow *lw, const gchar *text) { guint n; gint64 n_bytes = 0; - + n = layout_list_count(lw, &n_bytes); - + if (n) { guint s; @@ -631,11 +586,11 @@ void layout_status_update_info(LayoutWindow *lw, const gchar *text) { ss = ""; } - + s = layout_selection_count(lw, &s_bytes); - + layout_bars_new_selection(lw, s); - + if (s > 0) { gchar *b = text_from_size_abrev(n_bytes); @@ -654,9 +609,9 @@ void layout_status_update_info(LayoutWindow *lw, const gchar *text) { buf = g_strdup_printf(_("%d files%s"), n, ss); } - + text = buf; - + image_osd_update(lw->image); } else @@ -664,7 +619,7 @@ void layout_status_update_info(LayoutWindow *lw, const gchar *text) text = ""; } } - + if (lw->info_status) gtk_label_set_text(GTK_LABEL(lw->info_status), text); g_free(buf); } @@ -674,12 +629,13 @@ void layout_status_update_image(LayoutWindow *lw) guint64 n; if (!layout_valid(&lw) || !lw->image) return; + if (!lw->info_zoom || !lw->info_details) return; /*called from layout_style_set */ n = layout_list_count(lw, NULL); - + if (!n) { - gtk_label_set_text(GTK_LABEL(lw->info_zoom), ""); + gtk_button_set_label(GTK_BUTTON(lw->info_zoom), ""); gtk_label_set_text(GTK_LABEL(lw->info_details), ""); } else @@ -688,7 +644,7 @@ void layout_status_update_image(LayoutWindow *lw) gchar *b; text = image_zoom_get_as_text(lw->image); - gtk_label_set_text(GTK_LABEL(lw->info_zoom), text); + gtk_button_set_label(GTK_BUTTON(lw->info_zoom), text); g_free(text); b = image_get_fd(lw->image) ? text_from_size(image_get_fd(lw->image)->size) : g_strdup("0"); @@ -707,17 +663,20 @@ void layout_status_update_image(LayoutWindow *lw) else { gint width, height; - + image_get_image_size(lw->image, &width, &height); text = g_strdup_printf(_("( %d x %d ) %s bytes"), width, height, b); } + g_signal_emit_by_name (lw->image->pr, "update-pixel"); + g_free(b); - + gtk_label_set_text(GTK_LABEL(lw->info_details), text); g_free(text); } + layout_util_sync_color(lw); /* update color button */ } void layout_status_update_all(LayoutWindow *lw) @@ -725,10 +684,10 @@ void layout_status_update_all(LayoutWindow *lw) layout_status_update_progress(lw, 0.0, NULL); layout_status_update_info(lw, NULL); layout_status_update_image(lw); - layout_status_update_write(lw); + layout_util_status_update_write(lw); } -static GtkWidget *layout_status_label(gchar *text, GtkWidget *box, gint start, gint size, gint expand) +static GtkWidget *layout_status_label(gchar *text, GtkWidget *box, gboolean start, gint size, gboolean expand) { GtkWidget *label; GtkWidget *frame; @@ -753,9 +712,11 @@ static GtkWidget *layout_status_label(gchar *text, GtkWidget *box, gint start, g return label; } -static void layout_status_setup(LayoutWindow *lw, GtkWidget *box, gint small_format) +static void layout_status_setup(LayoutWindow *lw, GtkWidget *box, gboolean small_format) { GtkWidget *hbox; + GtkWidget *toolbar; + GtkWidget *toolbar_frame; if (lw->info_box) return; @@ -782,23 +743,20 @@ static void layout_status_setup(LayoutWindow *lw, GtkWidget *box, gint small_for } lw->info_progress_bar = gtk_progress_bar_new(); gtk_widget_set_size_request(lw->info_progress_bar, PROGRESS_WIDTH, -1); +#if GTK_CHECK_VERSION(3,0,0) + gtk_progress_bar_set_text(GTK_PROGRESS_BAR(lw->info_progress_bar), ""); + gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(lw->info_progress_bar), TRUE); +#endif gtk_box_pack_start(GTK_BOX(hbox), lw->info_progress_bar, FALSE, FALSE, 0); gtk_widget_show(lw->info_progress_bar); lw->info_sort = layout_sort_button(lw); + gtk_widget_set_tooltip_text(GTK_WIDGET(lw->info_sort), _("Select sort order")); gtk_box_pack_start(GTK_BOX(hbox), lw->info_sort, FALSE, FALSE, 0); gtk_widget_show(lw->info_sort); - lw->info_color = layout_color_button(lw); - gtk_widget_show(lw->info_color); - - lw->info_write = layout_write_button(lw); - gtk_widget_show(lw->info_write); - - if (small_format) gtk_box_pack_end(GTK_BOX(hbox), lw->info_color, FALSE, FALSE, 0); - if (small_format) gtk_box_pack_end(GTK_BOX(hbox), lw->info_write, FALSE, FALSE, 0); - lw->info_status = layout_status_label(NULL, lw->info_box, TRUE, 0, (!small_format)); + gtk_widget_set_tooltip_text(GTK_WIDGET(lw->info_status), _("Folder contents (files selected)")); if (small_format) { @@ -806,14 +764,29 @@ static void layout_status_setup(LayoutWindow *lw, GtkWidget *box, gint small_for gtk_box_pack_start(GTK_BOX(lw->info_box), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); } - else + lw->info_details = layout_status_label(NULL, hbox, TRUE, 0, TRUE); + gtk_widget_set_tooltip_text(GTK_WIDGET(lw->info_details), _("(Image dimensions) Image size")); + toolbar = layout_actions_toolbar(lw, TOOLBAR_STATUS); + + toolbar_frame = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME(toolbar_frame), GTK_SHADOW_IN); + gtk_container_add(GTK_CONTAINER(toolbar_frame), toolbar); + gtk_widget_show(toolbar_frame); + gtk_widget_show(toolbar); + gtk_box_pack_end(GTK_BOX(hbox), toolbar_frame, FALSE, FALSE, 0); + lw->info_zoom = layout_zoom_button(lw, hbox, ZOOM_LABEL_WIDTH, TRUE); + gtk_widget_set_tooltip_text(GTK_WIDGET(lw->info_zoom), _("Select zoom mode")); + gtk_widget_show(lw->info_zoom); + + if (small_format) { - hbox = lw->info_box; + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(lw->info_box), hbox, FALSE, FALSE, 0); + gtk_widget_show(hbox); } - lw->info_details = layout_status_label(NULL, hbox, TRUE, 0, TRUE); - if (!small_format) gtk_box_pack_start(GTK_BOX(hbox), lw->info_color, FALSE, FALSE, 0); - if (!small_format) gtk_box_pack_start(GTK_BOX(hbox), lw->info_write, FALSE, FALSE, 0); - lw->info_zoom = layout_status_label(NULL, hbox, FALSE, ZOOM_LABEL_WIDTH, FALSE); + lw->info_pixel = layout_status_label(NULL, hbox, FALSE, 0, small_format); /* expand only in small format */ + gtk_widget_set_tooltip_text(GTK_WIDGET(lw->info_pixel), _("[Pixel x,y coord]: (Pixel R,G,B value)")); + if (!lw->options.show_info_pixel) gtk_widget_hide(gtk_widget_get_parent(lw->info_pixel)); } /* @@ -842,9 +815,14 @@ static void layout_list_thumb_cb(ViewFile *vf, gdouble val, const gchar *text, g layout_status_update_progress(lw, val, text); } +static void layout_list_sync_thumb(LayoutWindow *lw) +{ + if (lw->vf) vf_thumb_set(lw->vf, lw->options.show_thumbnails); +} + static GtkWidget *layout_list_new(LayoutWindow *lw) { - lw->vf = vf_new(lw->file_view_type, NULL); + lw->vf = vf_new(lw->options.file_view_type, NULL); vf_set_layout(lw->vf, lw); vf_set_status_func(lw->vf, layout_list_status_cb, lw); @@ -852,23 +830,11 @@ static GtkWidget *layout_list_new(LayoutWindow *lw) vf_marks_set(lw->vf, lw->options.show_marks); - switch (lw->file_view_type) - { - case FILEVIEW_ICON: - break; - case FILEVIEW_LIST: - vf_thumb_set(lw->vf, lw->options.show_thumbnails); - break; - } + layout_list_sync_thumb(lw); return lw->vf->widget; } -static void layout_list_sync_thumb(LayoutWindow *lw) -{ - if (lw->vf) vf_thumb_set(lw->vf, lw->options.show_thumbnails); -} - static void layout_list_sync_marks(LayoutWindow *lw) { if (lw->vf) vf_marks_set(lw->vf, lw->options.show_marks); @@ -877,9 +843,6 @@ static void layout_list_sync_marks(LayoutWindow *lw) static void layout_list_scroll_to_subpart(LayoutWindow *lw, const gchar *needle) { if (!lw) return; -#if 0 - if (lw->vf) vf_scroll_to_subpart(lw->vf, needle); -#endif } GList *layout_list(LayoutWindow *lw) @@ -913,7 +876,7 @@ gint layout_list_get_index(LayoutWindow *lw, FileData *fd) { if (!layout_valid(&lw) || !fd) return -1; - if (lw->vf) return vf_index_by_path(lw->vf, fd->path); + if (lw->vf) return vf_index_by_fd(lw->vf, fd); return -1; } @@ -1005,6 +968,14 @@ void layout_selection_to_mark(LayoutWindow *lw, gint mark, SelectionToMarkMode m layout_status_update_info(lw, NULL); /* osd in fullscreen mode */ } +void layout_mark_filter_toggle(LayoutWindow *lw, gint mark) +{ + if (!layout_valid(&lw)) return; + + if (lw->vf) vf_mark_filter_toggle(lw->vf, mark); +} + + /* *----------------------------------------------------------------------------- * access @@ -1022,25 +993,29 @@ static void layout_sync_path(LayoutWindow *lw) if (!lw->dir_fd) return; if (lw->path_entry) gtk_entry_set_text(GTK_ENTRY(lw->path_entry), lw->dir_fd->path); - if (lw->vd) vd_set_fd(lw->vd, lw->dir_fd); + if (lw->vd) vd_set_fd(lw->vd, lw->dir_fd); if (lw->vf) vf_set_fd(lw->vf, lw->dir_fd); } -gint layout_set_path(LayoutWindow *lw, const gchar *path) +gboolean layout_set_path(LayoutWindow *lw, const gchar *path) { FileData *fd; + gboolean ret; + if (!path) return FALSE; - fd = file_data_new_simple(path); - gint ret = layout_set_fd(lw, fd); + + fd = file_data_new_group(path); + ret = layout_set_fd(lw, fd); file_data_unref(fd); return ret; } -gint layout_set_fd(LayoutWindow *lw, FileData *fd) +gboolean layout_set_fd(LayoutWindow *lw, FileData *fd) { - gint have_file = FALSE; + gboolean have_file = FALSE; + gboolean dir_changed = TRUE; if (!layout_valid(&lw)) return FALSE; @@ -1068,6 +1043,7 @@ gint layout_set_fd(LayoutWindow *lw, FileData *fd) if (lw->dir_fd && strcmp(lw->dir_fd->path, base) == 0) { g_free(base); + dir_changed = FALSE; } else if (isdir(base)) { @@ -1076,7 +1052,7 @@ gint layout_set_fd(LayoutWindow *lw, FileData *fd) file_data_unregister_real_time_monitor(lw->dir_fd); file_data_unref(lw->dir_fd); } - lw->dir_fd = file_data_new_simple(base); + lw->dir_fd = file_data_new_dir(base); file_data_register_real_time_monitor(lw->dir_fd); g_free(base); } @@ -1091,7 +1067,7 @@ gint layout_set_fd(LayoutWindow *lw, FileData *fd) if (lw->path_entry) tab_completion_append_to_history(lw->path_entry, lw->dir_fd->path); layout_sync_path(lw); layout_list_sync_sort(lw); - + if (have_file) { gint row; @@ -1111,8 +1087,8 @@ gint layout_set_fd(LayoutWindow *lw, FileData *fd) layout_image_set_index(lw, 0); } - if (options->metadata.confirm_on_dir_change) - metadata_write_queue_confirm(NULL, NULL); + if (options->metadata.confirm_on_dir_change && dir_changed) + metadata_write_queue_confirm(FALSE, NULL, NULL); return TRUE; } @@ -1121,7 +1097,11 @@ static void layout_refresh_lists(LayoutWindow *lw) { if (lw->vd) vd_refresh(lw->vd); - if (lw->vf) vf_refresh(lw->vf); + if (lw->vf) + { + vf_refresh(lw->vf); + vf_thumb_update(lw->vf); + } } void layout_refresh(LayoutWindow *lw) @@ -1135,7 +1115,7 @@ void layout_refresh(LayoutWindow *lw) if (lw->image) layout_image_refresh(lw); } -void layout_thumb_set(LayoutWindow *lw, gint enable) +void layout_thumb_set(LayoutWindow *lw, gboolean enable) { if (!layout_valid(&lw)) return; @@ -1147,7 +1127,7 @@ void layout_thumb_set(LayoutWindow *lw, gint enable) layout_list_sync_thumb(lw); } -void layout_marks_set(LayoutWindow *lw, gint enable) +void layout_marks_set(LayoutWindow *lw, gboolean enable) { if (!layout_valid(&lw)) return; @@ -1159,21 +1139,21 @@ void layout_marks_set(LayoutWindow *lw, gint enable) layout_list_sync_marks(lw); } -gint layout_thumb_get(LayoutWindow *lw) +gboolean layout_thumb_get(LayoutWindow *lw) { if (!layout_valid(&lw)) return FALSE; return lw->options.show_thumbnails; } -gint layout_marks_get(LayoutWindow *lw) +gboolean layout_marks_get(LayoutWindow *lw) { if (!layout_valid(&lw)) return FALSE; return lw->options.show_marks; } -void layout_sort_set(LayoutWindow *lw, SortType type, gint ascend) +void layout_sort_set(LayoutWindow *lw, SortType type, gboolean ascend) { if (!layout_valid(&lw)) return; if (lw->sort_method == type && lw->sort_ascend == ascend) return; @@ -1181,12 +1161,12 @@ void layout_sort_set(LayoutWindow *lw, SortType type, gint ascend) lw->sort_method = type; lw->sort_ascend = ascend; - if (lw->info_sort) gtk_label_set_text(GTK_LABEL(GTK_BIN(lw->info_sort)->child), + if (lw->info_sort) gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(lw->info_sort))), sort_type_get_text(type)); layout_list_sync_sort(lw); } -gint layout_sort_get(LayoutWindow *lw, SortType *type, gint *ascend) +gboolean layout_sort_get(LayoutWindow *lw, SortType *type, gboolean *ascend) { if (!layout_valid(&lw)) return FALSE; @@ -1196,32 +1176,50 @@ gint layout_sort_get(LayoutWindow *lw, SortType *type, gint *ascend) return TRUE; } -gint layout_geometry_get(LayoutWindow *lw, gint *x, gint *y, gint *w, gint *h) +gboolean layout_geometry_get(LayoutWindow *lw, gint *x, gint *y, gint *w, gint *h) { + GdkWindow *window; if (!layout_valid(&lw)) return FALSE; - gdk_window_get_root_origin(lw->window->window, x, y); - gdk_drawable_get_size(lw->window->window, w, h); + window = gtk_widget_get_window(lw->window); + gdk_window_get_root_origin(window, x, y); + *w = gdk_window_get_width(window); + *h = gdk_window_get_height(window); return TRUE; } -gint layout_geometry_get_dividers(LayoutWindow *lw, gint *h, gint *v) +gboolean layout_geometry_get_dividers(LayoutWindow *lw, gint *h, gint *v) { + GtkAllocation h_allocation; + GtkAllocation v_allocation; + if (!layout_valid(&lw)) return FALSE; - if (lw->h_pane && GTK_PANED(lw->h_pane)->child1->allocation.x >= 0) + if (lw->h_pane) + { + GtkWidget *child = gtk_paned_get_child1(GTK_PANED(lw->h_pane)); + gtk_widget_get_allocation(child, &h_allocation); + } + + if (lw->v_pane) + { + GtkWidget *child = gtk_paned_get_child1(GTK_PANED(lw->v_pane)); + gtk_widget_get_allocation(child, &v_allocation); + } + + if (lw->h_pane && h_allocation.x >= 0) { - *h = GTK_PANED(lw->h_pane)->child1->allocation.width; + *h = h_allocation.width; } else if (h != &lw->options.main_window.hdivider_pos) { *h = lw->options.main_window.hdivider_pos; } - if (lw->v_pane && GTK_PANED(lw->v_pane)->child1->allocation.x >= 0) + if (lw->v_pane && v_allocation.x >= 0) { - *v = GTK_PANED(lw->v_pane)->child1->allocation.height; + *v = v_allocation.height; } else if (v != &lw->options.main_window.vdivider_pos) { @@ -1235,20 +1233,20 @@ void layout_views_set(LayoutWindow *lw, DirViewType dir_view_type, FileViewType { if (!layout_valid(&lw)) return; - if (lw->options.dir_view_type == dir_view_type && lw->file_view_type == file_view_type) return; + if (lw->options.dir_view_type == dir_view_type && lw->options.file_view_type == file_view_type) return; lw->options.dir_view_type = dir_view_type; - lw->file_view_type = file_view_type; + lw->options.file_view_type = file_view_type; layout_style_set(lw, -1, NULL); } -gint layout_views_get(LayoutWindow *lw, DirViewType *dir_view_type, FileViewType *file_view_type) +gboolean layout_views_get(LayoutWindow *lw, DirViewType *dir_view_type, FileViewType *file_view_type) { if (!layout_valid(&lw)) return FALSE; *dir_view_type = lw->options.dir_view_type; - *file_view_type = lw->file_view_type; + *file_view_type = lw->options.file_view_type; return TRUE; } @@ -1259,7 +1257,7 @@ gint layout_views_get(LayoutWindow *lw, DirViewType *dir_view_type, FileViewType *----------------------------------------------------------------------------- */ -static gint layout_location_single(LayoutLocation l) +static gboolean layout_location_single(LayoutLocation l) { return (l == LAYOUT_LEFT || l == LAYOUT_RIGHT || @@ -1267,13 +1265,13 @@ static gint layout_location_single(LayoutLocation l) l == LAYOUT_BOTTOM); } -static gint layout_location_vertical(LayoutLocation l) +static gboolean layout_location_vertical(LayoutLocation l) { return (l & LAYOUT_TOP || l & LAYOUT_BOTTOM); } -static gint layout_location_first(LayoutLocation l) +static gboolean layout_location_first(LayoutLocation l) { return (l & LAYOUT_TOP || l & LAYOUT_LEFT); @@ -1313,11 +1311,13 @@ static void layout_location_compute(LayoutLocation l1, LayoutLocation l2, *----------------------------------------------------------------------------- */ -gint layout_geometry_get_tools(LayoutWindow *lw, gint *x, gint *y, gint *w, gint *h, gint *divider_pos) +gboolean layout_geometry_get_tools(LayoutWindow *lw, gint *x, gint *y, gint *w, gint *h, gint *divider_pos) { + GdkWindow *window; + GtkAllocation allocation; if (!layout_valid(&lw)) return FALSE; - if (!lw->tools || !GTK_WIDGET_VISIBLE(lw->tools)) + if (!lw->tools || !gtk_widget_get_visible(lw->tools)) { /* use the stored values (sort of breaks success return value) */ @@ -1326,34 +1326,57 @@ gint layout_geometry_get_tools(LayoutWindow *lw, gint *x, gint *y, gint *w, gint return FALSE; } - gdk_window_get_root_origin(lw->tools->window, x, y); - gdk_drawable_get_size(lw->tools->window, w, h); + window = gtk_widget_get_window(lw->tools); + gdk_window_get_root_origin(window, x, y); + *w = gdk_window_get_width(window); + *h = gdk_window_get_height(window); + gtk_widget_get_allocation(gtk_paned_get_child1(GTK_PANED(lw->tools_pane)), &allocation); if (GTK_IS_VPANED(lw->tools_pane)) { - *divider_pos = GTK_PANED(lw->tools_pane)->child1->allocation.height; + *divider_pos = allocation.height; } else { - *divider_pos = GTK_PANED(lw->tools_pane)->child1->allocation.width; + *divider_pos = allocation.width; + } + + return TRUE; +} + +gboolean layout_geometry_get_log_window(LayoutWindow *lw, gint *x, gint *y, + gint *w, gint *h) +{ + GdkWindow *window; + + if (!layout_valid(&lw)) return FALSE; + + if (!lw->log_window) + { + return FALSE; } + window = gtk_widget_get_window(lw->log_window); + gdk_window_get_root_origin(window, x, y); + *w = gdk_window_get_width(window); + *h = gdk_window_get_height(window); + return TRUE; } static void layout_tools_geometry_sync(LayoutWindow *lw) { - layout_geometry_get_tools(lw, &options->layout.float_window.x, &options->layout.float_window.x, - &options->layout.float_window.w, &options->layout.float_window.h, &lw->options.float_window.vdivider_pos); + layout_geometry_get_tools(lw, &lw->options.float_window.x, &lw->options.float_window.y, + &lw->options.float_window.w, &lw->options.float_window.h, &lw->options.float_window.vdivider_pos); } -static void layout_tools_hide(LayoutWindow *lw, gint hide) +static void layout_tools_hide(LayoutWindow *lw, gboolean hide) { if (!lw->tools) return; if (hide) { - if (GTK_WIDGET_VISIBLE(lw->tools)) + if (gtk_widget_get_visible(lw->tools)) { layout_tools_geometry_sync(lw); gtk_widget_hide(lw->tools); @@ -1361,7 +1384,7 @@ static void layout_tools_hide(LayoutWindow *lw, gint hide) } else { - if (!GTK_WIDGET_VISIBLE(lw->tools)) + if (!gtk_widget_get_visible(lw->tools)) { gtk_widget_show(lw->tools); if (lw->vf) vf_refresh(lw->vf); @@ -1371,7 +1394,7 @@ static void layout_tools_hide(LayoutWindow *lw, gint hide) lw->options.tools_hidden = hide; } -static gint layout_tools_delete_cb(GtkWidget *widget, GdkEventAny *event, gpointer data) +static gboolean layout_tools_delete_cb(GtkWidget *widget, GdkEventAny *event, gpointer data) { LayoutWindow *lw = data; @@ -1384,15 +1407,11 @@ static void layout_tools_setup(LayoutWindow *lw, GtkWidget *tools, GtkWidget *fi { GtkWidget *vbox; GtkWidget *w1, *w2; - gint vertical; - gint new_window = FALSE; + gboolean vertical; + gboolean new_window = FALSE; vertical = (layout_location_single(lw->image_location) && !layout_location_vertical(lw->image_location)) || (!layout_location_single(lw->image_location) && layout_location_vertical(layout_grid_compass(lw))); -#if 0 - layout_location_compute(lw->dir_location, lw->file_location, - tools, files, &w1, &w2); -#endif /* for now, tools/dir are always first in order */ w1 = tools; w2 = files; @@ -1407,7 +1426,7 @@ static void layout_tools_setup(LayoutWindow *lw, GtkWidget *tools, GtkWidget *fi G_CALLBACK(layout_tools_delete_cb), lw); layout_keyboard_init(lw, lw->tools); - if (options->layout.save_window_positions) + if (options->save_window_positions) { hints = GDK_HINT_USER_POS; } @@ -1433,7 +1452,7 @@ static void layout_tools_setup(LayoutWindow *lw, GtkWidget *tools, GtkWidget *fi { layout_tools_geometry_sync(lw); /* dump the contents */ - gtk_widget_destroy(GTK_BIN(lw->tools)->child); + gtk_widget_destroy(gtk_bin_get_child(GTK_BIN(lw->tools))); } layout_actions_add_window(lw, lw->tools); @@ -1463,10 +1482,10 @@ static void layout_tools_setup(LayoutWindow *lw, GtkWidget *tools, GtkWidget *fi if (new_window) { - if (options->layout.save_window_positions) + if (options->save_window_positions) { - gtk_window_set_default_size(GTK_WINDOW(lw->tools), options->layout.float_window.w, options->layout.float_window.h); - gtk_window_move(GTK_WINDOW(lw->tools), options->layout.float_window.x, options->layout.float_window.y); + gtk_window_set_default_size(GTK_WINDOW(lw->tools), lw->options.float_window.w, lw->options.float_window.h); + gtk_window_move(GTK_WINDOW(lw->tools), lw->options.float_window.x, lw->options.float_window.y); } else { @@ -1483,7 +1502,7 @@ static void layout_tools_setup(LayoutWindow *lw, GtkWidget *tools, GtkWidget *fi } } - if (!options->layout.save_window_positions) + if (!options->save_window_positions) { if (vertical) { @@ -1562,17 +1581,17 @@ void layout_split_change(LayoutWindow *lw, ImageSplitMode mode) if (lw->split_images[i]) { gtk_widget_hide(lw->split_images[i]->widget); - if (lw->split_images[i]->widget->parent != lw->utility_box) - gtk_container_remove(GTK_CONTAINER(lw->split_images[i]->widget->parent), lw->split_images[i]->widget); + if (gtk_widget_get_parent(lw->split_images[i]->widget) != lw->utility_paned) + gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(lw->split_images[i]->widget)), lw->split_images[i]->widget); } } - gtk_container_remove(GTK_CONTAINER(lw->utility_box), lw->split_image_widget); + gtk_container_remove(GTK_CONTAINER(lw->utility_paned), lw->split_image_widget); image = layout_image_setup_split(lw, mode); - gtk_box_pack_start(GTK_BOX(lw->utility_box), image, TRUE, TRUE, 0); - gtk_box_reorder_child(GTK_BOX(lw->utility_box), image, 0); + gtk_paned_pack1(GTK_PANED(lw->utility_paned), image, TRUE, FALSE); gtk_widget_show(image); + layout_util_sync(lw); } static void layout_grid_setup(LayoutWindow *lw) @@ -1587,7 +1606,6 @@ static void layout_grid_setup(LayoutWindow *lw) GtkWidget *files; layout_actions_setup(lw); - layout_actions_add_window(lw, lw->window); lw->group_box = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(lw->main_box), lw->group_box, TRUE, TRUE, 0); @@ -1597,6 +1615,7 @@ static void layout_grid_setup(LayoutWindow *lw) if (lw->utility_box) { + layout_split_change(lw, lw->split_mode); /* this re-creates image frame for the new configuration */ image_sb = lw->utility_box; } else @@ -1605,7 +1624,7 @@ static void layout_grid_setup(LayoutWindow *lw) image = layout_image_setup_split(lw, lw->split_mode); image_sb = layout_bars_prepare(lw, image); } - + tools = layout_tools_new(lw); files = layout_list_new(lw); @@ -1617,7 +1636,7 @@ static void layout_grid_setup(LayoutWindow *lw) layout_tools_setup(lw, tools, files); - gtk_widget_grab_focus(lw->image->widget); + image_grab_focus(lw->image); return; } @@ -1684,12 +1703,13 @@ static void layout_grid_setup(LayoutWindow *lw) gtk_paned_set_position(GTK_PANED(lw->h_pane), lw->options.main_window.hdivider_pos); gtk_paned_set_position(GTK_PANED(lw->v_pane), lw->options.main_window.vdivider_pos); - gtk_widget_grab_focus(lw->image->widget); + image_grab_focus(lw->image); } void layout_style_set(LayoutWindow *lw, gint style, const gchar *order) { FileData *dir_fd; + gint i; if (!layout_valid(&lw)) return; @@ -1710,30 +1730,27 @@ void layout_style_set(LayoutWindow *lw, gint style, const gchar *order) /* remember state */ - layout_image_slideshow_stop(lw); + /* layout_image_slideshow_stop(lw); slideshow should survive */ layout_image_full_screen_stop(lw); dir_fd = lw->dir_fd; if (dir_fd) file_data_unregister_real_time_monitor(dir_fd); lw->dir_fd = NULL; - /* lw->image is preserved together with lw->utility_box */ - if (lw->utility_box) - { - /* preserve utility_box (image + sidebars) to be reused later in layout_grid_setup */ - gtk_widget_hide(lw->utility_box); - g_object_ref(lw->utility_box); - gtk_container_remove(GTK_CONTAINER(lw->utility_box->parent), lw->utility_box); - } - layout_geometry_get_dividers(lw, &lw->options.main_window.hdivider_pos, &lw->options.main_window.vdivider_pos); + /* preserve utility_box (image + sidebars), menu_bar and toolbars to be reused later in layout_grid_setup */ + /* lw->image is preserved together with lw->utility_box */ + if (lw->utility_box) gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(lw->utility_box)), lw->utility_box); + if (lw->menu_bar) gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(lw->menu_bar)), lw->menu_bar); + for (i = 0; i < TOOLBAR_COUNT; i++) + if (lw->toolbar[i]) gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(lw->toolbar[i])), lw->toolbar[i]); + /* clear it all */ lw->h_pane = NULL; lw->v_pane = NULL; - lw->toolbar = NULL; lw->path_entry = NULL; lw->dir_view = NULL; lw->vd = NULL; @@ -1744,15 +1761,17 @@ void layout_style_set(LayoutWindow *lw, gint style, const gchar *order) lw->info_box = NULL; lw->info_progress_bar = NULL; lw->info_sort = NULL; - lw->info_color = NULL; lw->info_status = NULL; lw->info_details = NULL; + lw->info_pixel = NULL; lw->info_zoom = NULL; +/* if (lw->ui_manager) g_object_unref(lw->ui_manager); lw->ui_manager = NULL; lw->action_group = NULL; - lw->action_group_external = NULL; + lw->action_group_editors = NULL; +*/ gtk_container_remove(GTK_CONTAINER(lw->main_box), lw->group_box); lw->group_box = NULL; @@ -1765,6 +1784,9 @@ void layout_style_set(LayoutWindow *lw, gint style, const gchar *order) layout_util_sync(lw); layout_status_update_all(lw); + + // printf("%d %d %d \n", G_OBJECT(lw->utility_box)->ref_count, G_OBJECT(lw->menu_bar)->ref_count, G_OBJECT(lw->toolbar)->ref_count); + /* sync */ if (image_get_fd(lw->image)) @@ -1782,20 +1804,6 @@ void layout_style_set(LayoutWindow *lw, gint style, const gchar *order) file_data_unref(dir_fd); } -void layout_styles_update(void) -{ - GList *work; - - work = layout_window_list; - while (work) - { - LayoutWindow *lw = work->data; - work = work->next; - - layout_style_set(lw, options->layout.style, options->layout.order); - } -} - void layout_colors_update(void) { GList *work; @@ -1803,17 +1811,25 @@ void layout_colors_update(void) work = layout_window_list; while (work) { + gint i; LayoutWindow *lw = work->data; work = work->next; if (!lw->image) continue; - image_background_set_color(lw->image, options->image.use_custom_border_color ? &options->image.border_color : NULL); + + for (i = 0; i < MAX_SPLIT_IMAGES; i++) + { + if (!lw->split_images[i]) continue; + image_background_set_color_from_options(lw->split_images[i], !!lw->full_screen); + } + + image_background_set_color_from_options(lw->image, !!lw->full_screen); } } void layout_tools_float_toggle(LayoutWindow *lw) { - gint popped; + gboolean popped; if (!lw) return; @@ -1853,7 +1869,7 @@ void layout_tools_hide_toggle(LayoutWindow *lw) layout_tools_float_set(lw, lw->options.tools_float, !lw->options.tools_hidden); } -void layout_tools_float_set(LayoutWindow *lw, gint popped, gint hidden) +void layout_tools_float_set(LayoutWindow *lw, gboolean popped, gboolean hidden) { if (!layout_valid(&lw)) return; @@ -1871,7 +1887,7 @@ void layout_tools_float_set(LayoutWindow *lw, gint popped, gint hidden) layout_style_set(lw, -1, NULL); } -gint layout_tools_float_get(LayoutWindow *lw, gint *popped, gint *hidden) +gboolean layout_tools_float_get(LayoutWindow *lw, gboolean *popped, gboolean *hidden) { if (!layout_valid(&lw)) return FALSE; @@ -1884,25 +1900,258 @@ gint layout_tools_float_get(LayoutWindow *lw, gint *popped, gint *hidden) void layout_toolbar_toggle(LayoutWindow *lw) { if (!layout_valid(&lw)) return; - if (!lw->toolbar) return; + if (!lw->toolbar[TOOLBAR_MAIN]) return; lw->options.toolbar_hidden = !lw->options.toolbar_hidden; if (lw->options.toolbar_hidden) { - if (GTK_WIDGET_VISIBLE(lw->toolbar)) gtk_widget_hide(lw->toolbar); + if (gtk_widget_get_visible(lw->toolbar[TOOLBAR_MAIN])) gtk_widget_hide(lw->toolbar[TOOLBAR_MAIN]); } else { - if (!GTK_WIDGET_VISIBLE(lw->toolbar)) gtk_widget_show(lw->toolbar); + if (!gtk_widget_get_visible(lw->toolbar[TOOLBAR_MAIN])) gtk_widget_show(lw->toolbar[TOOLBAR_MAIN]); } } -gint layout_toolbar_hidden(LayoutWindow *lw) +void layout_info_pixel_set(LayoutWindow *lw, gboolean show) { - if (!layout_valid(&lw)) return TRUE; + GtkWidget *frame; + + if (!layout_valid(&lw)) return; + if (!lw->info_pixel) return; + + lw->options.show_info_pixel = show; + + frame = gtk_widget_get_parent(lw->info_pixel); + if (!lw->options.show_info_pixel) + { + gtk_widget_hide(frame); + } + else + { + gtk_widget_show(frame); + } - return lw->options.toolbar_hidden; + g_signal_emit_by_name (lw->image->pr, "update-pixel"); +} + +/* + *----------------------------------------------------------------------------- + * configuration + *----------------------------------------------------------------------------- + */ + +#define CONFIG_WINDOW_DEF_WIDTH 600 +#define CONFIG_WINDOW_DEF_HEIGHT 400 + +typedef struct _LayoutConfig LayoutConfig; +struct _LayoutConfig +{ + LayoutWindow *lw; + + GtkWidget *configwindow; + GtkWidget *home_path_entry; + GtkWidget *layout_widget; + + LayoutOptions options; +}; + +static gint layout_config_delete_cb(GtkWidget *w, GdkEventAny *event, gpointer data); + +static void layout_config_close_cb(GtkWidget *widget, gpointer data) +{ + LayoutConfig *lc = data; + + gtk_widget_destroy(lc->configwindow); + free_layout_options_content(&lc->options); + g_free(lc); +} + +static gint layout_config_delete_cb(GtkWidget *w, GdkEventAny *event, gpointer data) +{ + layout_config_close_cb(w, data); + return TRUE; +} + +static void layout_config_apply_cb(GtkWidget *widget, gpointer data) +{ + LayoutConfig *lc = data; + + g_free(lc->options.order); + lc->options.order = layout_config_get(lc->layout_widget, &lc->options.style); + + config_entry_to_option(lc->home_path_entry, &lc->options.home_path, remove_trailing_slash); + + layout_apply_options(lc->lw, &lc->options); +} + +static void layout_config_help_cb(GtkWidget *widget, gpointer data) +{ + help_window_show("GuideOptionsLayout.html"); +} + +static void layout_config_ok_cb(GtkWidget *widget, gpointer data) +{ + LayoutConfig *lc = data; + layout_config_apply_cb(widget, lc); + layout_config_close_cb(widget, lc); +} + +static void home_path_set_current_cb(GtkWidget *widget, gpointer data) +{ + LayoutConfig *lc = data; + gtk_entry_set_text(GTK_ENTRY(lc->home_path_entry), layout_get_path(lc->lw)); +} + +static void startup_path_set_current_cb(GtkWidget *widget, gpointer data) +{ + LayoutConfig *lc = data; + lc->options.startup_path = STARTUP_PATH_CURRENT; +} + +static void startup_path_set_last_cb(GtkWidget *widget, gpointer data) +{ + LayoutConfig *lc = data; + lc->options.startup_path = STARTUP_PATH_LAST; +} + +static void startup_path_set_home_cb(GtkWidget *widget, gpointer data) +{ + LayoutConfig *lc = data; + lc->options.startup_path = STARTUP_PATH_HOME; +} + + +/* +static void layout_config_save_cb(GtkWidget *widget, gpointer data) +{ + layout_config_apply(); + save_options(options); +} +*/ + +void layout_show_config_window(LayoutWindow *lw) +{ + LayoutConfig *lc; + GtkWidget *win_vbox; + GtkWidget *hbox; + GtkWidget *vbox; + GtkWidget *button; + GtkWidget *ct_button; + GtkWidget *group; + GtkWidget *frame; + GtkWidget *tabcomp; + + lc = g_new0(LayoutConfig, 1); + lc->lw = lw; + layout_sync_options_with_current_state(lw); + copy_layout_options(&lc->options, &lw->options); + + lc->configwindow = window_new(GTK_WINDOW_TOPLEVEL, "Layout", PIXBUF_INLINE_ICON_CONFIG, NULL, _("Window options and layout")); + gtk_window_set_type_hint(GTK_WINDOW(lc->configwindow), GDK_WINDOW_TYPE_HINT_DIALOG); + + g_signal_connect(G_OBJECT(lc->configwindow), "delete_event", + G_CALLBACK(layout_config_delete_cb), lc); + + gtk_window_set_default_size(GTK_WINDOW(lc->configwindow), CONFIG_WINDOW_DEF_WIDTH, CONFIG_WINDOW_DEF_HEIGHT); + gtk_window_set_resizable(GTK_WINDOW(lc->configwindow), TRUE); + gtk_container_set_border_width(GTK_CONTAINER(lc->configwindow), PREF_PAD_BORDER); + + win_vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE); + gtk_container_add(GTK_CONTAINER(lc->configwindow), win_vbox); + gtk_widget_show(win_vbox); + + hbox = gtk_hbutton_box_new(); + gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(hbox), PREF_PAD_BUTTON_GAP); + gtk_box_pack_end(GTK_BOX(win_vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show(hbox); + + button = pref_button_new(NULL, GTK_STOCK_OK, NULL, FALSE, + G_CALLBACK(layout_config_ok_cb), lc); + gtk_container_add(GTK_CONTAINER(hbox), button); + gtk_widget_set_can_default(button, TRUE); + gtk_widget_grab_default(button); + gtk_widget_show(button); + + ct_button = button; +/* + button = pref_button_new(NULL, GTK_STOCK_SAVE, NULL, FALSE, + G_CALLBACK(layout_config_save_cb), NULL); + gtk_container_add(GTK_CONTAINER(hbox), button); + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); + gtk_widget_show(button); +*/ + button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE, + G_CALLBACK(layout_config_help_cb), lc); + gtk_container_add(GTK_CONTAINER(hbox), button); + gtk_widget_set_can_default(button, TRUE); + gtk_widget_show(button); + + button = pref_button_new(NULL, GTK_STOCK_APPLY, NULL, FALSE, + G_CALLBACK(layout_config_apply_cb), lc); + gtk_container_add(GTK_CONTAINER(hbox), button); + gtk_widget_set_can_default(button, TRUE); + gtk_widget_show(button); + + button = pref_button_new(NULL, GTK_STOCK_CANCEL, NULL, FALSE, + G_CALLBACK(layout_config_close_cb), lc); + gtk_container_add(GTK_CONTAINER(hbox), button); + gtk_widget_set_can_default(button, TRUE); + gtk_widget_show(button); + + if (!generic_dialog_get_alternative_button_order(lc->configwindow)) + { + gtk_box_reorder_child(GTK_BOX(hbox), ct_button, -1); + } + + frame = pref_frame_new(win_vbox, TRUE, NULL, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP); + + vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE); + gtk_container_add(GTK_CONTAINER(frame), vbox); + gtk_widget_show(vbox); + + + group = pref_group_new(vbox, FALSE, _("General options"), GTK_ORIENTATION_VERTICAL); + + pref_label_new(group, _("Home path (empty to use your home directory)")); + hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE); + + tabcomp = tab_completion_new(&lc->home_path_entry, lc->options.home_path, NULL, NULL); + tab_completion_add_select_button(lc->home_path_entry, NULL, TRUE); + gtk_box_pack_start(GTK_BOX(hbox), tabcomp, TRUE, TRUE, 0); + gtk_widget_show(tabcomp); + + button = pref_button_new(hbox, NULL, _("Use current"), FALSE, + G_CALLBACK(home_path_set_current_cb), lc); + + pref_checkbox_new_int(group, _("Show date in directories list view"), + lc->options.show_directory_date, &lc->options.show_directory_date); + + pref_checkbox_new_int(group, _("Exit program when this window is closed"), + lc->options.exit_on_close, &lc->options.exit_on_close); + + group = pref_group_new(vbox, FALSE, _("Start-up directory:"), GTK_ORIENTATION_VERTICAL); + + button = pref_radiobutton_new(group, NULL, _("No change"), + (lc->options.startup_path == STARTUP_PATH_CURRENT), + G_CALLBACK(startup_path_set_current_cb), lc); + button = pref_radiobutton_new(group, button, _("Restore last path"), + (lc->options.startup_path == STARTUP_PATH_LAST), + G_CALLBACK(startup_path_set_last_cb), lc); + button = pref_radiobutton_new(group, button, _("Home path"), + (lc->options.startup_path == STARTUP_PATH_HOME), + G_CALLBACK(startup_path_set_home_cb), lc); + + group = pref_group_new(vbox, FALSE, _("Layout"), GTK_ORIENTATION_VERTICAL); + + lc->layout_widget = layout_config_new(); + layout_config_set(lc->layout_widget, lw->options.style, lw->options.order); + gtk_box_pack_start(GTK_BOX(group), lc->layout_widget, TRUE, TRUE, 0); + + gtk_widget_show(lc->layout_widget); + gtk_widget_show(lc->configwindow); } /* @@ -1913,6 +2162,7 @@ gint layout_toolbar_hidden(LayoutWindow *lw) void layout_sync_options_with_current_state(LayoutWindow *lw) { + Histogram *histogram; if (!layout_valid(&lw)) return; lw->options.main_window.maximized = window_maximized(lw->window); @@ -1929,17 +2179,41 @@ void layout_sync_options_with_current_state(LayoutWindow *lw) layout_geometry_get_tools(lw, &lw->options.float_window.x, &lw->options.float_window.y, &lw->options.float_window.w, &lw->options.float_window.h, &lw->options.float_window.vdivider_pos); -// if (options->startup.restore_path && options->startup.use_last_path) -// { -// g_free(options->startup.path); -// options->startup.path = g_strdup(layout_get_path(NULL)); -// } + lw->options.image_overlay.state = image_osd_get(lw->image); + histogram = image_osd_get_histogram(lw->image); + + lw->options.image_overlay.histogram_channel = histogram->histogram_channel; + lw->options.image_overlay.histogram_mode = histogram->histogram_mode; + + g_free(lw->options.last_path); + lw->options.last_path = g_strdup(layout_get_path(lw)); + + layout_geometry_get_log_window(lw, &lw->options.log_window.x, &lw->options.log_window.y, + &lw->options.log_window.w, &lw->options.log_window.h); + +} + +void layout_apply_options(LayoutWindow *lw, LayoutOptions *lop) +{ + gboolean refresh_style; + gboolean refresh_lists; + + if (!layout_valid(&lw)) return; +/* FIXME: add other options too */ + + refresh_style = (lop->style != lw->options.style || strcmp(lop->order, lw->options.order) != 0); + refresh_lists = (lop->show_directory_date != lw->options.show_directory_date); + + copy_layout_options(&lw->options, lop); + + if (refresh_style) layout_style_set(lw, lw->options.style, lw->options.order); + if (refresh_lists) layout_refresh(lw); } void layout_close(LayoutWindow *lw) { - if (layout_window_list && layout_window_list->next) + if (!lw->options.exit_on_close && layout_window_list && layout_window_list->next) { layout_free(lw); } @@ -1951,16 +2225,26 @@ void layout_close(LayoutWindow *lw) void layout_free(LayoutWindow *lw) { + gint i; if (!lw) return; layout_window_list = g_list_remove(layout_window_list, lw); + if (current_lw == lw) current_lw = NULL; if (lw->exif_window) g_signal_handlers_disconnect_matched(G_OBJECT(lw->exif_window), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, lw); - + layout_bars_close(lw); + g_object_unref(lw->menu_bar); + g_object_unref(lw->utility_box); + + for (i = 0; i < TOOLBAR_COUNT; i++) + { + if (lw->toolbar[i]) g_object_unref(lw->toolbar[i]); + } + gtk_widget_destroy(lw->window); - + if (lw->split_image_sizegroup) g_object_unref(lw->split_image_sizegroup); file_data_unregister_notify_func(layout_image_notify_cb, lw); @@ -1971,12 +2255,11 @@ void layout_free(LayoutWindow *lw) file_data_unref(lw->dir_fd); } - string_list_free(lw->toolbar_actions); free_layout_options_content(&lw->options); g_free(lw); } -static gint layout_delete_cb(GtkWidget *widget, GdkEventAny *event, gpointer data) +static gboolean layout_delete_cb(GtkWidget *widget, GdkEventAny *event, gpointer data) { LayoutWindow *lw = data; @@ -1995,38 +2278,35 @@ LayoutWindow *layout_new_with_geometry(FileData *dir_fd, LayoutOptions *lop, LayoutWindow *lw; GdkGeometry hint; GdkWindowHints hint_mask; + Histogram *histogram; + DEBUG_1("%s layout_new: start", get_exec_time()); lw = g_new0(LayoutWindow, 1); if (lop) copy_layout_options(&lw->options, lop); else - copy_layout_options(&lw->options, &options->layout); + init_layout_options(&lw->options); lw->sort_method = SORT_NAME; lw->sort_ascend = TRUE; + layout_set_unique_id(lw); // lw->options.tools_float = popped; // lw->options.tools_hidden = hidden; - - lw->utility_box = NULL; - lw->bar_sort = NULL; // lw->bar_sort_enabled = options->panels.sort.enabled; - - lw->bar = NULL; // lw->bar_enabled = options->panels.info.enabled; - lw->exif_window = NULL; /* default layout */ layout_config_parse(lw->options.style, lw->options.order, &lw->dir_location, &lw->file_location, &lw->image_location); - if (lw->options.dir_view_type >= VIEW_DIR_TYPES_COUNT) lw->options.dir_view_type = 0; - if (lw->options.file_view_type >= VIEW_FILE_TYPES_COUNT) lw->options.file_view_type = 0; + if (lw->options.dir_view_type > DIRVIEW_LAST) lw->options.dir_view_type = 0; + if (lw->options.file_view_type > FILEVIEW_LAST) lw->options.file_view_type = 0; /* divider positions */ - if (!lw->options.save_window_positions) + if (!options->save_window_positions) { lw->options.main_window.hdivider_pos = MAIN_WINDOW_DIV_HPOS; lw->options.main_window.vdivider_pos = MAIN_WINDOW_DIV_VPOS; @@ -2039,7 +2319,7 @@ LayoutWindow *layout_new_with_geometry(FileData *dir_fd, LayoutOptions *lop, gtk_window_set_resizable(GTK_WINDOW(lw->window), TRUE); gtk_container_set_border_width(GTK_CONTAINER(lw->window), 0); - if (lw->options.save_window_positions) + if (options->save_window_positions) { hint_mask = GDK_HINT_USER_POS; } @@ -2055,7 +2335,7 @@ LayoutWindow *layout_new_with_geometry(FileData *dir_fd, LayoutOptions *lop, gtk_window_set_geometry_hints(GTK_WINDOW(lw->window), NULL, &hint, GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE | hint_mask); - if (lw->options.save_window_positions) + if (options->save_window_positions) { gtk_window_set_default_size(GTK_WINDOW(lw->window), lw->options.main_window.w, lw->options.main_window.h); // if (!layout_window_list) @@ -2072,6 +2352,9 @@ LayoutWindow *layout_new_with_geometry(FileData *dir_fd, LayoutOptions *lop, g_signal_connect(G_OBJECT(lw->window), "delete_event", G_CALLBACK(layout_delete_cb), lw); + g_signal_connect(G_OBJECT(lw->window), "focus-in-event", + G_CALLBACK(layout_set_current_cb), lw); + layout_keyboard_init(lw, lw->window); #ifdef HAVE_LIRC @@ -2097,7 +2380,7 @@ LayoutWindow *layout_new_with_geometry(FileData *dir_fd, LayoutOptions *lop, GdkPixbuf *pixbuf; pixbuf = pixbuf_inline(PIXBUF_INLINE_LOGO); - + /* FIXME: the zoom value set here is the value, which is then copied again and again in "Leave Zoom at previous setting" mode. This is not ideal. */ image_change_pixbuf(lw->image, pixbuf, 0.0, FALSE); @@ -2115,98 +2398,122 @@ LayoutWindow *layout_new_with_geometry(FileData *dir_fd, LayoutOptions *lop, gtk_widget_show(lw->window); layout_tools_hide(lw, lw->options.tools_hidden); - image_osd_set(lw->image, options->image_overlay.common.state | (options->image_overlay.common.show_at_startup ? OSD_SHOW_INFO : OSD_SHOW_NOTHING)); + image_osd_set(lw->image, lw->options.image_overlay.state); + histogram = image_osd_get_histogram(lw->image); + + histogram->histogram_channel = lw->options.image_overlay.histogram_channel; + histogram->histogram_mode = lw->options.image_overlay.histogram_mode; layout_window_list = g_list_append(layout_window_list, lw); file_data_register_notify_func(layout_image_notify_cb, lw, NOTIFY_PRIORITY_LOW); + DEBUG_1("%s layout_new: end", get_exec_time()); + return lw; } void layout_write_attributes(LayoutOptions *layout, GString *outstr, gint indent) { - WRITE_INT(*layout, style); - WRITE_CHAR(*layout, order); - WRITE_UINT(*layout, dir_view_type); - WRITE_UINT(*layout, file_view_type); - WRITE_BOOL(*layout, show_marks); - WRITE_BOOL(*layout, show_thumbnails); - WRITE_BOOL(*layout, show_directory_date); - WRITE_CHAR(*layout, home_path); + WRITE_NL(); WRITE_CHAR(*layout, id); + + WRITE_NL(); WRITE_INT(*layout, style); + WRITE_NL(); WRITE_CHAR(*layout, order); + WRITE_NL(); WRITE_UINT(*layout, dir_view_type); + WRITE_NL(); WRITE_UINT(*layout, file_view_type); + WRITE_NL(); WRITE_BOOL(*layout, show_marks); + WRITE_NL(); WRITE_BOOL(*layout, show_thumbnails); + WRITE_NL(); WRITE_BOOL(*layout, show_directory_date); + WRITE_NL(); WRITE_CHAR(*layout, home_path); + WRITE_NL(); WRITE_CHAR(*layout, last_path); + WRITE_NL(); WRITE_UINT(*layout, startup_path); + WRITE_NL(); WRITE_BOOL(*layout, exit_on_close); + WRITE_SEPARATOR(); + + WRITE_NL(); WRITE_INT(*layout, main_window.x); + WRITE_NL(); WRITE_INT(*layout, main_window.y); + WRITE_NL(); WRITE_INT(*layout, main_window.w); + WRITE_NL(); WRITE_INT(*layout, main_window.h); + WRITE_NL(); WRITE_BOOL(*layout, main_window.maximized); + WRITE_NL(); WRITE_INT(*layout, main_window.hdivider_pos); + WRITE_NL(); WRITE_INT(*layout, main_window.vdivider_pos); WRITE_SEPARATOR(); - WRITE_BOOL(*layout, save_window_positions); + WRITE_NL(); WRITE_INT(*layout, folder_window.vdivider_pos); WRITE_SEPARATOR(); - WRITE_INT(*layout, main_window.x); - WRITE_INT(*layout, main_window.y); - WRITE_INT(*layout, main_window.w); - WRITE_INT(*layout, main_window.h); - WRITE_BOOL(*layout, main_window.maximized); - WRITE_INT(*layout, main_window.hdivider_pos); - WRITE_INT(*layout, main_window.vdivider_pos); + WRITE_NL(); WRITE_INT(*layout, float_window.x); + WRITE_NL(); WRITE_INT(*layout, float_window.y); + WRITE_NL(); WRITE_INT(*layout, float_window.w); + WRITE_NL(); WRITE_INT(*layout, float_window.h); + WRITE_NL(); WRITE_INT(*layout, float_window.vdivider_pos); WRITE_SEPARATOR(); - WRITE_INT(*layout, float_window.x); - WRITE_INT(*layout, float_window.y); - WRITE_INT(*layout, float_window.w); - WRITE_INT(*layout, float_window.h); - WRITE_INT(*layout, float_window.vdivider_pos); + WRITE_NL(); WRITE_INT(*layout, properties_window.w); + WRITE_NL(); WRITE_INT(*layout, properties_window.h); WRITE_SEPARATOR(); - WRITE_INT(*layout, properties_window.w); - WRITE_INT(*layout, properties_window.h); + WRITE_NL(); WRITE_BOOL(*layout, tools_float); + WRITE_NL(); WRITE_BOOL(*layout, tools_hidden); WRITE_SEPARATOR(); - WRITE_BOOL(*layout, tools_float); - WRITE_BOOL(*layout, tools_hidden); - WRITE_BOOL(*layout, tools_restore_state); + WRITE_NL(); WRITE_BOOL(*layout, toolbar_hidden); + WRITE_NL(); WRITE_BOOL(*layout, show_info_pixel); + + WRITE_NL(); WRITE_UINT(*layout, image_overlay.state); + WRITE_NL(); WRITE_INT(*layout, image_overlay.histogram_channel); + WRITE_NL(); WRITE_INT(*layout, image_overlay.histogram_mode); + + WRITE_NL(); WRITE_INT(*layout, log_window.x); + WRITE_NL(); WRITE_INT(*layout, log_window.y); + WRITE_NL(); WRITE_INT(*layout, log_window.w); + WRITE_NL(); WRITE_INT(*layout, log_window.h); WRITE_SEPARATOR(); - WRITE_BOOL(*layout, toolbar_hidden); + WRITE_NL(); WRITE_BOOL(*layout, animate); } void layout_write_config(LayoutWindow *lw, GString *outstr, gint indent) { layout_sync_options_with_current_state(lw); - WRITE_STRING("options, outstr, indent + 1); - WRITE_STRING(">\n"); + WRITE_STRING(">"); bar_sort_write_config(lw->bar_sort, outstr, indent + 1); bar_write_config(lw->bar, outstr, indent + 1); - - layout_toolbar_write_config(lw, outstr, indent + 1); - WRITE_STRING("\n"); + WRITE_NL(); WRITE_STRING(""); } void layout_load_attributes(LayoutOptions *layout, const gchar **attribute_names, const gchar **attribute_values) { - + gchar *id = NULL; + while (*attribute_names) { const gchar *option = *attribute_names++; const gchar *value = *attribute_values++; /* layout options */ + if (READ_CHAR_FULL("id", id)) continue; if (READ_INT(*layout, style)) continue; if (READ_CHAR(*layout, order)) continue; - + if (READ_UINT(*layout, dir_view_type)) continue; if (READ_UINT(*layout, file_view_type)) continue; if (READ_BOOL(*layout, show_marks)) continue; if (READ_BOOL(*layout, show_thumbnails)) continue; if (READ_BOOL(*layout, show_directory_date)) continue; if (READ_CHAR(*layout, home_path)) continue; + if (READ_CHAR(*layout, last_path)) continue; + if (READ_UINT_CLAMP(*layout, startup_path, 0, STARTUP_PATH_HOME)) continue; + if (READ_BOOL(*layout, exit_on_close)) continue; /* window positions */ - if (READ_BOOL(*layout, save_window_positions)) continue; - if (READ_INT(*layout, main_window.x)) continue; if (READ_INT(*layout, main_window.y)) continue; if (READ_INT(*layout, main_window.w)) continue; @@ -2215,25 +2522,63 @@ void layout_load_attributes(LayoutOptions *layout, const gchar **attribute_names if (READ_INT(*layout, main_window.hdivider_pos)) continue; if (READ_INT(*layout, main_window.vdivider_pos)) continue; + if (READ_INT_CLAMP(*layout, folder_window.vdivider_pos, 1, 1000)) continue; + if (READ_INT(*layout, float_window.x)) continue; if (READ_INT(*layout, float_window.y)) continue; if (READ_INT(*layout, float_window.w)) continue; if (READ_INT(*layout, float_window.h)) continue; if (READ_INT(*layout, float_window.vdivider_pos)) continue; - + if (READ_INT(*layout, properties_window.w)) continue; if (READ_INT(*layout, properties_window.h)) continue; if (READ_BOOL(*layout, tools_float)) continue; if (READ_BOOL(*layout, tools_hidden)) continue; - if (READ_BOOL(*layout, tools_restore_state)) continue; if (READ_BOOL(*layout, toolbar_hidden)) continue; + if (READ_BOOL(*layout, show_info_pixel)) continue; - DEBUG_1("unknown attribute %s = %s", option, value); + if (READ_UINT(*layout, image_overlay.state)) continue; + if (READ_INT(*layout, image_overlay.histogram_channel)) continue; + if (READ_INT(*layout, image_overlay.histogram_mode)) continue; + + if (READ_INT(*layout, log_window.x)) continue; + if (READ_INT(*layout, log_window.y)) continue; + if (READ_INT(*layout, log_window.w)) continue; + if (READ_INT(*layout, log_window.h)) continue; + + if (READ_BOOL(*layout, animate)) continue; + + log_printf("unknown attribute %s = %s\n", option, value); } + if (id && strcmp(id, LAYOUT_ID_CURRENT) != 0) + { + g_free(layout->id); + layout->id = id; + } + else + { + g_free(id); + } +} +static void layout_config_startup_path(LayoutOptions *lop, gchar **path) +{ + switch (lop->startup_path) + { + case STARTUP_PATH_LAST: + *path = (lop->last_path && isdir(lop->last_path)) ? g_strdup(lop->last_path) : get_current_dir(); + break; + case STARTUP_PATH_HOME: + *path = (lop->home_path && isdir(lop->home_path)) ? g_strdup(lop->home_path) : g_strdup(homedir()); + break; + default: + *path = get_current_dir(); + break; + } } + static void layout_config_commandline(LayoutOptions *lop, gchar **path) { if (command_line->startup_blank) @@ -2248,15 +2593,8 @@ static void layout_config_commandline(LayoutOptions *lop, gchar **path) { *path = g_strdup(command_line->path); } - else if (options->startup.restore_path && options->startup.path && isdir(options->startup.path)) - { - *path = g_strdup(options->startup.path); - } - else - { - *path = get_current_dir(); - } - + else layout_config_startup_path(lop, path); + if (command_line->tools_show) { lop->tools_float = FALSE; @@ -2273,23 +2611,18 @@ LayoutWindow *layout_new_from_config(const gchar **attribute_names, const gchar LayoutOptions lop; LayoutWindow *lw; gchar *path = NULL; - - memset(&lop, 0, sizeof(LayoutOptions)); - copy_layout_options(&lop, &options->layout); + + init_layout_options(&lop); if (attribute_names) layout_load_attributes(&lop, attribute_names, attribute_values); - + if (use_commandline) { layout_config_commandline(&lop, &path); } - else if (options->startup.restore_path && options->startup.path && isdir(options->startup.path)) - { - path = g_strdup(options->startup.path); - } else { - path = get_current_dir(); + layout_config_startup_path(&lop, &path); } lw = layout_new_with_geometry(NULL, &lop, use_commandline ? command_line->geometry : NULL); @@ -2298,12 +2631,25 @@ LayoutWindow *layout_new_from_config(const gchar **attribute_names, const gchar if (use_commandline && command_line->startup_full_screen) layout_image_full_screen_start(lw); if (use_commandline && command_line->startup_in_slideshow) layout_image_slideshow_start(lw); - + if (use_commandline && command_line->log_window_show) log_window_new(lw); g_free(path); free_layout_options_content(&lop); return lw; } +void layout_update_from_config(LayoutWindow *lw, const gchar **attribute_names, const gchar **attribute_values) +{ + LayoutOptions lop; + + init_layout_options(&lop); + + if (attribute_names) layout_load_attributes(&lop, attribute_names, attribute_values); + + layout_apply_options(lw, &lop); + + free_layout_options_content(&lop); +} + /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */