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[] = {
117 /* config memory values */
118 static ConfOptions *c_options = NULL;
125 static GtkWidget *configwindow = NULL;
126 static GtkListStore *filter_store = NULL;
127 static GtkTreeStore *accel_store = NULL;
129 static GtkWidget *safe_delete_path_entry;
131 static GtkWidget *color_profile_input_file_entry[COLOR_PROFILE_INPUTS];
132 static GtkWidget *color_profile_input_name_entry[COLOR_PROFILE_INPUTS];
133 static GtkWidget *color_profile_screen_file_entry;
135 static GtkWidget *sidecar_ext_entry;
136 static GtkWidget *help_search_engine_entry;
139 #define CONFIG_WINDOW_DEF_WIDTH 700
140 #define CONFIG_WINDOW_DEF_HEIGHT 600
143 *-----------------------------------------------------------------------------
144 * option widget callbacks (private)
145 *-----------------------------------------------------------------------------
148 static void zoom_increment_cb(GtkWidget *spin, gpointer data)
150 c_options->image.zoom_increment = (gint)(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) * 100.0 + 0.01);
153 static void slideshow_delay_hours_cb(GtkWidget *spin, gpointer data)
155 gint mins_secs_tenths, delay;
157 mins_secs_tenths = c_options->slideshow.delay %
158 (3600 * SLIDESHOW_SUBSECOND_PRECISION);
160 delay = (gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
161 (3600 * SLIDESHOW_SUBSECOND_PRECISION) +
164 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
165 SLIDESHOW_SUBSECOND_PRECISION;
168 static void slideshow_delay_minutes_cb(GtkWidget *spin, gpointer data)
170 gint hours, secs_tenths, delay;
172 hours = c_options->slideshow.delay / (3600 * SLIDESHOW_SUBSECOND_PRECISION);
173 secs_tenths = c_options->slideshow.delay % (60 * SLIDESHOW_SUBSECOND_PRECISION);
175 delay = hours * (3600 * SLIDESHOW_SUBSECOND_PRECISION) +
176 (gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
177 (60 * SLIDESHOW_SUBSECOND_PRECISION) + secs_tenths);
179 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
180 SLIDESHOW_SUBSECOND_PRECISION;
183 static void slideshow_delay_seconds_cb(GtkWidget *spin, gpointer data)
185 gint hours_mins, delay;
187 hours_mins = c_options->slideshow.delay / (60 * SLIDESHOW_SUBSECOND_PRECISION);
189 delay = (hours_mins * (60 * SLIDESHOW_SUBSECOND_PRECISION)) +
190 (gint)(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
191 (gdouble)(SLIDESHOW_SUBSECOND_PRECISION) + 0.01);
193 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
194 SLIDESHOW_SUBSECOND_PRECISION;
198 *-----------------------------------------------------------------------------
199 * sync progam to config window routine (private)
200 *-----------------------------------------------------------------------------
203 void config_entry_to_option(GtkWidget *entry, gchar **option, gchar *(*func)(const gchar *))
209 buf = gtk_entry_get_text(GTK_ENTRY(entry));
210 if (buf && strlen(buf) > 0)
215 *option = g_strdup(buf);
220 static gboolean accel_apply_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
222 gchar *accel_path, *accel;
224 gtk_tree_model_get(model, iter, AE_ACCEL, &accel_path, AE_KEY, &accel, -1);
226 if (accel_path && accel_path[0])
229 gtk_accelerator_parse(accel, &key.accel_key, &key.accel_mods);
230 gtk_accel_map_change_entry(accel_path, key.accel_key, key.accel_mods, TRUE);
240 static void config_window_apply(void)
243 gboolean refresh = FALSE;
245 config_entry_to_option(safe_delete_path_entry, &options->file_ops.safe_delete_path, remove_trailing_slash);
247 if (options->file_filter.show_hidden_files != c_options->file_filter.show_hidden_files) refresh = TRUE;
248 if (options->file_filter.show_parent_directory != c_options->file_filter.show_parent_directory) refresh = TRUE;
249 if (options->file_filter.show_dot_directory != c_options->file_filter.show_dot_directory) refresh = TRUE;
250 if (options->file_sort.case_sensitive != c_options->file_sort.case_sensitive) refresh = TRUE;
251 if (options->file_sort.natural != c_options->file_sort.natural) refresh = TRUE;
252 if (options->file_filter.disable_file_extension_checks != c_options->file_filter.disable_file_extension_checks) refresh = TRUE;
253 if (options->file_filter.disable != c_options->file_filter.disable) refresh = TRUE;
255 options->file_ops.confirm_delete = c_options->file_ops.confirm_delete;
256 options->file_ops.enable_delete_key = c_options->file_ops.enable_delete_key;
257 options->file_ops.safe_delete_enable = c_options->file_ops.safe_delete_enable;
258 options->file_ops.safe_delete_folder_maxsize = c_options->file_ops.safe_delete_folder_maxsize;
259 options->tools_restore_state = c_options->tools_restore_state;
260 options->save_window_positions = c_options->save_window_positions;
261 options->use_saved_window_positions_for_new_windows = c_options->use_saved_window_positions_for_new_windows;
262 options->save_dialog_window_positions = c_options->save_dialog_window_positions;
263 options->show_window_ids = c_options->show_window_ids;
264 options->image.scroll_reset_method = c_options->image.scroll_reset_method;
265 options->image.zoom_2pass = c_options->image.zoom_2pass;
266 options->image.fit_window_to_image = c_options->image.fit_window_to_image;
267 options->image.limit_window_size = c_options->image.limit_window_size;
268 options->image.zoom_to_fit_allow_expand = c_options->image.zoom_to_fit_allow_expand;
269 options->image.max_window_size = c_options->image.max_window_size;
270 options->image.limit_autofit_size = c_options->image.limit_autofit_size;
271 options->image.max_autofit_size = c_options->image.max_autofit_size;
272 options->image.max_enlargement_size = c_options->image.max_enlargement_size;
273 options->image.use_clutter_renderer = c_options->image.use_clutter_renderer;
274 options->progressive_key_scrolling = c_options->progressive_key_scrolling;
275 options->keyboard_scroll_step = c_options->keyboard_scroll_step;
277 if (options->thumbnails.max_width != c_options->thumbnails.max_width
278 || options->thumbnails.max_height != c_options->thumbnails.max_height
279 || options->thumbnails.quality != c_options->thumbnails.quality)
281 thumb_format_changed = TRUE;
283 options->thumbnails.max_width = c_options->thumbnails.max_width;
284 options->thumbnails.max_height = c_options->thumbnails.max_height;
285 options->thumbnails.quality = c_options->thumbnails.quality;
287 options->thumbnails.enable_caching = c_options->thumbnails.enable_caching;
288 options->thumbnails.cache_into_dirs = c_options->thumbnails.cache_into_dirs;
289 options->thumbnails.use_exif = c_options->thumbnails.use_exif;
290 options->thumbnails.use_ft_metadata = c_options->thumbnails.use_ft_metadata;
291 // options->thumbnails.use_ft_metadata_small = c_options->thumbnails.use_ft_metadata_small;
292 options->thumbnails.spec_standard = c_options->thumbnails.spec_standard;
293 options->metadata.enable_metadata_dirs = c_options->metadata.enable_metadata_dirs;
294 options->file_filter.show_hidden_files = c_options->file_filter.show_hidden_files;
295 options->file_filter.show_parent_directory = c_options->file_filter.show_parent_directory;
296 options->file_filter.show_dot_directory = c_options->file_filter.show_dot_directory;
297 options->file_filter.disable_file_extension_checks = c_options->file_filter.disable_file_extension_checks;
299 options->file_sort.case_sensitive = c_options->file_sort.case_sensitive;
300 options->file_sort.natural = c_options->file_sort.natural;
301 options->file_filter.disable = c_options->file_filter.disable;
303 config_entry_to_option(sidecar_ext_entry, &options->sidecar.ext, NULL);
304 sidecar_ext_parse(options->sidecar.ext);
306 options->slideshow.random = c_options->slideshow.random;
307 options->slideshow.repeat = c_options->slideshow.repeat;
308 options->slideshow.delay = c_options->slideshow.delay;
310 options->mousewheel_scrolls = c_options->mousewheel_scrolls;
311 options->image_lm_click_nav = c_options->image_lm_click_nav;
312 options->image_l_click_video = c_options->image_l_click_video;
313 options->image_l_click_video_editor = c_options->image_l_click_video_editor;
315 options->file_ops.enable_in_place_rename = c_options->file_ops.enable_in_place_rename;
317 options->image.tile_cache_max = c_options->image.tile_cache_max;
318 options->image.image_cache_max = c_options->image.image_cache_max;
320 options->image.zoom_quality = c_options->image.zoom_quality;
322 options->image.zoom_increment = c_options->image.zoom_increment;
324 options->image.enable_read_ahead = c_options->image.enable_read_ahead;
327 if (options->image.use_custom_border_color != c_options->image.use_custom_border_color
328 || options->image.use_custom_border_color_in_fullscreen != c_options->image.use_custom_border_color_in_fullscreen
329 || !gdk_color_equal(&options->image.border_color, &c_options->image.border_color))
331 options->image.use_custom_border_color_in_fullscreen = c_options->image.use_custom_border_color_in_fullscreen;
332 options->image.use_custom_border_color = c_options->image.use_custom_border_color;
333 options->image.border_color = c_options->image.border_color;
334 layout_colors_update();
335 view_window_colors_update();
338 options->image.alpha_color_1 = c_options->image.alpha_color_1;
339 options->image.alpha_color_2 = c_options->image.alpha_color_2;
341 options->fullscreen.screen = c_options->fullscreen.screen;
342 options->fullscreen.clean_flip = c_options->fullscreen.clean_flip;
343 options->fullscreen.disable_saver = c_options->fullscreen.disable_saver;
344 options->fullscreen.above = c_options->fullscreen.above;
345 if (c_options->image_overlay.template_string)
346 set_image_overlay_template_string(&options->image_overlay.template_string,
347 c_options->image_overlay.template_string);
348 if (c_options->image_overlay.font)
349 set_image_overlay_font_string(&options->image_overlay.font,
350 c_options->image_overlay.font);
351 options->image_overlay.text_red = c_options->image_overlay.text_red;
352 options->image_overlay.text_green = c_options->image_overlay.text_green;
353 options->image_overlay.text_blue = c_options->image_overlay.text_blue;
354 options->image_overlay.text_alpha = c_options->image_overlay.text_alpha;
355 options->image_overlay.background_red = c_options->image_overlay.background_red;
356 options->image_overlay.background_green = c_options->image_overlay.background_green;
357 options->image_overlay.background_blue = c_options->image_overlay.background_blue;
358 options->image_overlay.background_alpha = c_options->image_overlay.background_alpha;
359 options->update_on_time_change = c_options->update_on_time_change;
360 options->image.exif_proof_rotate_enable = c_options->image.exif_proof_rotate_enable;
362 options->duplicates_similarity_threshold = c_options->duplicates_similarity_threshold;
363 options->rot_invariant_sim = c_options->rot_invariant_sim;
365 options->tree_descend_subdirs = c_options->tree_descend_subdirs;
367 options->view_dir_list_single_click_enter = c_options->view_dir_list_single_click_enter;
369 options->open_recent_list_maxsize = c_options->open_recent_list_maxsize;
370 options->dnd_icon_size = c_options->dnd_icon_size;
371 options->clipboard_selection = c_options->clipboard_selection;
373 options->metadata.save_in_image_file = c_options->metadata.save_in_image_file;
374 options->metadata.save_legacy_IPTC = c_options->metadata.save_legacy_IPTC;
375 options->metadata.warn_on_write_problems = c_options->metadata.warn_on_write_problems;
376 options->metadata.save_legacy_format = c_options->metadata.save_legacy_format;
377 options->metadata.sync_grouped_files = c_options->metadata.sync_grouped_files;
378 options->metadata.confirm_write = c_options->metadata.confirm_write;
379 options->metadata.sidecar_extended_name = c_options->metadata.sidecar_extended_name;
380 options->metadata.confirm_timeout = c_options->metadata.confirm_timeout;
381 options->metadata.confirm_after_timeout = c_options->metadata.confirm_after_timeout;
382 options->metadata.confirm_on_image_change = c_options->metadata.confirm_on_image_change;
383 options->metadata.confirm_on_dir_change = c_options->metadata.confirm_on_dir_change;
384 options->metadata.keywords_case_sensitive = c_options->metadata.keywords_case_sensitive;
385 options->metadata.write_orientation = c_options->metadata.write_orientation;
386 options->stereo.mode = (c_options->stereo.mode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
387 (c_options->stereo.tmp.mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
388 (c_options->stereo.tmp.flip_right ? PR_STEREO_FLIP_RIGHT : 0) |
389 (c_options->stereo.tmp.mirror_left ? PR_STEREO_MIRROR_LEFT : 0) |
390 (c_options->stereo.tmp.flip_left ? PR_STEREO_FLIP_LEFT : 0) |
391 (c_options->stereo.tmp.swap ? PR_STEREO_SWAP : 0) |
392 (c_options->stereo.tmp.temp_disable ? PR_STEREO_TEMP_DISABLE : 0);
393 options->stereo.fsmode = (c_options->stereo.fsmode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
394 (c_options->stereo.tmp.fs_mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
395 (c_options->stereo.tmp.fs_flip_right ? PR_STEREO_FLIP_RIGHT : 0) |
396 (c_options->stereo.tmp.fs_mirror_left ? PR_STEREO_MIRROR_LEFT : 0) |
397 (c_options->stereo.tmp.fs_flip_left ? PR_STEREO_FLIP_LEFT : 0) |
398 (c_options->stereo.tmp.fs_swap ? PR_STEREO_SWAP : 0) |
399 (c_options->stereo.tmp.fs_temp_disable ? PR_STEREO_TEMP_DISABLE : 0);
400 options->stereo.enable_fsmode = c_options->stereo.enable_fsmode;
401 options->stereo.fixed_w = c_options->stereo.fixed_w;
402 options->stereo.fixed_h = c_options->stereo.fixed_h;
403 options->stereo.fixed_x1 = c_options->stereo.fixed_x1;
404 options->stereo.fixed_y1 = c_options->stereo.fixed_y1;
405 options->stereo.fixed_x2 = c_options->stereo.fixed_x2;
406 options->stereo.fixed_y2 = c_options->stereo.fixed_y2;
408 options->info_keywords.height = c_options->info_keywords.height;
409 options->info_title.height = c_options->info_title.height;
410 options->info_comment.height = c_options->info_comment.height;
411 options->info_rating.height = c_options->info_rating.height;
413 options->marks_save = c_options->marks_save;
414 options->with_rename = c_options->with_rename;
415 options->collections_on_top = c_options->collections_on_top;
416 config_entry_to_option(help_search_engine_entry, &options->help_search_engine, NULL);
418 options->read_metadata_in_idle = c_options->read_metadata_in_idle;
420 options->star_rating.star = c_options->star_rating.star;
421 options->star_rating.rejected = c_options->star_rating.rejected;
423 set_debug_level(debug_c);
427 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
429 config_entry_to_option(color_profile_input_name_entry[i], &options->color_profile.input_name[i], NULL);
430 config_entry_to_option(color_profile_input_file_entry[i], &options->color_profile.input_file[i], NULL);
432 config_entry_to_option(color_profile_screen_file_entry, &options->color_profile.screen_file, NULL);
433 options->color_profile.use_x11_screen_profile = c_options->color_profile.use_x11_screen_profile;
434 if (options->color_profile.render_intent != c_options->color_profile.render_intent)
436 options->color_profile.render_intent = c_options->color_profile.render_intent;
441 image_options_sync();
446 layout_refresh(NULL);
449 if (accel_store) gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_apply_cb, NULL);
455 *-----------------------------------------------------------------------------
456 * config window main button callbacks (private)
457 *-----------------------------------------------------------------------------
460 static void config_window_close_cb(GtkWidget *widget, gpointer data)
462 gtk_widget_destroy(configwindow);
467 static void config_window_help_cb(GtkWidget *widget, gpointer data)
469 GtkWidget *notebook = data;
472 static gchar *html_section[] =
474 "GuideOptionsGeneral.html",
475 "GuideOptionsImage.html",
476 "GuideOptionsWindow.html",
477 "GuideOptionsKeyboard.html",
478 "GuideOptionsFiltering.html",
479 "GuideOptionsMetadata.html",
480 "GuideOptionsColor.html",
481 "GuideOptionsStereo.html",
482 "GuideOptionsBehavior.html",
483 "GuideOptionsToolbar.html"
486 i = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
487 help_window_show(html_section[i]);
490 static gboolean config_window_delete(GtkWidget *widget, GdkEventAny *event, gpointer data)
492 config_window_close_cb(NULL, NULL);
496 static void config_window_ok_cb(GtkWidget *widget, gpointer data)
498 config_window_apply();
499 config_window_close_cb(NULL, NULL);
502 static void config_window_apply_cb(GtkWidget *widget, gpointer data)
505 lw = layout_window_list->data;
507 config_window_apply();
508 layout_util_sync(lw);
511 static void config_window_save_cb(GtkWidget *widget, gpointer data)
513 config_window_apply();
514 save_options(options);
518 *-----------------------------------------------------------------------------
519 * config window setup (private)
520 *-----------------------------------------------------------------------------
523 static void quality_menu_cb(GtkWidget *combo, gpointer data)
527 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
531 *option = GDK_INTERP_NEAREST;
534 *option = GDK_INTERP_TILES;
537 *option = GDK_INTERP_BILINEAR;
540 *option = GDK_INTERP_HYPER;
545 static void clipboard_selection_menu_cb(GtkWidget *combo, gpointer data)
549 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
561 static void add_quality_menu(GtkWidget *table, gint column, gint row, const gchar *text,
562 guint option, guint *option_c)
569 pref_table_label(table, column, row, text, 0.0);
571 combo = gtk_combo_box_text_new();
573 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Nearest (worst, but fastest)"));
574 if (option == GDK_INTERP_NEAREST) current = 0;
575 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Tiles"));
576 if (option == GDK_INTERP_TILES) current = 1;
577 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Bilinear"));
578 if (option == GDK_INTERP_BILINEAR) current = 2;
579 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Hyper (best, but slowest)"));
580 if (option == GDK_INTERP_HYPER) current = 3;
582 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
584 g_signal_connect(G_OBJECT(combo), "changed",
585 G_CALLBACK(quality_menu_cb), option_c);
587 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
588 GTK_EXPAND | GTK_FILL, 0, 0, 0);
589 gtk_widget_show(combo);
592 static void add_clipboard_selection_menu(GtkWidget *table, gint column, gint row, const gchar *text,
593 gint option, gint *option_c)
600 pref_table_label(table, column, row, text, 0.0);
602 combo = gtk_combo_box_text_new();
604 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("PRIMARY"));
605 if (option == PRIMARY) current = 0;
606 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("CLIPBOARD"));
607 if (option == CLIPBOARD) current = 1;
609 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
611 g_signal_connect(G_OBJECT(combo), "changed",
612 G_CALLBACK(clipboard_selection_menu_cb), option_c);
614 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
615 GTK_EXPAND | GTK_FILL, 0, 0, 0);
616 gtk_widget_show(combo);
619 static void thumb_size_menu_cb(GtkWidget *combo, gpointer data)
623 n = gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
626 if ((guint) n < sizeof(thumb_size_list) / sizeof(ThumbSize))
628 c_options->thumbnails.max_width = thumb_size_list[n].w;
629 c_options->thumbnails.max_height = thumb_size_list[n].h;
633 c_options->thumbnails.max_width = options->thumbnails.max_width;
634 c_options->thumbnails.max_height = options->thumbnails.max_height;
638 static void add_thumb_size_menu(GtkWidget *table, gint column, gint row, gchar *text)
644 c_options->thumbnails.max_width = options->thumbnails.max_width;
645 c_options->thumbnails.max_height = options->thumbnails.max_height;
647 pref_table_label(table, column, row, text, 0.0);
649 combo = gtk_combo_box_text_new();
652 for (i = 0; (guint) i < sizeof(thumb_size_list) / sizeof(ThumbSize); i++)
657 w = thumb_size_list[i].w;
658 h = thumb_size_list[i].h;
660 buf = g_strdup_printf("%d x %d", w, h);
661 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf);
664 if (w == options->thumbnails.max_width && h == options->thumbnails.max_height) current = i;
671 buf = g_strdup_printf("%s %d x %d", _("Custom"), options->thumbnails.max_width, options->thumbnails.max_height);
672 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf);
678 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
679 g_signal_connect(G_OBJECT(combo), "changed",
680 G_CALLBACK(thumb_size_menu_cb), NULL);
682 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
683 GTK_EXPAND | GTK_FILL, 0, 0, 0);
684 gtk_widget_show(combo);
687 static void stereo_mode_menu_cb(GtkWidget *combo, gpointer data)
691 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
695 *option = PR_STEREO_NONE;
698 *option = PR_STEREO_ANAGLYPH_RC;
701 *option = PR_STEREO_ANAGLYPH_GM;
704 *option = PR_STEREO_ANAGLYPH_YB;
707 *option = PR_STEREO_ANAGLYPH_GRAY_RC;
710 *option = PR_STEREO_ANAGLYPH_GRAY_GM;
713 *option = PR_STEREO_ANAGLYPH_GRAY_YB;
716 *option = PR_STEREO_ANAGLYPH_DB_RC;
719 *option = PR_STEREO_ANAGLYPH_DB_GM;
722 *option = PR_STEREO_ANAGLYPH_DB_YB;
725 *option = PR_STEREO_HORIZ;
728 *option = PR_STEREO_HORIZ | PR_STEREO_HALF;
731 *option = PR_STEREO_VERT;
734 *option = PR_STEREO_VERT | PR_STEREO_HALF;
737 *option = PR_STEREO_FIXED;
742 static void add_stereo_mode_menu(GtkWidget *table, gint column, gint row, const gchar *text,
743 gint option, gint *option_c, gboolean add_fixed)
750 pref_table_label(table, column, row, text, 0.0);
752 combo = gtk_combo_box_text_new();
754 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Single image"));
756 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Red-Cyan"));
757 if (option & PR_STEREO_ANAGLYPH_RC) current = 1;
758 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Green-Magenta"));
759 if (option & PR_STEREO_ANAGLYPH_GM) current = 2;
760 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Yellow-Blue"));
761 if (option & PR_STEREO_ANAGLYPH_YB) current = 3;
762 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Red-Cyan"));
763 if (option & PR_STEREO_ANAGLYPH_GRAY_RC) current = 4;
764 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Green-Magenta"));
765 if (option & PR_STEREO_ANAGLYPH_GRAY_GM) current = 5;
766 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Yellow-Blue"));
767 if (option & PR_STEREO_ANAGLYPH_GRAY_YB) current = 6;
768 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Red-Cyan"));
769 if (option & PR_STEREO_ANAGLYPH_DB_RC) current = 7;
770 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Green-Magenta"));
771 if (option & PR_STEREO_ANAGLYPH_DB_GM) current = 8;
772 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Yellow-Blue"));
773 if (option & PR_STEREO_ANAGLYPH_DB_YB) current = 9;
775 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Side by Side"));
776 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Side by Side Half size"));
777 if (option & PR_STEREO_HORIZ)
780 if (option & PR_STEREO_HALF) current = 11;
783 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Top - Bottom"));
784 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Top - Bottom Half size"));
785 if (option & PR_STEREO_VERT)
788 if (option & PR_STEREO_HALF) current = 13;
793 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Fixed position"));
794 if (option & PR_STEREO_FIXED) current = 14;
797 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
799 g_signal_connect(G_OBJECT(combo), "changed",
800 G_CALLBACK(stereo_mode_menu_cb), option_c);
802 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
803 GTK_EXPAND | GTK_FILL, 0, 0, 0);
804 gtk_widget_show(combo);
807 static void video_menu_cb(GtkWidget *combo, gpointer data)
809 gchar **option = data;
811 EditorDescription *ed = g_list_nth_data(editor_list_get(), gtk_combo_box_get_active(GTK_COMBO_BOX(combo)));
815 static void video_menu_populate(gpointer data, gpointer user_data)
817 GtkWidget *combo = user_data;
818 EditorDescription *ed = data;
820 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), ed->name);
823 static void add_video_menu(GtkWidget *table, gint column, gint row, const gchar *text,
824 gchar *option, gchar **option_c)
828 /* use lists since they are sorted */
829 GList *eds = editor_list_get();
833 pref_table_label(table, column, row, text, 0.0);
835 combo = gtk_combo_box_text_new();
836 g_list_foreach(eds,video_menu_populate,(gpointer)combo);
837 current = option ? g_list_index(eds,g_hash_table_lookup(editors,option)): -1;
839 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
841 g_signal_connect(G_OBJECT(combo), "changed",
842 G_CALLBACK(video_menu_cb), option_c);
844 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
845 GTK_EXPAND | GTK_FILL, 0, 0, 0);
846 gtk_widget_show(combo);
849 static void filter_store_populate(void)
853 if (!filter_store) return;
855 gtk_list_store_clear(filter_store);
857 work = filter_get_list();
866 gtk_list_store_append(filter_store, &iter);
867 gtk_list_store_set(filter_store, &iter, 0, fe, -1);
871 static void filter_store_ext_edit_cb(GtkCellRendererText *cell, gchar *path_str,
872 gchar *new_text, gpointer data)
874 GtkWidget *model = data;
875 FilterEntry *fe = data;
879 if (!new_text || strlen(new_text) < 1) return;
881 tpath = gtk_tree_path_new_from_string(path_str);
882 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
883 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
885 g_free(fe->extensions);
886 fe->extensions = g_strdup(new_text);
888 gtk_tree_path_free(tpath);
892 static void filter_store_class_edit_cb(GtkCellRendererText *cell, gchar *path_str,
893 gchar *new_text, gpointer data)
895 GtkWidget *model = data;
896 FilterEntry *fe = data;
901 if (!new_text || !new_text[0]) return;
903 tpath = gtk_tree_path_new_from_string(path_str);
904 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
905 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
907 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
909 if (strcmp(new_text, _(format_class_list[i])) == 0)
916 gtk_tree_path_free(tpath);
920 static void filter_store_desc_edit_cb(GtkCellRendererText *cell, gchar *path_str,
921 gchar *new_text, gpointer data)
923 GtkWidget *model = data;
928 if (!new_text || !new_text[0]) return;
930 tpath = gtk_tree_path_new_from_string(path_str);
931 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
932 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
934 g_free(fe->description);
935 fe->description = g_strdup(new_text);
937 gtk_tree_path_free(tpath);
940 static void filter_store_enable_cb(GtkCellRendererToggle *renderer,
941 gchar *path_str, gpointer data)
943 GtkWidget *model = data;
948 tpath = gtk_tree_path_new_from_string(path_str);
949 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
950 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
952 fe->enabled = !fe->enabled;
954 gtk_tree_path_free(tpath);
958 static void filter_store_writable_cb(GtkCellRendererToggle *renderer,
959 gchar *path_str, gpointer data)
961 GtkWidget *model = data;
966 tpath = gtk_tree_path_new_from_string(path_str);
967 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
968 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
970 fe->writable = !fe->writable;
971 if (fe->writable) fe->allow_sidecar = FALSE;
973 gtk_tree_path_free(tpath);
977 static void filter_store_sidecar_cb(GtkCellRendererToggle *renderer,
978 gchar *path_str, gpointer data)
980 GtkWidget *model = data;
985 tpath = gtk_tree_path_new_from_string(path_str);
986 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
987 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
989 fe->allow_sidecar = !fe->allow_sidecar;
990 if (fe->allow_sidecar) fe->writable = FALSE;
992 gtk_tree_path_free(tpath);
996 static void filter_set_func(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell,
997 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
1001 gtk_tree_model_get(tree_model, iter, 0, &fe, -1);
1003 switch (GPOINTER_TO_INT(data))
1006 g_object_set(GTK_CELL_RENDERER(cell),
1007 "active", fe->enabled, NULL);
1010 g_object_set(GTK_CELL_RENDERER(cell),
1011 "text", fe->extensions, NULL);
1013 case FE_DESCRIPTION:
1014 g_object_set(GTK_CELL_RENDERER(cell),
1015 "text", fe->description, NULL);
1018 g_object_set(GTK_CELL_RENDERER(cell),
1019 "text", _(format_class_list[fe->file_class]), NULL);
1022 g_object_set(GTK_CELL_RENDERER(cell),
1023 "active", fe->writable, NULL);
1025 case FE_ALLOW_SIDECAR:
1026 g_object_set(GTK_CELL_RENDERER(cell),
1027 "active", fe->allow_sidecar, NULL);
1032 static gboolean filter_add_scroll(gpointer data)
1036 GtkCellRenderer *cell;
1037 GtkTreeViewColumn *column;
1038 GList *list_columns;
1043 rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(filter_store), NULL);
1044 path = gtk_tree_path_new_from_indices(rows-1, -1);
1046 list_columns = gtk_tree_view_get_columns(GTK_TREE_VIEW(data));
1048 column = g_list_nth(list_columns,i)->data;
1049 title = gtk_tree_view_column_get_title(GTK_TREE_VIEW_COLUMN(column));
1051 } while (strcmp(title, "Filter") !=0 );
1053 list_cells = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(column));
1054 cell = g_list_last(list_cells)->data;
1056 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1057 path, column, FALSE, 0.0, 0.0 );
1058 gtk_tree_view_set_cursor_on_cell(GTK_TREE_VIEW(data),
1059 path, column, cell, TRUE);
1061 gtk_tree_path_free(path);
1062 g_list_free(list_cells);
1063 g_list_free(list_columns);
1068 static void filter_add_cb(GtkWidget *widget, gpointer data)
1070 filter_add_unique("description", ".new", FORMAT_CLASS_IMAGE, TRUE, FALSE, TRUE);
1071 filter_store_populate();
1073 g_idle_add((GSourceFunc)filter_add_scroll, data);
1076 static void filter_remove_cb(GtkWidget *widget, gpointer data)
1078 GtkWidget *filter_view = data;
1079 GtkTreeSelection *selection;
1083 if (!filter_store) return;
1084 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
1085 if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) return;
1086 gtk_tree_model_get(GTK_TREE_MODEL(filter_store), &iter, 0, &fe, -1);
1089 filter_remove_entry(fe);
1091 filter_store_populate();
1094 static gboolean filter_default_ok_scroll(GtkTreeView *data)
1098 GtkTreeViewColumn *column;
1100 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(filter_store), &iter);
1101 path = gtk_tree_model_get_path(GTK_TREE_MODEL(filter_store), &iter);
1102 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data),0);
1104 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1108 gtk_tree_path_free(path);
1113 static void filter_default_ok_cb(GenericDialog *gd, gpointer data)
1116 filter_add_defaults();
1118 filter_store_populate();
1120 g_idle_add((GSourceFunc)filter_default_ok_scroll, gd->data);
1123 static void dummy_cancel_cb(GenericDialog *gd, gpointer data)
1125 /* no op, only so cancel button appears */
1128 static void filter_default_cb(GtkWidget *widget, gpointer data)
1132 gd = generic_dialog_new(_("Reset filters"),
1133 "reset_filter", widget, TRUE,
1134 dummy_cancel_cb, data);
1135 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Reset filters"),
1136 _("This will reset the file filters to the defaults.\nContinue?"), TRUE);
1137 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, filter_default_ok_cb, TRUE);
1138 gtk_widget_show(gd->dialog);
1141 static void filter_disable_cb(GtkWidget *widget, gpointer data)
1143 GtkWidget *frame = data;
1145 gtk_widget_set_sensitive(frame,
1146 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
1149 static void safe_delete_view_cb(GtkWidget *widget, gpointer data)
1151 layout_set_path(NULL, gtk_entry_get_text(GTK_ENTRY(safe_delete_path_entry)));
1154 static void safe_delete_clear_ok_cb(GenericDialog *gd, gpointer data)
1156 file_util_trash_clear();
1159 static void safe_delete_clear_cb(GtkWidget *widget, gpointer data)
1163 gd = generic_dialog_new(_("Clear trash"),
1164 "clear_trash", widget, TRUE,
1165 dummy_cancel_cb, NULL);
1166 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Clear trash"),
1167 _("This will remove the trash contents."), FALSE);
1168 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, safe_delete_clear_ok_cb, TRUE);
1169 entry = gtk_entry_new();
1170 gtk_widget_set_can_focus(entry, FALSE);
1171 gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
1172 if (options->file_ops.safe_delete_path) gtk_entry_set_text(GTK_ENTRY(entry), options->file_ops.safe_delete_path);
1173 gtk_box_pack_start(GTK_BOX(gd->vbox), entry, FALSE, FALSE, 0);
1174 gtk_widget_show(entry);
1175 gtk_widget_show(gd->dialog);
1178 static void image_overlay_template_view_changed_cb(GtkWidget *widget, gpointer data)
1180 GtkWidget *pTextView;
1181 GtkTextBuffer *pTextBuffer;
1185 pTextView = GTK_WIDGET(data);
1187 pTextBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pTextView));
1188 gtk_text_buffer_get_start_iter(pTextBuffer, &iStart);
1189 gtk_text_buffer_get_end_iter(pTextBuffer, &iEnd);
1191 set_image_overlay_template_string(&c_options->image_overlay.template_string,
1192 gtk_text_buffer_get_text(pTextBuffer, &iStart, &iEnd, TRUE));
1195 static void image_overlay_default_template_ok_cb(GenericDialog *gd, gpointer data)
1197 GtkTextView *text_view = data;
1198 GtkTextBuffer *buffer;
1200 set_default_image_overlay_template_string(&options->image_overlay.template_string);
1201 if (!configwindow) return;
1203 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
1204 gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
1207 static void image_overlay_default_template_cb(GtkWidget *widget, gpointer data)
1211 gd = generic_dialog_new(_("Reset image overlay template string"),
1212 "reset_image_overlay_template_string", widget, TRUE,
1213 dummy_cancel_cb, data);
1214 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Reset image overlay template string"),
1215 _("This will reset the image overlay template string to the default.\nContinue?"), TRUE);
1216 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, image_overlay_default_template_ok_cb, TRUE);
1217 gtk_widget_show(gd->dialog);
1220 static void image_overlay_help_cb(GtkWidget *widget, gpointer data)
1222 help_window_show("GuideOptionsWindow.html#OverlayScreenDisplay");
1225 static void image_overlay_set_font_cb(GtkWidget *widget, gpointer data)
1227 #if GTK_CHECK_VERSION(3,4,0)
1230 PangoFontDescription *font_desc;
1232 dialog = gtk_font_chooser_dialog_new("Image Overlay Font", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1233 gtk_font_chooser_set_font(GTK_FONT_CHOOSER(dialog), options->image_overlay.font);
1235 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1237 font_desc = gtk_font_chooser_get_font_desc(GTK_FONT_CHOOSER(dialog));
1238 font = pango_font_description_to_string(font_desc);
1239 g_free(c_options->image_overlay.font);
1240 c_options->image_overlay.font = g_strdup(font);
1244 gtk_widget_destroy(dialog);
1248 font = gtk_font_button_get_font_name(GTK_FONT_BUTTON(widget));
1249 c_options->image_overlay.font = g_strdup(font);
1253 static void image_overlay_set_text_colour_cb(GtkWidget *widget, gpointer data)
1256 #if GTK_CHECK_VERSION(3,4,0)
1259 dialog = gtk_color_chooser_dialog_new("Image Overlay Text Colour", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1260 colour.red = options->image_overlay.text_red;
1261 colour.green = options->image_overlay.text_green;
1262 colour.blue = options->image_overlay.text_blue;
1263 colour.alpha = options->image_overlay.text_alpha;
1264 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1265 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(dialog), TRUE);
1267 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1269 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1270 c_options->image_overlay.text_red = colour.red*255;
1271 c_options->image_overlay.text_green = colour.green*255;
1272 c_options->image_overlay.text_blue = colour.blue*255;
1273 c_options->image_overlay.text_alpha = colour.alpha*255;
1275 gtk_widget_destroy(dialog);
1278 GtkColorSelection *colorsel;
1280 dialog = gtk_color_selection_dialog_new("Image Overlay Text Colour");
1281 gtk_window_set_keep_above(GTK_WINDOW(dialog),TRUE);
1282 colour.red = options->image_overlay.text_red*257;
1283 colour.green = options->image_overlay.text_green*257;
1284 colour.blue = options->image_overlay.text_blue*257;
1285 colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)));
1286 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
1287 gtk_color_selection_set_current_color(colorsel, &colour);
1288 gtk_color_selection_set_current_alpha(colorsel, options->image_overlay.text_alpha*257);
1290 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
1292 gtk_color_selection_get_current_color(colorsel, &colour);
1293 c_options->image_overlay.text_red = colour.red/257;
1294 c_options->image_overlay.text_green = colour.green/257;
1295 c_options->image_overlay.text_blue = colour.blue/257;
1296 c_options->image_overlay.text_alpha = gtk_color_selection_get_current_alpha(colorsel)/257;
1298 gtk_widget_destroy (dialog);
1303 static void image_overlay_set_background_colour_cb(GtkWidget *widget, gpointer data)
1306 #if GTK_CHECK_VERSION(3,4,0)
1309 dialog = gtk_color_chooser_dialog_new("Image Overlay Background Colour", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1310 colour.red = options->image_overlay.background_red;
1311 colour.green = options->image_overlay.background_green;
1312 colour.blue = options->image_overlay.background_blue;
1313 colour.alpha = options->image_overlay.background_alpha;
1314 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1315 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(dialog), TRUE);
1317 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1319 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1320 c_options->image_overlay.background_red = colour.red*255;
1321 c_options->image_overlay.background_green = colour.green*255;
1322 c_options->image_overlay.background_blue = colour.blue*255;
1323 c_options->image_overlay.background_alpha = colour.alpha*255;
1325 gtk_widget_destroy(dialog);
1328 GtkColorSelection *colorsel;
1330 dialog = gtk_color_selection_dialog_new("Image Overlay Background Colour");
1331 gtk_window_set_keep_above(GTK_WINDOW(dialog),TRUE);
1332 colour.red = options->image_overlay.background_red*257;
1333 colour.green = options->image_overlay.background_green*257;
1334 colour.blue = options->image_overlay.background_blue*257;
1335 colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)));
1336 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
1337 gtk_color_selection_set_current_color(colorsel, &colour);
1338 gtk_color_selection_set_current_alpha(colorsel, options->image_overlay.background_alpha*257);
1340 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
1342 gtk_color_selection_get_current_color(colorsel, &colour);
1343 c_options->image_overlay.background_red = colour.red/257;
1344 c_options->image_overlay.background_green = colour.green/257;
1345 c_options->image_overlay.background_blue = colour.blue/257;
1346 c_options->image_overlay.background_alpha = gtk_color_selection_get_current_alpha(colorsel)/257;
1348 gtk_widget_destroy(dialog);
1352 static void accel_store_populate(void)
1355 GList *groups, *actions;
1357 const gchar *accel_path;
1361 if (!accel_store || !layout_window_list || !layout_window_list->data) return;
1363 gtk_tree_store_clear(accel_store);
1364 lw = layout_window_list->data; /* get the actions from the first window, it should not matter, they should be the same in all windows */
1366 g_assert(lw && lw->ui_manager);
1367 groups = gtk_ui_manager_get_action_groups(lw->ui_manager);
1370 actions = gtk_action_group_list_actions(GTK_ACTION_GROUP(groups->data));
1373 action = GTK_ACTION(actions->data);
1374 accel_path = gtk_action_get_accel_path(action);
1375 if (accel_path && gtk_accel_map_lookup_entry(accel_path, &key))
1377 gchar *label, *label2, *tooltip, *accel;
1378 g_object_get(action,
1379 "tooltip", &tooltip,
1383 if (pango_parse_markup(label, -1, '_', NULL, &label2, NULL, NULL) && label2)
1389 accel = gtk_accelerator_name(key.accel_key, key.accel_mods);
1393 gtk_tree_store_append(accel_store, &iter, NULL);
1394 gtk_tree_store_set(accel_store, &iter,
1397 AE_TOOLTIP, tooltip ? tooltip : "",
1398 AE_ACCEL, accel_path,
1406 actions = actions->next;
1409 groups = groups->next;
1413 static void accel_store_cleared_cb(GtkCellRendererAccel *accel, gchar *path_string, gpointer user_data)
1418 static gboolean accel_remove_key_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1420 gchar *accel1 = data;
1425 gtk_tree_model_get(model, iter, AE_KEY, &accel2, -1);
1427 gtk_accelerator_parse(accel1, &key1.accel_key, &key1.accel_mods);
1428 gtk_accelerator_parse(accel2, &key2.accel_key, &key2.accel_mods);
1430 if (key1.accel_key == key2.accel_key && key1.accel_mods == key2.accel_mods)
1432 gtk_tree_store_set(accel_store, iter, AE_KEY, "", -1);
1433 DEBUG_1("accelerator key '%s' is already used, removing.", accel1);
1442 static void accel_store_edited_cb(GtkCellRendererAccel *accel, gchar *path_string, guint accel_key, GdkModifierType accel_mods, guint hardware_keycode, gpointer user_data)
1444 GtkTreeModel *model = (GtkTreeModel *)accel_store;
1448 GtkAccelKey old_key, key;
1449 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
1451 gtk_tree_model_get_iter(model, &iter, path);
1452 gtk_tree_model_get(model, &iter, AE_ACCEL, &accel_path, -1);
1454 /* test if the accelerator can be stored without conflicts*/
1455 gtk_accel_map_lookup_entry(accel_path, &old_key);
1457 /* change the key and read it back (change may fail on keys hardcoded in gtk)*/
1458 gtk_accel_map_change_entry(accel_path, accel_key, accel_mods, TRUE);
1459 gtk_accel_map_lookup_entry(accel_path, &key);
1461 /* restore the original for now, the key will be really changed when the changes are confirmed */
1462 gtk_accel_map_change_entry(accel_path, old_key.accel_key, old_key.accel_mods, TRUE);
1464 acc = gtk_accelerator_name(key.accel_key, key.accel_mods);
1465 gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_remove_key_cb, acc);
1467 gtk_tree_store_set(accel_store, &iter, AE_KEY, acc, -1);
1468 gtk_tree_path_free(path);
1472 static gboolean accel_default_scroll(GtkTreeView *data)
1476 GtkTreeViewColumn *column;
1478 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(accel_store), &iter);
1479 path = gtk_tree_model_get_path(GTK_TREE_MODEL(accel_store), &iter);
1480 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data),0);
1482 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1486 gtk_tree_path_free(path);
1491 static void accel_default_cb(GtkWidget *widget, gpointer data)
1493 accel_store_populate();
1495 g_idle_add((GSourceFunc)accel_default_scroll, data);
1498 void accel_remove_selection(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1500 gtk_tree_store_set(accel_store, iter, AE_KEY, "", -1);
1503 void accel_reset_selection(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1506 gchar *accel_path, *accel;
1508 gtk_tree_model_get(model, iter, AE_ACCEL, &accel_path, -1);
1509 gtk_accel_map_lookup_entry(accel_path, &key);
1510 accel = gtk_accelerator_name(key.accel_key, key.accel_mods);
1512 gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_remove_key_cb, accel);
1514 gtk_tree_store_set(accel_store, iter, AE_KEY, accel, -1);
1519 static void accel_reset_cb(GtkWidget *widget, gpointer data)
1521 GtkTreeSelection *selection;
1523 if (!accel_store) return;
1524 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data));
1525 gtk_tree_selection_selected_foreach(selection, &accel_reset_selection, NULL);
1530 static GtkWidget *scrolled_notebook_page(GtkWidget *notebook, const gchar *title)
1534 GtkWidget *scrolled;
1535 GtkWidget *viewport;
1537 scrolled = gtk_scrolled_window_new(NULL, NULL);
1538 gtk_container_set_border_width(GTK_CONTAINER(scrolled), PREF_PAD_BORDER);
1539 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
1540 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1541 label = gtk_label_new(title);
1542 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled, label);
1543 gtk_widget_show(scrolled);
1545 viewport = gtk_viewport_new(NULL, NULL);
1546 gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
1547 gtk_container_add(GTK_CONTAINER(scrolled), viewport);
1548 gtk_widget_show(viewport);
1550 vbox = gtk_vbox_new(FALSE, 0);
1551 gtk_container_add(GTK_CONTAINER(viewport), vbox);
1552 gtk_widget_show(vbox);
1557 static void cache_standard_cb(GtkWidget *widget, gpointer data)
1559 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1561 c_options->thumbnails.spec_standard =TRUE;
1562 c_options->thumbnails.cache_into_dirs = FALSE;
1566 c_options->thumbnails.spec_standard =FALSE;
1570 static void cache_geeqie_cb(GtkWidget *widget, gpointer data)
1572 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1574 c_options->thumbnails.spec_standard =TRUE;
1575 c_options->thumbnails.cache_into_dirs = FALSE;
1579 c_options->thumbnails.spec_standard =FALSE;
1583 static void cache_local_cb(GtkWidget *widget, gpointer data)
1585 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1587 c_options->thumbnails.cache_into_dirs = TRUE;
1588 c_options->thumbnails.spec_standard =FALSE;
1592 c_options->thumbnails.cache_into_dirs = FALSE;
1596 static void help_search_engine_entry_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1597 GdkEvent *event, gpointer userdata)
1599 if (pos == GTK_ENTRY_ICON_PRIMARY)
1601 gtk_entry_set_text(GTK_ENTRY(userdata), HELP_SEARCH_ENGINE);
1605 gtk_entry_set_text(GTK_ENTRY(userdata), "");
1609 static void star_rating_star_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1610 GdkEvent *event, gpointer userdata)
1612 gchar *rating_symbol;
1614 if (pos == GTK_ENTRY_ICON_PRIMARY)
1616 rating_symbol = g_strdup_printf("U+%X", STAR_RATING_STAR);
1617 gtk_entry_set_text(GTK_ENTRY(userdata), rating_symbol);
1618 g_free(rating_symbol);
1622 gtk_entry_set_text(GTK_ENTRY(userdata), "U+");
1623 gtk_widget_grab_focus(GTK_WIDGET(userdata));
1624 gtk_editable_select_region(GTK_EDITABLE(userdata), 2, 2);
1628 static void star_rating_rejected_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1629 GdkEvent *event, gpointer userdata)
1631 gchar *rating_symbol;
1633 if (pos == GTK_ENTRY_ICON_PRIMARY)
1635 rating_symbol = g_strdup_printf("U+%X", STAR_RATING_REJECTED);
1636 gtk_entry_set_text(GTK_ENTRY(userdata), rating_symbol);
1637 g_free(rating_symbol);
1641 gtk_entry_set_text(GTK_ENTRY(userdata), "U+");
1642 gtk_widget_grab_focus(GTK_WIDGET(userdata));
1643 gtk_editable_select_region(GTK_EDITABLE(userdata), 2, 2);
1647 static guint star_rating_symbol_test(GtkWidget *widget, gpointer data)
1649 GtkContainer *hbox = data;
1650 GString *str = g_string_new(NULL);
1651 GtkEntry *hex_code_entry;
1652 gchar *hex_code_full;
1655 guint64 hex_value = 0;
1657 list = gtk_container_get_children(hbox);
1659 hex_code_entry = g_list_nth_data(list, 2);
1660 hex_code_full = g_strdup(gtk_entry_get_text(hex_code_entry));
1662 hex_code = g_strsplit(hex_code_full, "+", 2);
1663 if (hex_code[0] && hex_code[1])
1665 hex_value = strtoull(hex_code[1], NULL, 16);
1667 if (!hex_value || hex_value > 0x10FFFF)
1669 hex_value = 0x003F; // Unicode 'Question Mark'
1671 str = g_string_append_unichar(str, (gunichar)hex_value);
1672 gtk_label_set_text(g_list_nth_data(list, 1), str->str);
1674 g_strfreev(hex_code);
1675 g_string_free(str, TRUE);
1676 g_free(hex_code_full);
1681 static void star_rating_star_test_cb(GtkWidget *widget, gpointer data)
1683 guint64 star_symbol;
1685 star_symbol = star_rating_symbol_test(widget, data);
1686 c_options->star_rating.star = star_symbol;
1689 static void star_rating_rejected_test_cb(GtkWidget *widget, gpointer data)
1691 guint64 rejected_symbol;
1693 rejected_symbol = star_rating_symbol_test(widget, data);
1694 c_options->star_rating.rejected = rejected_symbol;
1697 /* general options tab */
1698 static void config_tab_general(GtkWidget *notebook)
1703 GtkWidget *group_frame;
1704 GtkWidget *subgroup;
1706 GtkWidget *ct_button;
1709 gint hours, minutes, remainder;
1711 GtkWidget *star_rating_entry;
1713 gchar *rating_symbol;
1715 vbox = scrolled_notebook_page(notebook, _("General"));
1717 group = pref_group_new(vbox, FALSE, _("Thumbnails"), GTK_ORIENTATION_VERTICAL);
1719 table = pref_table_new(group, 2, 2, FALSE, FALSE);
1720 add_thumb_size_menu(table, 0, 0, _("Size:"));
1721 add_quality_menu(table, 0, 1, _("Quality:"), options->thumbnails.quality, &c_options->thumbnails.quality);
1723 ct_button = pref_checkbox_new_int(group, _("Cache thumbnails"),
1724 options->thumbnails.enable_caching, &c_options->thumbnails.enable_caching);
1726 subgroup = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1727 pref_checkbox_link_sensitivity(ct_button, subgroup);
1729 group_frame = pref_frame_new(subgroup, TRUE, _("Use Geeqie thumbnail style and cache"),
1730 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1731 button = pref_radiobutton_new(group_frame, NULL, get_thumbnails_cache_dir(),
1732 !options->thumbnails.spec_standard,
1733 G_CALLBACK(cache_geeqie_cb), NULL);
1735 group_frame = pref_frame_new(subgroup, TRUE,
1736 _("Store thumbnails local to image folder (non-standard)"),
1737 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1738 pref_radiobutton_new(group_frame, button, "*/.thumbnails",
1739 options->thumbnails.cache_into_dirs,
1740 G_CALLBACK(cache_local_cb), NULL);
1742 group_frame = pref_frame_new(subgroup, TRUE,
1743 _("Use standard thumbnail style and cache, shared with other applications"),
1744 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1745 pref_radiobutton_new(group_frame, button, get_thumbnails_standard_cache_dir(),
1746 options->thumbnails.spec_standard,
1747 G_CALLBACK(cache_standard_cb), NULL);
1749 pref_checkbox_new_int(group, _("Use EXIF thumbnails when available (EXIF thumbnails may be outdated)"),
1750 options->thumbnails.use_exif, &c_options->thumbnails.use_exif);
1752 #ifdef HAVE_FFMPEGTHUMBNAILER_METADATA
1753 pref_checkbox_new_int(group, _("Use embedded metadata in video files as thumbnails when available"),
1754 options->thumbnails.use_ft_metadata, &c_options->thumbnails.use_ft_metadata);
1756 // pref_checkbox_new_int(group, _("Ignore embedded metadata if size is too small"),
1757 // options->thumbnails.use_ft_metadata_small, &c_options->thumbnails.use_ft_metadata_small);
1760 group = pref_group_new(vbox, FALSE, _("Star Rating"), GTK_ORIENTATION_VERTICAL);
1762 c_options->star_rating.star = options->star_rating.star;
1763 c_options->star_rating.rejected = options->star_rating.rejected;
1765 str = g_string_new(NULL);
1766 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1767 pref_label_new(hbox, "Star character: ");
1768 str = g_string_append_unichar(str, options->star_rating.star);
1769 pref_label_new(hbox, g_strdup(str->str));
1770 rating_symbol = g_strdup_printf("U+%X", options->star_rating.star);
1771 star_rating_entry = gtk_entry_new();
1772 gtk_entry_set_text(GTK_ENTRY(star_rating_entry), rating_symbol);
1773 gtk_box_pack_start(GTK_BOX(hbox), star_rating_entry, FALSE, FALSE, 0);
1774 gtk_entry_set_width_chars(GTK_ENTRY(star_rating_entry), 15);
1775 gtk_widget_show(star_rating_entry);
1776 button = pref_button_new(NULL, NULL, _("Set"), FALSE,
1777 G_CALLBACK(star_rating_star_test_cb), hbox);
1778 gtk_widget_set_tooltip_text(button, _("Display selected character"));
1779 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1780 gtk_widget_show(button);
1781 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."));
1782 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1783 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1784 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1785 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1786 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1787 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1788 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1789 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1790 g_signal_connect(GTK_ENTRY(star_rating_entry), "icon-press",
1791 G_CALLBACK(star_rating_star_icon_cb),
1794 g_string_free(str, TRUE);
1795 g_free(rating_symbol);
1797 str = g_string_new(NULL);
1798 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1799 pref_label_new(hbox, "Rejected character: ");
1800 str = g_string_append_unichar(str, options->star_rating.rejected);
1801 pref_label_new(hbox, g_strdup(str->str));
1802 rating_symbol = g_strdup_printf("U+%X", options->star_rating.rejected);
1803 star_rating_entry = gtk_entry_new();
1804 gtk_entry_set_text(GTK_ENTRY(star_rating_entry), rating_symbol);
1805 gtk_box_pack_start(GTK_BOX(hbox), star_rating_entry, FALSE, FALSE, 0);
1806 gtk_entry_set_width_chars(GTK_ENTRY(star_rating_entry), 15);
1807 gtk_widget_show(star_rating_entry);
1808 button = pref_button_new(NULL, NULL, _("Set"), FALSE,
1809 G_CALLBACK(star_rating_rejected_test_cb), hbox);
1810 gtk_widget_set_tooltip_text(button, _("Display selected character"));
1811 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1812 gtk_widget_show(button);
1813 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."));
1814 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1815 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1816 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1817 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1818 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1819 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1820 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1821 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1822 g_signal_connect(GTK_ENTRY(star_rating_entry), "icon-press",
1823 G_CALLBACK(star_rating_rejected_icon_cb),
1826 g_string_free(str, TRUE);
1827 g_free(rating_symbol);
1829 group = pref_group_new(vbox, FALSE, _("Slide show"), GTK_ORIENTATION_VERTICAL);
1831 c_options->slideshow.delay = options->slideshow.delay;
1832 hours = options->slideshow.delay / (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1833 remainder = options->slideshow.delay % (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1834 minutes = remainder / (60 * SLIDESHOW_SUBSECOND_PRECISION);
1835 seconds = (gdouble)(remainder % (60 * SLIDESHOW_SUBSECOND_PRECISION)) /
1836 SLIDESHOW_SUBSECOND_PRECISION;
1838 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1840 spin = pref_spin_new(hbox, _("Delay between image change hrs:mins:secs.dec"), NULL,
1842 options->slideshow.delay ? hours : 0.0,
1843 G_CALLBACK(slideshow_delay_hours_cb), NULL);
1844 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1845 spin = pref_spin_new(hbox, ":" , NULL,
1847 options->slideshow.delay ? minutes: 0.0,
1848 G_CALLBACK(slideshow_delay_minutes_cb), NULL);
1849 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1850 spin = pref_spin_new(hbox, ":", NULL,
1851 SLIDESHOW_MIN_SECONDS, 59, 1.0, 1,
1852 options->slideshow.delay ? seconds : 10.0,
1853 G_CALLBACK(slideshow_delay_seconds_cb), NULL);
1854 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1856 pref_checkbox_new_int(group, _("Random"), options->slideshow.random, &c_options->slideshow.random);
1857 pref_checkbox_new_int(group, _("Repeat"), options->slideshow.repeat, &c_options->slideshow.repeat);
1859 group = pref_group_new(vbox, FALSE, _("Image loading and caching"), GTK_ORIENTATION_VERTICAL);
1861 pref_spin_new_int(group, _("Decoded image cache size (Mb):"), NULL,
1862 0, 99999, 1, options->image.image_cache_max, &c_options->image.image_cache_max);
1863 pref_checkbox_new_int(group, _("Preload next image"),
1864 options->image.enable_read_ahead, &c_options->image.enable_read_ahead);
1866 pref_checkbox_new_int(group, _("Refresh on file change"),
1867 options->update_on_time_change, &c_options->update_on_time_change);
1869 group = pref_group_new(vbox, FALSE, _("Info sidebar heights"), GTK_ORIENTATION_VERTICAL);
1870 pref_label_new(group, _("NOTE! Geeqie must be restarted for changes to take effect"));
1871 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1872 pref_spin_new_int(hbox, _("Keywords:"), NULL,
1874 options->info_keywords.height, &c_options->info_keywords.height);
1875 pref_spin_new_int(hbox, _("Title:"), NULL,
1877 options->info_title.height, &c_options->info_title.height);
1878 pref_spin_new_int(hbox, _("Comment:"), NULL,
1880 options->info_comment.height, &c_options->info_comment.height);
1881 pref_spin_new_int(hbox, _("Rating:"), NULL,
1883 options->info_rating.height, &c_options->info_rating.height);
1885 group = pref_group_new(vbox, FALSE, _("On-line help search engine"), GTK_ORIENTATION_VERTICAL);
1887 help_search_engine_entry = gtk_entry_new();
1888 gtk_entry_set_text(GTK_ENTRY(help_search_engine_entry), options->help_search_engine);
1889 gtk_box_pack_start(GTK_BOX(group), help_search_engine_entry, FALSE, FALSE, 0);
1890 gtk_widget_show(help_search_engine_entry);
1892 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"));
1894 gtk_entry_set_icon_from_stock(GTK_ENTRY(help_search_engine_entry),
1895 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1896 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(help_search_engine_entry),
1897 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1898 gtk_entry_set_icon_from_stock(GTK_ENTRY(help_search_engine_entry),
1899 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1900 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(help_search_engine_entry),
1901 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1902 g_signal_connect(GTK_ENTRY(help_search_engine_entry), "icon-press",
1903 G_CALLBACK(help_search_engine_entry_icon_cb),
1904 help_search_engine_entry);
1908 static void config_tab_image(GtkWidget *notebook)
1913 GtkWidget *ct_button;
1914 GtkWidget *enlargement_button;
1918 vbox = scrolled_notebook_page(notebook, _("Image"));
1920 group = pref_group_new(vbox, FALSE, _("Zoom"), GTK_ORIENTATION_VERTICAL);
1922 table = pref_table_new(group, 2, 1, FALSE, FALSE);
1923 add_quality_menu(table, 0, 0, _("Quality:"), options->image.zoom_quality, &c_options->image.zoom_quality);
1926 pref_checkbox_new_int(group, _("Use GPU acceleration via Clutter library"),
1927 options->image.use_clutter_renderer, &c_options->image.use_clutter_renderer);
1930 pref_checkbox_new_int(group, _("Two pass rendering (apply HQ zoom and color correction in second pass)"),
1931 options->image.zoom_2pass, &c_options->image.zoom_2pass);
1933 c_options->image.zoom_increment = options->image.zoom_increment;
1934 spin = pref_spin_new(group, _("Zoom increment:"), NULL,
1935 0.01, 4.0, 0.01, 2, (gdouble)options->image.zoom_increment / 100.0,
1936 G_CALLBACK(zoom_increment_cb), NULL);
1937 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1939 group = pref_group_new(vbox, FALSE, _("Fit image to window"), GTK_ORIENTATION_VERTICAL);
1941 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1942 enlargement_button = pref_checkbox_new_int(hbox, _("Allow enlargement of image (max. size in %)"),
1943 options->image.zoom_to_fit_allow_expand, &c_options->image.zoom_to_fit_allow_expand);
1944 spin = pref_spin_new_int(hbox, NULL, NULL,
1946 options->image.max_enlargement_size, &c_options->image.max_enlargement_size);
1947 pref_checkbox_link_sensitivity(enlargement_button, spin);
1948 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."));
1950 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1951 ct_button = pref_checkbox_new_int(hbox, _("Virtual window size (% of actual window):"),
1952 options->image.limit_autofit_size, &c_options->image.limit_autofit_size);
1953 spin = pref_spin_new_int(hbox, NULL, NULL,
1955 options->image.max_autofit_size, &c_options->image.max_autofit_size);
1956 pref_checkbox_link_sensitivity(ct_button, spin);
1957 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."));
1959 group = pref_group_new(vbox, FALSE, _("Appearance"), GTK_ORIENTATION_VERTICAL);
1961 pref_checkbox_new_int(group, _("Use custom border color in window mode"),
1962 options->image.use_custom_border_color, &c_options->image.use_custom_border_color);
1964 pref_checkbox_new_int(group, _("Use custom border color in fullscreen mode"),
1965 options->image.use_custom_border_color_in_fullscreen, &c_options->image.use_custom_border_color_in_fullscreen);
1967 pref_color_button_new(group, _("Border color"), &options->image.border_color,
1968 G_CALLBACK(pref_color_button_set_cb), &c_options->image.border_color);
1970 c_options->image.border_color = options->image.border_color;
1972 pref_color_button_new(group, _("Alpha channel color 1"), &options->image.alpha_color_1,
1973 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_1);
1975 pref_color_button_new(group, _("Alpha channel color 2"), &options->image.alpha_color_2,
1976 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_2);
1978 c_options->image.alpha_color_1 = options->image.alpha_color_1;
1979 c_options->image.alpha_color_2 = options->image.alpha_color_2;
1981 group = pref_group_new(vbox, FALSE, _("Convenience"), GTK_ORIENTATION_VERTICAL);
1983 pref_checkbox_new_int(group, _("Auto rotate proofs using Exif information"),
1984 options->image.exif_proof_rotate_enable, &c_options->image.exif_proof_rotate_enable);
1988 static void config_tab_windows(GtkWidget *notebook)
1994 GtkWidget *ct_button;
1996 GtkWidget *image_overlay_template_view;
1997 GtkWidget *scrolled;
1998 GtkTextBuffer *buffer;
2000 vbox = scrolled_notebook_page(notebook, _("Windows"));
2002 group = pref_group_new(vbox, FALSE, _("State"), GTK_ORIENTATION_VERTICAL);
2004 ct_button = pref_checkbox_new_int(group, _("Remember window positions"),
2005 options->save_window_positions, &c_options->save_window_positions);
2007 button = pref_checkbox_new_int(group, _("Use saved window positions also for new windows"),
2008 options->use_saved_window_positions_for_new_windows, &c_options->use_saved_window_positions_for_new_windows);
2009 pref_checkbox_link_sensitivity(ct_button, button);
2011 pref_checkbox_new_int(group, _("Remember tool state (float/hidden)"),
2012 options->tools_restore_state, &c_options->tools_restore_state);
2014 pref_checkbox_new_int(group, _("Remember dialog window positions"),
2015 options->save_dialog_window_positions, &c_options->save_dialog_window_positions);
2017 pref_checkbox_new_int(group, _("Show window IDs"),
2018 options->show_window_ids, &c_options->show_window_ids);
2020 group = pref_group_new(vbox, FALSE, _("Size"), GTK_ORIENTATION_VERTICAL);
2022 pref_checkbox_new_int(group, _("Fit window to image when tools are hidden/floating"),
2023 options->image.fit_window_to_image, &c_options->image.fit_window_to_image);
2025 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2026 ct_button = pref_checkbox_new_int(hbox, _("Limit size when auto-sizing window (%):"),
2027 options->image.limit_window_size, &c_options->image.limit_window_size);
2028 spin = pref_spin_new_int(hbox, NULL, NULL,
2030 options->image.max_window_size, &c_options->image.max_window_size);
2031 pref_checkbox_link_sensitivity(ct_button, spin);
2033 group = pref_group_new(vbox, FALSE, _("Full screen"), GTK_ORIENTATION_VERTICAL);
2035 c_options->fullscreen.screen = options->fullscreen.screen;
2036 c_options->fullscreen.above = options->fullscreen.above;
2037 hbox = fullscreen_prefs_selection_new(_("Location:"), &c_options->fullscreen.screen, &c_options->fullscreen.above);
2038 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2039 gtk_widget_show(hbox);
2041 pref_checkbox_new_int(group, _("Smooth image flip"),
2042 options->fullscreen.clean_flip, &c_options->fullscreen.clean_flip);
2043 pref_checkbox_new_int(group, _("Disable screen saver"),
2044 options->fullscreen.disable_saver, &c_options->fullscreen.disable_saver);
2047 group = pref_group_new(vbox, FALSE, _("Overlay Screen Display"), GTK_ORIENTATION_VERTICAL);
2049 pref_label_new(group, _("Image overlay template"));
2051 scrolled = gtk_scrolled_window_new(NULL, NULL);
2052 gtk_widget_set_size_request(scrolled, 200, 150);
2053 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2054 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
2055 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2056 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 5);
2057 gtk_widget_show(scrolled);
2059 image_overlay_template_view = gtk_text_view_new();
2061 gtk_widget_set_tooltip_markup(image_overlay_template_view,
2062 _("<i>%name%</i> results in the filename of the picture.\n"
2063 "Also available: <i>%collection%</i>, <i>%number%</i>, <i>%total%</i>, <i>%date%</i>,\n"
2064 "<i>%size%</i> (filesize), <i>%width%</i>, <i>%height%</i>, <i>%res%</i> (resolution),\n"
2065 "<i>%rating%</i>, <i>%keywords%</i>, <i>%comment%</i> (XMP), <i>%imagecomment%</i> (JPEG)\n"
2066 "To access exif data use the exif name, e. g. <i>%formatted.Camera%</i> is the formatted camera name,\n"
2067 "<i>%Exif.Photo.DateTimeOriginal%</i> the date of the original shot.\n"
2068 "<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"
2069 "If two or more variables are connected with the |-sign, it prints available variables with a separator.\n"
2070 "<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"
2071 "if there's no ISO information in the Exif data.\n"
2072 "If a line is empty, it is removed. This allows one to add lines that totally disappear when no data is available.\n"
2074 gtk_container_add(GTK_CONTAINER(scrolled), image_overlay_template_view);
2075 gtk_widget_show(image_overlay_template_view);
2077 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2079 #if GTK_CHECK_VERSION(3,4,0)
2080 button = pref_button_new(NULL, GTK_STOCK_SELECT_FONT, _("Font"), FALSE,
2081 G_CALLBACK(image_overlay_set_font_cb), notebook);
2083 button = gtk_font_button_new();
2084 gtk_font_button_set_title(GTK_FONT_BUTTON(button), "Image Overlay Font");
2085 gtk_font_button_set_font_name(GTK_FONT_BUTTON(button), options->image_overlay.font);
2086 g_signal_connect(G_OBJECT(button), "font-set",
2087 G_CALLBACK(image_overlay_set_font_cb),NULL);
2089 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2090 gtk_widget_show(button);
2092 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Text"), FALSE,
2093 G_CALLBACK(image_overlay_set_text_colour_cb), NULL);
2094 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2095 gtk_widget_show(button);
2097 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Background"), FALSE,
2098 G_CALLBACK(image_overlay_set_background_colour_cb), NULL);
2099 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2100 gtk_widget_show(button);
2101 image_overlay_set_text_colours();
2103 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2104 G_CALLBACK(image_overlay_default_template_cb), image_overlay_template_view);
2105 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2106 gtk_widget_show(button);
2108 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
2109 G_CALLBACK(image_overlay_help_cb), NULL);
2110 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2111 gtk_widget_show(button);
2113 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(image_overlay_template_view));
2114 if (options->image_overlay.template_string) gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
2115 g_signal_connect(G_OBJECT(buffer), "changed",
2116 G_CALLBACK(image_overlay_template_view_changed_cb), image_overlay_template_view);
2121 static GtkTreeModel *create_class_model(void)
2123 GtkListStore *model;
2127 /* create list store */
2128 model = gtk_list_store_new(1, G_TYPE_STRING);
2129 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
2131 gtk_list_store_append(model, &iter);
2132 gtk_list_store_set(model, &iter, 0, _(format_class_list[i]), -1);
2134 return GTK_TREE_MODEL (model);
2139 static void config_tab_files(GtkWidget *notebook)
2146 GtkWidget *ct_button;
2147 GtkWidget *scrolled;
2148 GtkWidget *filter_view;
2149 GtkCellRenderer *renderer;
2150 GtkTreeSelection *selection;
2151 GtkTreeViewColumn *column;
2153 vbox = scrolled_notebook_page(notebook, _("Files"));
2155 group = pref_box_new(vbox, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
2157 pref_checkbox_new_int(group, _("Show hidden files or folders"),
2158 options->file_filter.show_hidden_files, &c_options->file_filter.show_hidden_files);
2159 pref_checkbox_new_int(group, _("Show parent folder (..)"),
2160 options->file_filter.show_parent_directory, &c_options->file_filter.show_parent_directory);
2161 pref_checkbox_new_int(group, _("Case sensitive sort"),
2162 options->file_sort.case_sensitive, &c_options->file_sort.case_sensitive);
2163 pref_checkbox_new_int(group, _("Natural sort order"),
2164 options->file_sort.natural, &c_options->file_sort.natural);
2165 pref_checkbox_new_int(group, _("Disable file extension checks"),
2166 options->file_filter.disable_file_extension_checks, &c_options->file_filter.disable_file_extension_checks);
2168 ct_button = pref_checkbox_new_int(group, _("Disable File Filtering"),
2169 options->file_filter.disable, &c_options->file_filter.disable);
2172 group = pref_group_new(vbox, FALSE, _("Grouping sidecar extensions"), GTK_ORIENTATION_VERTICAL);
2174 sidecar_ext_entry = gtk_entry_new();
2175 gtk_entry_set_text(GTK_ENTRY(sidecar_ext_entry), options->sidecar.ext);
2176 gtk_box_pack_start(GTK_BOX(group), sidecar_ext_entry, FALSE, FALSE, 0);
2177 gtk_widget_show(sidecar_ext_entry);
2179 group = pref_group_new(vbox, TRUE, _("File types"), GTK_ORIENTATION_VERTICAL);
2181 frame = pref_group_parent(group);
2182 g_signal_connect(G_OBJECT(ct_button), "toggled",
2183 G_CALLBACK(filter_disable_cb), frame);
2184 gtk_widget_set_sensitive(frame, !options->file_filter.disable);
2186 scrolled = gtk_scrolled_window_new(NULL, NULL);
2187 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2188 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2189 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2190 gtk_widget_show(scrolled);
2192 filter_store = gtk_list_store_new(1, G_TYPE_POINTER);
2193 filter_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(filter_store));
2194 g_object_unref(filter_store);
2195 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
2196 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_SINGLE);
2198 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(filter_view), FALSE);
2200 column = gtk_tree_view_column_new();
2201 gtk_tree_view_column_set_title(column, _("Filter"));
2202 gtk_tree_view_column_set_resizable(column, TRUE);
2204 renderer = gtk_cell_renderer_toggle_new();
2205 g_signal_connect(G_OBJECT(renderer), "toggled",
2206 G_CALLBACK(filter_store_enable_cb), filter_store);
2207 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2208 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2209 GINT_TO_POINTER(FE_ENABLE), NULL);
2211 renderer = gtk_cell_renderer_text_new();
2212 g_signal_connect(G_OBJECT(renderer), "edited",
2213 G_CALLBACK(filter_store_ext_edit_cb), filter_store);
2214 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2215 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2216 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2217 GINT_TO_POINTER(FE_EXTENSION), NULL);
2218 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2220 column = gtk_tree_view_column_new();
2221 gtk_tree_view_column_set_title(column, _("Description"));
2222 gtk_tree_view_column_set_resizable(column, TRUE);
2223 gtk_tree_view_column_set_fixed_width(column, 200);
2224 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
2226 renderer = gtk_cell_renderer_text_new();
2227 g_signal_connect(G_OBJECT(renderer), "edited",
2228 G_CALLBACK(filter_store_desc_edit_cb), filter_store);
2229 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2230 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2231 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2232 GINT_TO_POINTER(FE_DESCRIPTION), NULL);
2233 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2235 column = gtk_tree_view_column_new();
2236 gtk_tree_view_column_set_title(column, _("Class"));
2237 gtk_tree_view_column_set_resizable(column, TRUE);
2238 renderer = gtk_cell_renderer_combo_new();
2239 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE,
2240 "model", create_class_model(),
2245 g_signal_connect(G_OBJECT(renderer), "edited",
2246 G_CALLBACK(filter_store_class_edit_cb), filter_store);
2247 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2248 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2249 GINT_TO_POINTER(FE_CLASS), NULL);
2250 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2252 column = gtk_tree_view_column_new();
2253 gtk_tree_view_column_set_title(column, _("Writable"));
2254 gtk_tree_view_column_set_resizable(column, FALSE);
2255 renderer = gtk_cell_renderer_toggle_new();
2256 g_signal_connect(G_OBJECT(renderer), "toggled",
2257 G_CALLBACK(filter_store_writable_cb), filter_store);
2258 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2259 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2260 GINT_TO_POINTER(FE_WRITABLE), NULL);
2261 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2263 column = gtk_tree_view_column_new();
2264 gtk_tree_view_column_set_title(column, _("Sidecar is allowed"));
2265 gtk_tree_view_column_set_resizable(column, FALSE);
2266 renderer = gtk_cell_renderer_toggle_new();
2267 g_signal_connect(G_OBJECT(renderer), "toggled",
2268 G_CALLBACK(filter_store_sidecar_cb), filter_store);
2269 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2270 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2271 GINT_TO_POINTER(FE_ALLOW_SIDECAR), NULL);
2272 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2275 filter_store_populate();
2276 gtk_container_add(GTK_CONTAINER(scrolled), filter_view);
2277 gtk_widget_show(filter_view);
2279 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2281 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2282 G_CALLBACK(filter_default_cb), filter_view);
2283 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2284 gtk_widget_show(button);
2286 button = pref_button_new(NULL, GTK_STOCK_REMOVE, NULL, FALSE,
2287 G_CALLBACK(filter_remove_cb), filter_view);
2288 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2289 gtk_widget_show(button);
2291 button = pref_button_new(NULL, GTK_STOCK_ADD, NULL, FALSE,
2292 G_CALLBACK(filter_add_cb), filter_view);
2293 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2294 gtk_widget_show(button);
2298 static void config_tab_metadata(GtkWidget *notebook)
2303 GtkWidget *ct_button;
2307 vbox = scrolled_notebook_page(notebook, _("Metadata"));
2310 group = pref_group_new(vbox, FALSE, _("Metadata writing process"), GTK_ORIENTATION_VERTICAL);
2312 label = pref_label_new(group, _("Warning: Geeqie is built without Exiv2. Some options are disabled."));
2314 label = pref_label_new(group, _("Metadata are written in the following order. The process ends after first success."));
2315 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2317 ct_button = pref_checkbox_new_int(group, _("1) Save metadata in image files, or sidecar files, according to the XMP standard"),
2318 options->metadata.save_in_image_file, &c_options->metadata.save_in_image_file);
2320 gtk_widget_set_sensitive(ct_button, FALSE);
2323 pref_checkbox_new_int(group, _("2) Save metadata in '.metadata' folder, local to image folder (non-standard)"),
2324 options->metadata.enable_metadata_dirs, &c_options->metadata.enable_metadata_dirs);
2326 text = g_strdup_printf(_("3) Save metadata in Geeqie private directory '%s'"), get_metadata_cache_dir());
2327 label = pref_label_new(group, text);
2328 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2329 gtk_misc_set_padding(GTK_MISC(label), 22, 0);
2332 group = pref_group_new(vbox, FALSE, _("Step 1: Write to image files"), GTK_ORIENTATION_VERTICAL);
2334 gtk_widget_set_sensitive(group, FALSE);
2337 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2338 pref_checkbox_link_sensitivity(ct_button, hbox);
2340 pref_checkbox_new_int(hbox, _("Store metadata also in legacy IPTC tags (converted according to IPTC4XMP standard)"),
2341 options->metadata.save_legacy_IPTC, &c_options->metadata.save_legacy_IPTC);
2343 pref_checkbox_new_int(hbox, _("Warn if the image files are unwritable"),
2344 options->metadata.warn_on_write_problems, &c_options->metadata.warn_on_write_problems);
2346 pref_checkbox_new_int(hbox, _("Ask before writing to image files"),
2347 options->metadata.confirm_write, &c_options->metadata.confirm_write);
2349 pref_checkbox_new_int(hbox, _("Create sidecar files named image.ext.xmp (as opposed to image.xmp)"),
2350 options->metadata.sidecar_extended_name, &c_options->metadata.sidecar_extended_name);
2352 group = pref_group_new(vbox, FALSE, _("Step 2 and 3: write to Geeqie private files"), GTK_ORIENTATION_VERTICAL);
2354 gtk_widget_set_sensitive(group, FALSE);
2357 pref_checkbox_new_int(group, _("Use GQview legacy metadata format (supports only keywords and comments) instead of XMP"),
2358 options->metadata.save_legacy_format, &c_options->metadata.save_legacy_format);
2361 group = pref_group_new(vbox, FALSE, _("Miscellaneous"), GTK_ORIENTATION_VERTICAL);
2362 pref_checkbox_new_int(group, _("Write the same description tags (keywords, comment, etc.) to all grouped sidecars"),
2363 options->metadata.sync_grouped_files, &c_options->metadata.sync_grouped_files);
2365 pref_checkbox_new_int(group, _("Allow keywords to differ only in case"),
2366 options->metadata.keywords_case_sensitive, &c_options->metadata.keywords_case_sensitive);
2368 ct_button = pref_checkbox_new_int(group, _("Write altered image orientation to the metadata"),
2369 options->metadata.write_orientation, &c_options->metadata.write_orientation);
2371 gtk_widget_set_sensitive(ct_button, FALSE);
2374 group = pref_group_new(vbox, FALSE, _("Auto-save options"), GTK_ORIENTATION_VERTICAL);
2376 ct_button = pref_checkbox_new_int(group, _("Write metadata after timeout"),
2377 options->metadata.confirm_after_timeout, &c_options->metadata.confirm_after_timeout);
2379 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2380 pref_checkbox_link_sensitivity(ct_button, hbox);
2382 pref_spin_new_int(hbox, _("Timeout (seconds):"), NULL, 0, 900, 1,
2383 options->metadata.confirm_timeout, &c_options->metadata.confirm_timeout);
2385 pref_checkbox_new_int(group, _("Write metadata on image change"),
2386 options->metadata.confirm_on_image_change, &c_options->metadata.confirm_on_image_change);
2388 pref_checkbox_new_int(group, _("Write metadata on directory change"),
2389 options->metadata.confirm_on_dir_change, &c_options->metadata.confirm_on_dir_change);
2391 group = pref_group_new(vbox, FALSE, _("Pre-load metadata"), GTK_ORIENTATION_VERTICAL);
2393 ct_button = pref_checkbox_new_int(group, _("Read metadata in background"),
2394 options->read_metadata_in_idle, &c_options->read_metadata_in_idle);
2395 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");
2400 static void intent_menu_cb(GtkWidget *combo, gpointer data)
2402 gint *option = data;
2404 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
2408 *option = INTENT_PERCEPTUAL;
2411 *option = INTENT_RELATIVE_COLORIMETRIC;
2414 *option = INTENT_SATURATION;
2417 *option = INTENT_ABSOLUTE_COLORIMETRIC;
2422 static void add_intent_menu(GtkWidget *table, gint column, gint row, const gchar *text,
2423 gint option, gint *option_c)
2430 pref_table_label(table, column, row, text, 0.0);
2432 combo = gtk_combo_box_text_new();
2434 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Perceptual"));
2435 if (option == INTENT_PERCEPTUAL) current = 0;
2436 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Relative Colorimetric"));
2437 if (option == INTENT_RELATIVE_COLORIMETRIC) current = 1;
2438 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Saturation"));
2439 if (option == INTENT_SATURATION) current = 2;
2440 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Absolute Colorimetric"));
2441 if (option == INTENT_ABSOLUTE_COLORIMETRIC) current = 3;
2443 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
2445 gtk_widget_set_tooltip_text(combo,"Refer to the lcms documentation for the defaults used when the selected Intent is not available");
2447 g_signal_connect(G_OBJECT(combo), "changed",
2448 G_CALLBACK(intent_menu_cb), option_c);
2450 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
2451 GTK_EXPAND | GTK_FILL, 0, 0, 0);
2452 gtk_widget_show(combo);
2456 static void config_tab_color(GtkWidget *notebook)
2465 vbox = scrolled_notebook_page(notebook, _("Color management"));
2467 group = pref_group_new(vbox, FALSE, _("Input profiles"), GTK_ORIENTATION_VERTICAL);
2469 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
2472 table = pref_table_new(group, 3, COLOR_PROFILE_INPUTS + 1, FALSE, FALSE);
2473 gtk_table_set_col_spacings(GTK_TABLE(table), PREF_PAD_GAP);
2475 label = pref_table_label(table, 0, 0, _("Type"), 0.0);
2476 pref_label_bold(label, TRUE, FALSE);
2478 label = pref_table_label(table, 1, 0, _("Menu name"), 0.0);
2479 pref_label_bold(label, TRUE, FALSE);
2481 label = pref_table_label(table, 2, 0, _("File"), 0.0);
2482 pref_label_bold(label, TRUE, FALSE);
2484 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
2489 buf = g_strdup_printf(_("Input %d:"), i + COLOR_PROFILE_FILE);
2490 pref_table_label(table, 0, i + 1, buf, 1.0);
2493 entry = gtk_entry_new();
2494 gtk_entry_set_max_length(GTK_ENTRY(entry), EDITOR_NAME_MAX_LENGTH);
2495 if (options->color_profile.input_name[i])
2497 gtk_entry_set_text(GTK_ENTRY(entry), options->color_profile.input_name[i]);
2499 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, i + 1, i + 2,
2500 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2501 gtk_widget_show(entry);
2502 color_profile_input_name_entry[i] = entry;
2504 tabcomp = tab_completion_new(&entry, options->color_profile.input_file[i], NULL, ".icc", "ICC Files", NULL);
2505 tab_completion_add_select_button(entry, _("Select color profile"), FALSE);
2506 gtk_widget_set_size_request(entry, 160, -1);
2507 gtk_table_attach(GTK_TABLE(table), tabcomp, 2, 3, i + 1, i + 2,
2508 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2509 gtk_widget_show(tabcomp);
2510 color_profile_input_file_entry[i] = entry;
2513 group = pref_group_new(vbox, FALSE, _("Screen profile"), GTK_ORIENTATION_VERTICAL);
2515 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
2517 pref_checkbox_new_int(group, _("Use system screen profile if available"),
2518 options->color_profile.use_x11_screen_profile, &c_options->color_profile.use_x11_screen_profile);
2520 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2522 pref_table_label(table, 0, 0, _("Screen:"), 1.0);
2523 tabcomp = tab_completion_new(&color_profile_screen_file_entry,
2524 options->color_profile.screen_file, NULL, ".icc", "ICC Files", NULL);
2525 tab_completion_add_select_button(color_profile_screen_file_entry, _("Select color profile"), FALSE);
2526 gtk_widget_set_size_request(color_profile_screen_file_entry, 160, -1);
2528 add_intent_menu(table, 0, 1, _("Render Intent:"), options->color_profile.render_intent, &c_options->color_profile.render_intent);
2530 gtk_table_attach(GTK_TABLE(table), tabcomp, 1, 2,
2532 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2534 gtk_widget_show(tabcomp);
2537 /* advanced entry tab */
2538 static void config_tab_behavior(GtkWidget *notebook)
2545 GtkWidget *ct_button;
2549 GtkWidget *with_rename;
2550 GtkWidget *collections_on_top;
2552 vbox = scrolled_notebook_page(notebook, _("Behavior"));
2554 group = pref_group_new(vbox, FALSE, _("Delete"), GTK_ORIENTATION_VERTICAL);
2556 pref_checkbox_new_int(group, _("Confirm file delete"),
2557 options->file_ops.confirm_delete, &c_options->file_ops.confirm_delete);
2558 pref_checkbox_new_int(group, _("Enable Delete key"),
2559 options->file_ops.enable_delete_key, &c_options->file_ops.enable_delete_key);
2561 ct_button = pref_checkbox_new_int(group, _("Safe delete"),
2562 options->file_ops.safe_delete_enable, &c_options->file_ops.safe_delete_enable);
2564 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2565 pref_checkbox_link_sensitivity(ct_button, hbox);
2567 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_SPACE);
2568 pref_label_new(hbox, _("Folder:"));
2570 tabcomp = tab_completion_new(&safe_delete_path_entry, options->file_ops.safe_delete_path, NULL, NULL, NULL, NULL);
2571 tab_completion_add_select_button(safe_delete_path_entry, NULL, TRUE);
2572 gtk_box_pack_start(GTK_BOX(hbox), tabcomp, TRUE, TRUE, 0);
2573 gtk_widget_show(tabcomp);
2575 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2576 pref_checkbox_link_sensitivity(ct_button, hbox);
2578 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_GAP);
2579 spin = pref_spin_new_int(hbox, _("Maximum size:"), _("MB"),
2580 0, 2048, 1, options->file_ops.safe_delete_folder_maxsize, &c_options->file_ops.safe_delete_folder_maxsize);
2581 gtk_widget_set_tooltip_markup(spin, _("Set to 0 for unlimited size"));
2582 button = pref_button_new(NULL, NULL, _("View"), FALSE,
2583 G_CALLBACK(safe_delete_view_cb), NULL);
2584 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2585 gtk_widget_show(button);
2587 button = pref_button_new(NULL, GTK_STOCK_CLEAR, NULL, FALSE,
2588 G_CALLBACK(safe_delete_clear_cb), NULL);
2589 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2590 gtk_widget_show(button);
2593 group = pref_group_new(vbox, FALSE, _("Behavior"), GTK_ORIENTATION_VERTICAL);
2595 pref_checkbox_new_int(group, _("Descend folders in tree view"),
2596 options->tree_descend_subdirs, &c_options->tree_descend_subdirs);
2598 pref_checkbox_new_int(group, _("In place renaming"),
2599 options->file_ops.enable_in_place_rename, &c_options->file_ops.enable_in_place_rename);
2601 pref_checkbox_new_int(group, _("List directory view uses single click to enter"),
2602 options->view_dir_list_single_click_enter, &c_options->view_dir_list_single_click_enter);
2604 marks = pref_checkbox_new_int(group, _("Save marks on exit"),
2605 options->marks_save, &c_options->marks_save);
2606 gtk_widget_set_tooltip_text(marks,"Note that marks linked to a keyword will be saved irrespective of this setting");
2608 with_rename = pref_checkbox_new_int(group, _("Use \"With Rename\" as default for Copy/Move dialogs"),
2609 options->with_rename, &c_options->with_rename);
2610 gtk_widget_set_tooltip_text(with_rename,"Change the default button for Copy/Move dialogs");
2612 collections_on_top = pref_checkbox_new_int(group, _("Open collections on top"),
2613 options->collections_on_top, &c_options->collections_on_top);
2614 gtk_widget_set_tooltip_text(collections_on_top,"Open collections window on top");
2616 pref_spin_new_int(group, _("Recent folder list maximum size"), NULL,
2617 1, 50, 1, options->open_recent_list_maxsize, &c_options->open_recent_list_maxsize);
2619 pref_spin_new_int(group, _("Drag'n drop icon size"), NULL,
2620 16, 256, 16, options->dnd_icon_size, &c_options->dnd_icon_size);
2622 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2623 add_clipboard_selection_menu(table, 0, 0, _("Copy path clipboard selection:"), options->clipboard_selection, &c_options->clipboard_selection);
2625 group = pref_group_new(vbox, FALSE, _("Navigation"), GTK_ORIENTATION_VERTICAL);
2627 pref_checkbox_new_int(group, _("Progressive keyboard scrolling"),
2628 options->progressive_key_scrolling, &c_options->progressive_key_scrolling);
2629 pref_spin_new_int(group, _("Keyboard scrolling step multiplier:"), NULL,
2630 1, 32, 1, options->keyboard_scroll_step, (int *)&c_options->keyboard_scroll_step);
2631 pref_checkbox_new_int(group, _("Mouse wheel scrolls image"),
2632 options->mousewheel_scrolls, &c_options->mousewheel_scrolls);
2633 pref_checkbox_new_int(group, _("Navigation by left or middle click on image"),
2634 options->image_lm_click_nav, &c_options->image_lm_click_nav);
2635 pref_checkbox_new_int(group, _("Play video by left click on image"),
2636 options->image_l_click_video, &c_options->image_l_click_video);
2637 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2638 add_video_menu(table, 0, 0, _("Play with:"), options->image_l_click_video_editor, &c_options->image_l_click_video_editor);
2642 group = pref_group_new(vbox, FALSE, _("Debugging"), GTK_ORIENTATION_VERTICAL);
2644 pref_spin_new_int(group, _("Debug level:"), NULL,
2645 DEBUG_LEVEL_MIN, DEBUG_LEVEL_MAX, 1, get_debug_level(), &debug_c);
2647 pref_checkbox_new_int(group, _("Timer data"),
2648 options->log_window.timer_data, &c_options->log_window.timer_data);
2650 pref_spin_new_int(group, _("Log Window max. lines:"), NULL,
2651 1, 99999, 1, options->log_window_lines, &options->log_window_lines);
2655 /* accelerators tab */
2656 static void config_tab_accelerators(GtkWidget *notebook)
2662 GtkWidget *scrolled;
2663 GtkWidget *accel_view;
2664 GtkCellRenderer *renderer;
2665 GtkTreeSelection *selection;
2666 GtkTreeViewColumn *column;
2668 vbox = scrolled_notebook_page(notebook, _("Keyboard"));
2670 group = pref_group_new(vbox, TRUE, _("Accelerators"), GTK_ORIENTATION_VERTICAL);
2672 scrolled = gtk_scrolled_window_new(NULL, NULL);
2673 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2674 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2675 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2676 gtk_widget_show(scrolled);
2678 accel_store = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
2680 accel_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(accel_store));
2681 g_object_unref(accel_store);
2682 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(accel_view));
2683 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_MULTIPLE);
2685 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(accel_view), FALSE);
2687 renderer = gtk_cell_renderer_text_new();
2689 column = gtk_tree_view_column_new_with_attributes(_("Action"),
2694 gtk_tree_view_column_set_sort_column_id(column, AE_ACTION);
2695 gtk_tree_view_column_set_resizable(column, TRUE);
2696 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2699 renderer = gtk_cell_renderer_accel_new();
2700 g_signal_connect(G_OBJECT(renderer), "accel-cleared",
2701 G_CALLBACK(accel_store_cleared_cb), accel_store);
2702 g_signal_connect(G_OBJECT(renderer), "accel-edited",
2703 G_CALLBACK(accel_store_edited_cb), accel_store);
2706 g_object_set (renderer,
2708 "accel-mode", GTK_CELL_RENDERER_ACCEL_MODE_OTHER,
2711 column = gtk_tree_view_column_new_with_attributes(_("KEY"),
2716 gtk_tree_view_column_set_sort_column_id(column, AE_KEY);
2717 gtk_tree_view_column_set_resizable(column, TRUE);
2718 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2720 renderer = gtk_cell_renderer_text_new();
2722 column = gtk_tree_view_column_new_with_attributes(_("Tooltip"),
2727 gtk_tree_view_column_set_sort_column_id(column, AE_TOOLTIP);
2728 gtk_tree_view_column_set_resizable(column, TRUE);
2729 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2731 renderer = gtk_cell_renderer_text_new();
2733 column = gtk_tree_view_column_new_with_attributes("Accel",
2738 gtk_tree_view_column_set_sort_column_id(column, AE_ACCEL);
2739 gtk_tree_view_column_set_resizable(column, TRUE);
2740 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2742 accel_store_populate();
2743 gtk_container_add(GTK_CONTAINER(scrolled), accel_view);
2744 gtk_widget_show(accel_view);
2746 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2748 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2749 G_CALLBACK(accel_default_cb), accel_view);
2750 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2751 gtk_widget_show(button);
2753 button = pref_button_new(NULL, NULL, _("Reset selected"), FALSE,
2754 G_CALLBACK(accel_reset_cb), accel_view);
2755 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2756 gtk_widget_show(button);
2760 static void config_tab_toolbar(GtkWidget *notebook)
2763 GtkWidget *toolbardata;
2766 lw = layout_window_list->data;
2768 vbox = scrolled_notebook_page(notebook, _("Toolbar"));
2770 toolbardata = toolbar_select_new(lw);
2771 gtk_box_pack_start(GTK_BOX(vbox), toolbardata, TRUE, TRUE, 0);
2772 gtk_widget_show(vbox);
2776 static void config_tab_stereo(GtkWidget *notebook)
2784 GtkWidget *fs_button;
2785 vbox = scrolled_notebook_page(notebook, _("Stereo"));
2787 group = pref_group_new(vbox, FALSE, _("Windowed stereo mode"), GTK_ORIENTATION_VERTICAL);
2789 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2790 add_stereo_mode_menu(table, 0, 0, _("Windowed stereo mode"), options->stereo.mode, &c_options->stereo.mode, FALSE);
2792 table = pref_table_new(group, 2, 2, TRUE, FALSE);
2793 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2794 pref_checkbox_new_int(box, _("Mirror left image"),
2795 options->stereo.mode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.mirror_left);
2796 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2797 pref_checkbox_new_int(box, _("Flip left image"),
2798 options->stereo.mode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.flip_left);
2799 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2800 pref_checkbox_new_int(box, _("Mirror right image"),
2801 options->stereo.mode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.mirror_right);
2802 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2803 pref_checkbox_new_int(box, _("Flip right image"),
2804 options->stereo.mode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.flip_right);
2805 pref_checkbox_new_int(group, _("Swap left and right images"),
2806 options->stereo.mode & PR_STEREO_SWAP, &c_options->stereo.tmp.swap);
2807 pref_checkbox_new_int(group, _("Disable stereo mode on single image source"),
2808 options->stereo.mode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.temp_disable);
2810 group = pref_group_new(vbox, FALSE, _("Fullscreen stereo mode"), GTK_ORIENTATION_VERTICAL);
2811 fs_button = pref_checkbox_new_int(group, _("Use different settings for fullscreen"),
2812 options->stereo.enable_fsmode, &c_options->stereo.enable_fsmode);
2813 box2 = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2814 pref_checkbox_link_sensitivity(fs_button, box2);
2815 table = pref_table_new(box2, 2, 1, FALSE, FALSE);
2816 add_stereo_mode_menu(table, 0, 0, _("Fullscreen stereo mode"), options->stereo.fsmode, &c_options->stereo.fsmode, TRUE);
2817 table = pref_table_new(box2, 2, 2, TRUE, FALSE);
2818 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2819 pref_checkbox_new_int(box, _("Mirror left image"),
2820 options->stereo.fsmode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.fs_mirror_left);
2821 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2822 pref_checkbox_new_int(box, _("Flip left image"),
2823 options->stereo.fsmode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.fs_flip_left);
2824 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2825 pref_checkbox_new_int(box, _("Mirror right image"),
2826 options->stereo.fsmode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.fs_mirror_right);
2827 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2828 pref_checkbox_new_int(box, _("Flip right image"),
2829 options->stereo.fsmode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.fs_flip_right);
2830 pref_checkbox_new_int(box2, _("Swap left and right images"),
2831 options->stereo.fsmode & PR_STEREO_SWAP, &c_options->stereo.tmp.fs_swap);
2832 pref_checkbox_new_int(box2, _("Disable stereo mode on single image source"),
2833 options->stereo.fsmode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.fs_temp_disable);
2835 group2 = pref_group_new(box2, FALSE, _("Fixed position"), GTK_ORIENTATION_VERTICAL);
2836 table = pref_table_new(group2, 5, 3, FALSE, FALSE);
2837 pref_table_spin_new_int(table, 0, 0, _("Width"), NULL,
2838 1, 5000, 1, options->stereo.fixed_w, &c_options->stereo.fixed_w);
2839 pref_table_spin_new_int(table, 3, 0, _("Height"), NULL,
2840 1, 5000, 1, options->stereo.fixed_h, &c_options->stereo.fixed_h);
2841 pref_table_spin_new_int(table, 0, 1, _("Left X"), NULL,
2842 0, 5000, 1, options->stereo.fixed_x1, &c_options->stereo.fixed_x1);
2843 pref_table_spin_new_int(table, 3, 1, _("Left Y"), NULL,
2844 0, 5000, 1, options->stereo.fixed_y1, &c_options->stereo.fixed_y1);
2845 pref_table_spin_new_int(table, 0, 2, _("Right X"), NULL,
2846 0, 5000, 1, options->stereo.fixed_x2, &c_options->stereo.fixed_x2);
2847 pref_table_spin_new_int(table, 3, 2, _("Right Y"), NULL,
2848 0, 5000, 1, options->stereo.fixed_y2, &c_options->stereo.fixed_y2);
2852 /* Main preferences window */
2853 static void config_window_create(void)
2855 GtkWidget *win_vbox;
2857 GtkWidget *notebook;
2859 GtkWidget *ct_button;
2861 if (!c_options) c_options = init_options(NULL);
2863 configwindow = window_new(GTK_WINDOW_TOPLEVEL, "preferences", PIXBUF_INLINE_ICON_CONFIG, NULL, _("Preferences"));
2864 gtk_window_set_type_hint(GTK_WINDOW(configwindow), GDK_WINDOW_TYPE_HINT_DIALOG);
2865 g_signal_connect(G_OBJECT(configwindow), "delete_event",
2866 G_CALLBACK(config_window_delete), NULL);
2867 gtk_window_set_default_size(GTK_WINDOW(configwindow), CONFIG_WINDOW_DEF_WIDTH, CONFIG_WINDOW_DEF_HEIGHT);
2868 gtk_window_set_resizable(GTK_WINDOW(configwindow), TRUE);
2869 gtk_container_set_border_width(GTK_CONTAINER(configwindow), PREF_PAD_BORDER);
2871 win_vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE);
2872 gtk_container_add(GTK_CONTAINER(configwindow), win_vbox);
2873 gtk_widget_show(win_vbox);
2875 notebook = gtk_notebook_new();
2876 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
2877 gtk_box_pack_start(GTK_BOX(win_vbox), notebook, TRUE, TRUE, 0);
2879 config_tab_general(notebook);
2880 config_tab_image(notebook);
2881 config_tab_windows(notebook);
2882 config_tab_accelerators(notebook);
2883 config_tab_files(notebook);
2884 config_tab_metadata(notebook);
2885 config_tab_color(notebook);
2886 config_tab_stereo(notebook);
2887 config_tab_behavior(notebook);
2888 config_tab_toolbar(notebook);
2890 hbox = gtk_hbutton_box_new();
2891 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
2892 gtk_box_set_spacing(GTK_BOX(hbox), PREF_PAD_BUTTON_GAP);
2893 gtk_box_pack_end(GTK_BOX(win_vbox), hbox, FALSE, FALSE, 0);
2894 gtk_widget_show(hbox);
2896 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
2897 G_CALLBACK(config_window_help_cb), notebook);
2898 gtk_container_add(GTK_CONTAINER(hbox), button);
2899 gtk_widget_set_can_default(button, TRUE);
2900 gtk_widget_show(button);
2902 button = pref_button_new(NULL, GTK_STOCK_OK, NULL, FALSE,
2903 G_CALLBACK(config_window_ok_cb), NULL);
2904 gtk_container_add(GTK_CONTAINER(hbox), button);
2905 gtk_widget_set_can_default(button, TRUE);
2906 gtk_widget_grab_default(button);
2907 gtk_widget_show(button);
2911 button = pref_button_new(NULL, GTK_STOCK_SAVE, NULL, FALSE,
2912 G_CALLBACK(config_window_save_cb), NULL);
2913 gtk_container_add(GTK_CONTAINER(hbox), button);
2914 gtk_widget_set_can_default(button, TRUE);
2915 gtk_widget_show(button);
2917 button = pref_button_new(NULL, GTK_STOCK_APPLY, NULL, FALSE,
2918 G_CALLBACK(config_window_apply_cb), NULL);
2919 gtk_container_add(GTK_CONTAINER(hbox), button);
2920 gtk_widget_set_can_default(button, TRUE);
2921 gtk_widget_show(button);
2923 button = pref_button_new(NULL, GTK_STOCK_CANCEL, NULL, FALSE,
2924 G_CALLBACK(config_window_close_cb), NULL);
2925 gtk_container_add(GTK_CONTAINER(hbox), button);
2926 gtk_widget_set_can_default(button, TRUE);
2927 gtk_widget_show(button);
2929 if (!generic_dialog_get_alternative_button_order(configwindow))
2931 gtk_box_reorder_child(GTK_BOX(hbox), ct_button, -1);
2934 gtk_widget_show(notebook);
2936 gtk_widget_show(configwindow);
2940 *-----------------------------------------------------------------------------
2941 * config window show (public)
2942 *-----------------------------------------------------------------------------
2945 void show_config_window(void)
2949 gtk_window_present(GTK_WINDOW(configwindow));
2953 config_window_create();
2962 void show_about_window(LayoutWindow *lw)
2964 GdkPixbuf *pixbuf_logo;
2965 GdkPixbuf *pixbuf_icon;
2966 gchar *authors[1000];
2974 #define LINE_LENGTH 1000
2975 gchar line[LINE_LENGTH];
2977 copyright = g_string_new(NULL);
2978 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");
2980 zd_path = g_build_filename(GQ_BIN_DIR, TIMEZONE_DATABASE, NULL);
2981 cd = ZDOpenDatabase(zd_path);
2984 copyright = g_string_append(copyright, ZDGetNotice(cd));
2986 ZDCloseDatabase(cd);
2990 path = g_build_filename(GQ_HELPDIR, "AUTHORS", NULL);
2991 fp = fopen(path, "r");
2994 while(fgets(line, LINE_LENGTH, fp))
2996 /* get rid of ending \n from fgets */
2997 line[strlen(line) - 1] = '\0';
2998 authors[i_authors] = g_strdup(line);
3001 authors[i_authors] = NULL;
3006 comment = g_strconcat("Development and bug reports:\n", GQ_EMAIL_ADDRESS,
3007 "\nhttps://github.com/BestImageViewer/geeqie/issues",NULL);
3009 pixbuf_logo = pixbuf_inline(PIXBUF_INLINE_LOGO);
3010 pixbuf_icon = pixbuf_inline(PIXBUF_INLINE_ICON);
3011 gtk_show_about_dialog(GTK_WINDOW(lw->window),
3012 "title", _("About Geeqie"),
3014 "program-name", GQ_APPNAME,
3016 "logo", pixbuf_logo,
3017 "icon", pixbuf_icon,
3018 "website", GQ_WEBSITE,
3019 "website-label", "Website",
3020 "comments", comment,
3022 "translator-credits", _("translator-credits"),
3023 "wrap-license", TRUE,
3024 "license", copyright->str,
3027 g_string_free(copyright, TRUE);
3030 while(n < i_authors)
3040 static void image_overlay_set_text_colours()
3042 c_options->image_overlay.text_red = options->image_overlay.text_red;
3043 c_options->image_overlay.text_green = options->image_overlay.text_green;
3044 c_options->image_overlay.text_blue = options->image_overlay.text_blue;
3045 c_options->image_overlay.text_alpha = options->image_overlay.text_alpha;
3046 c_options->image_overlay.background_red = options->image_overlay.background_red;
3047 c_options->image_overlay.background_green = options->image_overlay.background_green;
3048 c_options->image_overlay.background_blue = options->image_overlay.background_blue;
3049 c_options->image_overlay.background_alpha = options->image_overlay.background_alpha;
3051 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */