2 * Copyright (C) 2006 John Ellis
3 * Copyright (C) 2008 - 2016 The Geeqie Team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "preferences.h"
27 #include "cache_maint.h"
31 #include "filefilter.h"
32 #include "fullscreen.h"
34 #include "image-overlay.h"
35 #include "color-man.h"
37 #include "layout_config.h"
38 #include "layout_util.h"
39 #include "pixbuf_util.h"
40 #include "slideshow.h"
44 #include "ui_fileops.h"
46 #include "ui_tabcomp.h"
47 #include "ui_utildlg.h"
49 #include "zonedetect.h"
61 #define EDITOR_NAME_MAX_LENGTH 32
62 #define EDITOR_COMMAND_MAX_LENGTH 1024
64 static void image_overlay_set_text_colours();
66 typedef struct _ThumbSize ThumbSize;
73 static ThumbSize thumb_size_list[] =
107 gchar *format_class_list[] = {
115 /* config memory values */
116 static ConfOptions *c_options = NULL;
123 static GtkWidget *configwindow = NULL;
124 static GtkListStore *filter_store = NULL;
125 static GtkTreeStore *accel_store = NULL;
127 static GtkWidget *safe_delete_path_entry;
129 static GtkWidget *color_profile_input_file_entry[COLOR_PROFILE_INPUTS];
130 static GtkWidget *color_profile_input_name_entry[COLOR_PROFILE_INPUTS];
131 static GtkWidget *color_profile_screen_file_entry;
133 static GtkWidget *sidecar_ext_entry;
134 static GtkWidget *help_search_engine_entry;
137 #define CONFIG_WINDOW_DEF_WIDTH 700
138 #define CONFIG_WINDOW_DEF_HEIGHT 600
141 *-----------------------------------------------------------------------------
142 * option widget callbacks (private)
143 *-----------------------------------------------------------------------------
146 static void zoom_increment_cb(GtkWidget *spin, gpointer data)
148 c_options->image.zoom_increment = (gint)(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) * 100.0 + 0.01);
151 static void slideshow_delay_hours_cb(GtkWidget *spin, gpointer data)
153 gint mins_secs_tenths, delay;
155 mins_secs_tenths = c_options->slideshow.delay %
156 (3600 * SLIDESHOW_SUBSECOND_PRECISION);
158 delay = (gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
159 (3600 * SLIDESHOW_SUBSECOND_PRECISION) +
162 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
163 SLIDESHOW_SUBSECOND_PRECISION;
166 static void slideshow_delay_minutes_cb(GtkWidget *spin, gpointer data)
168 gint hours, secs_tenths, delay;
170 hours = c_options->slideshow.delay / (3600 * SLIDESHOW_SUBSECOND_PRECISION);
171 secs_tenths = c_options->slideshow.delay % (60 * SLIDESHOW_SUBSECOND_PRECISION);
173 delay = hours * (3600 * SLIDESHOW_SUBSECOND_PRECISION) +
174 (gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
175 (60 * SLIDESHOW_SUBSECOND_PRECISION) + secs_tenths);
177 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
178 SLIDESHOW_SUBSECOND_PRECISION;
181 static void slideshow_delay_seconds_cb(GtkWidget *spin, gpointer data)
183 gint hours_mins, delay;
185 hours_mins = c_options->slideshow.delay / (60 * SLIDESHOW_SUBSECOND_PRECISION);
187 delay = (hours_mins * (60 * SLIDESHOW_SUBSECOND_PRECISION)) +
188 (gint)(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
189 (gdouble)(SLIDESHOW_SUBSECOND_PRECISION) + 0.01);
191 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
192 SLIDESHOW_SUBSECOND_PRECISION;
196 *-----------------------------------------------------------------------------
197 * sync progam to config window routine (private)
198 *-----------------------------------------------------------------------------
201 void config_entry_to_option(GtkWidget *entry, gchar **option, gchar *(*func)(const gchar *))
207 buf = gtk_entry_get_text(GTK_ENTRY(entry));
208 if (buf && strlen(buf) > 0)
213 *option = g_strdup(buf);
218 static gboolean accel_apply_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
220 gchar *accel_path, *accel;
222 gtk_tree_model_get(model, iter, AE_ACCEL, &accel_path, AE_KEY, &accel, -1);
224 if (accel_path && accel_path[0])
227 gtk_accelerator_parse(accel, &key.accel_key, &key.accel_mods);
228 gtk_accel_map_change_entry(accel_path, key.accel_key, key.accel_mods, TRUE);
238 static void config_window_apply(void)
241 gboolean refresh = FALSE;
243 config_entry_to_option(safe_delete_path_entry, &options->file_ops.safe_delete_path, remove_trailing_slash);
245 if (options->file_filter.show_hidden_files != c_options->file_filter.show_hidden_files) refresh = TRUE;
246 if (options->file_filter.show_parent_directory != c_options->file_filter.show_parent_directory) refresh = TRUE;
247 if (options->file_filter.show_dot_directory != c_options->file_filter.show_dot_directory) refresh = TRUE;
248 if (options->file_sort.case_sensitive != c_options->file_sort.case_sensitive) refresh = TRUE;
249 if (options->file_sort.natural != c_options->file_sort.natural) refresh = TRUE;
250 if (options->file_filter.disable_file_extension_checks != c_options->file_filter.disable_file_extension_checks) refresh = TRUE;
251 if (options->file_filter.disable != c_options->file_filter.disable) refresh = TRUE;
253 options->file_ops.confirm_delete = c_options->file_ops.confirm_delete;
254 options->file_ops.enable_delete_key = c_options->file_ops.enable_delete_key;
255 options->file_ops.safe_delete_enable = c_options->file_ops.safe_delete_enable;
256 options->file_ops.safe_delete_folder_maxsize = c_options->file_ops.safe_delete_folder_maxsize;
257 options->tools_restore_state = c_options->tools_restore_state;
258 options->save_window_positions = c_options->save_window_positions;
259 options->use_saved_window_positions_for_new_windows = c_options->use_saved_window_positions_for_new_windows;
260 options->save_dialog_window_positions = c_options->save_dialog_window_positions;
261 options->show_window_ids = c_options->show_window_ids;
262 options->image.scroll_reset_method = c_options->image.scroll_reset_method;
263 options->image.zoom_2pass = c_options->image.zoom_2pass;
264 options->image.fit_window_to_image = c_options->image.fit_window_to_image;
265 options->image.limit_window_size = c_options->image.limit_window_size;
266 options->image.zoom_to_fit_allow_expand = c_options->image.zoom_to_fit_allow_expand;
267 options->image.max_window_size = c_options->image.max_window_size;
268 options->image.limit_autofit_size = c_options->image.limit_autofit_size;
269 options->image.max_autofit_size = c_options->image.max_autofit_size;
270 options->image.max_enlargement_size = c_options->image.max_enlargement_size;
271 options->image.use_clutter_renderer = c_options->image.use_clutter_renderer;
272 options->progressive_key_scrolling = c_options->progressive_key_scrolling;
273 options->keyboard_scroll_step = c_options->keyboard_scroll_step;
275 if (options->thumbnails.max_width != c_options->thumbnails.max_width
276 || options->thumbnails.max_height != c_options->thumbnails.max_height
277 || options->thumbnails.quality != c_options->thumbnails.quality)
279 thumb_format_changed = TRUE;
281 options->thumbnails.max_width = c_options->thumbnails.max_width;
282 options->thumbnails.max_height = c_options->thumbnails.max_height;
283 options->thumbnails.quality = c_options->thumbnails.quality;
285 options->thumbnails.enable_caching = c_options->thumbnails.enable_caching;
286 options->thumbnails.cache_into_dirs = c_options->thumbnails.cache_into_dirs;
287 options->thumbnails.use_exif = c_options->thumbnails.use_exif;
288 options->thumbnails.use_ft_metadata = c_options->thumbnails.use_ft_metadata;
289 // options->thumbnails.use_ft_metadata_small = c_options->thumbnails.use_ft_metadata_small;
290 options->thumbnails.spec_standard = c_options->thumbnails.spec_standard;
291 options->metadata.enable_metadata_dirs = c_options->metadata.enable_metadata_dirs;
292 options->file_filter.show_hidden_files = c_options->file_filter.show_hidden_files;
293 options->file_filter.show_parent_directory = c_options->file_filter.show_parent_directory;
294 options->file_filter.show_dot_directory = c_options->file_filter.show_dot_directory;
295 options->file_filter.disable_file_extension_checks = c_options->file_filter.disable_file_extension_checks;
297 options->file_sort.case_sensitive = c_options->file_sort.case_sensitive;
298 options->file_sort.natural = c_options->file_sort.natural;
299 options->file_filter.disable = c_options->file_filter.disable;
301 config_entry_to_option(sidecar_ext_entry, &options->sidecar.ext, NULL);
302 sidecar_ext_parse(options->sidecar.ext);
304 options->slideshow.random = c_options->slideshow.random;
305 options->slideshow.repeat = c_options->slideshow.repeat;
306 options->slideshow.delay = c_options->slideshow.delay;
308 options->mousewheel_scrolls = c_options->mousewheel_scrolls;
309 options->image_lm_click_nav = c_options->image_lm_click_nav;
310 options->image_l_click_video = c_options->image_l_click_video;
311 options->image_l_click_video_editor = c_options->image_l_click_video_editor;
313 options->file_ops.enable_in_place_rename = c_options->file_ops.enable_in_place_rename;
315 options->image.tile_cache_max = c_options->image.tile_cache_max;
316 options->image.image_cache_max = c_options->image.image_cache_max;
318 options->image.zoom_quality = c_options->image.zoom_quality;
320 options->image.zoom_increment = c_options->image.zoom_increment;
322 options->image.enable_read_ahead = c_options->image.enable_read_ahead;
325 if (options->image.use_custom_border_color != c_options->image.use_custom_border_color
326 || options->image.use_custom_border_color_in_fullscreen != c_options->image.use_custom_border_color_in_fullscreen
327 || !gdk_color_equal(&options->image.border_color, &c_options->image.border_color))
329 options->image.use_custom_border_color_in_fullscreen = c_options->image.use_custom_border_color_in_fullscreen;
330 options->image.use_custom_border_color = c_options->image.use_custom_border_color;
331 options->image.border_color = c_options->image.border_color;
332 layout_colors_update();
333 view_window_colors_update();
336 options->image.alpha_color_1 = c_options->image.alpha_color_1;
337 options->image.alpha_color_2 = c_options->image.alpha_color_2;
339 options->fullscreen.screen = c_options->fullscreen.screen;
340 options->fullscreen.clean_flip = c_options->fullscreen.clean_flip;
341 options->fullscreen.disable_saver = c_options->fullscreen.disable_saver;
342 options->fullscreen.above = c_options->fullscreen.above;
343 if (c_options->image_overlay.template_string)
344 set_image_overlay_template_string(&options->image_overlay.template_string,
345 c_options->image_overlay.template_string);
346 if (c_options->image_overlay.font)
347 set_image_overlay_font_string(&options->image_overlay.font,
348 c_options->image_overlay.font);
349 options->image_overlay.text_red = c_options->image_overlay.text_red;
350 options->image_overlay.text_green = c_options->image_overlay.text_green;
351 options->image_overlay.text_blue = c_options->image_overlay.text_blue;
352 options->image_overlay.text_alpha = c_options->image_overlay.text_alpha;
353 options->image_overlay.background_red = c_options->image_overlay.background_red;
354 options->image_overlay.background_green = c_options->image_overlay.background_green;
355 options->image_overlay.background_blue = c_options->image_overlay.background_blue;
356 options->image_overlay.background_alpha = c_options->image_overlay.background_alpha;
357 options->update_on_time_change = c_options->update_on_time_change;
358 options->image.exif_proof_rotate_enable = c_options->image.exif_proof_rotate_enable;
360 options->duplicates_similarity_threshold = c_options->duplicates_similarity_threshold;
361 options->rot_invariant_sim = c_options->rot_invariant_sim;
363 options->tree_descend_subdirs = c_options->tree_descend_subdirs;
365 options->view_dir_list_single_click_enter = c_options->view_dir_list_single_click_enter;
367 options->open_recent_list_maxsize = c_options->open_recent_list_maxsize;
368 options->dnd_icon_size = c_options->dnd_icon_size;
369 options->clipboard_selection = c_options->clipboard_selection;
371 options->metadata.save_in_image_file = c_options->metadata.save_in_image_file;
372 options->metadata.save_legacy_IPTC = c_options->metadata.save_legacy_IPTC;
373 options->metadata.warn_on_write_problems = c_options->metadata.warn_on_write_problems;
374 options->metadata.save_legacy_format = c_options->metadata.save_legacy_format;
375 options->metadata.sync_grouped_files = c_options->metadata.sync_grouped_files;
376 options->metadata.confirm_write = c_options->metadata.confirm_write;
377 options->metadata.sidecar_extended_name = c_options->metadata.sidecar_extended_name;
378 options->metadata.confirm_timeout = c_options->metadata.confirm_timeout;
379 options->metadata.confirm_after_timeout = c_options->metadata.confirm_after_timeout;
380 options->metadata.confirm_on_image_change = c_options->metadata.confirm_on_image_change;
381 options->metadata.confirm_on_dir_change = c_options->metadata.confirm_on_dir_change;
382 options->metadata.keywords_case_sensitive = c_options->metadata.keywords_case_sensitive;
383 options->metadata.write_orientation = c_options->metadata.write_orientation;
384 options->stereo.mode = (c_options->stereo.mode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
385 (c_options->stereo.tmp.mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
386 (c_options->stereo.tmp.flip_right ? PR_STEREO_FLIP_RIGHT : 0) |
387 (c_options->stereo.tmp.mirror_left ? PR_STEREO_MIRROR_LEFT : 0) |
388 (c_options->stereo.tmp.flip_left ? PR_STEREO_FLIP_LEFT : 0) |
389 (c_options->stereo.tmp.swap ? PR_STEREO_SWAP : 0) |
390 (c_options->stereo.tmp.temp_disable ? PR_STEREO_TEMP_DISABLE : 0);
391 options->stereo.fsmode = (c_options->stereo.fsmode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
392 (c_options->stereo.tmp.fs_mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
393 (c_options->stereo.tmp.fs_flip_right ? PR_STEREO_FLIP_RIGHT : 0) |
394 (c_options->stereo.tmp.fs_mirror_left ? PR_STEREO_MIRROR_LEFT : 0) |
395 (c_options->stereo.tmp.fs_flip_left ? PR_STEREO_FLIP_LEFT : 0) |
396 (c_options->stereo.tmp.fs_swap ? PR_STEREO_SWAP : 0) |
397 (c_options->stereo.tmp.fs_temp_disable ? PR_STEREO_TEMP_DISABLE : 0);
398 options->stereo.enable_fsmode = c_options->stereo.enable_fsmode;
399 options->stereo.fixed_w = c_options->stereo.fixed_w;
400 options->stereo.fixed_h = c_options->stereo.fixed_h;
401 options->stereo.fixed_x1 = c_options->stereo.fixed_x1;
402 options->stereo.fixed_y1 = c_options->stereo.fixed_y1;
403 options->stereo.fixed_x2 = c_options->stereo.fixed_x2;
404 options->stereo.fixed_y2 = c_options->stereo.fixed_y2;
406 options->info_keywords.height = c_options->info_keywords.height;
407 options->info_title.height = c_options->info_title.height;
408 options->info_comment.height = c_options->info_comment.height;
409 options->info_rating.height = c_options->info_rating.height;
411 options->marks_save = c_options->marks_save;
412 options->with_rename = c_options->with_rename;
413 config_entry_to_option(help_search_engine_entry, &options->help_search_engine, NULL);
415 options->read_metadata_in_idle = c_options->read_metadata_in_idle;
417 options->star_rating.star = c_options->star_rating.star;
418 options->star_rating.rejected = c_options->star_rating.rejected;
420 set_debug_level(debug_c);
424 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
426 config_entry_to_option(color_profile_input_name_entry[i], &options->color_profile.input_name[i], NULL);
427 config_entry_to_option(color_profile_input_file_entry[i], &options->color_profile.input_file[i], NULL);
429 config_entry_to_option(color_profile_screen_file_entry, &options->color_profile.screen_file, NULL);
430 options->color_profile.use_x11_screen_profile = c_options->color_profile.use_x11_screen_profile;
431 if (options->color_profile.render_intent != c_options->color_profile.render_intent)
433 options->color_profile.render_intent = c_options->color_profile.render_intent;
438 image_options_sync();
443 layout_refresh(NULL);
446 if (accel_store) gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_apply_cb, NULL);
452 *-----------------------------------------------------------------------------
453 * config window main button callbacks (private)
454 *-----------------------------------------------------------------------------
457 static void config_window_close_cb(GtkWidget *widget, gpointer data)
459 gtk_widget_destroy(configwindow);
464 static void config_window_help_cb(GtkWidget *widget, gpointer data)
466 GtkWidget *notebook = data;
469 static gchar *html_section[] =
471 "GuideOptionsGeneral.html",
472 "GuideOptionsImage.html",
473 "GuideOptionsWindow.html",
474 "GuideOptionsKeyboard.html",
475 "GuideOptionsFiltering.html",
476 "GuideOptionsMetadata.html",
477 "GuideOptionsColor.html",
478 "GuideOptionsStereo.html",
479 "GuideOptionsBehavior.html",
480 "GuideOptionsToolbar.html"
483 i = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
484 help_window_show(html_section[i]);
487 static gboolean config_window_delete(GtkWidget *widget, GdkEventAny *event, gpointer data)
489 config_window_close_cb(NULL, NULL);
493 static void config_window_ok_cb(GtkWidget *widget, gpointer data)
495 config_window_apply();
496 config_window_close_cb(NULL, NULL);
499 static void config_window_apply_cb(GtkWidget *widget, gpointer data)
502 lw = layout_window_list->data;
504 config_window_apply();
505 layout_util_sync(lw);
508 static void config_window_save_cb(GtkWidget *widget, gpointer data)
510 config_window_apply();
511 save_options(options);
515 *-----------------------------------------------------------------------------
516 * config window setup (private)
517 *-----------------------------------------------------------------------------
520 static void quality_menu_cb(GtkWidget *combo, gpointer data)
524 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
528 *option = GDK_INTERP_NEAREST;
531 *option = GDK_INTERP_TILES;
534 *option = GDK_INTERP_BILINEAR;
537 *option = GDK_INTERP_HYPER;
542 static void clipboard_selection_menu_cb(GtkWidget *combo, gpointer data)
546 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
558 static void add_quality_menu(GtkWidget *table, gint column, gint row, const gchar *text,
559 guint option, guint *option_c)
566 pref_table_label(table, column, row, text, 0.0);
568 combo = gtk_combo_box_text_new();
570 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Nearest (worst, but fastest)"));
571 if (option == GDK_INTERP_NEAREST) current = 0;
572 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Tiles"));
573 if (option == GDK_INTERP_TILES) current = 1;
574 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Bilinear"));
575 if (option == GDK_INTERP_BILINEAR) current = 2;
576 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Hyper (best, but slowest)"));
577 if (option == GDK_INTERP_HYPER) current = 3;
579 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
581 g_signal_connect(G_OBJECT(combo), "changed",
582 G_CALLBACK(quality_menu_cb), option_c);
584 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
585 GTK_EXPAND | GTK_FILL, 0, 0, 0);
586 gtk_widget_show(combo);
589 static void add_clipboard_selection_menu(GtkWidget *table, gint column, gint row, const gchar *text,
590 gint option, gint *option_c)
597 pref_table_label(table, column, row, text, 0.0);
599 combo = gtk_combo_box_text_new();
601 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("PRIMARY"));
602 if (option == PRIMARY) current = 0;
603 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("CLIPBOARD"));
604 if (option == CLIPBOARD) current = 1;
606 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
608 g_signal_connect(G_OBJECT(combo), "changed",
609 G_CALLBACK(clipboard_selection_menu_cb), option_c);
611 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
612 GTK_EXPAND | GTK_FILL, 0, 0, 0);
613 gtk_widget_show(combo);
616 static void thumb_size_menu_cb(GtkWidget *combo, gpointer data)
620 n = gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
623 if ((guint) n < sizeof(thumb_size_list) / sizeof(ThumbSize))
625 c_options->thumbnails.max_width = thumb_size_list[n].w;
626 c_options->thumbnails.max_height = thumb_size_list[n].h;
630 c_options->thumbnails.max_width = options->thumbnails.max_width;
631 c_options->thumbnails.max_height = options->thumbnails.max_height;
635 static void add_thumb_size_menu(GtkWidget *table, gint column, gint row, gchar *text)
641 c_options->thumbnails.max_width = options->thumbnails.max_width;
642 c_options->thumbnails.max_height = options->thumbnails.max_height;
644 pref_table_label(table, column, row, text, 0.0);
646 combo = gtk_combo_box_text_new();
649 for (i = 0; (guint) i < sizeof(thumb_size_list) / sizeof(ThumbSize); i++)
654 w = thumb_size_list[i].w;
655 h = thumb_size_list[i].h;
657 buf = g_strdup_printf("%d x %d", w, h);
658 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf);
661 if (w == options->thumbnails.max_width && h == options->thumbnails.max_height) current = i;
668 buf = g_strdup_printf("%s %d x %d", _("Custom"), options->thumbnails.max_width, options->thumbnails.max_height);
669 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf);
675 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
676 g_signal_connect(G_OBJECT(combo), "changed",
677 G_CALLBACK(thumb_size_menu_cb), NULL);
679 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
680 GTK_EXPAND | GTK_FILL, 0, 0, 0);
681 gtk_widget_show(combo);
684 static void stereo_mode_menu_cb(GtkWidget *combo, gpointer data)
688 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
692 *option = PR_STEREO_NONE;
695 *option = PR_STEREO_ANAGLYPH_RC;
698 *option = PR_STEREO_ANAGLYPH_GM;
701 *option = PR_STEREO_ANAGLYPH_YB;
704 *option = PR_STEREO_ANAGLYPH_GRAY_RC;
707 *option = PR_STEREO_ANAGLYPH_GRAY_GM;
710 *option = PR_STEREO_ANAGLYPH_GRAY_YB;
713 *option = PR_STEREO_ANAGLYPH_DB_RC;
716 *option = PR_STEREO_ANAGLYPH_DB_GM;
719 *option = PR_STEREO_ANAGLYPH_DB_YB;
722 *option = PR_STEREO_HORIZ;
725 *option = PR_STEREO_HORIZ | PR_STEREO_HALF;
728 *option = PR_STEREO_VERT;
731 *option = PR_STEREO_VERT | PR_STEREO_HALF;
734 *option = PR_STEREO_FIXED;
739 static void add_stereo_mode_menu(GtkWidget *table, gint column, gint row, const gchar *text,
740 gint option, gint *option_c, gboolean add_fixed)
747 pref_table_label(table, column, row, text, 0.0);
749 combo = gtk_combo_box_text_new();
751 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Single image"));
753 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Red-Cyan"));
754 if (option & PR_STEREO_ANAGLYPH_RC) current = 1;
755 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Green-Magenta"));
756 if (option & PR_STEREO_ANAGLYPH_GM) current = 2;
757 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Yellow-Blue"));
758 if (option & PR_STEREO_ANAGLYPH_YB) current = 3;
759 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Red-Cyan"));
760 if (option & PR_STEREO_ANAGLYPH_GRAY_RC) current = 4;
761 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Green-Magenta"));
762 if (option & PR_STEREO_ANAGLYPH_GRAY_GM) current = 5;
763 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Yellow-Blue"));
764 if (option & PR_STEREO_ANAGLYPH_GRAY_YB) current = 6;
765 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Red-Cyan"));
766 if (option & PR_STEREO_ANAGLYPH_DB_RC) current = 7;
767 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Green-Magenta"));
768 if (option & PR_STEREO_ANAGLYPH_DB_GM) current = 8;
769 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Yellow-Blue"));
770 if (option & PR_STEREO_ANAGLYPH_DB_YB) current = 9;
772 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Side by Side"));
773 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Side by Side Half size"));
774 if (option & PR_STEREO_HORIZ)
777 if (option & PR_STEREO_HALF) current = 11;
780 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Top - Bottom"));
781 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Top - Bottom Half size"));
782 if (option & PR_STEREO_VERT)
785 if (option & PR_STEREO_HALF) current = 13;
790 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Fixed position"));
791 if (option & PR_STEREO_FIXED) current = 14;
794 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
796 g_signal_connect(G_OBJECT(combo), "changed",
797 G_CALLBACK(stereo_mode_menu_cb), option_c);
799 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
800 GTK_EXPAND | GTK_FILL, 0, 0, 0);
801 gtk_widget_show(combo);
804 static void video_menu_cb(GtkWidget *combo, gpointer data)
806 gchar **option = data;
808 EditorDescription *ed = g_list_nth_data(editor_list_get(), gtk_combo_box_get_active(GTK_COMBO_BOX(combo)));
812 static void video_menu_populate(gpointer data, gpointer user_data)
814 GtkWidget *combo = user_data;
815 EditorDescription *ed = data;
817 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), ed->name);
820 static void add_video_menu(GtkWidget *table, gint column, gint row, const gchar *text,
821 gchar *option, gchar **option_c)
825 /* use lists since they are sorted */
826 GList *eds = editor_list_get();
830 pref_table_label(table, column, row, text, 0.0);
832 combo = gtk_combo_box_text_new();
833 g_list_foreach(eds,video_menu_populate,(gpointer)combo);
834 current = option ? g_list_index(eds,g_hash_table_lookup(editors,option)): -1;
836 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
838 g_signal_connect(G_OBJECT(combo), "changed",
839 G_CALLBACK(video_menu_cb), option_c);
841 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
842 GTK_EXPAND | GTK_FILL, 0, 0, 0);
843 gtk_widget_show(combo);
846 static void filter_store_populate(void)
850 if (!filter_store) return;
852 gtk_list_store_clear(filter_store);
854 work = filter_get_list();
863 gtk_list_store_append(filter_store, &iter);
864 gtk_list_store_set(filter_store, &iter, 0, fe, -1);
868 static void filter_store_ext_edit_cb(GtkCellRendererText *cell, gchar *path_str,
869 gchar *new_text, gpointer data)
871 GtkWidget *model = data;
872 FilterEntry *fe = data;
876 if (!new_text || strlen(new_text) < 1) return;
878 tpath = gtk_tree_path_new_from_string(path_str);
879 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
880 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
882 g_free(fe->extensions);
883 fe->extensions = g_strdup(new_text);
885 gtk_tree_path_free(tpath);
889 static void filter_store_class_edit_cb(GtkCellRendererText *cell, gchar *path_str,
890 gchar *new_text, gpointer data)
892 GtkWidget *model = data;
893 FilterEntry *fe = data;
898 if (!new_text || !new_text[0]) return;
900 tpath = gtk_tree_path_new_from_string(path_str);
901 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
902 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
904 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
906 if (strcmp(new_text, _(format_class_list[i])) == 0)
913 gtk_tree_path_free(tpath);
917 static void filter_store_desc_edit_cb(GtkCellRendererText *cell, gchar *path_str,
918 gchar *new_text, gpointer data)
920 GtkWidget *model = data;
925 if (!new_text || !new_text[0]) return;
927 tpath = gtk_tree_path_new_from_string(path_str);
928 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
929 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
931 g_free(fe->description);
932 fe->description = g_strdup(new_text);
934 gtk_tree_path_free(tpath);
937 static void filter_store_enable_cb(GtkCellRendererToggle *renderer,
938 gchar *path_str, gpointer data)
940 GtkWidget *model = data;
945 tpath = gtk_tree_path_new_from_string(path_str);
946 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
947 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
949 fe->enabled = !fe->enabled;
951 gtk_tree_path_free(tpath);
955 static void filter_store_writable_cb(GtkCellRendererToggle *renderer,
956 gchar *path_str, gpointer data)
958 GtkWidget *model = data;
963 tpath = gtk_tree_path_new_from_string(path_str);
964 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
965 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
967 fe->writable = !fe->writable;
968 if (fe->writable) fe->allow_sidecar = FALSE;
970 gtk_tree_path_free(tpath);
974 static void filter_store_sidecar_cb(GtkCellRendererToggle *renderer,
975 gchar *path_str, gpointer data)
977 GtkWidget *model = data;
982 tpath = gtk_tree_path_new_from_string(path_str);
983 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
984 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
986 fe->allow_sidecar = !fe->allow_sidecar;
987 if (fe->allow_sidecar) fe->writable = FALSE;
989 gtk_tree_path_free(tpath);
993 static void filter_set_func(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell,
994 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
998 gtk_tree_model_get(tree_model, iter, 0, &fe, -1);
1000 switch (GPOINTER_TO_INT(data))
1003 g_object_set(GTK_CELL_RENDERER(cell),
1004 "active", fe->enabled, NULL);
1007 g_object_set(GTK_CELL_RENDERER(cell),
1008 "text", fe->extensions, NULL);
1010 case FE_DESCRIPTION:
1011 g_object_set(GTK_CELL_RENDERER(cell),
1012 "text", fe->description, NULL);
1015 g_object_set(GTK_CELL_RENDERER(cell),
1016 "text", _(format_class_list[fe->file_class]), NULL);
1019 g_object_set(GTK_CELL_RENDERER(cell),
1020 "active", fe->writable, NULL);
1022 case FE_ALLOW_SIDECAR:
1023 g_object_set(GTK_CELL_RENDERER(cell),
1024 "active", fe->allow_sidecar, NULL);
1029 static gboolean filter_add_scroll(gpointer data)
1033 GtkCellRenderer *cell;
1034 GtkTreeViewColumn *column;
1035 GList *list_columns;
1040 rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(filter_store), NULL);
1041 path = gtk_tree_path_new_from_indices(rows-1, -1);
1043 list_columns = gtk_tree_view_get_columns(GTK_TREE_VIEW(data));
1045 column = g_list_nth(list_columns,i)->data;
1046 title = gtk_tree_view_column_get_title(GTK_TREE_VIEW_COLUMN(column));
1048 } while (strcmp(title, "Filter") !=0 );
1050 list_cells = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(column));
1051 cell = g_list_last(list_cells)->data;
1053 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1054 path, column, FALSE, 0.0, 0.0 );
1055 gtk_tree_view_set_cursor_on_cell(GTK_TREE_VIEW(data),
1056 path, column, cell, TRUE);
1058 gtk_tree_path_free(path);
1059 g_list_free(list_cells);
1060 g_list_free(list_columns);
1065 static void filter_add_cb(GtkWidget *widget, gpointer data)
1067 filter_add_unique("description", ".new", FORMAT_CLASS_IMAGE, TRUE, FALSE, TRUE);
1068 filter_store_populate();
1070 g_idle_add((GSourceFunc)filter_add_scroll, data);
1073 static void filter_remove_cb(GtkWidget *widget, gpointer data)
1075 GtkWidget *filter_view = data;
1076 GtkTreeSelection *selection;
1080 if (!filter_store) return;
1081 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
1082 if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) return;
1083 gtk_tree_model_get(GTK_TREE_MODEL(filter_store), &iter, 0, &fe, -1);
1086 filter_remove_entry(fe);
1088 filter_store_populate();
1091 static gboolean filter_default_ok_scroll(GtkTreeView *data)
1095 GtkTreeViewColumn *column;
1097 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(filter_store), &iter);
1098 path = gtk_tree_model_get_path(GTK_TREE_MODEL(filter_store), &iter);
1099 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data),0);
1101 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1105 gtk_tree_path_free(path);
1110 static void filter_default_ok_cb(GenericDialog *gd, gpointer data)
1113 filter_add_defaults();
1115 filter_store_populate();
1117 g_idle_add((GSourceFunc)filter_default_ok_scroll, gd->data);
1120 static void dummy_cancel_cb(GenericDialog *gd, gpointer data)
1122 /* no op, only so cancel button appears */
1125 static void filter_default_cb(GtkWidget *widget, gpointer data)
1129 gd = generic_dialog_new(_("Reset filters"),
1130 "reset_filter", widget, TRUE,
1131 dummy_cancel_cb, data);
1132 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Reset filters"),
1133 _("This will reset the file filters to the defaults.\nContinue?"), TRUE);
1134 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, filter_default_ok_cb, TRUE);
1135 gtk_widget_show(gd->dialog);
1138 static void filter_disable_cb(GtkWidget *widget, gpointer data)
1140 GtkWidget *frame = data;
1142 gtk_widget_set_sensitive(frame,
1143 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
1146 static void safe_delete_view_cb(GtkWidget *widget, gpointer data)
1148 layout_set_path(NULL, gtk_entry_get_text(GTK_ENTRY(safe_delete_path_entry)));
1151 static void safe_delete_clear_ok_cb(GenericDialog *gd, gpointer data)
1153 file_util_trash_clear();
1156 static void safe_delete_clear_cb(GtkWidget *widget, gpointer data)
1160 gd = generic_dialog_new(_("Clear trash"),
1161 "clear_trash", widget, TRUE,
1162 dummy_cancel_cb, NULL);
1163 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Clear trash"),
1164 _("This will remove the trash contents."), FALSE);
1165 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, safe_delete_clear_ok_cb, TRUE);
1166 entry = gtk_entry_new();
1167 gtk_widget_set_can_focus(entry, FALSE);
1168 gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
1169 if (options->file_ops.safe_delete_path) gtk_entry_set_text(GTK_ENTRY(entry), options->file_ops.safe_delete_path);
1170 gtk_box_pack_start(GTK_BOX(gd->vbox), entry, FALSE, FALSE, 0);
1171 gtk_widget_show(entry);
1172 gtk_widget_show(gd->dialog);
1175 static void image_overlay_template_view_changed_cb(GtkWidget *widget, gpointer data)
1177 GtkWidget *pTextView;
1178 GtkTextBuffer *pTextBuffer;
1182 pTextView = GTK_WIDGET(data);
1184 pTextBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pTextView));
1185 gtk_text_buffer_get_start_iter(pTextBuffer, &iStart);
1186 gtk_text_buffer_get_end_iter(pTextBuffer, &iEnd);
1188 set_image_overlay_template_string(&c_options->image_overlay.template_string,
1189 gtk_text_buffer_get_text(pTextBuffer, &iStart, &iEnd, TRUE));
1192 static void image_overlay_default_template_ok_cb(GenericDialog *gd, gpointer data)
1194 GtkTextView *text_view = data;
1195 GtkTextBuffer *buffer;
1197 set_default_image_overlay_template_string(&options->image_overlay.template_string);
1198 if (!configwindow) return;
1200 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
1201 gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
1204 static void image_overlay_default_template_cb(GtkWidget *widget, gpointer data)
1208 gd = generic_dialog_new(_("Reset image overlay template string"),
1209 "reset_image_overlay_template_string", widget, TRUE,
1210 dummy_cancel_cb, data);
1211 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Reset image overlay template string"),
1212 _("This will reset the image overlay template string to the default.\nContinue?"), TRUE);
1213 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, image_overlay_default_template_ok_cb, TRUE);
1214 gtk_widget_show(gd->dialog);
1217 static void image_overlay_help_cb(GtkWidget *widget, gpointer data)
1219 help_window_show("GuideOptionsWindow.html#OverlayScreenDisplay");
1222 static void image_overlay_set_font_cb(GtkWidget *widget, gpointer data)
1224 #if GTK_CHECK_VERSION(3,4,0)
1227 PangoFontDescription *font_desc;
1229 dialog = gtk_font_chooser_dialog_new("Image Overlay Font", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1230 gtk_font_chooser_set_font(GTK_FONT_CHOOSER(dialog), options->image_overlay.font);
1232 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1234 font_desc = gtk_font_chooser_get_font_desc(GTK_FONT_CHOOSER(dialog));
1235 font = pango_font_description_to_string(font_desc);
1236 g_free(c_options->image_overlay.font);
1237 c_options->image_overlay.font = g_strdup(font);
1241 gtk_widget_destroy(dialog);
1245 font = gtk_font_button_get_font_name(GTK_FONT_BUTTON(widget));
1246 c_options->image_overlay.font = g_strdup(font);
1250 static void image_overlay_set_text_colour_cb(GtkWidget *widget, gpointer data)
1253 #if GTK_CHECK_VERSION(3,4,0)
1256 dialog = gtk_color_chooser_dialog_new("Image Overlay Text Colour", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1257 colour.red = options->image_overlay.text_red;
1258 colour.green = options->image_overlay.text_green;
1259 colour.blue = options->image_overlay.text_blue;
1260 colour.alpha = options->image_overlay.text_alpha;
1261 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1262 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(dialog), TRUE);
1264 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1266 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1267 c_options->image_overlay.text_red = colour.red*255;
1268 c_options->image_overlay.text_green = colour.green*255;
1269 c_options->image_overlay.text_blue = colour.blue*255;
1270 c_options->image_overlay.text_alpha = colour.alpha*255;
1272 gtk_widget_destroy(dialog);
1275 GtkColorSelection *colorsel;
1277 dialog = gtk_color_selection_dialog_new("Image Overlay Text Colour");
1278 gtk_window_set_keep_above(GTK_WINDOW(dialog),TRUE);
1279 colour.red = options->image_overlay.text_red*257;
1280 colour.green = options->image_overlay.text_green*257;
1281 colour.blue = options->image_overlay.text_blue*257;
1282 colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)));
1283 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
1284 gtk_color_selection_set_current_color(colorsel, &colour);
1285 gtk_color_selection_set_current_alpha(colorsel, options->image_overlay.text_alpha*257);
1287 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
1289 gtk_color_selection_get_current_color(colorsel, &colour);
1290 c_options->image_overlay.text_red = colour.red/257;
1291 c_options->image_overlay.text_green = colour.green/257;
1292 c_options->image_overlay.text_blue = colour.blue/257;
1293 c_options->image_overlay.text_alpha = gtk_color_selection_get_current_alpha(colorsel)/257;
1295 gtk_widget_destroy (dialog);
1300 static void image_overlay_set_background_colour_cb(GtkWidget *widget, gpointer data)
1303 #if GTK_CHECK_VERSION(3,4,0)
1306 dialog = gtk_color_chooser_dialog_new("Image Overlay Background Colour", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1307 colour.red = options->image_overlay.background_red;
1308 colour.green = options->image_overlay.background_green;
1309 colour.blue = options->image_overlay.background_blue;
1310 colour.alpha = options->image_overlay.background_alpha;
1311 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1312 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(dialog), TRUE);
1314 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1316 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1317 c_options->image_overlay.background_red = colour.red*255;
1318 c_options->image_overlay.background_green = colour.green*255;
1319 c_options->image_overlay.background_blue = colour.blue*255;
1320 c_options->image_overlay.background_alpha = colour.alpha*255;
1322 gtk_widget_destroy(dialog);
1325 GtkColorSelection *colorsel;
1327 dialog = gtk_color_selection_dialog_new("Image Overlay Background Colour");
1328 gtk_window_set_keep_above(GTK_WINDOW(dialog),TRUE);
1329 colour.red = options->image_overlay.background_red*257;
1330 colour.green = options->image_overlay.background_green*257;
1331 colour.blue = options->image_overlay.background_blue*257;
1332 colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)));
1333 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
1334 gtk_color_selection_set_current_color(colorsel, &colour);
1335 gtk_color_selection_set_current_alpha(colorsel, options->image_overlay.background_alpha*257);
1337 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
1339 gtk_color_selection_get_current_color(colorsel, &colour);
1340 c_options->image_overlay.background_red = colour.red/257;
1341 c_options->image_overlay.background_green = colour.green/257;
1342 c_options->image_overlay.background_blue = colour.blue/257;
1343 c_options->image_overlay.background_alpha = gtk_color_selection_get_current_alpha(colorsel)/257;
1345 gtk_widget_destroy(dialog);
1349 static void accel_store_populate(void)
1352 GList *groups, *actions;
1354 const gchar *accel_path;
1358 if (!accel_store || !layout_window_list || !layout_window_list->data) return;
1360 gtk_tree_store_clear(accel_store);
1361 lw = layout_window_list->data; /* get the actions from the first window, it should not matter, they should be the same in all windows */
1363 g_assert(lw && lw->ui_manager);
1364 groups = gtk_ui_manager_get_action_groups(lw->ui_manager);
1367 actions = gtk_action_group_list_actions(GTK_ACTION_GROUP(groups->data));
1370 action = GTK_ACTION(actions->data);
1371 accel_path = gtk_action_get_accel_path(action);
1372 if (accel_path && gtk_accel_map_lookup_entry(accel_path, &key))
1374 gchar *label, *label2, *tooltip, *accel;
1375 g_object_get(action,
1376 "tooltip", &tooltip,
1380 if (pango_parse_markup(label, -1, '_', NULL, &label2, NULL, NULL) && label2)
1386 accel = gtk_accelerator_name(key.accel_key, key.accel_mods);
1390 gtk_tree_store_append(accel_store, &iter, NULL);
1391 gtk_tree_store_set(accel_store, &iter,
1394 AE_TOOLTIP, tooltip ? tooltip : "",
1395 AE_ACCEL, accel_path,
1403 actions = actions->next;
1406 groups = groups->next;
1410 static void accel_store_cleared_cb(GtkCellRendererAccel *accel, gchar *path_string, gpointer user_data)
1415 static gboolean accel_remove_key_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1417 gchar *accel1 = data;
1422 gtk_tree_model_get(model, iter, AE_KEY, &accel2, -1);
1424 gtk_accelerator_parse(accel1, &key1.accel_key, &key1.accel_mods);
1425 gtk_accelerator_parse(accel2, &key2.accel_key, &key2.accel_mods);
1427 if (key1.accel_key == key2.accel_key && key1.accel_mods == key2.accel_mods)
1429 gtk_tree_store_set(accel_store, iter, AE_KEY, "", -1);
1430 DEBUG_1("accelerator key '%s' is already used, removing.", accel1);
1439 static void accel_store_edited_cb(GtkCellRendererAccel *accel, gchar *path_string, guint accel_key, GdkModifierType accel_mods, guint hardware_keycode, gpointer user_data)
1441 GtkTreeModel *model = (GtkTreeModel *)accel_store;
1445 GtkAccelKey old_key, key;
1446 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
1448 gtk_tree_model_get_iter(model, &iter, path);
1449 gtk_tree_model_get(model, &iter, AE_ACCEL, &accel_path, -1);
1451 /* test if the accelerator can be stored without conflicts*/
1452 gtk_accel_map_lookup_entry(accel_path, &old_key);
1454 /* change the key and read it back (change may fail on keys hardcoded in gtk)*/
1455 gtk_accel_map_change_entry(accel_path, accel_key, accel_mods, TRUE);
1456 gtk_accel_map_lookup_entry(accel_path, &key);
1458 /* restore the original for now, the key will be really changed when the changes are confirmed */
1459 gtk_accel_map_change_entry(accel_path, old_key.accel_key, old_key.accel_mods, TRUE);
1461 acc = gtk_accelerator_name(key.accel_key, key.accel_mods);
1462 gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_remove_key_cb, acc);
1464 gtk_tree_store_set(accel_store, &iter, AE_KEY, acc, -1);
1465 gtk_tree_path_free(path);
1469 static gboolean accel_default_scroll(GtkTreeView *data)
1473 GtkTreeViewColumn *column;
1475 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(accel_store), &iter);
1476 path = gtk_tree_model_get_path(GTK_TREE_MODEL(accel_store), &iter);
1477 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data),0);
1479 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1483 gtk_tree_path_free(path);
1488 static void accel_default_cb(GtkWidget *widget, gpointer data)
1490 accel_store_populate();
1492 g_idle_add((GSourceFunc)accel_default_scroll, data);
1495 void accel_remove_selection(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1497 gtk_tree_store_set(accel_store, iter, AE_KEY, "", -1);
1500 void accel_reset_selection(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1503 gchar *accel_path, *accel;
1505 gtk_tree_model_get(model, iter, AE_ACCEL, &accel_path, -1);
1506 gtk_accel_map_lookup_entry(accel_path, &key);
1507 accel = gtk_accelerator_name(key.accel_key, key.accel_mods);
1509 gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_remove_key_cb, accel);
1511 gtk_tree_store_set(accel_store, iter, AE_KEY, accel, -1);
1516 static void accel_reset_cb(GtkWidget *widget, gpointer data)
1518 GtkTreeSelection *selection;
1520 if (!accel_store) return;
1521 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data));
1522 gtk_tree_selection_selected_foreach(selection, &accel_reset_selection, NULL);
1527 static GtkWidget *scrolled_notebook_page(GtkWidget *notebook, const gchar *title)
1531 GtkWidget *scrolled;
1532 GtkWidget *viewport;
1534 scrolled = gtk_scrolled_window_new(NULL, NULL);
1535 gtk_container_set_border_width(GTK_CONTAINER(scrolled), PREF_PAD_BORDER);
1536 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
1537 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1538 label = gtk_label_new(title);
1539 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled, label);
1540 gtk_widget_show(scrolled);
1542 viewport = gtk_viewport_new(NULL, NULL);
1543 gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
1544 gtk_container_add(GTK_CONTAINER(scrolled), viewport);
1545 gtk_widget_show(viewport);
1547 vbox = gtk_vbox_new(FALSE, 0);
1548 gtk_container_add(GTK_CONTAINER(viewport), vbox);
1549 gtk_widget_show(vbox);
1554 static void cache_standard_cb(GtkWidget *widget, gpointer data)
1556 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1558 c_options->thumbnails.spec_standard =TRUE;
1559 c_options->thumbnails.cache_into_dirs = FALSE;
1563 c_options->thumbnails.spec_standard =FALSE;
1567 static void cache_geeqie_cb(GtkWidget *widget, gpointer data)
1569 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1571 c_options->thumbnails.spec_standard =TRUE;
1572 c_options->thumbnails.cache_into_dirs = FALSE;
1576 c_options->thumbnails.spec_standard =FALSE;
1580 static void cache_local_cb(GtkWidget *widget, gpointer data)
1582 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1584 c_options->thumbnails.cache_into_dirs = TRUE;
1585 c_options->thumbnails.spec_standard =FALSE;
1589 c_options->thumbnails.cache_into_dirs = FALSE;
1593 static void help_search_engine_entry_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1594 GdkEvent *event, gpointer userdata)
1596 if (pos == GTK_ENTRY_ICON_PRIMARY)
1598 gtk_entry_set_text(GTK_ENTRY(userdata), HELP_SEARCH_ENGINE);
1602 gtk_entry_set_text(GTK_ENTRY(userdata), "");
1606 static void star_rating_star_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1607 GdkEvent *event, gpointer userdata)
1609 gchar *rating_symbol;
1611 if (pos == GTK_ENTRY_ICON_PRIMARY)
1613 rating_symbol = g_strdup_printf("U+%X", STAR_RATING_STAR);
1614 gtk_entry_set_text(GTK_ENTRY(userdata), rating_symbol);
1615 g_free(rating_symbol);
1619 gtk_entry_set_text(GTK_ENTRY(userdata), "U+");
1620 gtk_widget_grab_focus(GTK_WIDGET(userdata));
1621 gtk_editable_select_region(GTK_EDITABLE(userdata), 2, 2);
1625 static void star_rating_rejected_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1626 GdkEvent *event, gpointer userdata)
1628 gchar *rating_symbol;
1630 if (pos == GTK_ENTRY_ICON_PRIMARY)
1632 rating_symbol = g_strdup_printf("U+%X", STAR_RATING_REJECTED);
1633 gtk_entry_set_text(GTK_ENTRY(userdata), rating_symbol);
1634 g_free(rating_symbol);
1638 gtk_entry_set_text(GTK_ENTRY(userdata), "U+");
1639 gtk_widget_grab_focus(GTK_WIDGET(userdata));
1640 gtk_editable_select_region(GTK_EDITABLE(userdata), 2, 2);
1644 static guint star_rating_symbol_test(GtkWidget *widget, gpointer data)
1646 GtkContainer *hbox = data;
1647 GString *str = g_string_new(NULL);
1648 GtkEntry *hex_code_entry;
1649 gchar *hex_code_full;
1652 guint64 hex_value = 0;
1654 list = gtk_container_get_children(hbox);
1656 hex_code_entry = g_list_nth_data(list, 2);
1657 hex_code_full = g_strdup(gtk_entry_get_text(hex_code_entry));
1659 hex_code = g_strsplit(hex_code_full, "+", 2);
1660 if (hex_code[0] && hex_code[1])
1662 g_ascii_string_to_unsigned(hex_code[1], 16, 0, 0x10FFFF, &hex_value, NULL);
1666 hex_value = 0x003F; // Unicode 'Question Mark'
1668 str = g_string_append_unichar(str, hex_value);
1669 gtk_label_set_text(g_list_nth_data(list, 1), str->str);
1671 g_strfreev(hex_code);
1672 g_string_free(str, TRUE);
1673 g_free(hex_code_full);
1678 static void star_rating_star_test_cb(GtkWidget *widget, gpointer data)
1680 guint64 star_symbol;
1682 star_symbol = star_rating_symbol_test(widget, data);
1683 c_options->star_rating.star = star_symbol;
1686 static void star_rating_rejected_test_cb(GtkWidget *widget, gpointer data)
1688 guint64 rejected_symbol;
1690 rejected_symbol = star_rating_symbol_test(widget, data);
1691 c_options->star_rating.rejected = rejected_symbol;
1694 /* general options tab */
1695 static void config_tab_general(GtkWidget *notebook)
1700 GtkWidget *group_frame;
1701 GtkWidget *subgroup;
1703 GtkWidget *ct_button;
1706 gint hours, minutes, remainder;
1708 GtkWidget *star_rating_entry;
1710 gchar *rating_symbol;
1712 vbox = scrolled_notebook_page(notebook, _("General"));
1714 group = pref_group_new(vbox, FALSE, _("Thumbnails"), GTK_ORIENTATION_VERTICAL);
1716 table = pref_table_new(group, 2, 2, FALSE, FALSE);
1717 add_thumb_size_menu(table, 0, 0, _("Size:"));
1718 add_quality_menu(table, 0, 1, _("Quality:"), options->thumbnails.quality, &c_options->thumbnails.quality);
1720 ct_button = pref_checkbox_new_int(group, _("Cache thumbnails"),
1721 options->thumbnails.enable_caching, &c_options->thumbnails.enable_caching);
1723 subgroup = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1724 pref_checkbox_link_sensitivity(ct_button, subgroup);
1726 group_frame = pref_frame_new(subgroup, TRUE, _("Use Geeqie thumbnail style and cache"),
1727 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1728 button = pref_radiobutton_new(group_frame, NULL, get_thumbnails_cache_dir(),
1729 !options->thumbnails.spec_standard,
1730 G_CALLBACK(cache_geeqie_cb), NULL);
1732 group_frame = pref_frame_new(subgroup, TRUE,
1733 _("Store thumbnails local to image folder (non-standard)"),
1734 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1735 pref_radiobutton_new(group_frame, button, "*/.thumbnails",
1736 options->thumbnails.cache_into_dirs,
1737 G_CALLBACK(cache_local_cb), NULL);
1739 group_frame = pref_frame_new(subgroup, TRUE,
1740 _("Use standard thumbnail style and cache, shared with other applications"),
1741 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1742 pref_radiobutton_new(group_frame, button, get_thumbnails_standard_cache_dir(),
1743 options->thumbnails.spec_standard,
1744 G_CALLBACK(cache_standard_cb), NULL);
1746 pref_checkbox_new_int(group, _("Use EXIF thumbnails when available (EXIF thumbnails may be outdated)"),
1747 options->thumbnails.use_exif, &c_options->thumbnails.use_exif);
1749 #ifdef HAVE_FFMPEGTHUMBNAILER_METADATA
1750 pref_checkbox_new_int(group, _("Use embedded metadata in video files as thumbnails when available"),
1751 options->thumbnails.use_ft_metadata, &c_options->thumbnails.use_ft_metadata);
1753 // pref_checkbox_new_int(group, _("Ignore embedded metadata if size is too small"),
1754 // options->thumbnails.use_ft_metadata_small, &c_options->thumbnails.use_ft_metadata_small);
1757 group = pref_group_new(vbox, FALSE, _("Star Rating"), GTK_ORIENTATION_VERTICAL);
1759 c_options->star_rating.star = options->star_rating.star;
1760 c_options->star_rating.rejected = options->star_rating.rejected;
1762 str = g_string_new(NULL);
1763 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1764 pref_label_new(hbox, "Star character: ");
1765 str = g_string_append_unichar(str, options->star_rating.star);
1766 pref_label_new(hbox, g_strdup(str->str));
1767 rating_symbol = g_strdup_printf("U+%X", options->star_rating.star);
1768 star_rating_entry = gtk_entry_new();
1769 gtk_entry_set_text(GTK_ENTRY(star_rating_entry), rating_symbol);
1770 gtk_box_pack_start(GTK_BOX(hbox), star_rating_entry, FALSE, FALSE, 0);
1771 gtk_entry_set_width_chars(GTK_ENTRY(star_rating_entry), 15);
1772 gtk_widget_show(star_rating_entry);
1773 button = pref_button_new(NULL, NULL, _("Set"), FALSE,
1774 G_CALLBACK(star_rating_star_test_cb), hbox);
1775 gtk_widget_set_tooltip_text(button, _("Display selected character"));
1776 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1777 gtk_widget_show(button);
1778 gtk_widget_set_tooltip_text(star_rating_entry, _("Hexadecimal representation of a Unicode character. A list of all Unicode characters may be found on the Internet."));
1779 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1780 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1781 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1782 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1783 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1784 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1785 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1786 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1787 g_signal_connect(GTK_ENTRY(star_rating_entry), "icon-press",
1788 G_CALLBACK(star_rating_star_icon_cb),
1791 g_string_free(str, TRUE);
1792 g_free(rating_symbol);
1794 str = g_string_new(NULL);
1795 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1796 pref_label_new(hbox, "Rejected character: ");
1797 str = g_string_append_unichar(str, options->star_rating.rejected);
1798 pref_label_new(hbox, g_strdup(str->str));
1799 rating_symbol = g_strdup_printf("U+%X", options->star_rating.rejected);
1800 star_rating_entry = gtk_entry_new();
1801 gtk_entry_set_text(GTK_ENTRY(star_rating_entry), rating_symbol);
1802 gtk_box_pack_start(GTK_BOX(hbox), star_rating_entry, FALSE, FALSE, 0);
1803 gtk_entry_set_width_chars(GTK_ENTRY(star_rating_entry), 15);
1804 gtk_widget_show(star_rating_entry);
1805 button = pref_button_new(NULL, NULL, _("Set"), FALSE,
1806 G_CALLBACK(star_rating_rejected_test_cb), hbox);
1807 gtk_widget_set_tooltip_text(button, _("Display selected character"));
1808 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1809 gtk_widget_show(button);
1810 gtk_widget_set_tooltip_text(star_rating_entry, _("Hexadecimal representation of a Unicode character. A list of all Unicode characters may be found on the Internet."));
1811 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1812 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1813 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1814 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1815 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1816 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1817 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1818 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1819 g_signal_connect(GTK_ENTRY(star_rating_entry), "icon-press",
1820 G_CALLBACK(star_rating_rejected_icon_cb),
1823 g_string_free(str, TRUE);
1824 g_free(rating_symbol);
1826 group = pref_group_new(vbox, FALSE, _("Slide show"), GTK_ORIENTATION_VERTICAL);
1828 c_options->slideshow.delay = options->slideshow.delay;
1829 hours = options->slideshow.delay / (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1830 remainder = options->slideshow.delay % (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1831 minutes = remainder / (60 * SLIDESHOW_SUBSECOND_PRECISION);
1832 seconds = (gdouble)(remainder % (60 * SLIDESHOW_SUBSECOND_PRECISION)) /
1833 SLIDESHOW_SUBSECOND_PRECISION;
1835 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1837 spin = pref_spin_new(hbox, _("Delay between image change hrs:mins:secs.dec"), NULL,
1839 options->slideshow.delay ? hours : 0.0,
1840 G_CALLBACK(slideshow_delay_hours_cb), NULL);
1841 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1842 spin = pref_spin_new(hbox, ":" , NULL,
1844 options->slideshow.delay ? minutes: 0.0,
1845 G_CALLBACK(slideshow_delay_minutes_cb), NULL);
1846 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1847 spin = pref_spin_new(hbox, ":", NULL,
1848 SLIDESHOW_MIN_SECONDS, 59, 1.0, 1,
1849 options->slideshow.delay ? seconds : 10.0,
1850 G_CALLBACK(slideshow_delay_seconds_cb), NULL);
1851 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1853 pref_checkbox_new_int(group, _("Random"), options->slideshow.random, &c_options->slideshow.random);
1854 pref_checkbox_new_int(group, _("Repeat"), options->slideshow.repeat, &c_options->slideshow.repeat);
1856 group = pref_group_new(vbox, FALSE, _("Image loading and caching"), GTK_ORIENTATION_VERTICAL);
1858 pref_spin_new_int(group, _("Decoded image cache size (Mb):"), NULL,
1859 0, 99999, 1, options->image.image_cache_max, &c_options->image.image_cache_max);
1860 pref_checkbox_new_int(group, _("Preload next image"),
1861 options->image.enable_read_ahead, &c_options->image.enable_read_ahead);
1863 pref_checkbox_new_int(group, _("Refresh on file change"),
1864 options->update_on_time_change, &c_options->update_on_time_change);
1866 group = pref_group_new(vbox, FALSE, _("Info sidebar heights"), GTK_ORIENTATION_VERTICAL);
1867 pref_label_new(group, _("NOTE! Geeqie must be restarted for changes to take effect"));
1868 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1869 pref_spin_new_int(hbox, _("Keywords:"), NULL,
1871 options->info_keywords.height, &c_options->info_keywords.height);
1872 pref_spin_new_int(hbox, _("Title:"), NULL,
1874 options->info_title.height, &c_options->info_title.height);
1875 pref_spin_new_int(hbox, _("Comment:"), NULL,
1877 options->info_comment.height, &c_options->info_comment.height);
1878 pref_spin_new_int(hbox, _("Rating:"), NULL,
1880 options->info_rating.height, &c_options->info_rating.height);
1882 group = pref_group_new(vbox, FALSE, _("On-line help search engine"), GTK_ORIENTATION_VERTICAL);
1884 help_search_engine_entry = gtk_entry_new();
1885 gtk_entry_set_text(GTK_ENTRY(help_search_engine_entry), options->help_search_engine);
1886 gtk_box_pack_start(GTK_BOX(group), help_search_engine_entry, FALSE, FALSE, 0);
1887 gtk_widget_show(help_search_engine_entry);
1889 gtk_widget_set_tooltip_text(help_search_engine_entry, _("The format varies between search engines, e.g the format may be:\nhttps://www.search_engine.com/search?q=site:geeqie.org/help\nhttps://www.search_engine.com/?q=site:geeqie.org/help"));
1891 gtk_entry_set_icon_from_stock(GTK_ENTRY(help_search_engine_entry),
1892 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1893 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(help_search_engine_entry),
1894 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1895 gtk_entry_set_icon_from_stock(GTK_ENTRY(help_search_engine_entry),
1896 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1897 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(help_search_engine_entry),
1898 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1899 g_signal_connect(GTK_ENTRY(help_search_engine_entry), "icon-press",
1900 G_CALLBACK(help_search_engine_entry_icon_cb),
1901 help_search_engine_entry);
1905 static void config_tab_image(GtkWidget *notebook)
1910 GtkWidget *ct_button;
1911 GtkWidget *enlargement_button;
1915 vbox = scrolled_notebook_page(notebook, _("Image"));
1917 group = pref_group_new(vbox, FALSE, _("Zoom"), GTK_ORIENTATION_VERTICAL);
1919 table = pref_table_new(group, 2, 1, FALSE, FALSE);
1920 add_quality_menu(table, 0, 0, _("Quality:"), options->image.zoom_quality, &c_options->image.zoom_quality);
1923 pref_checkbox_new_int(group, _("Use GPU acceleration via Clutter library"),
1924 options->image.use_clutter_renderer, &c_options->image.use_clutter_renderer);
1927 pref_checkbox_new_int(group, _("Two pass rendering (apply HQ zoom and color correction in second pass)"),
1928 options->image.zoom_2pass, &c_options->image.zoom_2pass);
1930 c_options->image.zoom_increment = options->image.zoom_increment;
1931 spin = pref_spin_new(group, _("Zoom increment:"), NULL,
1932 0.01, 4.0, 0.01, 2, (gdouble)options->image.zoom_increment / 100.0,
1933 G_CALLBACK(zoom_increment_cb), NULL);
1934 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1936 group = pref_group_new(vbox, FALSE, _("Fit image to window"), GTK_ORIENTATION_VERTICAL);
1938 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1939 enlargement_button = pref_checkbox_new_int(hbox, _("Allow enlargement of image (max. size in %)"),
1940 options->image.zoom_to_fit_allow_expand, &c_options->image.zoom_to_fit_allow_expand);
1941 spin = pref_spin_new_int(hbox, NULL, NULL,
1943 options->image.max_enlargement_size, &c_options->image.max_enlargement_size);
1944 pref_checkbox_link_sensitivity(enlargement_button, spin);
1945 gtk_widget_set_tooltip_text(GTK_WIDGET(hbox), _("Enable this to allow Geeqie to increase the image size for images that are smaller than the current view area when the zoom is set to \"Fit image to window\". This value sets the maximum expansion permitted in percent i.e. 100% is full-size."));
1947 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1948 ct_button = pref_checkbox_new_int(hbox, _("Virtual window size (% of actual window):"),
1949 options->image.limit_autofit_size, &c_options->image.limit_autofit_size);
1950 spin = pref_spin_new_int(hbox, NULL, NULL,
1952 options->image.max_autofit_size, &c_options->image.max_autofit_size);
1953 pref_checkbox_link_sensitivity(ct_button, spin);
1954 gtk_widget_set_tooltip_text(GTK_WIDGET(hbox), _("This value will set the virtual size of the window when \"Fit image to window\" is set. Instead of using the actual size of the window, the specified percentage of the window will be used. It allows one to keep a border around the image (values lower than 100%) or to auto zoom the image (values greater than 100%). It affects fullscreen mode too."));
1956 group = pref_group_new(vbox, FALSE, _("Appearance"), GTK_ORIENTATION_VERTICAL);
1958 pref_checkbox_new_int(group, _("Use custom border color in window mode"),
1959 options->image.use_custom_border_color, &c_options->image.use_custom_border_color);
1961 pref_checkbox_new_int(group, _("Use custom border color in fullscreen mode"),
1962 options->image.use_custom_border_color_in_fullscreen, &c_options->image.use_custom_border_color_in_fullscreen);
1964 pref_color_button_new(group, _("Border color"), &options->image.border_color,
1965 G_CALLBACK(pref_color_button_set_cb), &c_options->image.border_color);
1967 c_options->image.border_color = options->image.border_color;
1969 pref_color_button_new(group, _("Alpha channel color 1"), &options->image.alpha_color_1,
1970 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_1);
1972 pref_color_button_new(group, _("Alpha channel color 2"), &options->image.alpha_color_2,
1973 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_2);
1975 c_options->image.alpha_color_1 = options->image.alpha_color_1;
1976 c_options->image.alpha_color_2 = options->image.alpha_color_2;
1978 group = pref_group_new(vbox, FALSE, _("Convenience"), GTK_ORIENTATION_VERTICAL);
1980 pref_checkbox_new_int(group, _("Auto rotate proofs using Exif information"),
1981 options->image.exif_proof_rotate_enable, &c_options->image.exif_proof_rotate_enable);
1985 static void config_tab_windows(GtkWidget *notebook)
1991 GtkWidget *ct_button;
1993 GtkWidget *image_overlay_template_view;
1994 GtkWidget *scrolled;
1995 GtkTextBuffer *buffer;
1997 vbox = scrolled_notebook_page(notebook, _("Windows"));
1999 group = pref_group_new(vbox, FALSE, _("State"), GTK_ORIENTATION_VERTICAL);
2001 ct_button = pref_checkbox_new_int(group, _("Remember window positions"),
2002 options->save_window_positions, &c_options->save_window_positions);
2004 button = pref_checkbox_new_int(group, _("Use saved window positions also for new windows"),
2005 options->use_saved_window_positions_for_new_windows, &c_options->use_saved_window_positions_for_new_windows);
2006 pref_checkbox_link_sensitivity(ct_button, button);
2008 pref_checkbox_new_int(group, _("Remember tool state (float/hidden)"),
2009 options->tools_restore_state, &c_options->tools_restore_state);
2011 pref_checkbox_new_int(group, _("Remember dialog window positions"),
2012 options->save_dialog_window_positions, &c_options->save_dialog_window_positions);
2014 pref_checkbox_new_int(group, _("Show window IDs"),
2015 options->show_window_ids, &c_options->show_window_ids);
2017 group = pref_group_new(vbox, FALSE, _("Size"), GTK_ORIENTATION_VERTICAL);
2019 pref_checkbox_new_int(group, _("Fit window to image when tools are hidden/floating"),
2020 options->image.fit_window_to_image, &c_options->image.fit_window_to_image);
2022 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2023 ct_button = pref_checkbox_new_int(hbox, _("Limit size when auto-sizing window (%):"),
2024 options->image.limit_window_size, &c_options->image.limit_window_size);
2025 spin = pref_spin_new_int(hbox, NULL, NULL,
2027 options->image.max_window_size, &c_options->image.max_window_size);
2028 pref_checkbox_link_sensitivity(ct_button, spin);
2030 group = pref_group_new(vbox, FALSE, _("Full screen"), GTK_ORIENTATION_VERTICAL);
2032 c_options->fullscreen.screen = options->fullscreen.screen;
2033 c_options->fullscreen.above = options->fullscreen.above;
2034 hbox = fullscreen_prefs_selection_new(_("Location:"), &c_options->fullscreen.screen, &c_options->fullscreen.above);
2035 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2036 gtk_widget_show(hbox);
2038 pref_checkbox_new_int(group, _("Smooth image flip"),
2039 options->fullscreen.clean_flip, &c_options->fullscreen.clean_flip);
2040 pref_checkbox_new_int(group, _("Disable screen saver"),
2041 options->fullscreen.disable_saver, &c_options->fullscreen.disable_saver);
2044 group = pref_group_new(vbox, FALSE, _("Overlay Screen Display"), GTK_ORIENTATION_VERTICAL);
2046 pref_label_new(group, _("Image overlay template"));
2048 scrolled = gtk_scrolled_window_new(NULL, NULL);
2049 gtk_widget_set_size_request(scrolled, 200, 150);
2050 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2051 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
2052 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2053 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 5);
2054 gtk_widget_show(scrolled);
2056 image_overlay_template_view = gtk_text_view_new();
2058 gtk_widget_set_tooltip_markup(image_overlay_template_view,
2059 _("<i>%name%</i> results in the filename of the picture.\n"
2060 "Also available: <i>%collection%</i>, <i>%number%</i>, <i>%total%</i>, <i>%date%</i>,\n"
2061 "<i>%size%</i> (filesize), <i>%width%</i>, <i>%height%</i>, <i>%res%</i> (resolution),\n"
2062 "<i>%rating%</i>, <i>%keywords%</i>, <i>%comment%</i> (XMP), <i>%imagecomment%</i> (JPEG)\n"
2063 "To access exif data use the exif name, e. g. <i>%formatted.Camera%</i> is the formatted camera name,\n"
2064 "<i>%Exif.Photo.DateTimeOriginal%</i> the date of the original shot.\n"
2065 "<i>%formatted.Camera:20</i> notation will truncate the displayed data to 20 characters and will add 3 dots at the end to denote the truncation.\n"
2066 "If two or more variables are connected with the |-sign, it prints available variables with a separator.\n"
2067 "<i>%formatted.ShutterSpeed%</i>|<i>%formatted.ISOSpeedRating%</i>|<i>%formatted.FocalLength%</i> could show \"1/20s - 400 - 80 mm\" or \"1/200 - 80 mm\",\n"
2068 "if there's no ISO information in the Exif data.\n"
2069 "If a line is empty, it is removed. This allows one to add lines that totally disappear when no data is available.\n"
2071 gtk_container_add(GTK_CONTAINER(scrolled), image_overlay_template_view);
2072 gtk_widget_show(image_overlay_template_view);
2074 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2076 #if GTK_CHECK_VERSION(3,4,0)
2077 button = pref_button_new(NULL, GTK_STOCK_SELECT_FONT, _("Font"), FALSE,
2078 G_CALLBACK(image_overlay_set_font_cb), notebook);
2080 button = gtk_font_button_new();
2081 gtk_font_button_set_title(GTK_FONT_BUTTON(button), "Image Overlay Font");
2082 gtk_font_button_set_font_name(GTK_FONT_BUTTON(button), options->image_overlay.font);
2083 g_signal_connect(G_OBJECT(button), "font-set",
2084 G_CALLBACK(image_overlay_set_font_cb),NULL);
2086 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2087 gtk_widget_show(button);
2089 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Text"), FALSE,
2090 G_CALLBACK(image_overlay_set_text_colour_cb), NULL);
2091 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2092 gtk_widget_show(button);
2094 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Background"), FALSE,
2095 G_CALLBACK(image_overlay_set_background_colour_cb), NULL);
2096 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2097 gtk_widget_show(button);
2098 image_overlay_set_text_colours();
2100 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2101 G_CALLBACK(image_overlay_default_template_cb), image_overlay_template_view);
2102 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2103 gtk_widget_show(button);
2105 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
2106 G_CALLBACK(image_overlay_help_cb), NULL);
2107 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2108 gtk_widget_show(button);
2110 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(image_overlay_template_view));
2111 if (options->image_overlay.template_string) gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
2112 g_signal_connect(G_OBJECT(buffer), "changed",
2113 G_CALLBACK(image_overlay_template_view_changed_cb), image_overlay_template_view);
2118 static GtkTreeModel *create_class_model(void)
2120 GtkListStore *model;
2124 /* create list store */
2125 model = gtk_list_store_new(1, G_TYPE_STRING);
2126 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
2128 gtk_list_store_append(model, &iter);
2129 gtk_list_store_set(model, &iter, 0, _(format_class_list[i]), -1);
2131 return GTK_TREE_MODEL (model);
2136 static void config_tab_files(GtkWidget *notebook)
2143 GtkWidget *ct_button;
2144 GtkWidget *scrolled;
2145 GtkWidget *filter_view;
2146 GtkCellRenderer *renderer;
2147 GtkTreeSelection *selection;
2148 GtkTreeViewColumn *column;
2150 vbox = scrolled_notebook_page(notebook, _("Files"));
2152 group = pref_box_new(vbox, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
2154 pref_checkbox_new_int(group, _("Show hidden files or folders"),
2155 options->file_filter.show_hidden_files, &c_options->file_filter.show_hidden_files);
2156 pref_checkbox_new_int(group, _("Show parent folder (..)"),
2157 options->file_filter.show_parent_directory, &c_options->file_filter.show_parent_directory);
2158 pref_checkbox_new_int(group, _("Case sensitive sort"),
2159 options->file_sort.case_sensitive, &c_options->file_sort.case_sensitive);
2160 pref_checkbox_new_int(group, _("Natural sort order"),
2161 options->file_sort.natural, &c_options->file_sort.natural);
2162 pref_checkbox_new_int(group, _("Disable file extension checks"),
2163 options->file_filter.disable_file_extension_checks, &c_options->file_filter.disable_file_extension_checks);
2165 ct_button = pref_checkbox_new_int(group, _("Disable File Filtering"),
2166 options->file_filter.disable, &c_options->file_filter.disable);
2169 group = pref_group_new(vbox, FALSE, _("Grouping sidecar extensions"), GTK_ORIENTATION_VERTICAL);
2171 sidecar_ext_entry = gtk_entry_new();
2172 gtk_entry_set_text(GTK_ENTRY(sidecar_ext_entry), options->sidecar.ext);
2173 gtk_box_pack_start(GTK_BOX(group), sidecar_ext_entry, FALSE, FALSE, 0);
2174 gtk_widget_show(sidecar_ext_entry);
2176 group = pref_group_new(vbox, TRUE, _("File types"), GTK_ORIENTATION_VERTICAL);
2178 frame = pref_group_parent(group);
2179 g_signal_connect(G_OBJECT(ct_button), "toggled",
2180 G_CALLBACK(filter_disable_cb), frame);
2181 gtk_widget_set_sensitive(frame, !options->file_filter.disable);
2183 scrolled = gtk_scrolled_window_new(NULL, NULL);
2184 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2185 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2186 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2187 gtk_widget_show(scrolled);
2189 filter_store = gtk_list_store_new(1, G_TYPE_POINTER);
2190 filter_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(filter_store));
2191 g_object_unref(filter_store);
2192 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
2193 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_SINGLE);
2195 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(filter_view), FALSE);
2197 column = gtk_tree_view_column_new();
2198 gtk_tree_view_column_set_title(column, _("Filter"));
2199 gtk_tree_view_column_set_resizable(column, TRUE);
2201 renderer = gtk_cell_renderer_toggle_new();
2202 g_signal_connect(G_OBJECT(renderer), "toggled",
2203 G_CALLBACK(filter_store_enable_cb), filter_store);
2204 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2205 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2206 GINT_TO_POINTER(FE_ENABLE), NULL);
2208 renderer = gtk_cell_renderer_text_new();
2209 g_signal_connect(G_OBJECT(renderer), "edited",
2210 G_CALLBACK(filter_store_ext_edit_cb), filter_store);
2211 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2212 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2213 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2214 GINT_TO_POINTER(FE_EXTENSION), NULL);
2215 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2217 column = gtk_tree_view_column_new();
2218 gtk_tree_view_column_set_title(column, _("Description"));
2219 gtk_tree_view_column_set_resizable(column, TRUE);
2220 gtk_tree_view_column_set_fixed_width(column, 200);
2221 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
2223 renderer = gtk_cell_renderer_text_new();
2224 g_signal_connect(G_OBJECT(renderer), "edited",
2225 G_CALLBACK(filter_store_desc_edit_cb), filter_store);
2226 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2227 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2228 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2229 GINT_TO_POINTER(FE_DESCRIPTION), NULL);
2230 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2232 column = gtk_tree_view_column_new();
2233 gtk_tree_view_column_set_title(column, _("Class"));
2234 gtk_tree_view_column_set_resizable(column, TRUE);
2235 renderer = gtk_cell_renderer_combo_new();
2236 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE,
2237 "model", create_class_model(),
2242 g_signal_connect(G_OBJECT(renderer), "edited",
2243 G_CALLBACK(filter_store_class_edit_cb), filter_store);
2244 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2245 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2246 GINT_TO_POINTER(FE_CLASS), NULL);
2247 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2249 column = gtk_tree_view_column_new();
2250 gtk_tree_view_column_set_title(column, _("Writable"));
2251 gtk_tree_view_column_set_resizable(column, FALSE);
2252 renderer = gtk_cell_renderer_toggle_new();
2253 g_signal_connect(G_OBJECT(renderer), "toggled",
2254 G_CALLBACK(filter_store_writable_cb), filter_store);
2255 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2256 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2257 GINT_TO_POINTER(FE_WRITABLE), NULL);
2258 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2260 column = gtk_tree_view_column_new();
2261 gtk_tree_view_column_set_title(column, _("Sidecar is allowed"));
2262 gtk_tree_view_column_set_resizable(column, FALSE);
2263 renderer = gtk_cell_renderer_toggle_new();
2264 g_signal_connect(G_OBJECT(renderer), "toggled",
2265 G_CALLBACK(filter_store_sidecar_cb), filter_store);
2266 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2267 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2268 GINT_TO_POINTER(FE_ALLOW_SIDECAR), NULL);
2269 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2272 filter_store_populate();
2273 gtk_container_add(GTK_CONTAINER(scrolled), filter_view);
2274 gtk_widget_show(filter_view);
2276 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2278 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2279 G_CALLBACK(filter_default_cb), filter_view);
2280 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2281 gtk_widget_show(button);
2283 button = pref_button_new(NULL, GTK_STOCK_REMOVE, NULL, FALSE,
2284 G_CALLBACK(filter_remove_cb), filter_view);
2285 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2286 gtk_widget_show(button);
2288 button = pref_button_new(NULL, GTK_STOCK_ADD, NULL, FALSE,
2289 G_CALLBACK(filter_add_cb), filter_view);
2290 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2291 gtk_widget_show(button);
2295 static void config_tab_metadata(GtkWidget *notebook)
2300 GtkWidget *ct_button;
2304 vbox = scrolled_notebook_page(notebook, _("Metadata"));
2307 group = pref_group_new(vbox, FALSE, _("Metadata writing process"), GTK_ORIENTATION_VERTICAL);
2309 label = pref_label_new(group, _("Warning: Geeqie is built without Exiv2. Some options are disabled."));
2311 label = pref_label_new(group, _("Metadata are written in the following order. The process ends after first success."));
2312 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2314 ct_button = pref_checkbox_new_int(group, _("1) Save metadata in image files, or sidecar files, according to the XMP standard"),
2315 options->metadata.save_in_image_file, &c_options->metadata.save_in_image_file);
2317 gtk_widget_set_sensitive(ct_button, FALSE);
2320 pref_checkbox_new_int(group, _("2) Save metadata in '.metadata' folder, local to image folder (non-standard)"),
2321 options->metadata.enable_metadata_dirs, &c_options->metadata.enable_metadata_dirs);
2323 text = g_strdup_printf(_("3) Save metadata in Geeqie private directory '%s'"), get_metadata_cache_dir());
2324 label = pref_label_new(group, text);
2325 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2326 gtk_misc_set_padding(GTK_MISC(label), 22, 0);
2329 group = pref_group_new(vbox, FALSE, _("Step 1: Write to image files"), GTK_ORIENTATION_VERTICAL);
2331 gtk_widget_set_sensitive(group, FALSE);
2334 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2335 pref_checkbox_link_sensitivity(ct_button, hbox);
2337 pref_checkbox_new_int(hbox, _("Store metadata also in legacy IPTC tags (converted according to IPTC4XMP standard)"),
2338 options->metadata.save_legacy_IPTC, &c_options->metadata.save_legacy_IPTC);
2340 pref_checkbox_new_int(hbox, _("Warn if the image files are unwritable"),
2341 options->metadata.warn_on_write_problems, &c_options->metadata.warn_on_write_problems);
2343 pref_checkbox_new_int(hbox, _("Ask before writing to image files"),
2344 options->metadata.confirm_write, &c_options->metadata.confirm_write);
2346 pref_checkbox_new_int(hbox, _("Create sidecar files named image.ext.xmp (as opposed to image.xmp)"),
2347 options->metadata.sidecar_extended_name, &c_options->metadata.sidecar_extended_name);
2349 group = pref_group_new(vbox, FALSE, _("Step 2 and 3: write to Geeqie private files"), GTK_ORIENTATION_VERTICAL);
2351 gtk_widget_set_sensitive(group, FALSE);
2354 pref_checkbox_new_int(group, _("Use GQview legacy metadata format (supports only keywords and comments) instead of XMP"),
2355 options->metadata.save_legacy_format, &c_options->metadata.save_legacy_format);
2358 group = pref_group_new(vbox, FALSE, _("Miscellaneous"), GTK_ORIENTATION_VERTICAL);
2359 pref_checkbox_new_int(group, _("Write the same description tags (keywords, comment, etc.) to all grouped sidecars"),
2360 options->metadata.sync_grouped_files, &c_options->metadata.sync_grouped_files);
2362 pref_checkbox_new_int(group, _("Allow keywords to differ only in case"),
2363 options->metadata.keywords_case_sensitive, &c_options->metadata.keywords_case_sensitive);
2365 ct_button = pref_checkbox_new_int(group, _("Write altered image orientation to the metadata"),
2366 options->metadata.write_orientation, &c_options->metadata.write_orientation);
2368 gtk_widget_set_sensitive(ct_button, FALSE);
2371 group = pref_group_new(vbox, FALSE, _("Auto-save options"), GTK_ORIENTATION_VERTICAL);
2373 ct_button = pref_checkbox_new_int(group, _("Write metadata after timeout"),
2374 options->metadata.confirm_after_timeout, &c_options->metadata.confirm_after_timeout);
2376 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2377 pref_checkbox_link_sensitivity(ct_button, hbox);
2379 pref_spin_new_int(hbox, _("Timeout (seconds):"), NULL, 0, 900, 1,
2380 options->metadata.confirm_timeout, &c_options->metadata.confirm_timeout);
2382 pref_checkbox_new_int(group, _("Write metadata on image change"),
2383 options->metadata.confirm_on_image_change, &c_options->metadata.confirm_on_image_change);
2385 pref_checkbox_new_int(group, _("Write metadata on directory change"),
2386 options->metadata.confirm_on_dir_change, &c_options->metadata.confirm_on_dir_change);
2388 group = pref_group_new(vbox, FALSE, _("Pre-load metadata"), GTK_ORIENTATION_VERTICAL);
2390 ct_button = pref_checkbox_new_int(group, _("Read metadata in background"),
2391 options->read_metadata_in_idle, &c_options->read_metadata_in_idle);
2392 gtk_widget_set_tooltip_text(ct_button,"On folder change, read DateTimeOriginal, DateTimeDigitized and Star Rating in the idle loop.\nIf this is not selected, initial loading of the folder will be faster but sorting on these items will be slower");
2397 static void intent_menu_cb(GtkWidget *combo, gpointer data)
2399 gint *option = data;
2401 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
2405 *option = INTENT_PERCEPTUAL;
2408 *option = INTENT_RELATIVE_COLORIMETRIC;
2411 *option = INTENT_SATURATION;
2414 *option = INTENT_ABSOLUTE_COLORIMETRIC;
2419 static void add_intent_menu(GtkWidget *table, gint column, gint row, const gchar *text,
2420 gint option, gint *option_c)
2427 pref_table_label(table, column, row, text, 0.0);
2429 combo = gtk_combo_box_text_new();
2431 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Perceptual"));
2432 if (option == INTENT_PERCEPTUAL) current = 0;
2433 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Relative Colorimetric"));
2434 if (option == INTENT_RELATIVE_COLORIMETRIC) current = 1;
2435 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Saturation"));
2436 if (option == INTENT_SATURATION) current = 2;
2437 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Absolute Colorimetric"));
2438 if (option == INTENT_ABSOLUTE_COLORIMETRIC) current = 3;
2440 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
2442 gtk_widget_set_tooltip_text(combo,"Refer to the lcms documentation for the defaults used when the selected Intent is not available");
2444 g_signal_connect(G_OBJECT(combo), "changed",
2445 G_CALLBACK(intent_menu_cb), option_c);
2447 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
2448 GTK_EXPAND | GTK_FILL, 0, 0, 0);
2449 gtk_widget_show(combo);
2453 static void config_tab_color(GtkWidget *notebook)
2462 vbox = scrolled_notebook_page(notebook, _("Color management"));
2464 group = pref_group_new(vbox, FALSE, _("Input profiles"), GTK_ORIENTATION_VERTICAL);
2466 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
2469 table = pref_table_new(group, 3, COLOR_PROFILE_INPUTS + 1, FALSE, FALSE);
2470 gtk_table_set_col_spacings(GTK_TABLE(table), PREF_PAD_GAP);
2472 label = pref_table_label(table, 0, 0, _("Type"), 0.0);
2473 pref_label_bold(label, TRUE, FALSE);
2475 label = pref_table_label(table, 1, 0, _("Menu name"), 0.0);
2476 pref_label_bold(label, TRUE, FALSE);
2478 label = pref_table_label(table, 2, 0, _("File"), 0.0);
2479 pref_label_bold(label, TRUE, FALSE);
2481 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
2486 buf = g_strdup_printf(_("Input %d:"), i + COLOR_PROFILE_FILE);
2487 pref_table_label(table, 0, i + 1, buf, 1.0);
2490 entry = gtk_entry_new();
2491 gtk_entry_set_max_length(GTK_ENTRY(entry), EDITOR_NAME_MAX_LENGTH);
2492 if (options->color_profile.input_name[i])
2494 gtk_entry_set_text(GTK_ENTRY(entry), options->color_profile.input_name[i]);
2496 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, i + 1, i + 2,
2497 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2498 gtk_widget_show(entry);
2499 color_profile_input_name_entry[i] = entry;
2501 tabcomp = tab_completion_new(&entry, options->color_profile.input_file[i], NULL, ".icc", "ICC Files", NULL);
2502 tab_completion_add_select_button(entry, _("Select color profile"), FALSE);
2503 gtk_widget_set_size_request(entry, 160, -1);
2504 gtk_table_attach(GTK_TABLE(table), tabcomp, 2, 3, i + 1, i + 2,
2505 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2506 gtk_widget_show(tabcomp);
2507 color_profile_input_file_entry[i] = entry;
2510 group = pref_group_new(vbox, FALSE, _("Screen profile"), GTK_ORIENTATION_VERTICAL);
2512 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
2514 pref_checkbox_new_int(group, _("Use system screen profile if available"),
2515 options->color_profile.use_x11_screen_profile, &c_options->color_profile.use_x11_screen_profile);
2517 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2519 pref_table_label(table, 0, 0, _("Screen:"), 1.0);
2520 tabcomp = tab_completion_new(&color_profile_screen_file_entry,
2521 options->color_profile.screen_file, NULL, ".icc", "ICC Files", NULL);
2522 tab_completion_add_select_button(color_profile_screen_file_entry, _("Select color profile"), FALSE);
2523 gtk_widget_set_size_request(color_profile_screen_file_entry, 160, -1);
2525 add_intent_menu(table, 0, 1, _("Render Intent:"), options->color_profile.render_intent, &c_options->color_profile.render_intent);
2527 gtk_table_attach(GTK_TABLE(table), tabcomp, 1, 2,
2529 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2531 gtk_widget_show(tabcomp);
2534 /* advanced entry tab */
2535 static void config_tab_behavior(GtkWidget *notebook)
2542 GtkWidget *ct_button;
2546 GtkWidget *with_rename;
2548 vbox = scrolled_notebook_page(notebook, _("Behavior"));
2550 group = pref_group_new(vbox, FALSE, _("Delete"), GTK_ORIENTATION_VERTICAL);
2552 pref_checkbox_new_int(group, _("Confirm file delete"),
2553 options->file_ops.confirm_delete, &c_options->file_ops.confirm_delete);
2554 pref_checkbox_new_int(group, _("Enable Delete key"),
2555 options->file_ops.enable_delete_key, &c_options->file_ops.enable_delete_key);
2557 ct_button = pref_checkbox_new_int(group, _("Safe delete"),
2558 options->file_ops.safe_delete_enable, &c_options->file_ops.safe_delete_enable);
2560 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2561 pref_checkbox_link_sensitivity(ct_button, hbox);
2563 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_SPACE);
2564 pref_label_new(hbox, _("Folder:"));
2566 tabcomp = tab_completion_new(&safe_delete_path_entry, options->file_ops.safe_delete_path, NULL, NULL, NULL, NULL);
2567 tab_completion_add_select_button(safe_delete_path_entry, NULL, TRUE);
2568 gtk_box_pack_start(GTK_BOX(hbox), tabcomp, TRUE, TRUE, 0);
2569 gtk_widget_show(tabcomp);
2571 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2572 pref_checkbox_link_sensitivity(ct_button, hbox);
2574 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_GAP);
2575 spin = pref_spin_new_int(hbox, _("Maximum size:"), _("MB"),
2576 0, 2048, 1, options->file_ops.safe_delete_folder_maxsize, &c_options->file_ops.safe_delete_folder_maxsize);
2577 gtk_widget_set_tooltip_markup(spin, _("Set to 0 for unlimited size"));
2578 button = pref_button_new(NULL, NULL, _("View"), FALSE,
2579 G_CALLBACK(safe_delete_view_cb), NULL);
2580 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2581 gtk_widget_show(button);
2583 button = pref_button_new(NULL, GTK_STOCK_CLEAR, NULL, FALSE,
2584 G_CALLBACK(safe_delete_clear_cb), NULL);
2585 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2586 gtk_widget_show(button);
2589 group = pref_group_new(vbox, FALSE, _("Behavior"), GTK_ORIENTATION_VERTICAL);
2591 pref_checkbox_new_int(group, _("Descend folders in tree view"),
2592 options->tree_descend_subdirs, &c_options->tree_descend_subdirs);
2594 pref_checkbox_new_int(group, _("In place renaming"),
2595 options->file_ops.enable_in_place_rename, &c_options->file_ops.enable_in_place_rename);
2597 pref_checkbox_new_int(group, _("List directory view uses single click to enter"),
2598 options->view_dir_list_single_click_enter, &c_options->view_dir_list_single_click_enter);
2600 marks = pref_checkbox_new_int(group, _("Save marks on exit"),
2601 options->marks_save, &c_options->marks_save);
2602 gtk_widget_set_tooltip_text(marks,"Note that marks linked to a keyword will be saved irrespective of this setting");
2604 with_rename = pref_checkbox_new_int(group, _("Use \"With Rename\" as default for Copy/Move dialogs"),
2605 options->with_rename, &c_options->with_rename);
2606 gtk_widget_set_tooltip_text(with_rename,"Change the default button for Copy/Move dialogs");
2608 pref_spin_new_int(group, _("Recent folder list maximum size"), NULL,
2609 1, 50, 1, options->open_recent_list_maxsize, &c_options->open_recent_list_maxsize);
2611 pref_spin_new_int(group, _("Drag'n drop icon size"), NULL,
2612 16, 256, 16, options->dnd_icon_size, &c_options->dnd_icon_size);
2614 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2615 add_clipboard_selection_menu(table, 0, 0, _("Copy path clipboard selection:"), options->clipboard_selection, &c_options->clipboard_selection);
2617 group = pref_group_new(vbox, FALSE, _("Navigation"), GTK_ORIENTATION_VERTICAL);
2619 pref_checkbox_new_int(group, _("Progressive keyboard scrolling"),
2620 options->progressive_key_scrolling, &c_options->progressive_key_scrolling);
2621 pref_spin_new_int(group, _("Keyboard scrolling step multiplier:"), NULL,
2622 1, 32, 1, options->keyboard_scroll_step, (int *)&c_options->keyboard_scroll_step);
2623 pref_checkbox_new_int(group, _("Mouse wheel scrolls image"),
2624 options->mousewheel_scrolls, &c_options->mousewheel_scrolls);
2625 pref_checkbox_new_int(group, _("Navigation by left or middle click on image"),
2626 options->image_lm_click_nav, &c_options->image_lm_click_nav);
2627 pref_checkbox_new_int(group, _("Play video by left click on image"),
2628 options->image_l_click_video, &c_options->image_l_click_video);
2629 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2630 add_video_menu(table, 0, 0, _("Play with:"), options->image_l_click_video_editor, &c_options->image_l_click_video_editor);
2634 group = pref_group_new(vbox, FALSE, _("Debugging"), GTK_ORIENTATION_VERTICAL);
2636 pref_spin_new_int(group, _("Debug level:"), NULL,
2637 DEBUG_LEVEL_MIN, DEBUG_LEVEL_MAX, 1, get_debug_level(), &debug_c);
2639 pref_checkbox_new_int(group, _("Timer data"),
2640 options->log_window.timer_data, &c_options->log_window.timer_data);
2642 pref_spin_new_int(group, _("Log Window max. lines:"), NULL,
2643 1, 99999, 1, options->log_window_lines, &options->log_window_lines);
2647 /* accelerators tab */
2648 static void config_tab_accelerators(GtkWidget *notebook)
2654 GtkWidget *scrolled;
2655 GtkWidget *accel_view;
2656 GtkCellRenderer *renderer;
2657 GtkTreeSelection *selection;
2658 GtkTreeViewColumn *column;
2660 vbox = scrolled_notebook_page(notebook, _("Keyboard"));
2662 group = pref_group_new(vbox, TRUE, _("Accelerators"), GTK_ORIENTATION_VERTICAL);
2664 scrolled = gtk_scrolled_window_new(NULL, NULL);
2665 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2666 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2667 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2668 gtk_widget_show(scrolled);
2670 accel_store = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
2672 accel_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(accel_store));
2673 g_object_unref(accel_store);
2674 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(accel_view));
2675 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_MULTIPLE);
2677 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(accel_view), FALSE);
2679 renderer = gtk_cell_renderer_text_new();
2681 column = gtk_tree_view_column_new_with_attributes(_("Action"),
2686 gtk_tree_view_column_set_sort_column_id(column, AE_ACTION);
2687 gtk_tree_view_column_set_resizable(column, TRUE);
2688 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2691 renderer = gtk_cell_renderer_accel_new();
2692 g_signal_connect(G_OBJECT(renderer), "accel-cleared",
2693 G_CALLBACK(accel_store_cleared_cb), accel_store);
2694 g_signal_connect(G_OBJECT(renderer), "accel-edited",
2695 G_CALLBACK(accel_store_edited_cb), accel_store);
2698 g_object_set (renderer,
2700 "accel-mode", GTK_CELL_RENDERER_ACCEL_MODE_OTHER,
2703 column = gtk_tree_view_column_new_with_attributes(_("KEY"),
2708 gtk_tree_view_column_set_sort_column_id(column, AE_KEY);
2709 gtk_tree_view_column_set_resizable(column, TRUE);
2710 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2712 renderer = gtk_cell_renderer_text_new();
2714 column = gtk_tree_view_column_new_with_attributes(_("Tooltip"),
2719 gtk_tree_view_column_set_sort_column_id(column, AE_TOOLTIP);
2720 gtk_tree_view_column_set_resizable(column, TRUE);
2721 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2723 renderer = gtk_cell_renderer_text_new();
2725 column = gtk_tree_view_column_new_with_attributes("Accel",
2730 gtk_tree_view_column_set_sort_column_id(column, AE_ACCEL);
2731 gtk_tree_view_column_set_resizable(column, TRUE);
2732 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2734 accel_store_populate();
2735 gtk_container_add(GTK_CONTAINER(scrolled), accel_view);
2736 gtk_widget_show(accel_view);
2738 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2740 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2741 G_CALLBACK(accel_default_cb), accel_view);
2742 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2743 gtk_widget_show(button);
2745 button = pref_button_new(NULL, NULL, _("Reset selected"), FALSE,
2746 G_CALLBACK(accel_reset_cb), accel_view);
2747 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2748 gtk_widget_show(button);
2752 static void config_tab_toolbar(GtkWidget *notebook)
2755 GtkWidget *toolbardata;
2758 lw = layout_window_list->data;
2760 vbox = scrolled_notebook_page(notebook, _("Toolbar"));
2762 toolbardata = toolbar_select_new(lw);
2763 gtk_box_pack_start(GTK_BOX(vbox), toolbardata, TRUE, TRUE, 0);
2764 gtk_widget_show(vbox);
2768 static void config_tab_stereo(GtkWidget *notebook)
2776 GtkWidget *fs_button;
2777 vbox = scrolled_notebook_page(notebook, _("Stereo"));
2779 group = pref_group_new(vbox, FALSE, _("Windowed stereo mode"), GTK_ORIENTATION_VERTICAL);
2781 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2782 add_stereo_mode_menu(table, 0, 0, _("Windowed stereo mode"), options->stereo.mode, &c_options->stereo.mode, FALSE);
2784 table = pref_table_new(group, 2, 2, TRUE, FALSE);
2785 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2786 pref_checkbox_new_int(box, _("Mirror left image"),
2787 options->stereo.mode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.mirror_left);
2788 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2789 pref_checkbox_new_int(box, _("Flip left image"),
2790 options->stereo.mode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.flip_left);
2791 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2792 pref_checkbox_new_int(box, _("Mirror right image"),
2793 options->stereo.mode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.mirror_right);
2794 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2795 pref_checkbox_new_int(box, _("Flip right image"),
2796 options->stereo.mode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.flip_right);
2797 pref_checkbox_new_int(group, _("Swap left and right images"),
2798 options->stereo.mode & PR_STEREO_SWAP, &c_options->stereo.tmp.swap);
2799 pref_checkbox_new_int(group, _("Disable stereo mode on single image source"),
2800 options->stereo.mode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.temp_disable);
2802 group = pref_group_new(vbox, FALSE, _("Fullscreen stereo mode"), GTK_ORIENTATION_VERTICAL);
2803 fs_button = pref_checkbox_new_int(group, _("Use different settings for fullscreen"),
2804 options->stereo.enable_fsmode, &c_options->stereo.enable_fsmode);
2805 box2 = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2806 pref_checkbox_link_sensitivity(fs_button, box2);
2807 table = pref_table_new(box2, 2, 1, FALSE, FALSE);
2808 add_stereo_mode_menu(table, 0, 0, _("Fullscreen stereo mode"), options->stereo.fsmode, &c_options->stereo.fsmode, TRUE);
2809 table = pref_table_new(box2, 2, 2, TRUE, FALSE);
2810 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2811 pref_checkbox_new_int(box, _("Mirror left image"),
2812 options->stereo.fsmode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.fs_mirror_left);
2813 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2814 pref_checkbox_new_int(box, _("Flip left image"),
2815 options->stereo.fsmode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.fs_flip_left);
2816 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2817 pref_checkbox_new_int(box, _("Mirror right image"),
2818 options->stereo.fsmode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.fs_mirror_right);
2819 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2820 pref_checkbox_new_int(box, _("Flip right image"),
2821 options->stereo.fsmode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.fs_flip_right);
2822 pref_checkbox_new_int(box2, _("Swap left and right images"),
2823 options->stereo.fsmode & PR_STEREO_SWAP, &c_options->stereo.tmp.fs_swap);
2824 pref_checkbox_new_int(box2, _("Disable stereo mode on single image source"),
2825 options->stereo.fsmode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.fs_temp_disable);
2827 group2 = pref_group_new(box2, FALSE, _("Fixed position"), GTK_ORIENTATION_VERTICAL);
2828 table = pref_table_new(group2, 5, 3, FALSE, FALSE);
2829 pref_table_spin_new_int(table, 0, 0, _("Width"), NULL,
2830 1, 5000, 1, options->stereo.fixed_w, &c_options->stereo.fixed_w);
2831 pref_table_spin_new_int(table, 3, 0, _("Height"), NULL,
2832 1, 5000, 1, options->stereo.fixed_h, &c_options->stereo.fixed_h);
2833 pref_table_spin_new_int(table, 0, 1, _("Left X"), NULL,
2834 0, 5000, 1, options->stereo.fixed_x1, &c_options->stereo.fixed_x1);
2835 pref_table_spin_new_int(table, 3, 1, _("Left Y"), NULL,
2836 0, 5000, 1, options->stereo.fixed_y1, &c_options->stereo.fixed_y1);
2837 pref_table_spin_new_int(table, 0, 2, _("Right X"), NULL,
2838 0, 5000, 1, options->stereo.fixed_x2, &c_options->stereo.fixed_x2);
2839 pref_table_spin_new_int(table, 3, 2, _("Right Y"), NULL,
2840 0, 5000, 1, options->stereo.fixed_y2, &c_options->stereo.fixed_y2);
2844 /* Main preferences window */
2845 static void config_window_create(void)
2847 GtkWidget *win_vbox;
2849 GtkWidget *notebook;
2851 GtkWidget *ct_button;
2853 if (!c_options) c_options = init_options(NULL);
2855 configwindow = window_new(GTK_WINDOW_TOPLEVEL, "preferences", PIXBUF_INLINE_ICON_CONFIG, NULL, _("Preferences"));
2856 gtk_window_set_type_hint(GTK_WINDOW(configwindow), GDK_WINDOW_TYPE_HINT_DIALOG);
2857 g_signal_connect(G_OBJECT(configwindow), "delete_event",
2858 G_CALLBACK(config_window_delete), NULL);
2859 gtk_window_set_default_size(GTK_WINDOW(configwindow), CONFIG_WINDOW_DEF_WIDTH, CONFIG_WINDOW_DEF_HEIGHT);
2860 gtk_window_set_resizable(GTK_WINDOW(configwindow), TRUE);
2861 gtk_container_set_border_width(GTK_CONTAINER(configwindow), PREF_PAD_BORDER);
2863 win_vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE);
2864 gtk_container_add(GTK_CONTAINER(configwindow), win_vbox);
2865 gtk_widget_show(win_vbox);
2867 notebook = gtk_notebook_new();
2868 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
2869 gtk_box_pack_start(GTK_BOX(win_vbox), notebook, TRUE, TRUE, 0);
2871 config_tab_general(notebook);
2872 config_tab_image(notebook);
2873 config_tab_windows(notebook);
2874 config_tab_accelerators(notebook);
2875 config_tab_files(notebook);
2876 config_tab_metadata(notebook);
2877 config_tab_color(notebook);
2878 config_tab_stereo(notebook);
2879 config_tab_behavior(notebook);
2880 config_tab_toolbar(notebook);
2882 hbox = gtk_hbutton_box_new();
2883 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
2884 gtk_box_set_spacing(GTK_BOX(hbox), PREF_PAD_BUTTON_GAP);
2885 gtk_box_pack_end(GTK_BOX(win_vbox), hbox, FALSE, FALSE, 0);
2886 gtk_widget_show(hbox);
2888 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
2889 G_CALLBACK(config_window_help_cb), notebook);
2890 gtk_container_add(GTK_CONTAINER(hbox), button);
2891 gtk_widget_set_can_default(button, TRUE);
2892 gtk_widget_show(button);
2894 button = pref_button_new(NULL, GTK_STOCK_OK, NULL, FALSE,
2895 G_CALLBACK(config_window_ok_cb), NULL);
2896 gtk_container_add(GTK_CONTAINER(hbox), button);
2897 gtk_widget_set_can_default(button, TRUE);
2898 gtk_widget_grab_default(button);
2899 gtk_widget_show(button);
2903 button = pref_button_new(NULL, GTK_STOCK_SAVE, NULL, FALSE,
2904 G_CALLBACK(config_window_save_cb), NULL);
2905 gtk_container_add(GTK_CONTAINER(hbox), button);
2906 gtk_widget_set_can_default(button, TRUE);
2907 gtk_widget_show(button);
2909 button = pref_button_new(NULL, GTK_STOCK_APPLY, NULL, FALSE,
2910 G_CALLBACK(config_window_apply_cb), NULL);
2911 gtk_container_add(GTK_CONTAINER(hbox), button);
2912 gtk_widget_set_can_default(button, TRUE);
2913 gtk_widget_show(button);
2915 button = pref_button_new(NULL, GTK_STOCK_CANCEL, NULL, FALSE,
2916 G_CALLBACK(config_window_close_cb), NULL);
2917 gtk_container_add(GTK_CONTAINER(hbox), button);
2918 gtk_widget_set_can_default(button, TRUE);
2919 gtk_widget_show(button);
2921 if (!generic_dialog_get_alternative_button_order(configwindow))
2923 gtk_box_reorder_child(GTK_BOX(hbox), ct_button, -1);
2926 gtk_widget_show(notebook);
2928 gtk_widget_show(configwindow);
2932 *-----------------------------------------------------------------------------
2933 * config window show (public)
2934 *-----------------------------------------------------------------------------
2937 void show_config_window(void)
2941 gtk_window_present(GTK_WINDOW(configwindow));
2945 config_window_create();
2954 void show_about_window(LayoutWindow *lw)
2956 GdkPixbuf *pixbuf_logo;
2957 GdkPixbuf *pixbuf_icon;
2958 gchar *authors[1000];
2966 #define LINE_LENGTH 1000
2967 gchar line[LINE_LENGTH];
2969 copyright = g_string_new(NULL);
2970 copyright = g_string_append(copyright, "This program comes with absolutely no warranty.\nGNU General Public License, version 2 or later.\nSee https://www.gnu.org/licenses/old-licenses/gpl-2.0.html\n\n");
2972 zd_path = g_build_filename(GQ_BIN_DIR, TIMEZONE_DATABASE, NULL);
2973 cd = ZDOpenDatabase(zd_path);
2976 copyright = g_string_append(copyright, ZDGetNotice(cd));
2978 ZDCloseDatabase(cd);
2982 path = g_build_filename(GQ_HELPDIR, "AUTHORS", NULL);
2983 fp = fopen(path, "r");
2986 while(fgets(line, LINE_LENGTH, fp))
2988 /* get rid of ending \n from fgets */
2989 line[strlen(line) - 1] = '\0';
2990 authors[i_authors] = g_strdup(line);
2993 authors[i_authors] = NULL;
2998 comment = g_strconcat("Development and bug reports:\n", GQ_EMAIL_ADDRESS,
2999 "\nhttps://github.com/BestImageViewer/geeqie/issues",NULL);
3001 pixbuf_logo = pixbuf_inline(PIXBUF_INLINE_LOGO);
3002 pixbuf_icon = pixbuf_inline(PIXBUF_INLINE_ICON);
3003 gtk_show_about_dialog(GTK_WINDOW(lw->window),
3004 "title", _("About Geeqie"),
3006 "program-name", GQ_APPNAME,
3008 "logo", pixbuf_logo,
3009 "icon", pixbuf_icon,
3010 "website", GQ_WEBSITE,
3011 "website-label", "Website",
3012 "comments", comment,
3014 "translator-credits", _("translator-credits"),
3015 "wrap-license", TRUE,
3016 "license", copyright->str,
3019 g_string_free(copyright, TRUE);
3022 while(n < i_authors)
3032 static void image_overlay_set_text_colours()
3034 c_options->image_overlay.text_red = options->image_overlay.text_red;
3035 c_options->image_overlay.text_green = options->image_overlay.text_green;
3036 c_options->image_overlay.text_blue = options->image_overlay.text_blue;
3037 c_options->image_overlay.text_alpha = options->image_overlay.text_alpha;
3038 c_options->image_overlay.background_red = options->image_overlay.background_red;
3039 c_options->image_overlay.background_green = options->image_overlay.background_green;
3040 c_options->image_overlay.background_blue = options->image_overlay.background_blue;
3041 c_options->image_overlay.background_alpha = options->image_overlay.background_alpha;
3043 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */