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.collection_preview = c_options->thumbnails.collection_preview;
291 options->thumbnails.use_ft_metadata = c_options->thumbnails.use_ft_metadata;
292 // options->thumbnails.use_ft_metadata_small = c_options->thumbnails.use_ft_metadata_small;
293 options->thumbnails.spec_standard = c_options->thumbnails.spec_standard;
294 options->metadata.enable_metadata_dirs = c_options->metadata.enable_metadata_dirs;
295 options->file_filter.show_hidden_files = c_options->file_filter.show_hidden_files;
296 options->file_filter.show_parent_directory = c_options->file_filter.show_parent_directory;
297 options->file_filter.show_dot_directory = c_options->file_filter.show_dot_directory;
298 options->file_filter.disable_file_extension_checks = c_options->file_filter.disable_file_extension_checks;
300 options->file_sort.case_sensitive = c_options->file_sort.case_sensitive;
301 options->file_sort.natural = c_options->file_sort.natural;
302 options->file_filter.disable = c_options->file_filter.disable;
304 config_entry_to_option(sidecar_ext_entry, &options->sidecar.ext, NULL);
305 sidecar_ext_parse(options->sidecar.ext);
307 options->slideshow.random = c_options->slideshow.random;
308 options->slideshow.repeat = c_options->slideshow.repeat;
309 options->slideshow.delay = c_options->slideshow.delay;
311 options->mousewheel_scrolls = c_options->mousewheel_scrolls;
312 options->image_lm_click_nav = c_options->image_lm_click_nav;
313 options->image_l_click_video = c_options->image_l_click_video;
314 options->image_l_click_video_editor = c_options->image_l_click_video_editor;
316 options->file_ops.enable_in_place_rename = c_options->file_ops.enable_in_place_rename;
318 options->image.tile_cache_max = c_options->image.tile_cache_max;
319 options->image.image_cache_max = c_options->image.image_cache_max;
321 options->image.zoom_quality = c_options->image.zoom_quality;
323 options->image.zoom_increment = c_options->image.zoom_increment;
325 options->image.enable_read_ahead = c_options->image.enable_read_ahead;
328 if (options->image.use_custom_border_color != c_options->image.use_custom_border_color
329 || options->image.use_custom_border_color_in_fullscreen != c_options->image.use_custom_border_color_in_fullscreen
330 || !gdk_color_equal(&options->image.border_color, &c_options->image.border_color))
332 options->image.use_custom_border_color_in_fullscreen = c_options->image.use_custom_border_color_in_fullscreen;
333 options->image.use_custom_border_color = c_options->image.use_custom_border_color;
334 options->image.border_color = c_options->image.border_color;
335 layout_colors_update();
336 view_window_colors_update();
339 options->image.alpha_color_1 = c_options->image.alpha_color_1;
340 options->image.alpha_color_2 = c_options->image.alpha_color_2;
342 options->fullscreen.screen = c_options->fullscreen.screen;
343 options->fullscreen.clean_flip = c_options->fullscreen.clean_flip;
344 options->fullscreen.disable_saver = c_options->fullscreen.disable_saver;
345 options->fullscreen.above = c_options->fullscreen.above;
346 if (c_options->image_overlay.template_string)
347 set_image_overlay_template_string(&options->image_overlay.template_string,
348 c_options->image_overlay.template_string);
349 if (c_options->image_overlay.font)
350 set_image_overlay_font_string(&options->image_overlay.font,
351 c_options->image_overlay.font);
352 options->image_overlay.text_red = c_options->image_overlay.text_red;
353 options->image_overlay.text_green = c_options->image_overlay.text_green;
354 options->image_overlay.text_blue = c_options->image_overlay.text_blue;
355 options->image_overlay.text_alpha = c_options->image_overlay.text_alpha;
356 options->image_overlay.background_red = c_options->image_overlay.background_red;
357 options->image_overlay.background_green = c_options->image_overlay.background_green;
358 options->image_overlay.background_blue = c_options->image_overlay.background_blue;
359 options->image_overlay.background_alpha = c_options->image_overlay.background_alpha;
360 options->update_on_time_change = c_options->update_on_time_change;
361 options->image.exif_proof_rotate_enable = c_options->image.exif_proof_rotate_enable;
363 options->duplicates_similarity_threshold = c_options->duplicates_similarity_threshold;
364 options->rot_invariant_sim = c_options->rot_invariant_sim;
366 options->tree_descend_subdirs = c_options->tree_descend_subdirs;
368 options->view_dir_list_single_click_enter = c_options->view_dir_list_single_click_enter;
370 options->open_recent_list_maxsize = c_options->open_recent_list_maxsize;
371 options->dnd_icon_size = c_options->dnd_icon_size;
372 options->clipboard_selection = c_options->clipboard_selection;
374 options->metadata.save_in_image_file = c_options->metadata.save_in_image_file;
375 options->metadata.save_legacy_IPTC = c_options->metadata.save_legacy_IPTC;
376 options->metadata.warn_on_write_problems = c_options->metadata.warn_on_write_problems;
377 options->metadata.save_legacy_format = c_options->metadata.save_legacy_format;
378 options->metadata.sync_grouped_files = c_options->metadata.sync_grouped_files;
379 options->metadata.confirm_write = c_options->metadata.confirm_write;
380 options->metadata.sidecar_extended_name = c_options->metadata.sidecar_extended_name;
381 options->metadata.confirm_timeout = c_options->metadata.confirm_timeout;
382 options->metadata.confirm_after_timeout = c_options->metadata.confirm_after_timeout;
383 options->metadata.confirm_on_image_change = c_options->metadata.confirm_on_image_change;
384 options->metadata.confirm_on_dir_change = c_options->metadata.confirm_on_dir_change;
385 options->metadata.keywords_case_sensitive = c_options->metadata.keywords_case_sensitive;
386 options->metadata.write_orientation = c_options->metadata.write_orientation;
387 options->stereo.mode = (c_options->stereo.mode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
388 (c_options->stereo.tmp.mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
389 (c_options->stereo.tmp.flip_right ? PR_STEREO_FLIP_RIGHT : 0) |
390 (c_options->stereo.tmp.mirror_left ? PR_STEREO_MIRROR_LEFT : 0) |
391 (c_options->stereo.tmp.flip_left ? PR_STEREO_FLIP_LEFT : 0) |
392 (c_options->stereo.tmp.swap ? PR_STEREO_SWAP : 0) |
393 (c_options->stereo.tmp.temp_disable ? PR_STEREO_TEMP_DISABLE : 0);
394 options->stereo.fsmode = (c_options->stereo.fsmode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
395 (c_options->stereo.tmp.fs_mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
396 (c_options->stereo.tmp.fs_flip_right ? PR_STEREO_FLIP_RIGHT : 0) |
397 (c_options->stereo.tmp.fs_mirror_left ? PR_STEREO_MIRROR_LEFT : 0) |
398 (c_options->stereo.tmp.fs_flip_left ? PR_STEREO_FLIP_LEFT : 0) |
399 (c_options->stereo.tmp.fs_swap ? PR_STEREO_SWAP : 0) |
400 (c_options->stereo.tmp.fs_temp_disable ? PR_STEREO_TEMP_DISABLE : 0);
401 options->stereo.enable_fsmode = c_options->stereo.enable_fsmode;
402 options->stereo.fixed_w = c_options->stereo.fixed_w;
403 options->stereo.fixed_h = c_options->stereo.fixed_h;
404 options->stereo.fixed_x1 = c_options->stereo.fixed_x1;
405 options->stereo.fixed_y1 = c_options->stereo.fixed_y1;
406 options->stereo.fixed_x2 = c_options->stereo.fixed_x2;
407 options->stereo.fixed_y2 = c_options->stereo.fixed_y2;
409 options->info_keywords.height = c_options->info_keywords.height;
410 options->info_title.height = c_options->info_title.height;
411 options->info_comment.height = c_options->info_comment.height;
412 options->info_rating.height = c_options->info_rating.height;
414 options->marks_save = c_options->marks_save;
415 options->with_rename = c_options->with_rename;
416 options->collections_on_top = c_options->collections_on_top;
417 config_entry_to_option(help_search_engine_entry, &options->help_search_engine, NULL);
419 options->read_metadata_in_idle = c_options->read_metadata_in_idle;
421 options->star_rating.star = c_options->star_rating.star;
422 options->star_rating.rejected = c_options->star_rating.rejected;
424 set_debug_level(debug_c);
428 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
430 config_entry_to_option(color_profile_input_name_entry[i], &options->color_profile.input_name[i], NULL);
431 config_entry_to_option(color_profile_input_file_entry[i], &options->color_profile.input_file[i], NULL);
433 config_entry_to_option(color_profile_screen_file_entry, &options->color_profile.screen_file, NULL);
434 options->color_profile.use_x11_screen_profile = c_options->color_profile.use_x11_screen_profile;
435 if (options->color_profile.render_intent != c_options->color_profile.render_intent)
437 options->color_profile.render_intent = c_options->color_profile.render_intent;
442 image_options_sync();
447 layout_refresh(NULL);
450 if (accel_store) gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_apply_cb, NULL);
456 *-----------------------------------------------------------------------------
457 * config window main button callbacks (private)
458 *-----------------------------------------------------------------------------
461 static void config_window_close_cb(GtkWidget *widget, gpointer data)
463 gtk_widget_destroy(configwindow);
468 static void config_window_help_cb(GtkWidget *widget, gpointer data)
470 GtkWidget *notebook = data;
473 static gchar *html_section[] =
475 "GuideOptionsGeneral.html",
476 "GuideOptionsImage.html",
477 "GuideOptionsWindow.html",
478 "GuideOptionsKeyboard.html",
479 "GuideOptionsFiltering.html",
480 "GuideOptionsMetadata.html",
481 "GuideOptionsColor.html",
482 "GuideOptionsStereo.html",
483 "GuideOptionsBehavior.html",
484 "GuideOptionsToolbar.html"
487 i = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
488 help_window_show(html_section[i]);
491 static gboolean config_window_delete(GtkWidget *widget, GdkEventAny *event, gpointer data)
493 config_window_close_cb(NULL, NULL);
497 static void config_window_ok_cb(GtkWidget *widget, gpointer data)
499 config_window_apply();
500 config_window_close_cb(NULL, NULL);
503 static void config_window_apply_cb(GtkWidget *widget, gpointer data)
506 lw = layout_window_list->data;
508 config_window_apply();
509 layout_util_sync(lw);
512 static void config_window_save_cb(GtkWidget *widget, gpointer data)
514 config_window_apply();
515 save_options(options);
519 *-----------------------------------------------------------------------------
520 * config window setup (private)
521 *-----------------------------------------------------------------------------
524 static void quality_menu_cb(GtkWidget *combo, gpointer data)
528 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
532 *option = GDK_INTERP_NEAREST;
535 *option = GDK_INTERP_TILES;
538 *option = GDK_INTERP_BILINEAR;
541 *option = GDK_INTERP_HYPER;
546 static void clipboard_selection_menu_cb(GtkWidget *combo, gpointer data)
550 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
562 static void add_quality_menu(GtkWidget *table, gint column, gint row, const gchar *text,
563 guint option, guint *option_c)
570 pref_table_label(table, column, row, text, 0.0);
572 combo = gtk_combo_box_text_new();
574 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Nearest (worst, but fastest)"));
575 if (option == GDK_INTERP_NEAREST) current = 0;
576 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Tiles"));
577 if (option == GDK_INTERP_TILES) current = 1;
578 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Bilinear"));
579 if (option == GDK_INTERP_BILINEAR) current = 2;
580 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Hyper (best, but slowest)"));
581 if (option == GDK_INTERP_HYPER) current = 3;
583 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
585 g_signal_connect(G_OBJECT(combo), "changed",
586 G_CALLBACK(quality_menu_cb), option_c);
588 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
589 GTK_EXPAND | GTK_FILL, 0, 0, 0);
590 gtk_widget_show(combo);
593 static void add_clipboard_selection_menu(GtkWidget *table, gint column, gint row, const gchar *text,
594 gint option, gint *option_c)
601 pref_table_label(table, column, row, text, 0.0);
603 combo = gtk_combo_box_text_new();
605 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("PRIMARY"));
606 if (option == PRIMARY) current = 0;
607 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("CLIPBOARD"));
608 if (option == CLIPBOARD) current = 1;
610 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
612 g_signal_connect(G_OBJECT(combo), "changed",
613 G_CALLBACK(clipboard_selection_menu_cb), option_c);
615 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
616 GTK_EXPAND | GTK_FILL, 0, 0, 0);
617 gtk_widget_show(combo);
620 static void thumb_size_menu_cb(GtkWidget *combo, gpointer data)
624 n = gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
627 if ((guint) n < sizeof(thumb_size_list) / sizeof(ThumbSize))
629 c_options->thumbnails.max_width = thumb_size_list[n].w;
630 c_options->thumbnails.max_height = thumb_size_list[n].h;
634 c_options->thumbnails.max_width = options->thumbnails.max_width;
635 c_options->thumbnails.max_height = options->thumbnails.max_height;
639 static void add_thumb_size_menu(GtkWidget *table, gint column, gint row, gchar *text)
645 c_options->thumbnails.max_width = options->thumbnails.max_width;
646 c_options->thumbnails.max_height = options->thumbnails.max_height;
648 pref_table_label(table, column, row, text, 0.0);
650 combo = gtk_combo_box_text_new();
653 for (i = 0; (guint) i < sizeof(thumb_size_list) / sizeof(ThumbSize); i++)
658 w = thumb_size_list[i].w;
659 h = thumb_size_list[i].h;
661 buf = g_strdup_printf("%d x %d", w, h);
662 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf);
665 if (w == options->thumbnails.max_width && h == options->thumbnails.max_height) current = i;
672 buf = g_strdup_printf("%s %d x %d", _("Custom"), options->thumbnails.max_width, options->thumbnails.max_height);
673 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf);
679 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
680 g_signal_connect(G_OBJECT(combo), "changed",
681 G_CALLBACK(thumb_size_menu_cb), NULL);
683 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
684 GTK_EXPAND | GTK_FILL, 0, 0, 0);
685 gtk_widget_show(combo);
688 static void stereo_mode_menu_cb(GtkWidget *combo, gpointer data)
692 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
696 *option = PR_STEREO_NONE;
699 *option = PR_STEREO_ANAGLYPH_RC;
702 *option = PR_STEREO_ANAGLYPH_GM;
705 *option = PR_STEREO_ANAGLYPH_YB;
708 *option = PR_STEREO_ANAGLYPH_GRAY_RC;
711 *option = PR_STEREO_ANAGLYPH_GRAY_GM;
714 *option = PR_STEREO_ANAGLYPH_GRAY_YB;
717 *option = PR_STEREO_ANAGLYPH_DB_RC;
720 *option = PR_STEREO_ANAGLYPH_DB_GM;
723 *option = PR_STEREO_ANAGLYPH_DB_YB;
726 *option = PR_STEREO_HORIZ;
729 *option = PR_STEREO_HORIZ | PR_STEREO_HALF;
732 *option = PR_STEREO_VERT;
735 *option = PR_STEREO_VERT | PR_STEREO_HALF;
738 *option = PR_STEREO_FIXED;
743 static void add_stereo_mode_menu(GtkWidget *table, gint column, gint row, const gchar *text,
744 gint option, gint *option_c, gboolean add_fixed)
751 pref_table_label(table, column, row, text, 0.0);
753 combo = gtk_combo_box_text_new();
755 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Single image"));
757 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Red-Cyan"));
758 if (option & PR_STEREO_ANAGLYPH_RC) current = 1;
759 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Green-Magenta"));
760 if (option & PR_STEREO_ANAGLYPH_GM) current = 2;
761 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Yellow-Blue"));
762 if (option & PR_STEREO_ANAGLYPH_YB) current = 3;
763 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Red-Cyan"));
764 if (option & PR_STEREO_ANAGLYPH_GRAY_RC) current = 4;
765 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Green-Magenta"));
766 if (option & PR_STEREO_ANAGLYPH_GRAY_GM) current = 5;
767 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Yellow-Blue"));
768 if (option & PR_STEREO_ANAGLYPH_GRAY_YB) current = 6;
769 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Red-Cyan"));
770 if (option & PR_STEREO_ANAGLYPH_DB_RC) current = 7;
771 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Green-Magenta"));
772 if (option & PR_STEREO_ANAGLYPH_DB_GM) current = 8;
773 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Yellow-Blue"));
774 if (option & PR_STEREO_ANAGLYPH_DB_YB) current = 9;
776 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Side by Side"));
777 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Side by Side Half size"));
778 if (option & PR_STEREO_HORIZ)
781 if (option & PR_STEREO_HALF) current = 11;
784 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Top - Bottom"));
785 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Top - Bottom Half size"));
786 if (option & PR_STEREO_VERT)
789 if (option & PR_STEREO_HALF) current = 13;
794 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Fixed position"));
795 if (option & PR_STEREO_FIXED) current = 14;
798 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
800 g_signal_connect(G_OBJECT(combo), "changed",
801 G_CALLBACK(stereo_mode_menu_cb), option_c);
803 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
804 GTK_EXPAND | GTK_FILL, 0, 0, 0);
805 gtk_widget_show(combo);
808 static void video_menu_cb(GtkWidget *combo, gpointer data)
810 gchar **option = data;
812 EditorDescription *ed = g_list_nth_data(editor_list_get(), gtk_combo_box_get_active(GTK_COMBO_BOX(combo)));
816 static void video_menu_populate(gpointer data, gpointer user_data)
818 GtkWidget *combo = user_data;
819 EditorDescription *ed = data;
821 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), ed->name);
824 static void add_video_menu(GtkWidget *table, gint column, gint row, const gchar *text,
825 gchar *option, gchar **option_c)
829 /* use lists since they are sorted */
830 GList *eds = editor_list_get();
834 pref_table_label(table, column, row, text, 0.0);
836 combo = gtk_combo_box_text_new();
837 g_list_foreach(eds,video_menu_populate,(gpointer)combo);
838 current = option ? g_list_index(eds,g_hash_table_lookup(editors,option)): -1;
840 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
842 g_signal_connect(G_OBJECT(combo), "changed",
843 G_CALLBACK(video_menu_cb), option_c);
845 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
846 GTK_EXPAND | GTK_FILL, 0, 0, 0);
847 gtk_widget_show(combo);
850 static void filter_store_populate(void)
854 if (!filter_store) return;
856 gtk_list_store_clear(filter_store);
858 work = filter_get_list();
867 gtk_list_store_append(filter_store, &iter);
868 gtk_list_store_set(filter_store, &iter, 0, fe, -1);
872 static void filter_store_ext_edit_cb(GtkCellRendererText *cell, gchar *path_str,
873 gchar *new_text, gpointer data)
875 GtkWidget *model = data;
876 FilterEntry *fe = data;
880 if (!new_text || strlen(new_text) < 1) return;
882 tpath = gtk_tree_path_new_from_string(path_str);
883 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
884 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
886 g_free(fe->extensions);
887 fe->extensions = g_strdup(new_text);
889 gtk_tree_path_free(tpath);
893 static void filter_store_class_edit_cb(GtkCellRendererText *cell, gchar *path_str,
894 gchar *new_text, gpointer data)
896 GtkWidget *model = data;
897 FilterEntry *fe = data;
902 if (!new_text || !new_text[0]) return;
904 tpath = gtk_tree_path_new_from_string(path_str);
905 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
906 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
908 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
910 if (strcmp(new_text, _(format_class_list[i])) == 0)
917 gtk_tree_path_free(tpath);
921 static void filter_store_desc_edit_cb(GtkCellRendererText *cell, gchar *path_str,
922 gchar *new_text, gpointer data)
924 GtkWidget *model = data;
929 if (!new_text || !new_text[0]) return;
931 tpath = gtk_tree_path_new_from_string(path_str);
932 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
933 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
935 g_free(fe->description);
936 fe->description = g_strdup(new_text);
938 gtk_tree_path_free(tpath);
941 static void filter_store_enable_cb(GtkCellRendererToggle *renderer,
942 gchar *path_str, gpointer data)
944 GtkWidget *model = data;
949 tpath = gtk_tree_path_new_from_string(path_str);
950 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
951 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
953 fe->enabled = !fe->enabled;
955 gtk_tree_path_free(tpath);
959 static void filter_store_writable_cb(GtkCellRendererToggle *renderer,
960 gchar *path_str, gpointer data)
962 GtkWidget *model = data;
967 tpath = gtk_tree_path_new_from_string(path_str);
968 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
969 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
971 fe->writable = !fe->writable;
972 if (fe->writable) fe->allow_sidecar = FALSE;
974 gtk_tree_path_free(tpath);
978 static void filter_store_sidecar_cb(GtkCellRendererToggle *renderer,
979 gchar *path_str, gpointer data)
981 GtkWidget *model = data;
986 tpath = gtk_tree_path_new_from_string(path_str);
987 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
988 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
990 fe->allow_sidecar = !fe->allow_sidecar;
991 if (fe->allow_sidecar) fe->writable = FALSE;
993 gtk_tree_path_free(tpath);
997 static void filter_set_func(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell,
998 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
1002 gtk_tree_model_get(tree_model, iter, 0, &fe, -1);
1004 switch (GPOINTER_TO_INT(data))
1007 g_object_set(GTK_CELL_RENDERER(cell),
1008 "active", fe->enabled, NULL);
1011 g_object_set(GTK_CELL_RENDERER(cell),
1012 "text", fe->extensions, NULL);
1014 case FE_DESCRIPTION:
1015 g_object_set(GTK_CELL_RENDERER(cell),
1016 "text", fe->description, NULL);
1019 g_object_set(GTK_CELL_RENDERER(cell),
1020 "text", _(format_class_list[fe->file_class]), NULL);
1023 g_object_set(GTK_CELL_RENDERER(cell),
1024 "active", fe->writable, NULL);
1026 case FE_ALLOW_SIDECAR:
1027 g_object_set(GTK_CELL_RENDERER(cell),
1028 "active", fe->allow_sidecar, NULL);
1033 static gboolean filter_add_scroll(gpointer data)
1037 GtkCellRenderer *cell;
1038 GtkTreeViewColumn *column;
1039 GList *list_columns;
1044 rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(filter_store), NULL);
1045 path = gtk_tree_path_new_from_indices(rows-1, -1);
1047 list_columns = gtk_tree_view_get_columns(GTK_TREE_VIEW(data));
1049 column = g_list_nth(list_columns,i)->data;
1050 title = gtk_tree_view_column_get_title(GTK_TREE_VIEW_COLUMN(column));
1052 } while (strcmp(title, "Filter") !=0 );
1054 list_cells = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(column));
1055 cell = g_list_last(list_cells)->data;
1057 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1058 path, column, FALSE, 0.0, 0.0 );
1059 gtk_tree_view_set_cursor_on_cell(GTK_TREE_VIEW(data),
1060 path, column, cell, TRUE);
1062 gtk_tree_path_free(path);
1063 g_list_free(list_cells);
1064 g_list_free(list_columns);
1069 static void filter_add_cb(GtkWidget *widget, gpointer data)
1071 filter_add_unique("description", ".new", FORMAT_CLASS_IMAGE, TRUE, FALSE, TRUE);
1072 filter_store_populate();
1074 g_idle_add((GSourceFunc)filter_add_scroll, data);
1077 static void filter_remove_cb(GtkWidget *widget, gpointer data)
1079 GtkWidget *filter_view = data;
1080 GtkTreeSelection *selection;
1084 if (!filter_store) return;
1085 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
1086 if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) return;
1087 gtk_tree_model_get(GTK_TREE_MODEL(filter_store), &iter, 0, &fe, -1);
1090 filter_remove_entry(fe);
1092 filter_store_populate();
1095 static gboolean filter_default_ok_scroll(GtkTreeView *data)
1099 GtkTreeViewColumn *column;
1101 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(filter_store), &iter);
1102 path = gtk_tree_model_get_path(GTK_TREE_MODEL(filter_store), &iter);
1103 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data),0);
1105 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1109 gtk_tree_path_free(path);
1114 static void filter_default_ok_cb(GenericDialog *gd, gpointer data)
1117 filter_add_defaults();
1119 filter_store_populate();
1121 g_idle_add((GSourceFunc)filter_default_ok_scroll, gd->data);
1124 static void dummy_cancel_cb(GenericDialog *gd, gpointer data)
1126 /* no op, only so cancel button appears */
1129 static void filter_default_cb(GtkWidget *widget, gpointer data)
1133 gd = generic_dialog_new(_("Reset filters"),
1134 "reset_filter", widget, TRUE,
1135 dummy_cancel_cb, data);
1136 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Reset filters"),
1137 _("This will reset the file filters to the defaults.\nContinue?"), TRUE);
1138 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, filter_default_ok_cb, TRUE);
1139 gtk_widget_show(gd->dialog);
1142 static void filter_disable_cb(GtkWidget *widget, gpointer data)
1144 GtkWidget *frame = data;
1146 gtk_widget_set_sensitive(frame,
1147 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
1150 static void safe_delete_view_cb(GtkWidget *widget, gpointer data)
1152 layout_set_path(NULL, gtk_entry_get_text(GTK_ENTRY(safe_delete_path_entry)));
1155 static void safe_delete_clear_ok_cb(GenericDialog *gd, gpointer data)
1157 file_util_trash_clear();
1160 static void safe_delete_clear_cb(GtkWidget *widget, gpointer data)
1164 gd = generic_dialog_new(_("Clear trash"),
1165 "clear_trash", widget, TRUE,
1166 dummy_cancel_cb, NULL);
1167 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Clear trash"),
1168 _("This will remove the trash contents."), FALSE);
1169 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, safe_delete_clear_ok_cb, TRUE);
1170 entry = gtk_entry_new();
1171 gtk_widget_set_can_focus(entry, FALSE);
1172 gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
1173 if (options->file_ops.safe_delete_path) gtk_entry_set_text(GTK_ENTRY(entry), options->file_ops.safe_delete_path);
1174 gtk_box_pack_start(GTK_BOX(gd->vbox), entry, FALSE, FALSE, 0);
1175 gtk_widget_show(entry);
1176 gtk_widget_show(gd->dialog);
1179 static void image_overlay_template_view_changed_cb(GtkWidget *widget, gpointer data)
1181 GtkWidget *pTextView;
1182 GtkTextBuffer *pTextBuffer;
1186 pTextView = GTK_WIDGET(data);
1188 pTextBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pTextView));
1189 gtk_text_buffer_get_start_iter(pTextBuffer, &iStart);
1190 gtk_text_buffer_get_end_iter(pTextBuffer, &iEnd);
1192 set_image_overlay_template_string(&c_options->image_overlay.template_string,
1193 gtk_text_buffer_get_text(pTextBuffer, &iStart, &iEnd, TRUE));
1196 static void image_overlay_default_template_ok_cb(GenericDialog *gd, gpointer data)
1198 GtkTextView *text_view = data;
1199 GtkTextBuffer *buffer;
1201 set_default_image_overlay_template_string(&options->image_overlay.template_string);
1202 if (!configwindow) return;
1204 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
1205 gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
1208 static void image_overlay_default_template_cb(GtkWidget *widget, gpointer data)
1212 gd = generic_dialog_new(_("Reset image overlay template string"),
1213 "reset_image_overlay_template_string", widget, TRUE,
1214 dummy_cancel_cb, data);
1215 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Reset image overlay template string"),
1216 _("This will reset the image overlay template string to the default.\nContinue?"), TRUE);
1217 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, image_overlay_default_template_ok_cb, TRUE);
1218 gtk_widget_show(gd->dialog);
1221 static void image_overlay_help_cb(GtkWidget *widget, gpointer data)
1223 help_window_show("GuideOptionsWindow.html#OverlayScreenDisplay");
1226 static void image_overlay_set_font_cb(GtkWidget *widget, gpointer data)
1228 #if GTK_CHECK_VERSION(3,4,0)
1231 PangoFontDescription *font_desc;
1233 dialog = gtk_font_chooser_dialog_new("Image Overlay Font", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1234 gtk_font_chooser_set_font(GTK_FONT_CHOOSER(dialog), options->image_overlay.font);
1236 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1238 font_desc = gtk_font_chooser_get_font_desc(GTK_FONT_CHOOSER(dialog));
1239 font = pango_font_description_to_string(font_desc);
1240 g_free(c_options->image_overlay.font);
1241 c_options->image_overlay.font = g_strdup(font);
1245 gtk_widget_destroy(dialog);
1249 font = gtk_font_button_get_font_name(GTK_FONT_BUTTON(widget));
1250 c_options->image_overlay.font = g_strdup(font);
1254 static void image_overlay_set_text_colour_cb(GtkWidget *widget, gpointer data)
1257 #if GTK_CHECK_VERSION(3,4,0)
1260 dialog = gtk_color_chooser_dialog_new("Image Overlay Text Colour", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1261 colour.red = options->image_overlay.text_red;
1262 colour.green = options->image_overlay.text_green;
1263 colour.blue = options->image_overlay.text_blue;
1264 colour.alpha = options->image_overlay.text_alpha;
1265 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1266 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(dialog), TRUE);
1268 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1270 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1271 c_options->image_overlay.text_red = colour.red*255;
1272 c_options->image_overlay.text_green = colour.green*255;
1273 c_options->image_overlay.text_blue = colour.blue*255;
1274 c_options->image_overlay.text_alpha = colour.alpha*255;
1276 gtk_widget_destroy(dialog);
1279 GtkColorSelection *colorsel;
1281 dialog = gtk_color_selection_dialog_new("Image Overlay Text Colour");
1282 gtk_window_set_keep_above(GTK_WINDOW(dialog),TRUE);
1283 colour.red = options->image_overlay.text_red*257;
1284 colour.green = options->image_overlay.text_green*257;
1285 colour.blue = options->image_overlay.text_blue*257;
1286 colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)));
1287 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
1288 gtk_color_selection_set_current_color(colorsel, &colour);
1289 gtk_color_selection_set_current_alpha(colorsel, options->image_overlay.text_alpha*257);
1291 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
1293 gtk_color_selection_get_current_color(colorsel, &colour);
1294 c_options->image_overlay.text_red = colour.red/257;
1295 c_options->image_overlay.text_green = colour.green/257;
1296 c_options->image_overlay.text_blue = colour.blue/257;
1297 c_options->image_overlay.text_alpha = gtk_color_selection_get_current_alpha(colorsel)/257;
1299 gtk_widget_destroy (dialog);
1304 static void image_overlay_set_background_colour_cb(GtkWidget *widget, gpointer data)
1307 #if GTK_CHECK_VERSION(3,4,0)
1310 dialog = gtk_color_chooser_dialog_new("Image Overlay Background Colour", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1311 colour.red = options->image_overlay.background_red;
1312 colour.green = options->image_overlay.background_green;
1313 colour.blue = options->image_overlay.background_blue;
1314 colour.alpha = options->image_overlay.background_alpha;
1315 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1316 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(dialog), TRUE);
1318 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1320 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1321 c_options->image_overlay.background_red = colour.red*255;
1322 c_options->image_overlay.background_green = colour.green*255;
1323 c_options->image_overlay.background_blue = colour.blue*255;
1324 c_options->image_overlay.background_alpha = colour.alpha*255;
1326 gtk_widget_destroy(dialog);
1329 GtkColorSelection *colorsel;
1331 dialog = gtk_color_selection_dialog_new("Image Overlay Background Colour");
1332 gtk_window_set_keep_above(GTK_WINDOW(dialog),TRUE);
1333 colour.red = options->image_overlay.background_red*257;
1334 colour.green = options->image_overlay.background_green*257;
1335 colour.blue = options->image_overlay.background_blue*257;
1336 colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)));
1337 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
1338 gtk_color_selection_set_current_color(colorsel, &colour);
1339 gtk_color_selection_set_current_alpha(colorsel, options->image_overlay.background_alpha*257);
1341 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
1343 gtk_color_selection_get_current_color(colorsel, &colour);
1344 c_options->image_overlay.background_red = colour.red/257;
1345 c_options->image_overlay.background_green = colour.green/257;
1346 c_options->image_overlay.background_blue = colour.blue/257;
1347 c_options->image_overlay.background_alpha = gtk_color_selection_get_current_alpha(colorsel)/257;
1349 gtk_widget_destroy(dialog);
1353 static void accel_store_populate(void)
1356 GList *groups, *actions;
1358 const gchar *accel_path;
1362 if (!accel_store || !layout_window_list || !layout_window_list->data) return;
1364 gtk_tree_store_clear(accel_store);
1365 lw = layout_window_list->data; /* get the actions from the first window, it should not matter, they should be the same in all windows */
1367 g_assert(lw && lw->ui_manager);
1368 groups = gtk_ui_manager_get_action_groups(lw->ui_manager);
1371 actions = gtk_action_group_list_actions(GTK_ACTION_GROUP(groups->data));
1374 action = GTK_ACTION(actions->data);
1375 accel_path = gtk_action_get_accel_path(action);
1376 if (accel_path && gtk_accel_map_lookup_entry(accel_path, &key))
1378 gchar *label, *label2, *tooltip, *accel;
1379 g_object_get(action,
1380 "tooltip", &tooltip,
1384 if (pango_parse_markup(label, -1, '_', NULL, &label2, NULL, NULL) && label2)
1390 accel = gtk_accelerator_name(key.accel_key, key.accel_mods);
1394 gtk_tree_store_append(accel_store, &iter, NULL);
1395 gtk_tree_store_set(accel_store, &iter,
1398 AE_TOOLTIP, tooltip ? tooltip : "",
1399 AE_ACCEL, accel_path,
1407 actions = actions->next;
1410 groups = groups->next;
1414 static void accel_store_cleared_cb(GtkCellRendererAccel *accel, gchar *path_string, gpointer user_data)
1419 static gboolean accel_remove_key_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1421 gchar *accel1 = data;
1426 gtk_tree_model_get(model, iter, AE_KEY, &accel2, -1);
1428 gtk_accelerator_parse(accel1, &key1.accel_key, &key1.accel_mods);
1429 gtk_accelerator_parse(accel2, &key2.accel_key, &key2.accel_mods);
1431 if (key1.accel_key == key2.accel_key && key1.accel_mods == key2.accel_mods)
1433 gtk_tree_store_set(accel_store, iter, AE_KEY, "", -1);
1434 DEBUG_1("accelerator key '%s' is already used, removing.", accel1);
1443 static void accel_store_edited_cb(GtkCellRendererAccel *accel, gchar *path_string, guint accel_key, GdkModifierType accel_mods, guint hardware_keycode, gpointer user_data)
1445 GtkTreeModel *model = (GtkTreeModel *)accel_store;
1449 GtkAccelKey old_key, key;
1450 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
1452 gtk_tree_model_get_iter(model, &iter, path);
1453 gtk_tree_model_get(model, &iter, AE_ACCEL, &accel_path, -1);
1455 /* test if the accelerator can be stored without conflicts*/
1456 gtk_accel_map_lookup_entry(accel_path, &old_key);
1458 /* change the key and read it back (change may fail on keys hardcoded in gtk)*/
1459 gtk_accel_map_change_entry(accel_path, accel_key, accel_mods, TRUE);
1460 gtk_accel_map_lookup_entry(accel_path, &key);
1462 /* restore the original for now, the key will be really changed when the changes are confirmed */
1463 gtk_accel_map_change_entry(accel_path, old_key.accel_key, old_key.accel_mods, TRUE);
1465 acc = gtk_accelerator_name(key.accel_key, key.accel_mods);
1466 gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_remove_key_cb, acc);
1468 gtk_tree_store_set(accel_store, &iter, AE_KEY, acc, -1);
1469 gtk_tree_path_free(path);
1473 static gboolean accel_default_scroll(GtkTreeView *data)
1477 GtkTreeViewColumn *column;
1479 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(accel_store), &iter);
1480 path = gtk_tree_model_get_path(GTK_TREE_MODEL(accel_store), &iter);
1481 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data),0);
1483 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1487 gtk_tree_path_free(path);
1492 static void accel_default_cb(GtkWidget *widget, gpointer data)
1494 accel_store_populate();
1496 g_idle_add((GSourceFunc)accel_default_scroll, data);
1499 void accel_remove_selection(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1501 gtk_tree_store_set(accel_store, iter, AE_KEY, "", -1);
1504 void accel_reset_selection(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1507 gchar *accel_path, *accel;
1509 gtk_tree_model_get(model, iter, AE_ACCEL, &accel_path, -1);
1510 gtk_accel_map_lookup_entry(accel_path, &key);
1511 accel = gtk_accelerator_name(key.accel_key, key.accel_mods);
1513 gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_remove_key_cb, accel);
1515 gtk_tree_store_set(accel_store, iter, AE_KEY, accel, -1);
1520 static void accel_reset_cb(GtkWidget *widget, gpointer data)
1522 GtkTreeSelection *selection;
1524 if (!accel_store) return;
1525 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data));
1526 gtk_tree_selection_selected_foreach(selection, &accel_reset_selection, NULL);
1531 static GtkWidget *scrolled_notebook_page(GtkWidget *notebook, const gchar *title)
1535 GtkWidget *scrolled;
1536 GtkWidget *viewport;
1538 scrolled = gtk_scrolled_window_new(NULL, NULL);
1539 gtk_container_set_border_width(GTK_CONTAINER(scrolled), PREF_PAD_BORDER);
1540 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
1541 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1542 label = gtk_label_new(title);
1543 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled, label);
1544 gtk_widget_show(scrolled);
1546 viewport = gtk_viewport_new(NULL, NULL);
1547 gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
1548 gtk_container_add(GTK_CONTAINER(scrolled), viewport);
1549 gtk_widget_show(viewport);
1551 vbox = gtk_vbox_new(FALSE, 0);
1552 gtk_container_add(GTK_CONTAINER(viewport), vbox);
1553 gtk_widget_show(vbox);
1558 static void cache_standard_cb(GtkWidget *widget, gpointer data)
1560 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1562 c_options->thumbnails.spec_standard =TRUE;
1563 c_options->thumbnails.cache_into_dirs = FALSE;
1567 static void cache_geeqie_cb(GtkWidget *widget, gpointer data)
1569 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1571 c_options->thumbnails.spec_standard =FALSE;
1572 c_options->thumbnails.cache_into_dirs = FALSE;
1576 static void cache_local_cb(GtkWidget *widget, gpointer data)
1578 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1580 c_options->thumbnails.cache_into_dirs = TRUE;
1581 c_options->thumbnails.spec_standard =FALSE;
1585 static void help_search_engine_entry_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1586 GdkEvent *event, gpointer userdata)
1588 if (pos == GTK_ENTRY_ICON_PRIMARY)
1590 gtk_entry_set_text(GTK_ENTRY(userdata), HELP_SEARCH_ENGINE);
1594 gtk_entry_set_text(GTK_ENTRY(userdata), "");
1598 static void star_rating_star_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1599 GdkEvent *event, gpointer userdata)
1601 gchar *rating_symbol;
1603 if (pos == GTK_ENTRY_ICON_PRIMARY)
1605 rating_symbol = g_strdup_printf("U+%X", STAR_RATING_STAR);
1606 gtk_entry_set_text(GTK_ENTRY(userdata), rating_symbol);
1607 g_free(rating_symbol);
1611 gtk_entry_set_text(GTK_ENTRY(userdata), "U+");
1612 gtk_widget_grab_focus(GTK_WIDGET(userdata));
1613 gtk_editable_select_region(GTK_EDITABLE(userdata), 2, 2);
1617 static void star_rating_rejected_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1618 GdkEvent *event, gpointer userdata)
1620 gchar *rating_symbol;
1622 if (pos == GTK_ENTRY_ICON_PRIMARY)
1624 rating_symbol = g_strdup_printf("U+%X", STAR_RATING_REJECTED);
1625 gtk_entry_set_text(GTK_ENTRY(userdata), rating_symbol);
1626 g_free(rating_symbol);
1630 gtk_entry_set_text(GTK_ENTRY(userdata), "U+");
1631 gtk_widget_grab_focus(GTK_WIDGET(userdata));
1632 gtk_editable_select_region(GTK_EDITABLE(userdata), 2, 2);
1636 static guint star_rating_symbol_test(GtkWidget *widget, gpointer data)
1638 GtkContainer *hbox = data;
1639 GString *str = g_string_new(NULL);
1640 GtkEntry *hex_code_entry;
1641 gchar *hex_code_full;
1644 guint64 hex_value = 0;
1646 list = gtk_container_get_children(hbox);
1648 hex_code_entry = g_list_nth_data(list, 2);
1649 hex_code_full = g_strdup(gtk_entry_get_text(hex_code_entry));
1651 hex_code = g_strsplit(hex_code_full, "+", 2);
1652 if (hex_code[0] && hex_code[1])
1654 hex_value = strtoull(hex_code[1], NULL, 16);
1656 if (!hex_value || hex_value > 0x10FFFF)
1658 hex_value = 0x003F; // Unicode 'Question Mark'
1660 str = g_string_append_unichar(str, (gunichar)hex_value);
1661 gtk_label_set_text(g_list_nth_data(list, 1), str->str);
1663 g_strfreev(hex_code);
1664 g_string_free(str, TRUE);
1665 g_free(hex_code_full);
1670 static void star_rating_star_test_cb(GtkWidget *widget, gpointer data)
1672 guint64 star_symbol;
1674 star_symbol = star_rating_symbol_test(widget, data);
1675 c_options->star_rating.star = star_symbol;
1678 static void star_rating_rejected_test_cb(GtkWidget *widget, gpointer data)
1680 guint64 rejected_symbol;
1682 rejected_symbol = star_rating_symbol_test(widget, data);
1683 c_options->star_rating.rejected = rejected_symbol;
1686 /* general options tab */
1687 static void config_tab_general(GtkWidget *notebook)
1692 GtkWidget *group_frame;
1693 GtkWidget *subgroup;
1695 GtkWidget *ct_button;
1698 gint hours, minutes, remainder;
1700 GtkWidget *star_rating_entry;
1702 gchar *rating_symbol;
1704 vbox = scrolled_notebook_page(notebook, _("General"));
1706 group = pref_group_new(vbox, FALSE, _("Thumbnails"), GTK_ORIENTATION_VERTICAL);
1708 table = pref_table_new(group, 2, 2, FALSE, FALSE);
1709 add_thumb_size_menu(table, 0, 0, _("Size:"));
1710 add_quality_menu(table, 0, 1, _("Quality:"), options->thumbnails.quality, &c_options->thumbnails.quality);
1712 ct_button = pref_checkbox_new_int(group, _("Cache thumbnails"),
1713 options->thumbnails.enable_caching, &c_options->thumbnails.enable_caching);
1715 subgroup = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1716 pref_checkbox_link_sensitivity(ct_button, subgroup);
1718 c_options->thumbnails.spec_standard = options->thumbnails.spec_standard;
1719 c_options->thumbnails.cache_into_dirs = options->thumbnails.cache_into_dirs;
1720 group_frame = pref_frame_new(subgroup, TRUE, _("Use Geeqie thumbnail style and cache"),
1721 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1722 button = pref_radiobutton_new(group_frame, NULL, get_thumbnails_cache_dir(),
1723 !options->thumbnails.spec_standard && !options->thumbnails.cache_into_dirs,
1724 G_CALLBACK(cache_geeqie_cb), NULL);
1726 group_frame = pref_frame_new(subgroup, TRUE,
1727 _("Store thumbnails local to image folder (non-standard)"),
1728 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1729 pref_radiobutton_new(group_frame, button, "*/.thumbnails",
1730 !options->thumbnails.spec_standard && options->thumbnails.cache_into_dirs,
1731 G_CALLBACK(cache_local_cb), NULL);
1733 group_frame = pref_frame_new(subgroup, TRUE,
1734 _("Use standard thumbnail style and cache, shared with other applications"),
1735 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1736 pref_radiobutton_new(group_frame, button, get_thumbnails_standard_cache_dir(),
1737 options->thumbnails.spec_standard && !options->thumbnails.cache_into_dirs,
1738 G_CALLBACK(cache_standard_cb), NULL);
1740 pref_checkbox_new_int(group, _("Use EXIF thumbnails when available (EXIF thumbnails may be outdated)"),
1741 options->thumbnails.use_exif, &c_options->thumbnails.use_exif);
1743 spin = pref_spin_new_int(group, _("Collection preview:"), NULL,
1745 options->thumbnails.collection_preview, &c_options->thumbnails.collection_preview);
1746 gtk_widget_set_tooltip_text(spin, _("The maximum number of thumbnails shown in a Collection preview montage"));
1748 #ifdef HAVE_FFMPEGTHUMBNAILER_METADATA
1749 pref_checkbox_new_int(group, _("Use embedded metadata in video files as thumbnails when available"),
1750 options->thumbnails.use_ft_metadata, &c_options->thumbnails.use_ft_metadata);
1752 // pref_checkbox_new_int(group, _("Ignore embedded metadata if size is too small"),
1753 // options->thumbnails.use_ft_metadata_small, &c_options->thumbnails.use_ft_metadata_small);
1756 group = pref_group_new(vbox, FALSE, _("Star Rating"), GTK_ORIENTATION_VERTICAL);
1758 c_options->star_rating.star = options->star_rating.star;
1759 c_options->star_rating.rejected = options->star_rating.rejected;
1761 str = g_string_new(NULL);
1762 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1763 pref_label_new(hbox, "Star character: ");
1764 str = g_string_append_unichar(str, options->star_rating.star);
1765 pref_label_new(hbox, g_strdup(str->str));
1766 rating_symbol = g_strdup_printf("U+%X", options->star_rating.star);
1767 star_rating_entry = gtk_entry_new();
1768 gtk_entry_set_text(GTK_ENTRY(star_rating_entry), rating_symbol);
1769 gtk_box_pack_start(GTK_BOX(hbox), star_rating_entry, FALSE, FALSE, 0);
1770 gtk_entry_set_width_chars(GTK_ENTRY(star_rating_entry), 15);
1771 gtk_widget_show(star_rating_entry);
1772 button = pref_button_new(NULL, NULL, _("Set"), FALSE,
1773 G_CALLBACK(star_rating_star_test_cb), hbox);
1774 gtk_widget_set_tooltip_text(button, _("Display selected character"));
1775 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1776 gtk_widget_show(button);
1777 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."));
1778 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1779 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1780 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1781 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1782 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1783 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1784 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1785 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1786 g_signal_connect(GTK_ENTRY(star_rating_entry), "icon-press",
1787 G_CALLBACK(star_rating_star_icon_cb),
1790 g_string_free(str, TRUE);
1791 g_free(rating_symbol);
1793 str = g_string_new(NULL);
1794 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1795 pref_label_new(hbox, "Rejected character: ");
1796 str = g_string_append_unichar(str, options->star_rating.rejected);
1797 pref_label_new(hbox, g_strdup(str->str));
1798 rating_symbol = g_strdup_printf("U+%X", options->star_rating.rejected);
1799 star_rating_entry = gtk_entry_new();
1800 gtk_entry_set_text(GTK_ENTRY(star_rating_entry), rating_symbol);
1801 gtk_box_pack_start(GTK_BOX(hbox), star_rating_entry, FALSE, FALSE, 0);
1802 gtk_entry_set_width_chars(GTK_ENTRY(star_rating_entry), 15);
1803 gtk_widget_show(star_rating_entry);
1804 button = pref_button_new(NULL, NULL, _("Set"), FALSE,
1805 G_CALLBACK(star_rating_rejected_test_cb), hbox);
1806 gtk_widget_set_tooltip_text(button, _("Display selected character"));
1807 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1808 gtk_widget_show(button);
1809 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."));
1810 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1811 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1812 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1813 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1814 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1815 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1816 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1817 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1818 g_signal_connect(GTK_ENTRY(star_rating_entry), "icon-press",
1819 G_CALLBACK(star_rating_rejected_icon_cb),
1822 g_string_free(str, TRUE);
1823 g_free(rating_symbol);
1825 group = pref_group_new(vbox, FALSE, _("Slide show"), GTK_ORIENTATION_VERTICAL);
1827 c_options->slideshow.delay = options->slideshow.delay;
1828 hours = options->slideshow.delay / (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1829 remainder = options->slideshow.delay % (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1830 minutes = remainder / (60 * SLIDESHOW_SUBSECOND_PRECISION);
1831 seconds = (gdouble)(remainder % (60 * SLIDESHOW_SUBSECOND_PRECISION)) /
1832 SLIDESHOW_SUBSECOND_PRECISION;
1834 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1836 spin = pref_spin_new(hbox, _("Delay between image change hrs:mins:secs.dec"), NULL,
1838 options->slideshow.delay ? hours : 0.0,
1839 G_CALLBACK(slideshow_delay_hours_cb), NULL);
1840 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1841 spin = pref_spin_new(hbox, ":" , NULL,
1843 options->slideshow.delay ? minutes: 0.0,
1844 G_CALLBACK(slideshow_delay_minutes_cb), NULL);
1845 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1846 spin = pref_spin_new(hbox, ":", NULL,
1847 SLIDESHOW_MIN_SECONDS, 59, 1.0, 1,
1848 options->slideshow.delay ? seconds : 10.0,
1849 G_CALLBACK(slideshow_delay_seconds_cb), NULL);
1850 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1852 pref_checkbox_new_int(group, _("Random"), options->slideshow.random, &c_options->slideshow.random);
1853 pref_checkbox_new_int(group, _("Repeat"), options->slideshow.repeat, &c_options->slideshow.repeat);
1855 group = pref_group_new(vbox, FALSE, _("Image loading and caching"), GTK_ORIENTATION_VERTICAL);
1857 pref_spin_new_int(group, _("Decoded image cache size (Mb):"), NULL,
1858 0, 99999, 1, options->image.image_cache_max, &c_options->image.image_cache_max);
1859 pref_checkbox_new_int(group, _("Preload next image"),
1860 options->image.enable_read_ahead, &c_options->image.enable_read_ahead);
1862 pref_checkbox_new_int(group, _("Refresh on file change"),
1863 options->update_on_time_change, &c_options->update_on_time_change);
1865 group = pref_group_new(vbox, FALSE, _("Info sidebar heights"), GTK_ORIENTATION_VERTICAL);
1866 pref_label_new(group, _("NOTE! Geeqie must be restarted for changes to take effect"));
1867 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1868 pref_spin_new_int(hbox, _("Keywords:"), NULL,
1870 options->info_keywords.height, &c_options->info_keywords.height);
1871 pref_spin_new_int(hbox, _("Title:"), NULL,
1873 options->info_title.height, &c_options->info_title.height);
1874 pref_spin_new_int(hbox, _("Comment:"), NULL,
1876 options->info_comment.height, &c_options->info_comment.height);
1877 pref_spin_new_int(hbox, _("Rating:"), NULL,
1879 options->info_rating.height, &c_options->info_rating.height);
1881 group = pref_group_new(vbox, FALSE, _("On-line help search engine"), GTK_ORIENTATION_VERTICAL);
1883 help_search_engine_entry = gtk_entry_new();
1884 gtk_entry_set_text(GTK_ENTRY(help_search_engine_entry), options->help_search_engine);
1885 gtk_box_pack_start(GTK_BOX(group), help_search_engine_entry, FALSE, FALSE, 0);
1886 gtk_widget_show(help_search_engine_entry);
1888 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"));
1890 gtk_entry_set_icon_from_stock(GTK_ENTRY(help_search_engine_entry),
1891 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1892 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(help_search_engine_entry),
1893 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1894 gtk_entry_set_icon_from_stock(GTK_ENTRY(help_search_engine_entry),
1895 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1896 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(help_search_engine_entry),
1897 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1898 g_signal_connect(GTK_ENTRY(help_search_engine_entry), "icon-press",
1899 G_CALLBACK(help_search_engine_entry_icon_cb),
1900 help_search_engine_entry);
1904 static void config_tab_image(GtkWidget *notebook)
1909 GtkWidget *ct_button;
1910 GtkWidget *enlargement_button;
1914 vbox = scrolled_notebook_page(notebook, _("Image"));
1916 group = pref_group_new(vbox, FALSE, _("Zoom"), GTK_ORIENTATION_VERTICAL);
1918 table = pref_table_new(group, 2, 1, FALSE, FALSE);
1919 add_quality_menu(table, 0, 0, _("Quality:"), options->image.zoom_quality, &c_options->image.zoom_quality);
1922 pref_checkbox_new_int(group, _("Use GPU acceleration via Clutter library"),
1923 options->image.use_clutter_renderer, &c_options->image.use_clutter_renderer);
1926 pref_checkbox_new_int(group, _("Two pass rendering (apply HQ zoom and color correction in second pass)"),
1927 options->image.zoom_2pass, &c_options->image.zoom_2pass);
1929 c_options->image.zoom_increment = options->image.zoom_increment;
1930 spin = pref_spin_new(group, _("Zoom increment:"), NULL,
1931 0.01, 4.0, 0.01, 2, (gdouble)options->image.zoom_increment / 100.0,
1932 G_CALLBACK(zoom_increment_cb), NULL);
1933 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1935 group = pref_group_new(vbox, FALSE, _("Fit image to window"), GTK_ORIENTATION_VERTICAL);
1937 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1938 enlargement_button = pref_checkbox_new_int(hbox, _("Allow enlargement of image (max. size in %)"),
1939 options->image.zoom_to_fit_allow_expand, &c_options->image.zoom_to_fit_allow_expand);
1940 spin = pref_spin_new_int(hbox, NULL, NULL,
1942 options->image.max_enlargement_size, &c_options->image.max_enlargement_size);
1943 pref_checkbox_link_sensitivity(enlargement_button, spin);
1944 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."));
1946 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1947 ct_button = pref_checkbox_new_int(hbox, _("Virtual window size (% of actual window):"),
1948 options->image.limit_autofit_size, &c_options->image.limit_autofit_size);
1949 spin = pref_spin_new_int(hbox, NULL, NULL,
1951 options->image.max_autofit_size, &c_options->image.max_autofit_size);
1952 pref_checkbox_link_sensitivity(ct_button, spin);
1953 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."));
1955 group = pref_group_new(vbox, FALSE, _("Appearance"), GTK_ORIENTATION_VERTICAL);
1957 pref_checkbox_new_int(group, _("Use custom border color in window mode"),
1958 options->image.use_custom_border_color, &c_options->image.use_custom_border_color);
1960 pref_checkbox_new_int(group, _("Use custom border color in fullscreen mode"),
1961 options->image.use_custom_border_color_in_fullscreen, &c_options->image.use_custom_border_color_in_fullscreen);
1963 pref_color_button_new(group, _("Border color"), &options->image.border_color,
1964 G_CALLBACK(pref_color_button_set_cb), &c_options->image.border_color);
1966 c_options->image.border_color = options->image.border_color;
1968 pref_color_button_new(group, _("Alpha channel color 1"), &options->image.alpha_color_1,
1969 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_1);
1971 pref_color_button_new(group, _("Alpha channel color 2"), &options->image.alpha_color_2,
1972 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_2);
1974 c_options->image.alpha_color_1 = options->image.alpha_color_1;
1975 c_options->image.alpha_color_2 = options->image.alpha_color_2;
1977 group = pref_group_new(vbox, FALSE, _("Convenience"), GTK_ORIENTATION_VERTICAL);
1979 pref_checkbox_new_int(group, _("Auto rotate proofs using Exif information"),
1980 options->image.exif_proof_rotate_enable, &c_options->image.exif_proof_rotate_enable);
1984 static void config_tab_windows(GtkWidget *notebook)
1990 GtkWidget *ct_button;
1992 GtkWidget *image_overlay_template_view;
1993 GtkWidget *scrolled;
1994 GtkTextBuffer *buffer;
1996 vbox = scrolled_notebook_page(notebook, _("Windows"));
1998 group = pref_group_new(vbox, FALSE, _("State"), GTK_ORIENTATION_VERTICAL);
2000 ct_button = pref_checkbox_new_int(group, _("Remember window positions"),
2001 options->save_window_positions, &c_options->save_window_positions);
2003 button = pref_checkbox_new_int(group, _("Use saved window positions also for new windows"),
2004 options->use_saved_window_positions_for_new_windows, &c_options->use_saved_window_positions_for_new_windows);
2005 pref_checkbox_link_sensitivity(ct_button, button);
2007 pref_checkbox_new_int(group, _("Remember tool state (float/hidden)"),
2008 options->tools_restore_state, &c_options->tools_restore_state);
2010 pref_checkbox_new_int(group, _("Remember dialog window positions"),
2011 options->save_dialog_window_positions, &c_options->save_dialog_window_positions);
2013 pref_checkbox_new_int(group, _("Show window IDs"),
2014 options->show_window_ids, &c_options->show_window_ids);
2016 group = pref_group_new(vbox, FALSE, _("Size"), GTK_ORIENTATION_VERTICAL);
2018 pref_checkbox_new_int(group, _("Fit window to image when tools are hidden/floating"),
2019 options->image.fit_window_to_image, &c_options->image.fit_window_to_image);
2021 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2022 ct_button = pref_checkbox_new_int(hbox, _("Limit size when auto-sizing window (%):"),
2023 options->image.limit_window_size, &c_options->image.limit_window_size);
2024 spin = pref_spin_new_int(hbox, NULL, NULL,
2026 options->image.max_window_size, &c_options->image.max_window_size);
2027 pref_checkbox_link_sensitivity(ct_button, spin);
2029 group = pref_group_new(vbox, FALSE, _("Full screen"), GTK_ORIENTATION_VERTICAL);
2031 c_options->fullscreen.screen = options->fullscreen.screen;
2032 c_options->fullscreen.above = options->fullscreen.above;
2033 hbox = fullscreen_prefs_selection_new(_("Location:"), &c_options->fullscreen.screen, &c_options->fullscreen.above);
2034 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2035 gtk_widget_show(hbox);
2037 pref_checkbox_new_int(group, _("Smooth image flip"),
2038 options->fullscreen.clean_flip, &c_options->fullscreen.clean_flip);
2039 pref_checkbox_new_int(group, _("Disable screen saver"),
2040 options->fullscreen.disable_saver, &c_options->fullscreen.disable_saver);
2043 group = pref_group_new(vbox, FALSE, _("Overlay Screen Display"), GTK_ORIENTATION_VERTICAL);
2045 pref_label_new(group, _("Image overlay template"));
2047 scrolled = gtk_scrolled_window_new(NULL, NULL);
2048 gtk_widget_set_size_request(scrolled, 200, 150);
2049 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2050 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
2051 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2052 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 5);
2053 gtk_widget_show(scrolled);
2055 image_overlay_template_view = gtk_text_view_new();
2057 gtk_widget_set_tooltip_markup(image_overlay_template_view,
2058 _("<i>%name%</i> results in the filename of the picture.\n"
2059 "Also available: <i>%collection%</i>, <i>%number%</i>, <i>%total%</i>, <i>%date%</i>,\n"
2060 "<i>%size%</i> (filesize), <i>%width%</i>, <i>%height%</i>, <i>%res%</i> (resolution),\n"
2061 "<i>%rating%</i>, <i>%keywords%</i>, <i>%comment%</i> (XMP), <i>%imagecomment%</i> (JPEG)\n"
2062 "To access exif data use the exif name, e. g. <i>%formatted.Camera%</i> is the formatted camera name,\n"
2063 "<i>%Exif.Photo.DateTimeOriginal%</i> the date of the original shot.\n"
2064 "<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"
2065 "If two or more variables are connected with the |-sign, it prints available variables with a separator.\n"
2066 "<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"
2067 "if there's no ISO information in the Exif data.\n"
2068 "If a line is empty, it is removed. This allows one to add lines that totally disappear when no data is available.\n"
2070 gtk_container_add(GTK_CONTAINER(scrolled), image_overlay_template_view);
2071 gtk_widget_show(image_overlay_template_view);
2073 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2075 #if GTK_CHECK_VERSION(3,4,0)
2076 button = pref_button_new(NULL, GTK_STOCK_SELECT_FONT, _("Font"), FALSE,
2077 G_CALLBACK(image_overlay_set_font_cb), notebook);
2079 button = gtk_font_button_new();
2080 gtk_font_button_set_title(GTK_FONT_BUTTON(button), "Image Overlay Font");
2081 gtk_font_button_set_font_name(GTK_FONT_BUTTON(button), options->image_overlay.font);
2082 g_signal_connect(G_OBJECT(button), "font-set",
2083 G_CALLBACK(image_overlay_set_font_cb),NULL);
2085 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2086 gtk_widget_show(button);
2088 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Text"), FALSE,
2089 G_CALLBACK(image_overlay_set_text_colour_cb), NULL);
2090 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2091 gtk_widget_show(button);
2093 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Background"), FALSE,
2094 G_CALLBACK(image_overlay_set_background_colour_cb), NULL);
2095 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2096 gtk_widget_show(button);
2097 image_overlay_set_text_colours();
2099 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2100 G_CALLBACK(image_overlay_default_template_cb), image_overlay_template_view);
2101 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2102 gtk_widget_show(button);
2104 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
2105 G_CALLBACK(image_overlay_help_cb), NULL);
2106 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2107 gtk_widget_show(button);
2109 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(image_overlay_template_view));
2110 if (options->image_overlay.template_string) gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
2111 g_signal_connect(G_OBJECT(buffer), "changed",
2112 G_CALLBACK(image_overlay_template_view_changed_cb), image_overlay_template_view);
2117 static GtkTreeModel *create_class_model(void)
2119 GtkListStore *model;
2123 /* create list store */
2124 model = gtk_list_store_new(1, G_TYPE_STRING);
2125 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
2127 gtk_list_store_append(model, &iter);
2128 gtk_list_store_set(model, &iter, 0, _(format_class_list[i]), -1);
2130 return GTK_TREE_MODEL (model);
2135 static void config_tab_files(GtkWidget *notebook)
2142 GtkWidget *ct_button;
2143 GtkWidget *scrolled;
2144 GtkWidget *filter_view;
2145 GtkCellRenderer *renderer;
2146 GtkTreeSelection *selection;
2147 GtkTreeViewColumn *column;
2149 vbox = scrolled_notebook_page(notebook, _("Files"));
2151 group = pref_box_new(vbox, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
2153 pref_checkbox_new_int(group, _("Show hidden files or folders"),
2154 options->file_filter.show_hidden_files, &c_options->file_filter.show_hidden_files);
2155 pref_checkbox_new_int(group, _("Show parent folder (..)"),
2156 options->file_filter.show_parent_directory, &c_options->file_filter.show_parent_directory);
2157 pref_checkbox_new_int(group, _("Case sensitive sort"),
2158 options->file_sort.case_sensitive, &c_options->file_sort.case_sensitive);
2159 pref_checkbox_new_int(group, _("Natural sort order"),
2160 options->file_sort.natural, &c_options->file_sort.natural);
2161 pref_checkbox_new_int(group, _("Disable file extension checks"),
2162 options->file_filter.disable_file_extension_checks, &c_options->file_filter.disable_file_extension_checks);
2164 ct_button = pref_checkbox_new_int(group, _("Disable File Filtering"),
2165 options->file_filter.disable, &c_options->file_filter.disable);
2168 group = pref_group_new(vbox, FALSE, _("Grouping sidecar extensions"), GTK_ORIENTATION_VERTICAL);
2170 sidecar_ext_entry = gtk_entry_new();
2171 gtk_entry_set_text(GTK_ENTRY(sidecar_ext_entry), options->sidecar.ext);
2172 gtk_box_pack_start(GTK_BOX(group), sidecar_ext_entry, FALSE, FALSE, 0);
2173 gtk_widget_show(sidecar_ext_entry);
2175 group = pref_group_new(vbox, TRUE, _("File types"), GTK_ORIENTATION_VERTICAL);
2177 frame = pref_group_parent(group);
2178 g_signal_connect(G_OBJECT(ct_button), "toggled",
2179 G_CALLBACK(filter_disable_cb), frame);
2180 gtk_widget_set_sensitive(frame, !options->file_filter.disable);
2182 scrolled = gtk_scrolled_window_new(NULL, NULL);
2183 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2184 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2185 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2186 gtk_widget_show(scrolled);
2188 filter_store = gtk_list_store_new(1, G_TYPE_POINTER);
2189 filter_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(filter_store));
2190 g_object_unref(filter_store);
2191 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
2192 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_SINGLE);
2194 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(filter_view), FALSE);
2196 column = gtk_tree_view_column_new();
2197 gtk_tree_view_column_set_title(column, _("Filter"));
2198 gtk_tree_view_column_set_resizable(column, TRUE);
2200 renderer = gtk_cell_renderer_toggle_new();
2201 g_signal_connect(G_OBJECT(renderer), "toggled",
2202 G_CALLBACK(filter_store_enable_cb), filter_store);
2203 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2204 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2205 GINT_TO_POINTER(FE_ENABLE), NULL);
2207 renderer = gtk_cell_renderer_text_new();
2208 g_signal_connect(G_OBJECT(renderer), "edited",
2209 G_CALLBACK(filter_store_ext_edit_cb), filter_store);
2210 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2211 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2212 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2213 GINT_TO_POINTER(FE_EXTENSION), NULL);
2214 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2216 column = gtk_tree_view_column_new();
2217 gtk_tree_view_column_set_title(column, _("Description"));
2218 gtk_tree_view_column_set_resizable(column, TRUE);
2219 gtk_tree_view_column_set_fixed_width(column, 200);
2220 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
2222 renderer = gtk_cell_renderer_text_new();
2223 g_signal_connect(G_OBJECT(renderer), "edited",
2224 G_CALLBACK(filter_store_desc_edit_cb), filter_store);
2225 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2226 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2227 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2228 GINT_TO_POINTER(FE_DESCRIPTION), NULL);
2229 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2231 column = gtk_tree_view_column_new();
2232 gtk_tree_view_column_set_title(column, _("Class"));
2233 gtk_tree_view_column_set_resizable(column, TRUE);
2234 renderer = gtk_cell_renderer_combo_new();
2235 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE,
2236 "model", create_class_model(),
2241 g_signal_connect(G_OBJECT(renderer), "edited",
2242 G_CALLBACK(filter_store_class_edit_cb), filter_store);
2243 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2244 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2245 GINT_TO_POINTER(FE_CLASS), NULL);
2246 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2248 column = gtk_tree_view_column_new();
2249 gtk_tree_view_column_set_title(column, _("Writable"));
2250 gtk_tree_view_column_set_resizable(column, FALSE);
2251 renderer = gtk_cell_renderer_toggle_new();
2252 g_signal_connect(G_OBJECT(renderer), "toggled",
2253 G_CALLBACK(filter_store_writable_cb), filter_store);
2254 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2255 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2256 GINT_TO_POINTER(FE_WRITABLE), NULL);
2257 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2259 column = gtk_tree_view_column_new();
2260 gtk_tree_view_column_set_title(column, _("Sidecar is allowed"));
2261 gtk_tree_view_column_set_resizable(column, FALSE);
2262 renderer = gtk_cell_renderer_toggle_new();
2263 g_signal_connect(G_OBJECT(renderer), "toggled",
2264 G_CALLBACK(filter_store_sidecar_cb), filter_store);
2265 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2266 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2267 GINT_TO_POINTER(FE_ALLOW_SIDECAR), NULL);
2268 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2271 filter_store_populate();
2272 gtk_container_add(GTK_CONTAINER(scrolled), filter_view);
2273 gtk_widget_show(filter_view);
2275 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2277 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2278 G_CALLBACK(filter_default_cb), filter_view);
2279 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2280 gtk_widget_show(button);
2282 button = pref_button_new(NULL, GTK_STOCK_REMOVE, NULL, FALSE,
2283 G_CALLBACK(filter_remove_cb), filter_view);
2284 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2285 gtk_widget_show(button);
2287 button = pref_button_new(NULL, GTK_STOCK_ADD, NULL, FALSE,
2288 G_CALLBACK(filter_add_cb), filter_view);
2289 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2290 gtk_widget_show(button);
2294 static void config_tab_metadata(GtkWidget *notebook)
2299 GtkWidget *ct_button;
2303 vbox = scrolled_notebook_page(notebook, _("Metadata"));
2306 group = pref_group_new(vbox, FALSE, _("Metadata writing process"), GTK_ORIENTATION_VERTICAL);
2308 label = pref_label_new(group, _("Warning: Geeqie is built without Exiv2. Some options are disabled."));
2310 label = pref_label_new(group, _("Metadata are written in the following order. The process ends after first success."));
2311 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2313 ct_button = pref_checkbox_new_int(group, _("1) Save metadata in image files, or sidecar files, according to the XMP standard"),
2314 options->metadata.save_in_image_file, &c_options->metadata.save_in_image_file);
2316 gtk_widget_set_sensitive(ct_button, FALSE);
2319 pref_checkbox_new_int(group, _("2) Save metadata in '.metadata' folder, local to image folder (non-standard)"),
2320 options->metadata.enable_metadata_dirs, &c_options->metadata.enable_metadata_dirs);
2322 text = g_strdup_printf(_("3) Save metadata in Geeqie private directory '%s'"), get_metadata_cache_dir());
2323 label = pref_label_new(group, text);
2324 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2325 gtk_misc_set_padding(GTK_MISC(label), 22, 0);
2328 group = pref_group_new(vbox, FALSE, _("Step 1: Write to image files"), GTK_ORIENTATION_VERTICAL);
2330 gtk_widget_set_sensitive(group, FALSE);
2333 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2334 pref_checkbox_link_sensitivity(ct_button, hbox);
2336 pref_checkbox_new_int(hbox, _("Store metadata also in legacy IPTC tags (converted according to IPTC4XMP standard)"),
2337 options->metadata.save_legacy_IPTC, &c_options->metadata.save_legacy_IPTC);
2339 pref_checkbox_new_int(hbox, _("Warn if the image files are unwritable"),
2340 options->metadata.warn_on_write_problems, &c_options->metadata.warn_on_write_problems);
2342 pref_checkbox_new_int(hbox, _("Ask before writing to image files"),
2343 options->metadata.confirm_write, &c_options->metadata.confirm_write);
2345 pref_checkbox_new_int(hbox, _("Create sidecar files named image.ext.xmp (as opposed to image.xmp)"),
2346 options->metadata.sidecar_extended_name, &c_options->metadata.sidecar_extended_name);
2348 group = pref_group_new(vbox, FALSE, _("Step 2 and 3: write to Geeqie private files"), GTK_ORIENTATION_VERTICAL);
2350 gtk_widget_set_sensitive(group, FALSE);
2353 pref_checkbox_new_int(group, _("Use GQview legacy metadata format (supports only keywords and comments) instead of XMP"),
2354 options->metadata.save_legacy_format, &c_options->metadata.save_legacy_format);
2357 group = pref_group_new(vbox, FALSE, _("Miscellaneous"), GTK_ORIENTATION_VERTICAL);
2358 pref_checkbox_new_int(group, _("Write the same description tags (keywords, comment, etc.) to all grouped sidecars"),
2359 options->metadata.sync_grouped_files, &c_options->metadata.sync_grouped_files);
2361 pref_checkbox_new_int(group, _("Allow keywords to differ only in case"),
2362 options->metadata.keywords_case_sensitive, &c_options->metadata.keywords_case_sensitive);
2364 ct_button = pref_checkbox_new_int(group, _("Write altered image orientation to the metadata"),
2365 options->metadata.write_orientation, &c_options->metadata.write_orientation);
2367 gtk_widget_set_sensitive(ct_button, FALSE);
2370 group = pref_group_new(vbox, FALSE, _("Auto-save options"), GTK_ORIENTATION_VERTICAL);
2372 ct_button = pref_checkbox_new_int(group, _("Write metadata after timeout"),
2373 options->metadata.confirm_after_timeout, &c_options->metadata.confirm_after_timeout);
2375 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2376 pref_checkbox_link_sensitivity(ct_button, hbox);
2378 pref_spin_new_int(hbox, _("Timeout (seconds):"), NULL, 0, 900, 1,
2379 options->metadata.confirm_timeout, &c_options->metadata.confirm_timeout);
2381 pref_checkbox_new_int(group, _("Write metadata on image change"),
2382 options->metadata.confirm_on_image_change, &c_options->metadata.confirm_on_image_change);
2384 pref_checkbox_new_int(group, _("Write metadata on directory change"),
2385 options->metadata.confirm_on_dir_change, &c_options->metadata.confirm_on_dir_change);
2387 group = pref_group_new(vbox, FALSE, _("Pre-load metadata"), GTK_ORIENTATION_VERTICAL);
2389 ct_button = pref_checkbox_new_int(group, _("Read metadata in background"),
2390 options->read_metadata_in_idle, &c_options->read_metadata_in_idle);
2391 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");
2396 static void intent_menu_cb(GtkWidget *combo, gpointer data)
2398 gint *option = data;
2400 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
2404 *option = INTENT_PERCEPTUAL;
2407 *option = INTENT_RELATIVE_COLORIMETRIC;
2410 *option = INTENT_SATURATION;
2413 *option = INTENT_ABSOLUTE_COLORIMETRIC;
2418 static void add_intent_menu(GtkWidget *table, gint column, gint row, const gchar *text,
2419 gint option, gint *option_c)
2426 pref_table_label(table, column, row, text, 0.0);
2428 combo = gtk_combo_box_text_new();
2430 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Perceptual"));
2431 if (option == INTENT_PERCEPTUAL) current = 0;
2432 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Relative Colorimetric"));
2433 if (option == INTENT_RELATIVE_COLORIMETRIC) current = 1;
2434 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Saturation"));
2435 if (option == INTENT_SATURATION) current = 2;
2436 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Absolute Colorimetric"));
2437 if (option == INTENT_ABSOLUTE_COLORIMETRIC) current = 3;
2439 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
2441 gtk_widget_set_tooltip_text(combo,"Refer to the lcms documentation for the defaults used when the selected Intent is not available");
2443 g_signal_connect(G_OBJECT(combo), "changed",
2444 G_CALLBACK(intent_menu_cb), option_c);
2446 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
2447 GTK_EXPAND | GTK_FILL, 0, 0, 0);
2448 gtk_widget_show(combo);
2452 static void config_tab_color(GtkWidget *notebook)
2461 vbox = scrolled_notebook_page(notebook, _("Color management"));
2463 group = pref_group_new(vbox, FALSE, _("Input profiles"), GTK_ORIENTATION_VERTICAL);
2465 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
2468 table = pref_table_new(group, 3, COLOR_PROFILE_INPUTS + 1, FALSE, FALSE);
2469 gtk_table_set_col_spacings(GTK_TABLE(table), PREF_PAD_GAP);
2471 label = pref_table_label(table, 0, 0, _("Type"), 0.0);
2472 pref_label_bold(label, TRUE, FALSE);
2474 label = pref_table_label(table, 1, 0, _("Menu name"), 0.0);
2475 pref_label_bold(label, TRUE, FALSE);
2477 label = pref_table_label(table, 2, 0, _("File"), 0.0);
2478 pref_label_bold(label, TRUE, FALSE);
2480 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
2485 buf = g_strdup_printf(_("Input %d:"), i + COLOR_PROFILE_FILE);
2486 pref_table_label(table, 0, i + 1, buf, 1.0);
2489 entry = gtk_entry_new();
2490 gtk_entry_set_max_length(GTK_ENTRY(entry), EDITOR_NAME_MAX_LENGTH);
2491 if (options->color_profile.input_name[i])
2493 gtk_entry_set_text(GTK_ENTRY(entry), options->color_profile.input_name[i]);
2495 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, i + 1, i + 2,
2496 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2497 gtk_widget_show(entry);
2498 color_profile_input_name_entry[i] = entry;
2500 tabcomp = tab_completion_new(&entry, options->color_profile.input_file[i], NULL, ".icc", "ICC Files", NULL);
2501 tab_completion_add_select_button(entry, _("Select color profile"), FALSE);
2502 gtk_widget_set_size_request(entry, 160, -1);
2503 gtk_table_attach(GTK_TABLE(table), tabcomp, 2, 3, i + 1, i + 2,
2504 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2505 gtk_widget_show(tabcomp);
2506 color_profile_input_file_entry[i] = entry;
2509 group = pref_group_new(vbox, FALSE, _("Screen profile"), GTK_ORIENTATION_VERTICAL);
2511 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
2513 pref_checkbox_new_int(group, _("Use system screen profile if available"),
2514 options->color_profile.use_x11_screen_profile, &c_options->color_profile.use_x11_screen_profile);
2516 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2518 pref_table_label(table, 0, 0, _("Screen:"), 1.0);
2519 tabcomp = tab_completion_new(&color_profile_screen_file_entry,
2520 options->color_profile.screen_file, NULL, ".icc", "ICC Files", NULL);
2521 tab_completion_add_select_button(color_profile_screen_file_entry, _("Select color profile"), FALSE);
2522 gtk_widget_set_size_request(color_profile_screen_file_entry, 160, -1);
2524 add_intent_menu(table, 0, 1, _("Render Intent:"), options->color_profile.render_intent, &c_options->color_profile.render_intent);
2526 gtk_table_attach(GTK_TABLE(table), tabcomp, 1, 2,
2528 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2530 gtk_widget_show(tabcomp);
2533 /* advanced entry tab */
2534 static void config_tab_behavior(GtkWidget *notebook)
2541 GtkWidget *ct_button;
2545 GtkWidget *with_rename;
2546 GtkWidget *collections_on_top;
2548 vbox = scrolled_notebook_page(notebook, _("Behavior"));
2550 group = pref_group_new(vbox, FALSE, _("Delete"), GTK_ORIENTATION_VERTICAL);
2552 pref_checkbox_new_int(group, _("Confirm file delete"),
2553 options->file_ops.confirm_delete, &c_options->file_ops.confirm_delete);
2554 pref_checkbox_new_int(group, _("Enable Delete key"),
2555 options->file_ops.enable_delete_key, &c_options->file_ops.enable_delete_key);
2557 ct_button = pref_checkbox_new_int(group, _("Safe delete"),
2558 options->file_ops.safe_delete_enable, &c_options->file_ops.safe_delete_enable);
2560 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2561 pref_checkbox_link_sensitivity(ct_button, hbox);
2563 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_SPACE);
2564 pref_label_new(hbox, _("Folder:"));
2566 tabcomp = tab_completion_new(&safe_delete_path_entry, options->file_ops.safe_delete_path, NULL, NULL, NULL, NULL);
2567 tab_completion_add_select_button(safe_delete_path_entry, NULL, TRUE);
2568 gtk_box_pack_start(GTK_BOX(hbox), tabcomp, TRUE, TRUE, 0);
2569 gtk_widget_show(tabcomp);
2571 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2572 pref_checkbox_link_sensitivity(ct_button, hbox);
2574 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_GAP);
2575 spin = pref_spin_new_int(hbox, _("Maximum size:"), _("MB"),
2576 0, 2048, 1, options->file_ops.safe_delete_folder_maxsize, &c_options->file_ops.safe_delete_folder_maxsize);
2577 gtk_widget_set_tooltip_markup(spin, _("Set to 0 for unlimited size"));
2578 button = pref_button_new(NULL, NULL, _("View"), FALSE,
2579 G_CALLBACK(safe_delete_view_cb), NULL);
2580 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2581 gtk_widget_show(button);
2583 button = pref_button_new(NULL, GTK_STOCK_CLEAR, NULL, FALSE,
2584 G_CALLBACK(safe_delete_clear_cb), NULL);
2585 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2586 gtk_widget_show(button);
2589 group = pref_group_new(vbox, FALSE, _("Behavior"), GTK_ORIENTATION_VERTICAL);
2591 pref_checkbox_new_int(group, _("Descend folders in tree view"),
2592 options->tree_descend_subdirs, &c_options->tree_descend_subdirs);
2594 pref_checkbox_new_int(group, _("In place renaming"),
2595 options->file_ops.enable_in_place_rename, &c_options->file_ops.enable_in_place_rename);
2597 pref_checkbox_new_int(group, _("List directory view uses single click to enter"),
2598 options->view_dir_list_single_click_enter, &c_options->view_dir_list_single_click_enter);
2600 marks = pref_checkbox_new_int(group, _("Save marks on exit"),
2601 options->marks_save, &c_options->marks_save);
2602 gtk_widget_set_tooltip_text(marks,"Note that marks linked to a keyword will be saved irrespective of this setting");
2604 with_rename = pref_checkbox_new_int(group, _("Use \"With Rename\" as default for Copy/Move dialogs"),
2605 options->with_rename, &c_options->with_rename);
2606 gtk_widget_set_tooltip_text(with_rename,"Change the default button for Copy/Move dialogs");
2608 collections_on_top = pref_checkbox_new_int(group, _("Open collections on top"),
2609 options->collections_on_top, &c_options->collections_on_top);
2610 gtk_widget_set_tooltip_text(collections_on_top,"Open collections window on top");
2612 pref_spin_new_int(group, _("Recent folder list maximum size"), NULL,
2613 1, 50, 1, options->open_recent_list_maxsize, &c_options->open_recent_list_maxsize);
2615 pref_spin_new_int(group, _("Drag'n drop icon size"), NULL,
2616 16, 256, 16, options->dnd_icon_size, &c_options->dnd_icon_size);
2618 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2619 add_clipboard_selection_menu(table, 0, 0, _("Copy path clipboard selection:"), options->clipboard_selection, &c_options->clipboard_selection);
2621 group = pref_group_new(vbox, FALSE, _("Navigation"), GTK_ORIENTATION_VERTICAL);
2623 pref_checkbox_new_int(group, _("Progressive keyboard scrolling"),
2624 options->progressive_key_scrolling, &c_options->progressive_key_scrolling);
2625 pref_spin_new_int(group, _("Keyboard scrolling step multiplier:"), NULL,
2626 1, 32, 1, options->keyboard_scroll_step, (int *)&c_options->keyboard_scroll_step);
2627 pref_checkbox_new_int(group, _("Mouse wheel scrolls image"),
2628 options->mousewheel_scrolls, &c_options->mousewheel_scrolls);
2629 pref_checkbox_new_int(group, _("Navigation by left or middle click on image"),
2630 options->image_lm_click_nav, &c_options->image_lm_click_nav);
2631 pref_checkbox_new_int(group, _("Play video by left click on image"),
2632 options->image_l_click_video, &c_options->image_l_click_video);
2633 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2634 add_video_menu(table, 0, 0, _("Play with:"), options->image_l_click_video_editor, &c_options->image_l_click_video_editor);
2638 group = pref_group_new(vbox, FALSE, _("Debugging"), GTK_ORIENTATION_VERTICAL);
2640 pref_spin_new_int(group, _("Debug level:"), NULL,
2641 DEBUG_LEVEL_MIN, DEBUG_LEVEL_MAX, 1, get_debug_level(), &debug_c);
2643 pref_checkbox_new_int(group, _("Timer data"),
2644 options->log_window.timer_data, &c_options->log_window.timer_data);
2646 pref_spin_new_int(group, _("Log Window max. lines:"), NULL,
2647 1, 99999, 1, options->log_window_lines, &options->log_window_lines);
2651 /* accelerators tab */
2652 static void config_tab_accelerators(GtkWidget *notebook)
2658 GtkWidget *scrolled;
2659 GtkWidget *accel_view;
2660 GtkCellRenderer *renderer;
2661 GtkTreeSelection *selection;
2662 GtkTreeViewColumn *column;
2664 vbox = scrolled_notebook_page(notebook, _("Keyboard"));
2666 group = pref_group_new(vbox, TRUE, _("Accelerators"), GTK_ORIENTATION_VERTICAL);
2668 scrolled = gtk_scrolled_window_new(NULL, NULL);
2669 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2670 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2671 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2672 gtk_widget_show(scrolled);
2674 accel_store = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
2676 accel_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(accel_store));
2677 g_object_unref(accel_store);
2678 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(accel_view));
2679 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_MULTIPLE);
2681 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(accel_view), FALSE);
2683 renderer = gtk_cell_renderer_text_new();
2685 column = gtk_tree_view_column_new_with_attributes(_("Action"),
2690 gtk_tree_view_column_set_sort_column_id(column, AE_ACTION);
2691 gtk_tree_view_column_set_resizable(column, TRUE);
2692 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2695 renderer = gtk_cell_renderer_accel_new();
2696 g_signal_connect(G_OBJECT(renderer), "accel-cleared",
2697 G_CALLBACK(accel_store_cleared_cb), accel_store);
2698 g_signal_connect(G_OBJECT(renderer), "accel-edited",
2699 G_CALLBACK(accel_store_edited_cb), accel_store);
2702 g_object_set (renderer,
2704 "accel-mode", GTK_CELL_RENDERER_ACCEL_MODE_OTHER,
2707 column = gtk_tree_view_column_new_with_attributes(_("KEY"),
2712 gtk_tree_view_column_set_sort_column_id(column, AE_KEY);
2713 gtk_tree_view_column_set_resizable(column, TRUE);
2714 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2716 renderer = gtk_cell_renderer_text_new();
2718 column = gtk_tree_view_column_new_with_attributes(_("Tooltip"),
2723 gtk_tree_view_column_set_sort_column_id(column, AE_TOOLTIP);
2724 gtk_tree_view_column_set_resizable(column, TRUE);
2725 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2727 renderer = gtk_cell_renderer_text_new();
2729 column = gtk_tree_view_column_new_with_attributes("Accel",
2734 gtk_tree_view_column_set_sort_column_id(column, AE_ACCEL);
2735 gtk_tree_view_column_set_resizable(column, TRUE);
2736 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2738 accel_store_populate();
2739 gtk_container_add(GTK_CONTAINER(scrolled), accel_view);
2740 gtk_widget_show(accel_view);
2742 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2744 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2745 G_CALLBACK(accel_default_cb), accel_view);
2746 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2747 gtk_widget_show(button);
2749 button = pref_button_new(NULL, NULL, _("Reset selected"), FALSE,
2750 G_CALLBACK(accel_reset_cb), accel_view);
2751 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2752 gtk_widget_show(button);
2756 static void config_tab_toolbar(GtkWidget *notebook)
2759 GtkWidget *toolbardata;
2762 lw = layout_window_list->data;
2764 vbox = scrolled_notebook_page(notebook, _("Toolbar"));
2766 toolbardata = toolbar_select_new(lw);
2767 gtk_box_pack_start(GTK_BOX(vbox), toolbardata, TRUE, TRUE, 0);
2768 gtk_widget_show(vbox);
2772 static void config_tab_stereo(GtkWidget *notebook)
2780 GtkWidget *fs_button;
2781 vbox = scrolled_notebook_page(notebook, _("Stereo"));
2783 group = pref_group_new(vbox, FALSE, _("Windowed stereo mode"), GTK_ORIENTATION_VERTICAL);
2785 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2786 add_stereo_mode_menu(table, 0, 0, _("Windowed stereo mode"), options->stereo.mode, &c_options->stereo.mode, FALSE);
2788 table = pref_table_new(group, 2, 2, TRUE, FALSE);
2789 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2790 pref_checkbox_new_int(box, _("Mirror left image"),
2791 options->stereo.mode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.mirror_left);
2792 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2793 pref_checkbox_new_int(box, _("Flip left image"),
2794 options->stereo.mode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.flip_left);
2795 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2796 pref_checkbox_new_int(box, _("Mirror right image"),
2797 options->stereo.mode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.mirror_right);
2798 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2799 pref_checkbox_new_int(box, _("Flip right image"),
2800 options->stereo.mode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.flip_right);
2801 pref_checkbox_new_int(group, _("Swap left and right images"),
2802 options->stereo.mode & PR_STEREO_SWAP, &c_options->stereo.tmp.swap);
2803 pref_checkbox_new_int(group, _("Disable stereo mode on single image source"),
2804 options->stereo.mode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.temp_disable);
2806 group = pref_group_new(vbox, FALSE, _("Fullscreen stereo mode"), GTK_ORIENTATION_VERTICAL);
2807 fs_button = pref_checkbox_new_int(group, _("Use different settings for fullscreen"),
2808 options->stereo.enable_fsmode, &c_options->stereo.enable_fsmode);
2809 box2 = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2810 pref_checkbox_link_sensitivity(fs_button, box2);
2811 table = pref_table_new(box2, 2, 1, FALSE, FALSE);
2812 add_stereo_mode_menu(table, 0, 0, _("Fullscreen stereo mode"), options->stereo.fsmode, &c_options->stereo.fsmode, TRUE);
2813 table = pref_table_new(box2, 2, 2, TRUE, FALSE);
2814 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2815 pref_checkbox_new_int(box, _("Mirror left image"),
2816 options->stereo.fsmode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.fs_mirror_left);
2817 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2818 pref_checkbox_new_int(box, _("Flip left image"),
2819 options->stereo.fsmode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.fs_flip_left);
2820 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2821 pref_checkbox_new_int(box, _("Mirror right image"),
2822 options->stereo.fsmode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.fs_mirror_right);
2823 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2824 pref_checkbox_new_int(box, _("Flip right image"),
2825 options->stereo.fsmode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.fs_flip_right);
2826 pref_checkbox_new_int(box2, _("Swap left and right images"),
2827 options->stereo.fsmode & PR_STEREO_SWAP, &c_options->stereo.tmp.fs_swap);
2828 pref_checkbox_new_int(box2, _("Disable stereo mode on single image source"),
2829 options->stereo.fsmode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.fs_temp_disable);
2831 group2 = pref_group_new(box2, FALSE, _("Fixed position"), GTK_ORIENTATION_VERTICAL);
2832 table = pref_table_new(group2, 5, 3, FALSE, FALSE);
2833 pref_table_spin_new_int(table, 0, 0, _("Width"), NULL,
2834 1, 5000, 1, options->stereo.fixed_w, &c_options->stereo.fixed_w);
2835 pref_table_spin_new_int(table, 3, 0, _("Height"), NULL,
2836 1, 5000, 1, options->stereo.fixed_h, &c_options->stereo.fixed_h);
2837 pref_table_spin_new_int(table, 0, 1, _("Left X"), NULL,
2838 0, 5000, 1, options->stereo.fixed_x1, &c_options->stereo.fixed_x1);
2839 pref_table_spin_new_int(table, 3, 1, _("Left Y"), NULL,
2840 0, 5000, 1, options->stereo.fixed_y1, &c_options->stereo.fixed_y1);
2841 pref_table_spin_new_int(table, 0, 2, _("Right X"), NULL,
2842 0, 5000, 1, options->stereo.fixed_x2, &c_options->stereo.fixed_x2);
2843 pref_table_spin_new_int(table, 3, 2, _("Right Y"), NULL,
2844 0, 5000, 1, options->stereo.fixed_y2, &c_options->stereo.fixed_y2);
2848 /* Main preferences window */
2849 static void config_window_create(void)
2851 GtkWidget *win_vbox;
2853 GtkWidget *notebook;
2855 GtkWidget *ct_button;
2857 if (!c_options) c_options = init_options(NULL);
2859 configwindow = window_new(GTK_WINDOW_TOPLEVEL, "preferences", PIXBUF_INLINE_ICON_CONFIG, NULL, _("Preferences"));
2860 gtk_window_set_type_hint(GTK_WINDOW(configwindow), GDK_WINDOW_TYPE_HINT_DIALOG);
2861 g_signal_connect(G_OBJECT(configwindow), "delete_event",
2862 G_CALLBACK(config_window_delete), NULL);
2863 gtk_window_set_default_size(GTK_WINDOW(configwindow), CONFIG_WINDOW_DEF_WIDTH, CONFIG_WINDOW_DEF_HEIGHT);
2864 gtk_window_set_resizable(GTK_WINDOW(configwindow), TRUE);
2865 gtk_container_set_border_width(GTK_CONTAINER(configwindow), PREF_PAD_BORDER);
2867 win_vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE);
2868 gtk_container_add(GTK_CONTAINER(configwindow), win_vbox);
2869 gtk_widget_show(win_vbox);
2871 notebook = gtk_notebook_new();
2872 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
2873 gtk_box_pack_start(GTK_BOX(win_vbox), notebook, TRUE, TRUE, 0);
2875 config_tab_general(notebook);
2876 config_tab_image(notebook);
2877 config_tab_windows(notebook);
2878 config_tab_accelerators(notebook);
2879 config_tab_files(notebook);
2880 config_tab_metadata(notebook);
2881 config_tab_color(notebook);
2882 config_tab_stereo(notebook);
2883 config_tab_behavior(notebook);
2884 config_tab_toolbar(notebook);
2886 hbox = gtk_hbutton_box_new();
2887 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
2888 gtk_box_set_spacing(GTK_BOX(hbox), PREF_PAD_BUTTON_GAP);
2889 gtk_box_pack_end(GTK_BOX(win_vbox), hbox, FALSE, FALSE, 0);
2890 gtk_widget_show(hbox);
2892 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
2893 G_CALLBACK(config_window_help_cb), notebook);
2894 gtk_container_add(GTK_CONTAINER(hbox), button);
2895 gtk_widget_set_can_default(button, TRUE);
2896 gtk_widget_show(button);
2898 button = pref_button_new(NULL, GTK_STOCK_OK, NULL, FALSE,
2899 G_CALLBACK(config_window_ok_cb), NULL);
2900 gtk_container_add(GTK_CONTAINER(hbox), button);
2901 gtk_widget_set_can_default(button, TRUE);
2902 gtk_widget_grab_default(button);
2903 gtk_widget_show(button);
2907 button = pref_button_new(NULL, GTK_STOCK_SAVE, NULL, FALSE,
2908 G_CALLBACK(config_window_save_cb), NULL);
2909 gtk_container_add(GTK_CONTAINER(hbox), button);
2910 gtk_widget_set_can_default(button, TRUE);
2911 gtk_widget_show(button);
2913 button = pref_button_new(NULL, GTK_STOCK_APPLY, NULL, FALSE,
2914 G_CALLBACK(config_window_apply_cb), NULL);
2915 gtk_container_add(GTK_CONTAINER(hbox), button);
2916 gtk_widget_set_can_default(button, TRUE);
2917 gtk_widget_show(button);
2919 button = pref_button_new(NULL, GTK_STOCK_CANCEL, NULL, FALSE,
2920 G_CALLBACK(config_window_close_cb), NULL);
2921 gtk_container_add(GTK_CONTAINER(hbox), button);
2922 gtk_widget_set_can_default(button, TRUE);
2923 gtk_widget_show(button);
2925 if (!generic_dialog_get_alternative_button_order(configwindow))
2927 gtk_box_reorder_child(GTK_BOX(hbox), ct_button, -1);
2930 gtk_widget_show(notebook);
2932 gtk_widget_show(configwindow);
2936 *-----------------------------------------------------------------------------
2937 * config window show (public)
2938 *-----------------------------------------------------------------------------
2941 void show_config_window(void)
2945 gtk_window_present(GTK_WINDOW(configwindow));
2949 config_window_create();
2958 void show_about_window(LayoutWindow *lw)
2960 GdkPixbuf *pixbuf_logo;
2961 GdkPixbuf *pixbuf_icon;
2962 gchar *authors[1000];
2970 #define LINE_LENGTH 1000
2971 gchar line[LINE_LENGTH];
2973 copyright = g_string_new(NULL);
2974 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");
2976 zd_path = g_build_filename(GQ_BIN_DIR, TIMEZONE_DATABASE, NULL);
2977 cd = ZDOpenDatabase(zd_path);
2980 copyright = g_string_append(copyright, ZDGetNotice(cd));
2982 ZDCloseDatabase(cd);
2986 path = g_build_filename(GQ_HELPDIR, "AUTHORS", NULL);
2987 fp = fopen(path, "r");
2990 while(fgets(line, LINE_LENGTH, fp))
2992 /* get rid of ending \n from fgets */
2993 line[strlen(line) - 1] = '\0';
2994 authors[i_authors] = g_strdup(line);
2997 authors[i_authors] = NULL;
3002 comment = g_strconcat("Development and bug reports:\n", GQ_EMAIL_ADDRESS,
3003 "\nhttps://github.com/BestImageViewer/geeqie/issues",NULL);
3005 pixbuf_logo = pixbuf_inline(PIXBUF_INLINE_LOGO);
3006 pixbuf_icon = pixbuf_inline(PIXBUF_INLINE_ICON);
3007 gtk_show_about_dialog(GTK_WINDOW(lw->window),
3008 "title", _("About Geeqie"),
3010 "program-name", GQ_APPNAME,
3012 "logo", pixbuf_logo,
3013 "icon", pixbuf_icon,
3014 "website", GQ_WEBSITE,
3015 "website-label", "Website",
3016 "comments", comment,
3018 "translator-credits", _("translator-credits"),
3019 "wrap-license", TRUE,
3020 "license", copyright->str,
3023 g_string_free(copyright, TRUE);
3026 while(n < i_authors)
3036 static void image_overlay_set_text_colours()
3038 c_options->image_overlay.text_red = options->image_overlay.text_red;
3039 c_options->image_overlay.text_green = options->image_overlay.text_green;
3040 c_options->image_overlay.text_blue = options->image_overlay.text_blue;
3041 c_options->image_overlay.text_alpha = options->image_overlay.text_alpha;
3042 c_options->image_overlay.background_red = options->image_overlay.background_red;
3043 c_options->image_overlay.background_green = options->image_overlay.background_green;
3044 c_options->image_overlay.background_blue = options->image_overlay.background_blue;
3045 c_options->image_overlay.background_alpha = options->image_overlay.background_alpha;
3047 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */