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 c_options->thumbnails.spec_standard =FALSE;
1571 static void cache_geeqie_cb(GtkWidget *widget, gpointer data)
1573 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1575 c_options->thumbnails.spec_standard =TRUE;
1576 c_options->thumbnails.cache_into_dirs = FALSE;
1580 c_options->thumbnails.spec_standard =FALSE;
1584 static void cache_local_cb(GtkWidget *widget, gpointer data)
1586 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1588 c_options->thumbnails.cache_into_dirs = TRUE;
1589 c_options->thumbnails.spec_standard =FALSE;
1593 c_options->thumbnails.cache_into_dirs = FALSE;
1597 static void help_search_engine_entry_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1598 GdkEvent *event, gpointer userdata)
1600 if (pos == GTK_ENTRY_ICON_PRIMARY)
1602 gtk_entry_set_text(GTK_ENTRY(userdata), HELP_SEARCH_ENGINE);
1606 gtk_entry_set_text(GTK_ENTRY(userdata), "");
1610 static void star_rating_star_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1611 GdkEvent *event, gpointer userdata)
1613 gchar *rating_symbol;
1615 if (pos == GTK_ENTRY_ICON_PRIMARY)
1617 rating_symbol = g_strdup_printf("U+%X", STAR_RATING_STAR);
1618 gtk_entry_set_text(GTK_ENTRY(userdata), rating_symbol);
1619 g_free(rating_symbol);
1623 gtk_entry_set_text(GTK_ENTRY(userdata), "U+");
1624 gtk_widget_grab_focus(GTK_WIDGET(userdata));
1625 gtk_editable_select_region(GTK_EDITABLE(userdata), 2, 2);
1629 static void star_rating_rejected_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1630 GdkEvent *event, gpointer userdata)
1632 gchar *rating_symbol;
1634 if (pos == GTK_ENTRY_ICON_PRIMARY)
1636 rating_symbol = g_strdup_printf("U+%X", STAR_RATING_REJECTED);
1637 gtk_entry_set_text(GTK_ENTRY(userdata), rating_symbol);
1638 g_free(rating_symbol);
1642 gtk_entry_set_text(GTK_ENTRY(userdata), "U+");
1643 gtk_widget_grab_focus(GTK_WIDGET(userdata));
1644 gtk_editable_select_region(GTK_EDITABLE(userdata), 2, 2);
1648 static guint star_rating_symbol_test(GtkWidget *widget, gpointer data)
1650 GtkContainer *hbox = data;
1651 GString *str = g_string_new(NULL);
1652 GtkEntry *hex_code_entry;
1653 gchar *hex_code_full;
1656 guint64 hex_value = 0;
1658 list = gtk_container_get_children(hbox);
1660 hex_code_entry = g_list_nth_data(list, 2);
1661 hex_code_full = g_strdup(gtk_entry_get_text(hex_code_entry));
1663 hex_code = g_strsplit(hex_code_full, "+", 2);
1664 if (hex_code[0] && hex_code[1])
1666 hex_value = strtoull(hex_code[1], NULL, 16);
1668 if (!hex_value || hex_value > 0x10FFFF)
1670 hex_value = 0x003F; // Unicode 'Question Mark'
1672 str = g_string_append_unichar(str, (gunichar)hex_value);
1673 gtk_label_set_text(g_list_nth_data(list, 1), str->str);
1675 g_strfreev(hex_code);
1676 g_string_free(str, TRUE);
1677 g_free(hex_code_full);
1682 static void star_rating_star_test_cb(GtkWidget *widget, gpointer data)
1684 guint64 star_symbol;
1686 star_symbol = star_rating_symbol_test(widget, data);
1687 c_options->star_rating.star = star_symbol;
1690 static void star_rating_rejected_test_cb(GtkWidget *widget, gpointer data)
1692 guint64 rejected_symbol;
1694 rejected_symbol = star_rating_symbol_test(widget, data);
1695 c_options->star_rating.rejected = rejected_symbol;
1698 /* general options tab */
1699 static void config_tab_general(GtkWidget *notebook)
1704 GtkWidget *group_frame;
1705 GtkWidget *subgroup;
1707 GtkWidget *ct_button;
1710 gint hours, minutes, remainder;
1712 GtkWidget *star_rating_entry;
1714 gchar *rating_symbol;
1716 vbox = scrolled_notebook_page(notebook, _("General"));
1718 group = pref_group_new(vbox, FALSE, _("Thumbnails"), GTK_ORIENTATION_VERTICAL);
1720 table = pref_table_new(group, 2, 2, FALSE, FALSE);
1721 add_thumb_size_menu(table, 0, 0, _("Size:"));
1722 add_quality_menu(table, 0, 1, _("Quality:"), options->thumbnails.quality, &c_options->thumbnails.quality);
1724 ct_button = pref_checkbox_new_int(group, _("Cache thumbnails"),
1725 options->thumbnails.enable_caching, &c_options->thumbnails.enable_caching);
1727 subgroup = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1728 pref_checkbox_link_sensitivity(ct_button, subgroup);
1730 group_frame = pref_frame_new(subgroup, TRUE, _("Use Geeqie thumbnail style and cache"),
1731 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1732 button = pref_radiobutton_new(group_frame, NULL, get_thumbnails_cache_dir(),
1733 !options->thumbnails.spec_standard,
1734 G_CALLBACK(cache_geeqie_cb), NULL);
1736 group_frame = pref_frame_new(subgroup, TRUE,
1737 _("Store thumbnails local to image folder (non-standard)"),
1738 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1739 pref_radiobutton_new(group_frame, button, "*/.thumbnails",
1740 options->thumbnails.cache_into_dirs,
1741 G_CALLBACK(cache_local_cb), NULL);
1743 group_frame = pref_frame_new(subgroup, TRUE,
1744 _("Use standard thumbnail style and cache, shared with other applications"),
1745 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1746 pref_radiobutton_new(group_frame, button, get_thumbnails_standard_cache_dir(),
1747 options->thumbnails.spec_standard,
1748 G_CALLBACK(cache_standard_cb), NULL);
1750 pref_checkbox_new_int(group, _("Use EXIF thumbnails when available (EXIF thumbnails may be outdated)"),
1751 options->thumbnails.use_exif, &c_options->thumbnails.use_exif);
1753 spin = pref_spin_new_int(group, _("Collection preview:"), NULL,
1755 options->thumbnails.collection_preview, &c_options->thumbnails.collection_preview);
1756 gtk_widget_set_tooltip_text(spin, _("The maximum number of thumbnails shown in a Collection preview montage"));
1758 #ifdef HAVE_FFMPEGTHUMBNAILER_METADATA
1759 pref_checkbox_new_int(group, _("Use embedded metadata in video files as thumbnails when available"),
1760 options->thumbnails.use_ft_metadata, &c_options->thumbnails.use_ft_metadata);
1762 // pref_checkbox_new_int(group, _("Ignore embedded metadata if size is too small"),
1763 // options->thumbnails.use_ft_metadata_small, &c_options->thumbnails.use_ft_metadata_small);
1766 group = pref_group_new(vbox, FALSE, _("Star Rating"), GTK_ORIENTATION_VERTICAL);
1768 c_options->star_rating.star = options->star_rating.star;
1769 c_options->star_rating.rejected = options->star_rating.rejected;
1771 str = g_string_new(NULL);
1772 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1773 pref_label_new(hbox, "Star character: ");
1774 str = g_string_append_unichar(str, options->star_rating.star);
1775 pref_label_new(hbox, g_strdup(str->str));
1776 rating_symbol = g_strdup_printf("U+%X", options->star_rating.star);
1777 star_rating_entry = gtk_entry_new();
1778 gtk_entry_set_text(GTK_ENTRY(star_rating_entry), rating_symbol);
1779 gtk_box_pack_start(GTK_BOX(hbox), star_rating_entry, FALSE, FALSE, 0);
1780 gtk_entry_set_width_chars(GTK_ENTRY(star_rating_entry), 15);
1781 gtk_widget_show(star_rating_entry);
1782 button = pref_button_new(NULL, NULL, _("Set"), FALSE,
1783 G_CALLBACK(star_rating_star_test_cb), hbox);
1784 gtk_widget_set_tooltip_text(button, _("Display selected character"));
1785 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1786 gtk_widget_show(button);
1787 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."));
1788 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1789 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1790 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1791 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1792 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1793 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1794 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1795 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1796 g_signal_connect(GTK_ENTRY(star_rating_entry), "icon-press",
1797 G_CALLBACK(star_rating_star_icon_cb),
1800 g_string_free(str, TRUE);
1801 g_free(rating_symbol);
1803 str = g_string_new(NULL);
1804 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1805 pref_label_new(hbox, "Rejected character: ");
1806 str = g_string_append_unichar(str, options->star_rating.rejected);
1807 pref_label_new(hbox, g_strdup(str->str));
1808 rating_symbol = g_strdup_printf("U+%X", options->star_rating.rejected);
1809 star_rating_entry = gtk_entry_new();
1810 gtk_entry_set_text(GTK_ENTRY(star_rating_entry), rating_symbol);
1811 gtk_box_pack_start(GTK_BOX(hbox), star_rating_entry, FALSE, FALSE, 0);
1812 gtk_entry_set_width_chars(GTK_ENTRY(star_rating_entry), 15);
1813 gtk_widget_show(star_rating_entry);
1814 button = pref_button_new(NULL, NULL, _("Set"), FALSE,
1815 G_CALLBACK(star_rating_rejected_test_cb), hbox);
1816 gtk_widget_set_tooltip_text(button, _("Display selected character"));
1817 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1818 gtk_widget_show(button);
1819 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."));
1820 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1821 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1822 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1823 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1824 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1825 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1826 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1827 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1828 g_signal_connect(GTK_ENTRY(star_rating_entry), "icon-press",
1829 G_CALLBACK(star_rating_rejected_icon_cb),
1832 g_string_free(str, TRUE);
1833 g_free(rating_symbol);
1835 group = pref_group_new(vbox, FALSE, _("Slide show"), GTK_ORIENTATION_VERTICAL);
1837 c_options->slideshow.delay = options->slideshow.delay;
1838 hours = options->slideshow.delay / (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1839 remainder = options->slideshow.delay % (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1840 minutes = remainder / (60 * SLIDESHOW_SUBSECOND_PRECISION);
1841 seconds = (gdouble)(remainder % (60 * SLIDESHOW_SUBSECOND_PRECISION)) /
1842 SLIDESHOW_SUBSECOND_PRECISION;
1844 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1846 spin = pref_spin_new(hbox, _("Delay between image change hrs:mins:secs.dec"), NULL,
1848 options->slideshow.delay ? hours : 0.0,
1849 G_CALLBACK(slideshow_delay_hours_cb), NULL);
1850 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1851 spin = pref_spin_new(hbox, ":" , NULL,
1853 options->slideshow.delay ? minutes: 0.0,
1854 G_CALLBACK(slideshow_delay_minutes_cb), NULL);
1855 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1856 spin = pref_spin_new(hbox, ":", NULL,
1857 SLIDESHOW_MIN_SECONDS, 59, 1.0, 1,
1858 options->slideshow.delay ? seconds : 10.0,
1859 G_CALLBACK(slideshow_delay_seconds_cb), NULL);
1860 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1862 pref_checkbox_new_int(group, _("Random"), options->slideshow.random, &c_options->slideshow.random);
1863 pref_checkbox_new_int(group, _("Repeat"), options->slideshow.repeat, &c_options->slideshow.repeat);
1865 group = pref_group_new(vbox, FALSE, _("Image loading and caching"), GTK_ORIENTATION_VERTICAL);
1867 pref_spin_new_int(group, _("Decoded image cache size (Mb):"), NULL,
1868 0, 99999, 1, options->image.image_cache_max, &c_options->image.image_cache_max);
1869 pref_checkbox_new_int(group, _("Preload next image"),
1870 options->image.enable_read_ahead, &c_options->image.enable_read_ahead);
1872 pref_checkbox_new_int(group, _("Refresh on file change"),
1873 options->update_on_time_change, &c_options->update_on_time_change);
1875 group = pref_group_new(vbox, FALSE, _("Info sidebar heights"), GTK_ORIENTATION_VERTICAL);
1876 pref_label_new(group, _("NOTE! Geeqie must be restarted for changes to take effect"));
1877 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1878 pref_spin_new_int(hbox, _("Keywords:"), NULL,
1880 options->info_keywords.height, &c_options->info_keywords.height);
1881 pref_spin_new_int(hbox, _("Title:"), NULL,
1883 options->info_title.height, &c_options->info_title.height);
1884 pref_spin_new_int(hbox, _("Comment:"), NULL,
1886 options->info_comment.height, &c_options->info_comment.height);
1887 pref_spin_new_int(hbox, _("Rating:"), NULL,
1889 options->info_rating.height, &c_options->info_rating.height);
1891 group = pref_group_new(vbox, FALSE, _("On-line help search engine"), GTK_ORIENTATION_VERTICAL);
1893 help_search_engine_entry = gtk_entry_new();
1894 gtk_entry_set_text(GTK_ENTRY(help_search_engine_entry), options->help_search_engine);
1895 gtk_box_pack_start(GTK_BOX(group), help_search_engine_entry, FALSE, FALSE, 0);
1896 gtk_widget_show(help_search_engine_entry);
1898 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"));
1900 gtk_entry_set_icon_from_stock(GTK_ENTRY(help_search_engine_entry),
1901 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1902 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(help_search_engine_entry),
1903 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1904 gtk_entry_set_icon_from_stock(GTK_ENTRY(help_search_engine_entry),
1905 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1906 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(help_search_engine_entry),
1907 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1908 g_signal_connect(GTK_ENTRY(help_search_engine_entry), "icon-press",
1909 G_CALLBACK(help_search_engine_entry_icon_cb),
1910 help_search_engine_entry);
1914 static void config_tab_image(GtkWidget *notebook)
1919 GtkWidget *ct_button;
1920 GtkWidget *enlargement_button;
1924 vbox = scrolled_notebook_page(notebook, _("Image"));
1926 group = pref_group_new(vbox, FALSE, _("Zoom"), GTK_ORIENTATION_VERTICAL);
1928 table = pref_table_new(group, 2, 1, FALSE, FALSE);
1929 add_quality_menu(table, 0, 0, _("Quality:"), options->image.zoom_quality, &c_options->image.zoom_quality);
1932 pref_checkbox_new_int(group, _("Use GPU acceleration via Clutter library"),
1933 options->image.use_clutter_renderer, &c_options->image.use_clutter_renderer);
1936 pref_checkbox_new_int(group, _("Two pass rendering (apply HQ zoom and color correction in second pass)"),
1937 options->image.zoom_2pass, &c_options->image.zoom_2pass);
1939 c_options->image.zoom_increment = options->image.zoom_increment;
1940 spin = pref_spin_new(group, _("Zoom increment:"), NULL,
1941 0.01, 4.0, 0.01, 2, (gdouble)options->image.zoom_increment / 100.0,
1942 G_CALLBACK(zoom_increment_cb), NULL);
1943 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1945 group = pref_group_new(vbox, FALSE, _("Fit image to window"), GTK_ORIENTATION_VERTICAL);
1947 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1948 enlargement_button = pref_checkbox_new_int(hbox, _("Allow enlargement of image (max. size in %)"),
1949 options->image.zoom_to_fit_allow_expand, &c_options->image.zoom_to_fit_allow_expand);
1950 spin = pref_spin_new_int(hbox, NULL, NULL,
1952 options->image.max_enlargement_size, &c_options->image.max_enlargement_size);
1953 pref_checkbox_link_sensitivity(enlargement_button, spin);
1954 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."));
1956 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1957 ct_button = pref_checkbox_new_int(hbox, _("Virtual window size (% of actual window):"),
1958 options->image.limit_autofit_size, &c_options->image.limit_autofit_size);
1959 spin = pref_spin_new_int(hbox, NULL, NULL,
1961 options->image.max_autofit_size, &c_options->image.max_autofit_size);
1962 pref_checkbox_link_sensitivity(ct_button, spin);
1963 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."));
1965 group = pref_group_new(vbox, FALSE, _("Appearance"), GTK_ORIENTATION_VERTICAL);
1967 pref_checkbox_new_int(group, _("Use custom border color in window mode"),
1968 options->image.use_custom_border_color, &c_options->image.use_custom_border_color);
1970 pref_checkbox_new_int(group, _("Use custom border color in fullscreen mode"),
1971 options->image.use_custom_border_color_in_fullscreen, &c_options->image.use_custom_border_color_in_fullscreen);
1973 pref_color_button_new(group, _("Border color"), &options->image.border_color,
1974 G_CALLBACK(pref_color_button_set_cb), &c_options->image.border_color);
1976 c_options->image.border_color = options->image.border_color;
1978 pref_color_button_new(group, _("Alpha channel color 1"), &options->image.alpha_color_1,
1979 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_1);
1981 pref_color_button_new(group, _("Alpha channel color 2"), &options->image.alpha_color_2,
1982 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_2);
1984 c_options->image.alpha_color_1 = options->image.alpha_color_1;
1985 c_options->image.alpha_color_2 = options->image.alpha_color_2;
1987 group = pref_group_new(vbox, FALSE, _("Convenience"), GTK_ORIENTATION_VERTICAL);
1989 pref_checkbox_new_int(group, _("Auto rotate proofs using Exif information"),
1990 options->image.exif_proof_rotate_enable, &c_options->image.exif_proof_rotate_enable);
1994 static void config_tab_windows(GtkWidget *notebook)
2000 GtkWidget *ct_button;
2002 GtkWidget *image_overlay_template_view;
2003 GtkWidget *scrolled;
2004 GtkTextBuffer *buffer;
2006 vbox = scrolled_notebook_page(notebook, _("Windows"));
2008 group = pref_group_new(vbox, FALSE, _("State"), GTK_ORIENTATION_VERTICAL);
2010 ct_button = pref_checkbox_new_int(group, _("Remember window positions"),
2011 options->save_window_positions, &c_options->save_window_positions);
2013 button = pref_checkbox_new_int(group, _("Use saved window positions also for new windows"),
2014 options->use_saved_window_positions_for_new_windows, &c_options->use_saved_window_positions_for_new_windows);
2015 pref_checkbox_link_sensitivity(ct_button, button);
2017 pref_checkbox_new_int(group, _("Remember tool state (float/hidden)"),
2018 options->tools_restore_state, &c_options->tools_restore_state);
2020 pref_checkbox_new_int(group, _("Remember dialog window positions"),
2021 options->save_dialog_window_positions, &c_options->save_dialog_window_positions);
2023 pref_checkbox_new_int(group, _("Show window IDs"),
2024 options->show_window_ids, &c_options->show_window_ids);
2026 group = pref_group_new(vbox, FALSE, _("Size"), GTK_ORIENTATION_VERTICAL);
2028 pref_checkbox_new_int(group, _("Fit window to image when tools are hidden/floating"),
2029 options->image.fit_window_to_image, &c_options->image.fit_window_to_image);
2031 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2032 ct_button = pref_checkbox_new_int(hbox, _("Limit size when auto-sizing window (%):"),
2033 options->image.limit_window_size, &c_options->image.limit_window_size);
2034 spin = pref_spin_new_int(hbox, NULL, NULL,
2036 options->image.max_window_size, &c_options->image.max_window_size);
2037 pref_checkbox_link_sensitivity(ct_button, spin);
2039 group = pref_group_new(vbox, FALSE, _("Full screen"), GTK_ORIENTATION_VERTICAL);
2041 c_options->fullscreen.screen = options->fullscreen.screen;
2042 c_options->fullscreen.above = options->fullscreen.above;
2043 hbox = fullscreen_prefs_selection_new(_("Location:"), &c_options->fullscreen.screen, &c_options->fullscreen.above);
2044 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2045 gtk_widget_show(hbox);
2047 pref_checkbox_new_int(group, _("Smooth image flip"),
2048 options->fullscreen.clean_flip, &c_options->fullscreen.clean_flip);
2049 pref_checkbox_new_int(group, _("Disable screen saver"),
2050 options->fullscreen.disable_saver, &c_options->fullscreen.disable_saver);
2053 group = pref_group_new(vbox, FALSE, _("Overlay Screen Display"), GTK_ORIENTATION_VERTICAL);
2055 pref_label_new(group, _("Image overlay template"));
2057 scrolled = gtk_scrolled_window_new(NULL, NULL);
2058 gtk_widget_set_size_request(scrolled, 200, 150);
2059 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2060 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
2061 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2062 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 5);
2063 gtk_widget_show(scrolled);
2065 image_overlay_template_view = gtk_text_view_new();
2067 gtk_widget_set_tooltip_markup(image_overlay_template_view,
2068 _("<i>%name%</i> results in the filename of the picture.\n"
2069 "Also available: <i>%collection%</i>, <i>%number%</i>, <i>%total%</i>, <i>%date%</i>,\n"
2070 "<i>%size%</i> (filesize), <i>%width%</i>, <i>%height%</i>, <i>%res%</i> (resolution),\n"
2071 "<i>%rating%</i>, <i>%keywords%</i>, <i>%comment%</i> (XMP), <i>%imagecomment%</i> (JPEG)\n"
2072 "To access exif data use the exif name, e. g. <i>%formatted.Camera%</i> is the formatted camera name,\n"
2073 "<i>%Exif.Photo.DateTimeOriginal%</i> the date of the original shot.\n"
2074 "<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"
2075 "If two or more variables are connected with the |-sign, it prints available variables with a separator.\n"
2076 "<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"
2077 "if there's no ISO information in the Exif data.\n"
2078 "If a line is empty, it is removed. This allows one to add lines that totally disappear when no data is available.\n"
2080 gtk_container_add(GTK_CONTAINER(scrolled), image_overlay_template_view);
2081 gtk_widget_show(image_overlay_template_view);
2083 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2085 #if GTK_CHECK_VERSION(3,4,0)
2086 button = pref_button_new(NULL, GTK_STOCK_SELECT_FONT, _("Font"), FALSE,
2087 G_CALLBACK(image_overlay_set_font_cb), notebook);
2089 button = gtk_font_button_new();
2090 gtk_font_button_set_title(GTK_FONT_BUTTON(button), "Image Overlay Font");
2091 gtk_font_button_set_font_name(GTK_FONT_BUTTON(button), options->image_overlay.font);
2092 g_signal_connect(G_OBJECT(button), "font-set",
2093 G_CALLBACK(image_overlay_set_font_cb),NULL);
2095 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2096 gtk_widget_show(button);
2098 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Text"), FALSE,
2099 G_CALLBACK(image_overlay_set_text_colour_cb), NULL);
2100 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2101 gtk_widget_show(button);
2103 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Background"), FALSE,
2104 G_CALLBACK(image_overlay_set_background_colour_cb), NULL);
2105 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2106 gtk_widget_show(button);
2107 image_overlay_set_text_colours();
2109 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2110 G_CALLBACK(image_overlay_default_template_cb), image_overlay_template_view);
2111 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2112 gtk_widget_show(button);
2114 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
2115 G_CALLBACK(image_overlay_help_cb), NULL);
2116 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2117 gtk_widget_show(button);
2119 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(image_overlay_template_view));
2120 if (options->image_overlay.template_string) gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
2121 g_signal_connect(G_OBJECT(buffer), "changed",
2122 G_CALLBACK(image_overlay_template_view_changed_cb), image_overlay_template_view);
2127 static GtkTreeModel *create_class_model(void)
2129 GtkListStore *model;
2133 /* create list store */
2134 model = gtk_list_store_new(1, G_TYPE_STRING);
2135 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
2137 gtk_list_store_append(model, &iter);
2138 gtk_list_store_set(model, &iter, 0, _(format_class_list[i]), -1);
2140 return GTK_TREE_MODEL (model);
2145 static void config_tab_files(GtkWidget *notebook)
2152 GtkWidget *ct_button;
2153 GtkWidget *scrolled;
2154 GtkWidget *filter_view;
2155 GtkCellRenderer *renderer;
2156 GtkTreeSelection *selection;
2157 GtkTreeViewColumn *column;
2159 vbox = scrolled_notebook_page(notebook, _("Files"));
2161 group = pref_box_new(vbox, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
2163 pref_checkbox_new_int(group, _("Show hidden files or folders"),
2164 options->file_filter.show_hidden_files, &c_options->file_filter.show_hidden_files);
2165 pref_checkbox_new_int(group, _("Show parent folder (..)"),
2166 options->file_filter.show_parent_directory, &c_options->file_filter.show_parent_directory);
2167 pref_checkbox_new_int(group, _("Case sensitive sort"),
2168 options->file_sort.case_sensitive, &c_options->file_sort.case_sensitive);
2169 pref_checkbox_new_int(group, _("Natural sort order"),
2170 options->file_sort.natural, &c_options->file_sort.natural);
2171 pref_checkbox_new_int(group, _("Disable file extension checks"),
2172 options->file_filter.disable_file_extension_checks, &c_options->file_filter.disable_file_extension_checks);
2174 ct_button = pref_checkbox_new_int(group, _("Disable File Filtering"),
2175 options->file_filter.disable, &c_options->file_filter.disable);
2178 group = pref_group_new(vbox, FALSE, _("Grouping sidecar extensions"), GTK_ORIENTATION_VERTICAL);
2180 sidecar_ext_entry = gtk_entry_new();
2181 gtk_entry_set_text(GTK_ENTRY(sidecar_ext_entry), options->sidecar.ext);
2182 gtk_box_pack_start(GTK_BOX(group), sidecar_ext_entry, FALSE, FALSE, 0);
2183 gtk_widget_show(sidecar_ext_entry);
2185 group = pref_group_new(vbox, TRUE, _("File types"), GTK_ORIENTATION_VERTICAL);
2187 frame = pref_group_parent(group);
2188 g_signal_connect(G_OBJECT(ct_button), "toggled",
2189 G_CALLBACK(filter_disable_cb), frame);
2190 gtk_widget_set_sensitive(frame, !options->file_filter.disable);
2192 scrolled = gtk_scrolled_window_new(NULL, NULL);
2193 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2194 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2195 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2196 gtk_widget_show(scrolled);
2198 filter_store = gtk_list_store_new(1, G_TYPE_POINTER);
2199 filter_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(filter_store));
2200 g_object_unref(filter_store);
2201 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
2202 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_SINGLE);
2204 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(filter_view), FALSE);
2206 column = gtk_tree_view_column_new();
2207 gtk_tree_view_column_set_title(column, _("Filter"));
2208 gtk_tree_view_column_set_resizable(column, TRUE);
2210 renderer = gtk_cell_renderer_toggle_new();
2211 g_signal_connect(G_OBJECT(renderer), "toggled",
2212 G_CALLBACK(filter_store_enable_cb), filter_store);
2213 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2214 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2215 GINT_TO_POINTER(FE_ENABLE), NULL);
2217 renderer = gtk_cell_renderer_text_new();
2218 g_signal_connect(G_OBJECT(renderer), "edited",
2219 G_CALLBACK(filter_store_ext_edit_cb), filter_store);
2220 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2221 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2222 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2223 GINT_TO_POINTER(FE_EXTENSION), NULL);
2224 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2226 column = gtk_tree_view_column_new();
2227 gtk_tree_view_column_set_title(column, _("Description"));
2228 gtk_tree_view_column_set_resizable(column, TRUE);
2229 gtk_tree_view_column_set_fixed_width(column, 200);
2230 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
2232 renderer = gtk_cell_renderer_text_new();
2233 g_signal_connect(G_OBJECT(renderer), "edited",
2234 G_CALLBACK(filter_store_desc_edit_cb), filter_store);
2235 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2236 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2237 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2238 GINT_TO_POINTER(FE_DESCRIPTION), NULL);
2239 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2241 column = gtk_tree_view_column_new();
2242 gtk_tree_view_column_set_title(column, _("Class"));
2243 gtk_tree_view_column_set_resizable(column, TRUE);
2244 renderer = gtk_cell_renderer_combo_new();
2245 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE,
2246 "model", create_class_model(),
2251 g_signal_connect(G_OBJECT(renderer), "edited",
2252 G_CALLBACK(filter_store_class_edit_cb), filter_store);
2253 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2254 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2255 GINT_TO_POINTER(FE_CLASS), NULL);
2256 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2258 column = gtk_tree_view_column_new();
2259 gtk_tree_view_column_set_title(column, _("Writable"));
2260 gtk_tree_view_column_set_resizable(column, FALSE);
2261 renderer = gtk_cell_renderer_toggle_new();
2262 g_signal_connect(G_OBJECT(renderer), "toggled",
2263 G_CALLBACK(filter_store_writable_cb), filter_store);
2264 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2265 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2266 GINT_TO_POINTER(FE_WRITABLE), NULL);
2267 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2269 column = gtk_tree_view_column_new();
2270 gtk_tree_view_column_set_title(column, _("Sidecar is allowed"));
2271 gtk_tree_view_column_set_resizable(column, FALSE);
2272 renderer = gtk_cell_renderer_toggle_new();
2273 g_signal_connect(G_OBJECT(renderer), "toggled",
2274 G_CALLBACK(filter_store_sidecar_cb), filter_store);
2275 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2276 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2277 GINT_TO_POINTER(FE_ALLOW_SIDECAR), NULL);
2278 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2281 filter_store_populate();
2282 gtk_container_add(GTK_CONTAINER(scrolled), filter_view);
2283 gtk_widget_show(filter_view);
2285 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2287 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2288 G_CALLBACK(filter_default_cb), filter_view);
2289 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2290 gtk_widget_show(button);
2292 button = pref_button_new(NULL, GTK_STOCK_REMOVE, NULL, FALSE,
2293 G_CALLBACK(filter_remove_cb), filter_view);
2294 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2295 gtk_widget_show(button);
2297 button = pref_button_new(NULL, GTK_STOCK_ADD, NULL, FALSE,
2298 G_CALLBACK(filter_add_cb), filter_view);
2299 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2300 gtk_widget_show(button);
2304 static void config_tab_metadata(GtkWidget *notebook)
2309 GtkWidget *ct_button;
2313 vbox = scrolled_notebook_page(notebook, _("Metadata"));
2316 group = pref_group_new(vbox, FALSE, _("Metadata writing process"), GTK_ORIENTATION_VERTICAL);
2318 label = pref_label_new(group, _("Warning: Geeqie is built without Exiv2. Some options are disabled."));
2320 label = pref_label_new(group, _("Metadata are written in the following order. The process ends after first success."));
2321 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2323 ct_button = pref_checkbox_new_int(group, _("1) Save metadata in image files, or sidecar files, according to the XMP standard"),
2324 options->metadata.save_in_image_file, &c_options->metadata.save_in_image_file);
2326 gtk_widget_set_sensitive(ct_button, FALSE);
2329 pref_checkbox_new_int(group, _("2) Save metadata in '.metadata' folder, local to image folder (non-standard)"),
2330 options->metadata.enable_metadata_dirs, &c_options->metadata.enable_metadata_dirs);
2332 text = g_strdup_printf(_("3) Save metadata in Geeqie private directory '%s'"), get_metadata_cache_dir());
2333 label = pref_label_new(group, text);
2334 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2335 gtk_misc_set_padding(GTK_MISC(label), 22, 0);
2338 group = pref_group_new(vbox, FALSE, _("Step 1: Write to image files"), GTK_ORIENTATION_VERTICAL);
2340 gtk_widget_set_sensitive(group, FALSE);
2343 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2344 pref_checkbox_link_sensitivity(ct_button, hbox);
2346 pref_checkbox_new_int(hbox, _("Store metadata also in legacy IPTC tags (converted according to IPTC4XMP standard)"),
2347 options->metadata.save_legacy_IPTC, &c_options->metadata.save_legacy_IPTC);
2349 pref_checkbox_new_int(hbox, _("Warn if the image files are unwritable"),
2350 options->metadata.warn_on_write_problems, &c_options->metadata.warn_on_write_problems);
2352 pref_checkbox_new_int(hbox, _("Ask before writing to image files"),
2353 options->metadata.confirm_write, &c_options->metadata.confirm_write);
2355 pref_checkbox_new_int(hbox, _("Create sidecar files named image.ext.xmp (as opposed to image.xmp)"),
2356 options->metadata.sidecar_extended_name, &c_options->metadata.sidecar_extended_name);
2358 group = pref_group_new(vbox, FALSE, _("Step 2 and 3: write to Geeqie private files"), GTK_ORIENTATION_VERTICAL);
2360 gtk_widget_set_sensitive(group, FALSE);
2363 pref_checkbox_new_int(group, _("Use GQview legacy metadata format (supports only keywords and comments) instead of XMP"),
2364 options->metadata.save_legacy_format, &c_options->metadata.save_legacy_format);
2367 group = pref_group_new(vbox, FALSE, _("Miscellaneous"), GTK_ORIENTATION_VERTICAL);
2368 pref_checkbox_new_int(group, _("Write the same description tags (keywords, comment, etc.) to all grouped sidecars"),
2369 options->metadata.sync_grouped_files, &c_options->metadata.sync_grouped_files);
2371 pref_checkbox_new_int(group, _("Allow keywords to differ only in case"),
2372 options->metadata.keywords_case_sensitive, &c_options->metadata.keywords_case_sensitive);
2374 ct_button = pref_checkbox_new_int(group, _("Write altered image orientation to the metadata"),
2375 options->metadata.write_orientation, &c_options->metadata.write_orientation);
2377 gtk_widget_set_sensitive(ct_button, FALSE);
2380 group = pref_group_new(vbox, FALSE, _("Auto-save options"), GTK_ORIENTATION_VERTICAL);
2382 ct_button = pref_checkbox_new_int(group, _("Write metadata after timeout"),
2383 options->metadata.confirm_after_timeout, &c_options->metadata.confirm_after_timeout);
2385 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2386 pref_checkbox_link_sensitivity(ct_button, hbox);
2388 pref_spin_new_int(hbox, _("Timeout (seconds):"), NULL, 0, 900, 1,
2389 options->metadata.confirm_timeout, &c_options->metadata.confirm_timeout);
2391 pref_checkbox_new_int(group, _("Write metadata on image change"),
2392 options->metadata.confirm_on_image_change, &c_options->metadata.confirm_on_image_change);
2394 pref_checkbox_new_int(group, _("Write metadata on directory change"),
2395 options->metadata.confirm_on_dir_change, &c_options->metadata.confirm_on_dir_change);
2397 group = pref_group_new(vbox, FALSE, _("Pre-load metadata"), GTK_ORIENTATION_VERTICAL);
2399 ct_button = pref_checkbox_new_int(group, _("Read metadata in background"),
2400 options->read_metadata_in_idle, &c_options->read_metadata_in_idle);
2401 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");
2406 static void intent_menu_cb(GtkWidget *combo, gpointer data)
2408 gint *option = data;
2410 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
2414 *option = INTENT_PERCEPTUAL;
2417 *option = INTENT_RELATIVE_COLORIMETRIC;
2420 *option = INTENT_SATURATION;
2423 *option = INTENT_ABSOLUTE_COLORIMETRIC;
2428 static void add_intent_menu(GtkWidget *table, gint column, gint row, const gchar *text,
2429 gint option, gint *option_c)
2436 pref_table_label(table, column, row, text, 0.0);
2438 combo = gtk_combo_box_text_new();
2440 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Perceptual"));
2441 if (option == INTENT_PERCEPTUAL) current = 0;
2442 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Relative Colorimetric"));
2443 if (option == INTENT_RELATIVE_COLORIMETRIC) current = 1;
2444 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Saturation"));
2445 if (option == INTENT_SATURATION) current = 2;
2446 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Absolute Colorimetric"));
2447 if (option == INTENT_ABSOLUTE_COLORIMETRIC) current = 3;
2449 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
2451 gtk_widget_set_tooltip_text(combo,"Refer to the lcms documentation for the defaults used when the selected Intent is not available");
2453 g_signal_connect(G_OBJECT(combo), "changed",
2454 G_CALLBACK(intent_menu_cb), option_c);
2456 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
2457 GTK_EXPAND | GTK_FILL, 0, 0, 0);
2458 gtk_widget_show(combo);
2462 static void config_tab_color(GtkWidget *notebook)
2471 vbox = scrolled_notebook_page(notebook, _("Color management"));
2473 group = pref_group_new(vbox, FALSE, _("Input profiles"), GTK_ORIENTATION_VERTICAL);
2475 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
2478 table = pref_table_new(group, 3, COLOR_PROFILE_INPUTS + 1, FALSE, FALSE);
2479 gtk_table_set_col_spacings(GTK_TABLE(table), PREF_PAD_GAP);
2481 label = pref_table_label(table, 0, 0, _("Type"), 0.0);
2482 pref_label_bold(label, TRUE, FALSE);
2484 label = pref_table_label(table, 1, 0, _("Menu name"), 0.0);
2485 pref_label_bold(label, TRUE, FALSE);
2487 label = pref_table_label(table, 2, 0, _("File"), 0.0);
2488 pref_label_bold(label, TRUE, FALSE);
2490 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
2495 buf = g_strdup_printf(_("Input %d:"), i + COLOR_PROFILE_FILE);
2496 pref_table_label(table, 0, i + 1, buf, 1.0);
2499 entry = gtk_entry_new();
2500 gtk_entry_set_max_length(GTK_ENTRY(entry), EDITOR_NAME_MAX_LENGTH);
2501 if (options->color_profile.input_name[i])
2503 gtk_entry_set_text(GTK_ENTRY(entry), options->color_profile.input_name[i]);
2505 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, i + 1, i + 2,
2506 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2507 gtk_widget_show(entry);
2508 color_profile_input_name_entry[i] = entry;
2510 tabcomp = tab_completion_new(&entry, options->color_profile.input_file[i], NULL, ".icc", "ICC Files", NULL);
2511 tab_completion_add_select_button(entry, _("Select color profile"), FALSE);
2512 gtk_widget_set_size_request(entry, 160, -1);
2513 gtk_table_attach(GTK_TABLE(table), tabcomp, 2, 3, i + 1, i + 2,
2514 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2515 gtk_widget_show(tabcomp);
2516 color_profile_input_file_entry[i] = entry;
2519 group = pref_group_new(vbox, FALSE, _("Screen profile"), GTK_ORIENTATION_VERTICAL);
2521 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
2523 pref_checkbox_new_int(group, _("Use system screen profile if available"),
2524 options->color_profile.use_x11_screen_profile, &c_options->color_profile.use_x11_screen_profile);
2526 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2528 pref_table_label(table, 0, 0, _("Screen:"), 1.0);
2529 tabcomp = tab_completion_new(&color_profile_screen_file_entry,
2530 options->color_profile.screen_file, NULL, ".icc", "ICC Files", NULL);
2531 tab_completion_add_select_button(color_profile_screen_file_entry, _("Select color profile"), FALSE);
2532 gtk_widget_set_size_request(color_profile_screen_file_entry, 160, -1);
2534 add_intent_menu(table, 0, 1, _("Render Intent:"), options->color_profile.render_intent, &c_options->color_profile.render_intent);
2536 gtk_table_attach(GTK_TABLE(table), tabcomp, 1, 2,
2538 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2540 gtk_widget_show(tabcomp);
2543 /* advanced entry tab */
2544 static void config_tab_behavior(GtkWidget *notebook)
2551 GtkWidget *ct_button;
2555 GtkWidget *with_rename;
2556 GtkWidget *collections_on_top;
2558 vbox = scrolled_notebook_page(notebook, _("Behavior"));
2560 group = pref_group_new(vbox, FALSE, _("Delete"), GTK_ORIENTATION_VERTICAL);
2562 pref_checkbox_new_int(group, _("Confirm file delete"),
2563 options->file_ops.confirm_delete, &c_options->file_ops.confirm_delete);
2564 pref_checkbox_new_int(group, _("Enable Delete key"),
2565 options->file_ops.enable_delete_key, &c_options->file_ops.enable_delete_key);
2567 ct_button = pref_checkbox_new_int(group, _("Safe delete"),
2568 options->file_ops.safe_delete_enable, &c_options->file_ops.safe_delete_enable);
2570 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2571 pref_checkbox_link_sensitivity(ct_button, hbox);
2573 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_SPACE);
2574 pref_label_new(hbox, _("Folder:"));
2576 tabcomp = tab_completion_new(&safe_delete_path_entry, options->file_ops.safe_delete_path, NULL, NULL, NULL, NULL);
2577 tab_completion_add_select_button(safe_delete_path_entry, NULL, TRUE);
2578 gtk_box_pack_start(GTK_BOX(hbox), tabcomp, TRUE, TRUE, 0);
2579 gtk_widget_show(tabcomp);
2581 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2582 pref_checkbox_link_sensitivity(ct_button, hbox);
2584 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_GAP);
2585 spin = pref_spin_new_int(hbox, _("Maximum size:"), _("MB"),
2586 0, 2048, 1, options->file_ops.safe_delete_folder_maxsize, &c_options->file_ops.safe_delete_folder_maxsize);
2587 gtk_widget_set_tooltip_markup(spin, _("Set to 0 for unlimited size"));
2588 button = pref_button_new(NULL, NULL, _("View"), FALSE,
2589 G_CALLBACK(safe_delete_view_cb), NULL);
2590 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2591 gtk_widget_show(button);
2593 button = pref_button_new(NULL, GTK_STOCK_CLEAR, NULL, FALSE,
2594 G_CALLBACK(safe_delete_clear_cb), NULL);
2595 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2596 gtk_widget_show(button);
2599 group = pref_group_new(vbox, FALSE, _("Behavior"), GTK_ORIENTATION_VERTICAL);
2601 pref_checkbox_new_int(group, _("Descend folders in tree view"),
2602 options->tree_descend_subdirs, &c_options->tree_descend_subdirs);
2604 pref_checkbox_new_int(group, _("In place renaming"),
2605 options->file_ops.enable_in_place_rename, &c_options->file_ops.enable_in_place_rename);
2607 pref_checkbox_new_int(group, _("List directory view uses single click to enter"),
2608 options->view_dir_list_single_click_enter, &c_options->view_dir_list_single_click_enter);
2610 marks = pref_checkbox_new_int(group, _("Save marks on exit"),
2611 options->marks_save, &c_options->marks_save);
2612 gtk_widget_set_tooltip_text(marks,"Note that marks linked to a keyword will be saved irrespective of this setting");
2614 with_rename = pref_checkbox_new_int(group, _("Use \"With Rename\" as default for Copy/Move dialogs"),
2615 options->with_rename, &c_options->with_rename);
2616 gtk_widget_set_tooltip_text(with_rename,"Change the default button for Copy/Move dialogs");
2618 collections_on_top = pref_checkbox_new_int(group, _("Open collections on top"),
2619 options->collections_on_top, &c_options->collections_on_top);
2620 gtk_widget_set_tooltip_text(collections_on_top,"Open collections window on top");
2622 pref_spin_new_int(group, _("Recent folder list maximum size"), NULL,
2623 1, 50, 1, options->open_recent_list_maxsize, &c_options->open_recent_list_maxsize);
2625 pref_spin_new_int(group, _("Drag'n drop icon size"), NULL,
2626 16, 256, 16, options->dnd_icon_size, &c_options->dnd_icon_size);
2628 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2629 add_clipboard_selection_menu(table, 0, 0, _("Copy path clipboard selection:"), options->clipboard_selection, &c_options->clipboard_selection);
2631 group = pref_group_new(vbox, FALSE, _("Navigation"), GTK_ORIENTATION_VERTICAL);
2633 pref_checkbox_new_int(group, _("Progressive keyboard scrolling"),
2634 options->progressive_key_scrolling, &c_options->progressive_key_scrolling);
2635 pref_spin_new_int(group, _("Keyboard scrolling step multiplier:"), NULL,
2636 1, 32, 1, options->keyboard_scroll_step, (int *)&c_options->keyboard_scroll_step);
2637 pref_checkbox_new_int(group, _("Mouse wheel scrolls image"),
2638 options->mousewheel_scrolls, &c_options->mousewheel_scrolls);
2639 pref_checkbox_new_int(group, _("Navigation by left or middle click on image"),
2640 options->image_lm_click_nav, &c_options->image_lm_click_nav);
2641 pref_checkbox_new_int(group, _("Play video by left click on image"),
2642 options->image_l_click_video, &c_options->image_l_click_video);
2643 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2644 add_video_menu(table, 0, 0, _("Play with:"), options->image_l_click_video_editor, &c_options->image_l_click_video_editor);
2648 group = pref_group_new(vbox, FALSE, _("Debugging"), GTK_ORIENTATION_VERTICAL);
2650 pref_spin_new_int(group, _("Debug level:"), NULL,
2651 DEBUG_LEVEL_MIN, DEBUG_LEVEL_MAX, 1, get_debug_level(), &debug_c);
2653 pref_checkbox_new_int(group, _("Timer data"),
2654 options->log_window.timer_data, &c_options->log_window.timer_data);
2656 pref_spin_new_int(group, _("Log Window max. lines:"), NULL,
2657 1, 99999, 1, options->log_window_lines, &options->log_window_lines);
2661 /* accelerators tab */
2662 static void config_tab_accelerators(GtkWidget *notebook)
2668 GtkWidget *scrolled;
2669 GtkWidget *accel_view;
2670 GtkCellRenderer *renderer;
2671 GtkTreeSelection *selection;
2672 GtkTreeViewColumn *column;
2674 vbox = scrolled_notebook_page(notebook, _("Keyboard"));
2676 group = pref_group_new(vbox, TRUE, _("Accelerators"), GTK_ORIENTATION_VERTICAL);
2678 scrolled = gtk_scrolled_window_new(NULL, NULL);
2679 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2680 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2681 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2682 gtk_widget_show(scrolled);
2684 accel_store = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
2686 accel_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(accel_store));
2687 g_object_unref(accel_store);
2688 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(accel_view));
2689 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_MULTIPLE);
2691 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(accel_view), FALSE);
2693 renderer = gtk_cell_renderer_text_new();
2695 column = gtk_tree_view_column_new_with_attributes(_("Action"),
2700 gtk_tree_view_column_set_sort_column_id(column, AE_ACTION);
2701 gtk_tree_view_column_set_resizable(column, TRUE);
2702 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2705 renderer = gtk_cell_renderer_accel_new();
2706 g_signal_connect(G_OBJECT(renderer), "accel-cleared",
2707 G_CALLBACK(accel_store_cleared_cb), accel_store);
2708 g_signal_connect(G_OBJECT(renderer), "accel-edited",
2709 G_CALLBACK(accel_store_edited_cb), accel_store);
2712 g_object_set (renderer,
2714 "accel-mode", GTK_CELL_RENDERER_ACCEL_MODE_OTHER,
2717 column = gtk_tree_view_column_new_with_attributes(_("KEY"),
2722 gtk_tree_view_column_set_sort_column_id(column, AE_KEY);
2723 gtk_tree_view_column_set_resizable(column, TRUE);
2724 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2726 renderer = gtk_cell_renderer_text_new();
2728 column = gtk_tree_view_column_new_with_attributes(_("Tooltip"),
2733 gtk_tree_view_column_set_sort_column_id(column, AE_TOOLTIP);
2734 gtk_tree_view_column_set_resizable(column, TRUE);
2735 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2737 renderer = gtk_cell_renderer_text_new();
2739 column = gtk_tree_view_column_new_with_attributes("Accel",
2744 gtk_tree_view_column_set_sort_column_id(column, AE_ACCEL);
2745 gtk_tree_view_column_set_resizable(column, TRUE);
2746 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2748 accel_store_populate();
2749 gtk_container_add(GTK_CONTAINER(scrolled), accel_view);
2750 gtk_widget_show(accel_view);
2752 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2754 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2755 G_CALLBACK(accel_default_cb), accel_view);
2756 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2757 gtk_widget_show(button);
2759 button = pref_button_new(NULL, NULL, _("Reset selected"), FALSE,
2760 G_CALLBACK(accel_reset_cb), accel_view);
2761 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2762 gtk_widget_show(button);
2766 static void config_tab_toolbar(GtkWidget *notebook)
2769 GtkWidget *toolbardata;
2772 lw = layout_window_list->data;
2774 vbox = scrolled_notebook_page(notebook, _("Toolbar"));
2776 toolbardata = toolbar_select_new(lw);
2777 gtk_box_pack_start(GTK_BOX(vbox), toolbardata, TRUE, TRUE, 0);
2778 gtk_widget_show(vbox);
2782 static void config_tab_stereo(GtkWidget *notebook)
2790 GtkWidget *fs_button;
2791 vbox = scrolled_notebook_page(notebook, _("Stereo"));
2793 group = pref_group_new(vbox, FALSE, _("Windowed stereo mode"), GTK_ORIENTATION_VERTICAL);
2795 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2796 add_stereo_mode_menu(table, 0, 0, _("Windowed stereo mode"), options->stereo.mode, &c_options->stereo.mode, FALSE);
2798 table = pref_table_new(group, 2, 2, TRUE, FALSE);
2799 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2800 pref_checkbox_new_int(box, _("Mirror left image"),
2801 options->stereo.mode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.mirror_left);
2802 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2803 pref_checkbox_new_int(box, _("Flip left image"),
2804 options->stereo.mode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.flip_left);
2805 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2806 pref_checkbox_new_int(box, _("Mirror right image"),
2807 options->stereo.mode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.mirror_right);
2808 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2809 pref_checkbox_new_int(box, _("Flip right image"),
2810 options->stereo.mode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.flip_right);
2811 pref_checkbox_new_int(group, _("Swap left and right images"),
2812 options->stereo.mode & PR_STEREO_SWAP, &c_options->stereo.tmp.swap);
2813 pref_checkbox_new_int(group, _("Disable stereo mode on single image source"),
2814 options->stereo.mode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.temp_disable);
2816 group = pref_group_new(vbox, FALSE, _("Fullscreen stereo mode"), GTK_ORIENTATION_VERTICAL);
2817 fs_button = pref_checkbox_new_int(group, _("Use different settings for fullscreen"),
2818 options->stereo.enable_fsmode, &c_options->stereo.enable_fsmode);
2819 box2 = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2820 pref_checkbox_link_sensitivity(fs_button, box2);
2821 table = pref_table_new(box2, 2, 1, FALSE, FALSE);
2822 add_stereo_mode_menu(table, 0, 0, _("Fullscreen stereo mode"), options->stereo.fsmode, &c_options->stereo.fsmode, TRUE);
2823 table = pref_table_new(box2, 2, 2, TRUE, FALSE);
2824 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2825 pref_checkbox_new_int(box, _("Mirror left image"),
2826 options->stereo.fsmode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.fs_mirror_left);
2827 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2828 pref_checkbox_new_int(box, _("Flip left image"),
2829 options->stereo.fsmode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.fs_flip_left);
2830 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2831 pref_checkbox_new_int(box, _("Mirror right image"),
2832 options->stereo.fsmode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.fs_mirror_right);
2833 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2834 pref_checkbox_new_int(box, _("Flip right image"),
2835 options->stereo.fsmode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.fs_flip_right);
2836 pref_checkbox_new_int(box2, _("Swap left and right images"),
2837 options->stereo.fsmode & PR_STEREO_SWAP, &c_options->stereo.tmp.fs_swap);
2838 pref_checkbox_new_int(box2, _("Disable stereo mode on single image source"),
2839 options->stereo.fsmode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.fs_temp_disable);
2841 group2 = pref_group_new(box2, FALSE, _("Fixed position"), GTK_ORIENTATION_VERTICAL);
2842 table = pref_table_new(group2, 5, 3, FALSE, FALSE);
2843 pref_table_spin_new_int(table, 0, 0, _("Width"), NULL,
2844 1, 5000, 1, options->stereo.fixed_w, &c_options->stereo.fixed_w);
2845 pref_table_spin_new_int(table, 3, 0, _("Height"), NULL,
2846 1, 5000, 1, options->stereo.fixed_h, &c_options->stereo.fixed_h);
2847 pref_table_spin_new_int(table, 0, 1, _("Left X"), NULL,
2848 0, 5000, 1, options->stereo.fixed_x1, &c_options->stereo.fixed_x1);
2849 pref_table_spin_new_int(table, 3, 1, _("Left Y"), NULL,
2850 0, 5000, 1, options->stereo.fixed_y1, &c_options->stereo.fixed_y1);
2851 pref_table_spin_new_int(table, 0, 2, _("Right X"), NULL,
2852 0, 5000, 1, options->stereo.fixed_x2, &c_options->stereo.fixed_x2);
2853 pref_table_spin_new_int(table, 3, 2, _("Right Y"), NULL,
2854 0, 5000, 1, options->stereo.fixed_y2, &c_options->stereo.fixed_y2);
2858 /* Main preferences window */
2859 static void config_window_create(void)
2861 GtkWidget *win_vbox;
2863 GtkWidget *notebook;
2865 GtkWidget *ct_button;
2867 if (!c_options) c_options = init_options(NULL);
2869 configwindow = window_new(GTK_WINDOW_TOPLEVEL, "preferences", PIXBUF_INLINE_ICON_CONFIG, NULL, _("Preferences"));
2870 gtk_window_set_type_hint(GTK_WINDOW(configwindow), GDK_WINDOW_TYPE_HINT_DIALOG);
2871 g_signal_connect(G_OBJECT(configwindow), "delete_event",
2872 G_CALLBACK(config_window_delete), NULL);
2873 gtk_window_set_default_size(GTK_WINDOW(configwindow), CONFIG_WINDOW_DEF_WIDTH, CONFIG_WINDOW_DEF_HEIGHT);
2874 gtk_window_set_resizable(GTK_WINDOW(configwindow), TRUE);
2875 gtk_container_set_border_width(GTK_CONTAINER(configwindow), PREF_PAD_BORDER);
2877 win_vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE);
2878 gtk_container_add(GTK_CONTAINER(configwindow), win_vbox);
2879 gtk_widget_show(win_vbox);
2881 notebook = gtk_notebook_new();
2882 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
2883 gtk_box_pack_start(GTK_BOX(win_vbox), notebook, TRUE, TRUE, 0);
2885 config_tab_general(notebook);
2886 config_tab_image(notebook);
2887 config_tab_windows(notebook);
2888 config_tab_accelerators(notebook);
2889 config_tab_files(notebook);
2890 config_tab_metadata(notebook);
2891 config_tab_color(notebook);
2892 config_tab_stereo(notebook);
2893 config_tab_behavior(notebook);
2894 config_tab_toolbar(notebook);
2896 hbox = gtk_hbutton_box_new();
2897 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
2898 gtk_box_set_spacing(GTK_BOX(hbox), PREF_PAD_BUTTON_GAP);
2899 gtk_box_pack_end(GTK_BOX(win_vbox), hbox, FALSE, FALSE, 0);
2900 gtk_widget_show(hbox);
2902 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
2903 G_CALLBACK(config_window_help_cb), notebook);
2904 gtk_container_add(GTK_CONTAINER(hbox), button);
2905 gtk_widget_set_can_default(button, TRUE);
2906 gtk_widget_show(button);
2908 button = pref_button_new(NULL, GTK_STOCK_OK, NULL, FALSE,
2909 G_CALLBACK(config_window_ok_cb), NULL);
2910 gtk_container_add(GTK_CONTAINER(hbox), button);
2911 gtk_widget_set_can_default(button, TRUE);
2912 gtk_widget_grab_default(button);
2913 gtk_widget_show(button);
2917 button = pref_button_new(NULL, GTK_STOCK_SAVE, NULL, FALSE,
2918 G_CALLBACK(config_window_save_cb), NULL);
2919 gtk_container_add(GTK_CONTAINER(hbox), button);
2920 gtk_widget_set_can_default(button, TRUE);
2921 gtk_widget_show(button);
2923 button = pref_button_new(NULL, GTK_STOCK_APPLY, NULL, FALSE,
2924 G_CALLBACK(config_window_apply_cb), NULL);
2925 gtk_container_add(GTK_CONTAINER(hbox), button);
2926 gtk_widget_set_can_default(button, TRUE);
2927 gtk_widget_show(button);
2929 button = pref_button_new(NULL, GTK_STOCK_CANCEL, NULL, FALSE,
2930 G_CALLBACK(config_window_close_cb), NULL);
2931 gtk_container_add(GTK_CONTAINER(hbox), button);
2932 gtk_widget_set_can_default(button, TRUE);
2933 gtk_widget_show(button);
2935 if (!generic_dialog_get_alternative_button_order(configwindow))
2937 gtk_box_reorder_child(GTK_BOX(hbox), ct_button, -1);
2940 gtk_widget_show(notebook);
2942 gtk_widget_show(configwindow);
2946 *-----------------------------------------------------------------------------
2947 * config window show (public)
2948 *-----------------------------------------------------------------------------
2951 void show_config_window(void)
2955 gtk_window_present(GTK_WINDOW(configwindow));
2959 config_window_create();
2968 void show_about_window(LayoutWindow *lw)
2970 GdkPixbuf *pixbuf_logo;
2971 GdkPixbuf *pixbuf_icon;
2972 gchar *authors[1000];
2980 #define LINE_LENGTH 1000
2981 gchar line[LINE_LENGTH];
2983 copyright = g_string_new(NULL);
2984 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");
2986 zd_path = g_build_filename(GQ_BIN_DIR, TIMEZONE_DATABASE, NULL);
2987 cd = ZDOpenDatabase(zd_path);
2990 copyright = g_string_append(copyright, ZDGetNotice(cd));
2992 ZDCloseDatabase(cd);
2996 path = g_build_filename(GQ_HELPDIR, "AUTHORS", NULL);
2997 fp = fopen(path, "r");
3000 while(fgets(line, LINE_LENGTH, fp))
3002 /* get rid of ending \n from fgets */
3003 line[strlen(line) - 1] = '\0';
3004 authors[i_authors] = g_strdup(line);
3007 authors[i_authors] = NULL;
3012 comment = g_strconcat("Development and bug reports:\n", GQ_EMAIL_ADDRESS,
3013 "\nhttps://github.com/BestImageViewer/geeqie/issues",NULL);
3015 pixbuf_logo = pixbuf_inline(PIXBUF_INLINE_LOGO);
3016 pixbuf_icon = pixbuf_inline(PIXBUF_INLINE_ICON);
3017 gtk_show_about_dialog(GTK_WINDOW(lw->window),
3018 "title", _("About Geeqie"),
3020 "program-name", GQ_APPNAME,
3022 "logo", pixbuf_logo,
3023 "icon", pixbuf_icon,
3024 "website", GQ_WEBSITE,
3025 "website-label", "Website",
3026 "comments", comment,
3028 "translator-credits", _("translator-credits"),
3029 "wrap-license", TRUE,
3030 "license", copyright->str,
3033 g_string_free(copyright, TRUE);
3036 while(n < i_authors)
3046 static void image_overlay_set_text_colours()
3048 c_options->image_overlay.text_red = options->image_overlay.text_red;
3049 c_options->image_overlay.text_green = options->image_overlay.text_green;
3050 c_options->image_overlay.text_blue = options->image_overlay.text_blue;
3051 c_options->image_overlay.text_alpha = options->image_overlay.text_alpha;
3052 c_options->image_overlay.background_red = options->image_overlay.background_red;
3053 c_options->image_overlay.background_green = options->image_overlay.background_green;
3054 c_options->image_overlay.background_blue = options->image_overlay.background_blue;
3055 c_options->image_overlay.background_alpha = options->image_overlay.background_alpha;
3057 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */