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"
60 #define EDITOR_NAME_MAX_LENGTH 32
61 #define EDITOR_COMMAND_MAX_LENGTH 1024
63 static void image_overlay_set_text_colours();
65 typedef struct _ThumbSize ThumbSize;
72 static ThumbSize thumb_size_list[] =
106 static gchar *format_class_list[] = {
114 /* config memory values */
115 static ConfOptions *c_options = NULL;
122 static GtkWidget *configwindow = NULL;
123 static GtkListStore *filter_store = NULL;
124 static GtkTreeStore *accel_store = NULL;
126 static GtkWidget *safe_delete_path_entry;
128 static GtkWidget *color_profile_input_file_entry[COLOR_PROFILE_INPUTS];
129 static GtkWidget *color_profile_input_name_entry[COLOR_PROFILE_INPUTS];
130 static GtkWidget *color_profile_screen_file_entry;
132 static GtkWidget *sidecar_ext_entry;
135 #define CONFIG_WINDOW_DEF_WIDTH 700
136 #define CONFIG_WINDOW_DEF_HEIGHT 600
139 *-----------------------------------------------------------------------------
140 * option widget callbacks (private)
141 *-----------------------------------------------------------------------------
144 static void zoom_increment_cb(GtkWidget *spin, gpointer data)
146 c_options->image.zoom_increment = (gint)(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) * 100.0 + 0.01);
149 static void slideshow_delay_hours_cb(GtkWidget *spin, gpointer data)
151 gint mins_secs_tenths, delay;
153 mins_secs_tenths = c_options->slideshow.delay %
154 (3600 * SLIDESHOW_SUBSECOND_PRECISION);
156 delay = (gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
157 (3600 * SLIDESHOW_SUBSECOND_PRECISION) +
160 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
161 SLIDESHOW_SUBSECOND_PRECISION;
164 static void slideshow_delay_minutes_cb(GtkWidget *spin, gpointer data)
166 gint hours, secs_tenths, delay;
168 hours = c_options->slideshow.delay / (3600 * SLIDESHOW_SUBSECOND_PRECISION);
169 secs_tenths = c_options->slideshow.delay % (60 * SLIDESHOW_SUBSECOND_PRECISION);
171 delay = hours * (3600 * SLIDESHOW_SUBSECOND_PRECISION) +
172 (gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
173 (60 * SLIDESHOW_SUBSECOND_PRECISION) + secs_tenths);
175 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
176 SLIDESHOW_SUBSECOND_PRECISION;
179 static void slideshow_delay_seconds_cb(GtkWidget *spin, gpointer data)
181 gint hours_mins, delay;
183 hours_mins = c_options->slideshow.delay / (60 * SLIDESHOW_SUBSECOND_PRECISION);
185 delay = (hours_mins * (60 * SLIDESHOW_SUBSECOND_PRECISION)) +
186 (gint)(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
187 (gdouble)(SLIDESHOW_SUBSECOND_PRECISION) + 0.01);
189 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
190 SLIDESHOW_SUBSECOND_PRECISION;
194 *-----------------------------------------------------------------------------
195 * sync progam to config window routine (private)
196 *-----------------------------------------------------------------------------
199 void config_entry_to_option(GtkWidget *entry, gchar **option, gchar *(*func)(const gchar *))
205 buf = gtk_entry_get_text(GTK_ENTRY(entry));
206 if (buf && strlen(buf) > 0)
211 *option = g_strdup(buf);
216 static gboolean accel_apply_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
218 gchar *accel_path, *accel;
220 gtk_tree_model_get(model, iter, AE_ACCEL, &accel_path, AE_KEY, &accel, -1);
222 if (accel_path && accel_path[0])
225 gtk_accelerator_parse(accel, &key.accel_key, &key.accel_mods);
226 gtk_accel_map_change_entry(accel_path, key.accel_key, key.accel_mods, TRUE);
236 static void config_window_apply(void)
239 gboolean refresh = FALSE;
241 config_entry_to_option(safe_delete_path_entry, &options->file_ops.safe_delete_path, remove_trailing_slash);
243 if (options->file_filter.show_hidden_files != c_options->file_filter.show_hidden_files) refresh = TRUE;
244 if (options->file_filter.show_parent_directory != c_options->file_filter.show_parent_directory) refresh = TRUE;
245 if (options->file_filter.show_dot_directory != c_options->file_filter.show_dot_directory) refresh = TRUE;
246 if (options->file_sort.case_sensitive != c_options->file_sort.case_sensitive) refresh = TRUE;
247 if (options->file_sort.natural != c_options->file_sort.natural) refresh = TRUE;
248 if (options->file_filter.disable_file_extension_checks != c_options->file_filter.disable_file_extension_checks) refresh = TRUE;
249 if (options->file_filter.disable != c_options->file_filter.disable) refresh = TRUE;
251 options->file_ops.confirm_delete = c_options->file_ops.confirm_delete;
252 options->file_ops.enable_delete_key = c_options->file_ops.enable_delete_key;
253 options->file_ops.safe_delete_enable = c_options->file_ops.safe_delete_enable;
254 options->file_ops.safe_delete_folder_maxsize = c_options->file_ops.safe_delete_folder_maxsize;
255 options->tools_restore_state = c_options->tools_restore_state;
256 options->save_window_positions = c_options->save_window_positions;
257 options->use_saved_window_positions_for_new_windows = c_options->use_saved_window_positions_for_new_windows;
258 options->save_dialog_window_positions = c_options->save_dialog_window_positions;
259 options->image.scroll_reset_method = c_options->image.scroll_reset_method;
260 options->image.zoom_2pass = c_options->image.zoom_2pass;
261 options->image.fit_window_to_image = c_options->image.fit_window_to_image;
262 options->image.limit_window_size = c_options->image.limit_window_size;
263 options->image.zoom_to_fit_allow_expand = c_options->image.zoom_to_fit_allow_expand;
264 options->image.max_window_size = c_options->image.max_window_size;
265 options->image.limit_autofit_size = c_options->image.limit_autofit_size;
266 options->image.max_autofit_size = c_options->image.max_autofit_size;
267 options->image.max_enlargement_size = c_options->image.max_enlargement_size;
268 options->image.use_clutter_renderer = c_options->image.use_clutter_renderer;
269 options->progressive_key_scrolling = c_options->progressive_key_scrolling;
270 options->keyboard_scroll_step = c_options->keyboard_scroll_step;
272 if (options->thumbnails.max_width != c_options->thumbnails.max_width
273 || options->thumbnails.max_height != c_options->thumbnails.max_height
274 || options->thumbnails.quality != c_options->thumbnails.quality)
276 thumb_format_changed = TRUE;
278 options->thumbnails.max_width = c_options->thumbnails.max_width;
279 options->thumbnails.max_height = c_options->thumbnails.max_height;
280 options->thumbnails.quality = c_options->thumbnails.quality;
282 options->thumbnails.enable_caching = c_options->thumbnails.enable_caching;
283 options->thumbnails.cache_into_dirs = c_options->thumbnails.cache_into_dirs;
284 options->thumbnails.use_exif = c_options->thumbnails.use_exif;
285 options->thumbnails.use_ft_metadata = c_options->thumbnails.use_ft_metadata;
286 // options->thumbnails.use_ft_metadata_small = c_options->thumbnails.use_ft_metadata_small;
287 options->thumbnails.spec_standard = c_options->thumbnails.spec_standard;
288 options->metadata.enable_metadata_dirs = c_options->metadata.enable_metadata_dirs;
289 options->file_filter.show_hidden_files = c_options->file_filter.show_hidden_files;
290 options->file_filter.show_parent_directory = c_options->file_filter.show_parent_directory;
291 options->file_filter.show_dot_directory = c_options->file_filter.show_dot_directory;
292 options->file_filter.disable_file_extension_checks = c_options->file_filter.disable_file_extension_checks;
294 options->file_sort.case_sensitive = c_options->file_sort.case_sensitive;
295 options->file_sort.natural = c_options->file_sort.natural;
296 options->file_filter.disable = c_options->file_filter.disable;
298 config_entry_to_option(sidecar_ext_entry, &options->sidecar.ext, NULL);
299 sidecar_ext_parse(options->sidecar.ext);
301 options->slideshow.random = c_options->slideshow.random;
302 options->slideshow.repeat = c_options->slideshow.repeat;
303 options->slideshow.delay = c_options->slideshow.delay;
305 options->mousewheel_scrolls = c_options->mousewheel_scrolls;
306 options->image_lm_click_nav = c_options->image_lm_click_nav;
307 options->image_l_click_video = c_options->image_l_click_video;
308 options->image_l_click_video_editor = c_options->image_l_click_video_editor;
310 options->file_ops.enable_in_place_rename = c_options->file_ops.enable_in_place_rename;
312 options->image.tile_cache_max = c_options->image.tile_cache_max;
313 options->image.image_cache_max = c_options->image.image_cache_max;
315 options->image.zoom_quality = c_options->image.zoom_quality;
317 options->image.zoom_increment = c_options->image.zoom_increment;
319 options->image.enable_read_ahead = c_options->image.enable_read_ahead;
322 if (options->image.use_custom_border_color != c_options->image.use_custom_border_color
323 || options->image.use_custom_border_color_in_fullscreen != c_options->image.use_custom_border_color_in_fullscreen
324 || !gdk_color_equal(&options->image.border_color, &c_options->image.border_color))
326 options->image.use_custom_border_color_in_fullscreen = c_options->image.use_custom_border_color_in_fullscreen;
327 options->image.use_custom_border_color = c_options->image.use_custom_border_color;
328 options->image.border_color = c_options->image.border_color;
329 layout_colors_update();
330 view_window_colors_update();
333 options->image.alpha_color_1 = c_options->image.alpha_color_1;
334 options->image.alpha_color_2 = c_options->image.alpha_color_2;
336 options->fullscreen.screen = c_options->fullscreen.screen;
337 options->fullscreen.clean_flip = c_options->fullscreen.clean_flip;
338 options->fullscreen.disable_saver = c_options->fullscreen.disable_saver;
339 options->fullscreen.above = c_options->fullscreen.above;
340 if (c_options->image_overlay.template_string)
341 set_image_overlay_template_string(&options->image_overlay.template_string,
342 c_options->image_overlay.template_string);
343 if (c_options->image_overlay.font)
344 set_image_overlay_font_string(&options->image_overlay.font,
345 c_options->image_overlay.font);
346 options->image_overlay.text_red = c_options->image_overlay.text_red;
347 options->image_overlay.text_green = c_options->image_overlay.text_green;
348 options->image_overlay.text_blue = c_options->image_overlay.text_blue;
349 options->image_overlay.text_alpha = c_options->image_overlay.text_alpha;
350 options->image_overlay.background_red = c_options->image_overlay.background_red;
351 options->image_overlay.background_green = c_options->image_overlay.background_green;
352 options->image_overlay.background_blue = c_options->image_overlay.background_blue;
353 options->image_overlay.background_alpha = c_options->image_overlay.background_alpha;
354 options->update_on_time_change = c_options->update_on_time_change;
355 options->image.exif_proof_rotate_enable = c_options->image.exif_proof_rotate_enable;
357 options->duplicates_similarity_threshold = c_options->duplicates_similarity_threshold;
358 options->rot_invariant_sim = c_options->rot_invariant_sim;
360 options->tree_descend_subdirs = c_options->tree_descend_subdirs;
362 options->view_dir_list_single_click_enter = c_options->view_dir_list_single_click_enter;
364 options->open_recent_list_maxsize = c_options->open_recent_list_maxsize;
365 options->dnd_icon_size = c_options->dnd_icon_size;
366 options->clipboard_selection = c_options->clipboard_selection;
368 options->metadata.save_in_image_file = c_options->metadata.save_in_image_file;
369 options->metadata.save_legacy_IPTC = c_options->metadata.save_legacy_IPTC;
370 options->metadata.warn_on_write_problems = c_options->metadata.warn_on_write_problems;
371 options->metadata.save_legacy_format = c_options->metadata.save_legacy_format;
372 options->metadata.sync_grouped_files = c_options->metadata.sync_grouped_files;
373 options->metadata.confirm_write = c_options->metadata.confirm_write;
374 options->metadata.sidecar_extended_name = c_options->metadata.sidecar_extended_name;
375 options->metadata.confirm_timeout = c_options->metadata.confirm_timeout;
376 options->metadata.confirm_after_timeout = c_options->metadata.confirm_after_timeout;
377 options->metadata.confirm_on_image_change = c_options->metadata.confirm_on_image_change;
378 options->metadata.confirm_on_dir_change = c_options->metadata.confirm_on_dir_change;
379 options->metadata.keywords_case_sensitive = c_options->metadata.keywords_case_sensitive;
380 options->metadata.write_orientation = c_options->metadata.write_orientation;
381 options->stereo.mode = (c_options->stereo.mode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
382 (c_options->stereo.tmp.mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
383 (c_options->stereo.tmp.flip_right ? PR_STEREO_FLIP_RIGHT : 0) |
384 (c_options->stereo.tmp.mirror_left ? PR_STEREO_MIRROR_LEFT : 0) |
385 (c_options->stereo.tmp.flip_left ? PR_STEREO_FLIP_LEFT : 0) |
386 (c_options->stereo.tmp.swap ? PR_STEREO_SWAP : 0) |
387 (c_options->stereo.tmp.temp_disable ? PR_STEREO_TEMP_DISABLE : 0);
388 options->stereo.fsmode = (c_options->stereo.fsmode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
389 (c_options->stereo.tmp.fs_mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
390 (c_options->stereo.tmp.fs_flip_right ? PR_STEREO_FLIP_RIGHT : 0) |
391 (c_options->stereo.tmp.fs_mirror_left ? PR_STEREO_MIRROR_LEFT : 0) |
392 (c_options->stereo.tmp.fs_flip_left ? PR_STEREO_FLIP_LEFT : 0) |
393 (c_options->stereo.tmp.fs_swap ? PR_STEREO_SWAP : 0) |
394 (c_options->stereo.tmp.fs_temp_disable ? PR_STEREO_TEMP_DISABLE : 0);
395 options->stereo.enable_fsmode = c_options->stereo.enable_fsmode;
396 options->stereo.fixed_w = c_options->stereo.fixed_w;
397 options->stereo.fixed_h = c_options->stereo.fixed_h;
398 options->stereo.fixed_x1 = c_options->stereo.fixed_x1;
399 options->stereo.fixed_y1 = c_options->stereo.fixed_y1;
400 options->stereo.fixed_x2 = c_options->stereo.fixed_x2;
401 options->stereo.fixed_y2 = c_options->stereo.fixed_y2;
403 options->info_keywords.height = c_options->info_keywords.height;
404 options->info_title.height = c_options->info_title.height;
405 options->info_comment.height = c_options->info_comment.height;
406 options->info_rating.height = c_options->info_rating.height;
409 set_debug_level(debug_c);
413 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
415 config_entry_to_option(color_profile_input_name_entry[i], &options->color_profile.input_name[i], NULL);
416 config_entry_to_option(color_profile_input_file_entry[i], &options->color_profile.input_file[i], NULL);
418 config_entry_to_option(color_profile_screen_file_entry, &options->color_profile.screen_file, NULL);
419 options->color_profile.use_x11_screen_profile = c_options->color_profile.use_x11_screen_profile;
420 if (options->color_profile.render_intent != c_options->color_profile.render_intent)
422 options->color_profile.render_intent = c_options->color_profile.render_intent;
427 image_options_sync();
432 layout_refresh(NULL);
435 if (accel_store) gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_apply_cb, NULL);
441 *-----------------------------------------------------------------------------
442 * config window main button callbacks (private)
443 *-----------------------------------------------------------------------------
446 static void config_window_close_cb(GtkWidget *widget, gpointer data)
448 gtk_widget_destroy(configwindow);
453 static void config_window_help_cb(GtkWidget *widget, gpointer data)
455 GtkWidget *notebook = data;
458 static gchar *html_section[] =
460 "GuideOptionsGeneral.html",
461 "GuideOptionsImage.html",
462 "GuideOptionsWindow.html",
463 "GuideOptionsKeyboard.html",
464 "GuideOptionsFiltering.html",
465 "GuideOptionsMetadata.html",
466 "GuideOptionsColor.html",
467 "GuideOptionsStereo.html",
468 "GuideOptionsBehavior.html",
469 "GuideOptionsToolbar.html"
472 i = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
473 help_window_show(html_section[i]);
476 static gboolean config_window_delete(GtkWidget *widget, GdkEventAny *event, gpointer data)
478 config_window_close_cb(NULL, NULL);
482 static void config_window_ok_cb(GtkWidget *widget, gpointer data)
484 config_window_apply();
485 config_window_close_cb(NULL, NULL);
488 static void config_window_apply_cb(GtkWidget *widget, gpointer data)
491 lw = layout_window_list->data;
493 config_window_apply();
494 layout_util_sync(lw);
497 static void config_window_save_cb(GtkWidget *widget, gpointer data)
499 config_window_apply();
500 save_options(options);
504 *-----------------------------------------------------------------------------
505 * config window setup (private)
506 *-----------------------------------------------------------------------------
509 static void quality_menu_cb(GtkWidget *combo, gpointer data)
513 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
517 *option = GDK_INTERP_NEAREST;
520 *option = GDK_INTERP_TILES;
523 *option = GDK_INTERP_BILINEAR;
526 *option = GDK_INTERP_HYPER;
531 static void clipboard_selection_menu_cb(GtkWidget *combo, gpointer data)
535 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
547 static void add_quality_menu(GtkWidget *table, gint column, gint row, const gchar *text,
548 guint option, guint *option_c)
555 pref_table_label(table, column, row, text, 0.0);
557 combo = gtk_combo_box_text_new();
559 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Nearest (worst, but fastest)"));
560 if (option == GDK_INTERP_NEAREST) current = 0;
561 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Tiles"));
562 if (option == GDK_INTERP_TILES) current = 1;
563 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Bilinear"));
564 if (option == GDK_INTERP_BILINEAR) current = 2;
565 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Hyper (best, but slowest)"));
566 if (option == GDK_INTERP_HYPER) current = 3;
568 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
570 g_signal_connect(G_OBJECT(combo), "changed",
571 G_CALLBACK(quality_menu_cb), option_c);
573 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
574 GTK_EXPAND | GTK_FILL, 0, 0, 0);
575 gtk_widget_show(combo);
578 static void add_clipboard_selection_menu(GtkWidget *table, gint column, gint row, const gchar *text,
579 gint option, gint *option_c)
586 pref_table_label(table, column, row, text, 0.0);
588 combo = gtk_combo_box_text_new();
590 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("PRIMARY"));
591 if (option == PRIMARY) current = 0;
592 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("CLIPBOARD"));
593 if (option == CLIPBOARD) current = 1;
595 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
597 g_signal_connect(G_OBJECT(combo), "changed",
598 G_CALLBACK(clipboard_selection_menu_cb), option_c);
600 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
601 GTK_EXPAND | GTK_FILL, 0, 0, 0);
602 gtk_widget_show(combo);
605 static void thumb_size_menu_cb(GtkWidget *combo, gpointer data)
609 n = gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
612 if ((guint) n < sizeof(thumb_size_list) / sizeof(ThumbSize))
614 c_options->thumbnails.max_width = thumb_size_list[n].w;
615 c_options->thumbnails.max_height = thumb_size_list[n].h;
619 c_options->thumbnails.max_width = options->thumbnails.max_width;
620 c_options->thumbnails.max_height = options->thumbnails.max_height;
624 static void add_thumb_size_menu(GtkWidget *table, gint column, gint row, gchar *text)
630 c_options->thumbnails.max_width = options->thumbnails.max_width;
631 c_options->thumbnails.max_height = options->thumbnails.max_height;
633 pref_table_label(table, column, row, text, 0.0);
635 combo = gtk_combo_box_text_new();
638 for (i = 0; (guint) i < sizeof(thumb_size_list) / sizeof(ThumbSize); i++)
643 w = thumb_size_list[i].w;
644 h = thumb_size_list[i].h;
646 buf = g_strdup_printf("%d x %d", w, h);
647 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf);
650 if (w == options->thumbnails.max_width && h == options->thumbnails.max_height) current = i;
657 buf = g_strdup_printf("%s %d x %d", _("Custom"), options->thumbnails.max_width, options->thumbnails.max_height);
658 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf);
664 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
665 g_signal_connect(G_OBJECT(combo), "changed",
666 G_CALLBACK(thumb_size_menu_cb), NULL);
668 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
669 GTK_EXPAND | GTK_FILL, 0, 0, 0);
670 gtk_widget_show(combo);
673 static void stereo_mode_menu_cb(GtkWidget *combo, gpointer data)
677 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
681 *option = PR_STEREO_NONE;
684 *option = PR_STEREO_ANAGLYPH_RC;
687 *option = PR_STEREO_ANAGLYPH_GM;
690 *option = PR_STEREO_ANAGLYPH_YB;
693 *option = PR_STEREO_ANAGLYPH_GRAY_RC;
696 *option = PR_STEREO_ANAGLYPH_GRAY_GM;
699 *option = PR_STEREO_ANAGLYPH_GRAY_YB;
702 *option = PR_STEREO_ANAGLYPH_DB_RC;
705 *option = PR_STEREO_ANAGLYPH_DB_GM;
708 *option = PR_STEREO_ANAGLYPH_DB_YB;
711 *option = PR_STEREO_HORIZ;
714 *option = PR_STEREO_HORIZ | PR_STEREO_HALF;
717 *option = PR_STEREO_VERT;
720 *option = PR_STEREO_VERT | PR_STEREO_HALF;
723 *option = PR_STEREO_FIXED;
728 static void add_stereo_mode_menu(GtkWidget *table, gint column, gint row, const gchar *text,
729 gint option, gint *option_c, gboolean add_fixed)
736 pref_table_label(table, column, row, text, 0.0);
738 combo = gtk_combo_box_text_new();
740 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Single image"));
742 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Red-Cyan"));
743 if (option & PR_STEREO_ANAGLYPH_RC) current = 1;
744 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Green-Magenta"));
745 if (option & PR_STEREO_ANAGLYPH_GM) current = 2;
746 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Yellow-Blue"));
747 if (option & PR_STEREO_ANAGLYPH_YB) current = 3;
748 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Red-Cyan"));
749 if (option & PR_STEREO_ANAGLYPH_GRAY_RC) current = 4;
750 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Green-Magenta"));
751 if (option & PR_STEREO_ANAGLYPH_GRAY_GM) current = 5;
752 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Yellow-Blue"));
753 if (option & PR_STEREO_ANAGLYPH_GRAY_YB) current = 6;
754 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Red-Cyan"));
755 if (option & PR_STEREO_ANAGLYPH_DB_RC) current = 7;
756 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Green-Magenta"));
757 if (option & PR_STEREO_ANAGLYPH_DB_GM) current = 8;
758 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Yellow-Blue"));
759 if (option & PR_STEREO_ANAGLYPH_DB_YB) current = 9;
761 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Side by Side"));
762 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Side by Side Half size"));
763 if (option & PR_STEREO_HORIZ)
766 if (option & PR_STEREO_HALF) current = 11;
769 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Top - Bottom"));
770 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Top - Bottom Half size"));
771 if (option & PR_STEREO_VERT)
774 if (option & PR_STEREO_HALF) current = 13;
779 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Fixed position"));
780 if (option & PR_STEREO_FIXED) current = 14;
783 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
785 g_signal_connect(G_OBJECT(combo), "changed",
786 G_CALLBACK(stereo_mode_menu_cb), option_c);
788 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
789 GTK_EXPAND | GTK_FILL, 0, 0, 0);
790 gtk_widget_show(combo);
793 static void video_menu_cb(GtkWidget *combo, gpointer data)
795 gchar **option = data;
797 EditorDescription *ed = g_list_nth_data(editor_list_get(), gtk_combo_box_get_active(GTK_COMBO_BOX(combo)));
801 static void video_menu_populate(gpointer data, gpointer user_data)
803 GtkWidget *combo = user_data;
804 EditorDescription *ed = data;
806 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), ed->name);
809 static void add_video_menu(GtkWidget *table, gint column, gint row, const gchar *text,
810 gchar *option, gchar **option_c)
814 /* use lists since they are sorted */
815 GList *eds = editor_list_get();
819 pref_table_label(table, column, row, text, 0.0);
821 combo = gtk_combo_box_text_new();
822 g_list_foreach(eds,video_menu_populate,(gpointer)combo);
823 current = option ? g_list_index(eds,g_hash_table_lookup(editors,option)): -1;
825 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
827 g_signal_connect(G_OBJECT(combo), "changed",
828 G_CALLBACK(video_menu_cb), option_c);
830 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
831 GTK_EXPAND | GTK_FILL, 0, 0, 0);
832 gtk_widget_show(combo);
835 static void filter_store_populate(void)
839 if (!filter_store) return;
841 gtk_list_store_clear(filter_store);
843 work = filter_get_list();
852 gtk_list_store_append(filter_store, &iter);
853 gtk_list_store_set(filter_store, &iter, 0, fe, -1);
857 static void filter_store_ext_edit_cb(GtkCellRendererText *cell, gchar *path_str,
858 gchar *new_text, gpointer data)
860 GtkWidget *model = data;
861 FilterEntry *fe = data;
865 if (!new_text || strlen(new_text) < 1) return;
867 tpath = gtk_tree_path_new_from_string(path_str);
868 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
869 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
871 g_free(fe->extensions);
872 fe->extensions = g_strdup(new_text);
874 gtk_tree_path_free(tpath);
878 static void filter_store_class_edit_cb(GtkCellRendererText *cell, gchar *path_str,
879 gchar *new_text, gpointer data)
881 GtkWidget *model = data;
882 FilterEntry *fe = data;
887 if (!new_text || !new_text[0]) return;
889 tpath = gtk_tree_path_new_from_string(path_str);
890 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
891 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
893 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
895 if (strcmp(new_text, _(format_class_list[i])) == 0)
902 gtk_tree_path_free(tpath);
906 static void filter_store_desc_edit_cb(GtkCellRendererText *cell, gchar *path_str,
907 gchar *new_text, gpointer data)
909 GtkWidget *model = data;
914 if (!new_text || !new_text[0]) return;
916 tpath = gtk_tree_path_new_from_string(path_str);
917 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
918 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
920 g_free(fe->description);
921 fe->description = g_strdup(new_text);
923 gtk_tree_path_free(tpath);
926 static void filter_store_enable_cb(GtkCellRendererToggle *renderer,
927 gchar *path_str, gpointer data)
929 GtkWidget *model = data;
934 tpath = gtk_tree_path_new_from_string(path_str);
935 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
936 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
938 fe->enabled = !fe->enabled;
940 gtk_tree_path_free(tpath);
944 static void filter_store_writable_cb(GtkCellRendererToggle *renderer,
945 gchar *path_str, gpointer data)
947 GtkWidget *model = data;
952 tpath = gtk_tree_path_new_from_string(path_str);
953 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
954 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
956 fe->writable = !fe->writable;
957 if (fe->writable) fe->allow_sidecar = FALSE;
959 gtk_tree_path_free(tpath);
963 static void filter_store_sidecar_cb(GtkCellRendererToggle *renderer,
964 gchar *path_str, gpointer data)
966 GtkWidget *model = data;
971 tpath = gtk_tree_path_new_from_string(path_str);
972 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
973 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
975 fe->allow_sidecar = !fe->allow_sidecar;
976 if (fe->allow_sidecar) fe->writable = FALSE;
978 gtk_tree_path_free(tpath);
982 static void filter_set_func(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell,
983 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
987 gtk_tree_model_get(tree_model, iter, 0, &fe, -1);
989 switch (GPOINTER_TO_INT(data))
992 g_object_set(GTK_CELL_RENDERER(cell),
993 "active", fe->enabled, NULL);
996 g_object_set(GTK_CELL_RENDERER(cell),
997 "text", fe->extensions, NULL);
1000 g_object_set(GTK_CELL_RENDERER(cell),
1001 "text", fe->description, NULL);
1004 g_object_set(GTK_CELL_RENDERER(cell),
1005 "text", _(format_class_list[fe->file_class]), NULL);
1008 g_object_set(GTK_CELL_RENDERER(cell),
1009 "active", fe->writable, NULL);
1011 case FE_ALLOW_SIDECAR:
1012 g_object_set(GTK_CELL_RENDERER(cell),
1013 "active", fe->allow_sidecar, NULL);
1018 static gboolean filter_add_scroll(gpointer data)
1022 GtkCellRenderer *cell;
1023 GtkTreeViewColumn *column;
1024 GList *list_columns;
1029 rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(filter_store), NULL);
1030 path = gtk_tree_path_new_from_indices(rows-1, -1);
1032 list_columns = gtk_tree_view_get_columns(GTK_TREE_VIEW(data));
1034 column = g_list_nth(list_columns,i)->data;
1035 title = gtk_tree_view_column_get_title(GTK_TREE_VIEW_COLUMN(column));
1037 } while (strcmp(title, "Filter") !=0 );
1039 list_cells = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(column));
1040 cell = g_list_last(list_cells)->data;
1042 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1043 path, column, FALSE, 0.0, 0.0 );
1044 gtk_tree_view_set_cursor_on_cell(GTK_TREE_VIEW(data),
1045 path, column, cell, TRUE);
1047 gtk_tree_path_free(path);
1048 g_list_free(list_cells);
1049 g_list_free(list_columns);
1054 static void filter_add_cb(GtkWidget *widget, gpointer data)
1056 filter_add_unique("description", ".new", FORMAT_CLASS_IMAGE, TRUE, FALSE, TRUE);
1057 filter_store_populate();
1059 g_idle_add((GSourceFunc)filter_add_scroll, data);
1062 static void filter_remove_cb(GtkWidget *widget, gpointer data)
1064 GtkWidget *filter_view = data;
1065 GtkTreeSelection *selection;
1069 if (!filter_store) return;
1070 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
1071 if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) return;
1072 gtk_tree_model_get(GTK_TREE_MODEL(filter_store), &iter, 0, &fe, -1);
1075 filter_remove_entry(fe);
1077 filter_store_populate();
1080 static gboolean filter_default_ok_scroll(GtkTreeView *data)
1084 GtkTreeViewColumn *column;
1086 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(filter_store), &iter);
1087 path = gtk_tree_model_get_path(GTK_TREE_MODEL(filter_store), &iter);
1088 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data),0);
1090 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1094 gtk_tree_path_free(path);
1099 static void filter_default_ok_cb(GenericDialog *gd, gpointer data)
1102 filter_add_defaults();
1104 filter_store_populate();
1106 g_idle_add((GSourceFunc)filter_default_ok_scroll, gd->data);
1109 static void dummy_cancel_cb(GenericDialog *gd, gpointer data)
1111 /* no op, only so cancel button appears */
1114 static void filter_default_cb(GtkWidget *widget, gpointer data)
1118 gd = generic_dialog_new(_("Reset filters"),
1119 "reset_filter", widget, TRUE,
1120 dummy_cancel_cb, data);
1121 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Reset filters"),
1122 _("This will reset the file filters to the defaults.\nContinue?"), TRUE);
1123 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, filter_default_ok_cb, TRUE);
1124 gtk_widget_show(gd->dialog);
1127 static void filter_disable_cb(GtkWidget *widget, gpointer data)
1129 GtkWidget *frame = data;
1131 gtk_widget_set_sensitive(frame,
1132 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
1135 static void safe_delete_view_cb(GtkWidget *widget, gpointer data)
1137 layout_set_path(NULL, gtk_entry_get_text(GTK_ENTRY(safe_delete_path_entry)));
1140 static void safe_delete_clear_ok_cb(GenericDialog *gd, gpointer data)
1142 file_util_trash_clear();
1145 static void safe_delete_clear_cb(GtkWidget *widget, gpointer data)
1149 gd = generic_dialog_new(_("Clear trash"),
1150 "clear_trash", widget, TRUE,
1151 dummy_cancel_cb, NULL);
1152 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Clear trash"),
1153 _("This will remove the trash contents."), FALSE);
1154 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, safe_delete_clear_ok_cb, TRUE);
1155 entry = gtk_entry_new();
1156 gtk_widget_set_can_focus(entry, FALSE);
1157 gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
1158 if (options->file_ops.safe_delete_path) gtk_entry_set_text(GTK_ENTRY(entry), options->file_ops.safe_delete_path);
1159 gtk_box_pack_start(GTK_BOX(gd->vbox), entry, FALSE, FALSE, 0);
1160 gtk_widget_show(entry);
1161 gtk_widget_show(gd->dialog);
1164 static void image_overlay_template_view_changed_cb(GtkWidget *widget, gpointer data)
1166 GtkWidget *pTextView;
1167 GtkTextBuffer *pTextBuffer;
1171 pTextView = GTK_WIDGET(data);
1173 pTextBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pTextView));
1174 gtk_text_buffer_get_start_iter(pTextBuffer, &iStart);
1175 gtk_text_buffer_get_end_iter(pTextBuffer, &iEnd);
1177 set_image_overlay_template_string(&c_options->image_overlay.template_string,
1178 gtk_text_buffer_get_text(pTextBuffer, &iStart, &iEnd, TRUE));
1181 static void image_overlay_default_template_ok_cb(GenericDialog *gd, gpointer data)
1183 GtkTextView *text_view = data;
1184 GtkTextBuffer *buffer;
1186 set_default_image_overlay_template_string(&options->image_overlay.template_string);
1187 if (!configwindow) return;
1189 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
1190 gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
1193 static void image_overlay_default_template_cb(GtkWidget *widget, gpointer data)
1197 gd = generic_dialog_new(_("Reset image overlay template string"),
1198 "reset_image_overlay_template_string", widget, TRUE,
1199 dummy_cancel_cb, data);
1200 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Reset image overlay template string"),
1201 _("This will reset the image overlay template string to the default.\nContinue?"), TRUE);
1202 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, image_overlay_default_template_ok_cb, TRUE);
1203 gtk_widget_show(gd->dialog);
1206 static void image_overlay_help_cb(GtkWidget *widget, gpointer data)
1208 help_window_show("GuideOptionsWindow.html#OverlayScreenDisplay");
1211 static void image_overlay_set_font_cb(GtkWidget *widget, gpointer data)
1213 #if GTK_CHECK_VERSION(3,4,0)
1216 PangoFontDescription *font_desc;
1218 dialog = gtk_font_chooser_dialog_new("Image Overlay Font", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1219 gtk_font_chooser_set_font(GTK_FONT_CHOOSER(dialog), options->image_overlay.font);
1221 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1223 font_desc = gtk_font_chooser_get_font_desc(GTK_FONT_CHOOSER(dialog));
1224 font = pango_font_description_to_string(font_desc);
1225 g_free(c_options->image_overlay.font);
1226 c_options->image_overlay.font = g_strdup(font);
1230 gtk_widget_destroy(dialog);
1234 font = gtk_font_button_get_font_name(GTK_FONT_BUTTON(widget));
1235 c_options->image_overlay.font = g_strdup(font);
1239 static void image_overlay_set_text_colour_cb(GtkWidget *widget, gpointer data)
1242 #if GTK_CHECK_VERSION(3,4,0)
1245 dialog = gtk_color_chooser_dialog_new("Image Overlay Text Colour", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1246 colour.red = options->image_overlay.text_red;
1247 colour.green = options->image_overlay.text_green;
1248 colour.blue = options->image_overlay.text_blue;
1249 colour.alpha = options->image_overlay.text_alpha;
1250 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1251 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(dialog), TRUE);
1253 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1255 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1256 c_options->image_overlay.text_red = colour.red*255;
1257 c_options->image_overlay.text_green = colour.green*255;
1258 c_options->image_overlay.text_blue = colour.blue*255;
1259 c_options->image_overlay.text_alpha = colour.alpha*255;
1261 gtk_widget_destroy(dialog);
1264 GtkColorSelection *colorsel;
1266 dialog = gtk_color_selection_dialog_new("Image Overlay Text Colour");
1267 gtk_window_set_keep_above(GTK_WINDOW(dialog),TRUE);
1268 colour.red = options->image_overlay.text_red*257;
1269 colour.green = options->image_overlay.text_green*257;
1270 colour.blue = options->image_overlay.text_blue*257;
1271 colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)));
1272 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
1273 gtk_color_selection_set_current_color(colorsel, &colour);
1274 gtk_color_selection_set_current_alpha(colorsel, options->image_overlay.text_alpha*257);
1276 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
1278 gtk_color_selection_get_current_color(colorsel, &colour);
1279 c_options->image_overlay.text_red = colour.red/257;
1280 c_options->image_overlay.text_green = colour.green/257;
1281 c_options->image_overlay.text_blue = colour.blue/257;
1282 c_options->image_overlay.text_alpha = gtk_color_selection_get_current_alpha(colorsel)/257;
1284 gtk_widget_destroy (dialog);
1289 static void image_overlay_set_background_colour_cb(GtkWidget *widget, gpointer data)
1292 #if GTK_CHECK_VERSION(3,4,0)
1295 dialog = gtk_color_chooser_dialog_new("Image Overlay Background Colour", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1296 colour.red = options->image_overlay.background_red;
1297 colour.green = options->image_overlay.background_green;
1298 colour.blue = options->image_overlay.background_blue;
1299 colour.alpha = options->image_overlay.background_alpha;
1300 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1301 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(dialog), TRUE);
1303 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1305 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1306 c_options->image_overlay.background_red = colour.red*255;
1307 c_options->image_overlay.background_green = colour.green*255;
1308 c_options->image_overlay.background_blue = colour.blue*255;
1309 c_options->image_overlay.background_alpha = colour.alpha*255;
1311 gtk_widget_destroy(dialog);
1314 GtkColorSelection *colorsel;
1316 dialog = gtk_color_selection_dialog_new("Image Overlay Background Colour");
1317 gtk_window_set_keep_above(GTK_WINDOW(dialog),TRUE);
1318 colour.red = options->image_overlay.background_red*257;
1319 colour.green = options->image_overlay.background_green*257;
1320 colour.blue = options->image_overlay.background_blue*257;
1321 colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)));
1322 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
1323 gtk_color_selection_set_current_color(colorsel, &colour);
1324 gtk_color_selection_set_current_alpha(colorsel, options->image_overlay.background_alpha*257);
1326 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
1328 gtk_color_selection_get_current_color(colorsel, &colour);
1329 c_options->image_overlay.background_red = colour.red/257;
1330 c_options->image_overlay.background_green = colour.green/257;
1331 c_options->image_overlay.background_blue = colour.blue/257;
1332 c_options->image_overlay.background_alpha = gtk_color_selection_get_current_alpha(colorsel)/257;
1334 gtk_widget_destroy(dialog);
1338 static void accel_store_populate(void)
1341 GList *groups, *actions;
1343 const gchar *accel_path;
1347 if (!accel_store || !layout_window_list || !layout_window_list->data) return;
1349 gtk_tree_store_clear(accel_store);
1350 lw = layout_window_list->data; /* get the actions from the first window, it should not matter, they should be the same in all windows */
1352 g_assert(lw && lw->ui_manager);
1353 groups = gtk_ui_manager_get_action_groups(lw->ui_manager);
1356 actions = gtk_action_group_list_actions(GTK_ACTION_GROUP(groups->data));
1359 action = GTK_ACTION(actions->data);
1360 accel_path = gtk_action_get_accel_path(action);
1361 if (accel_path && gtk_accel_map_lookup_entry(accel_path, &key))
1363 gchar *label, *label2, *tooltip, *accel;
1364 g_object_get(action,
1365 "tooltip", &tooltip,
1369 if (pango_parse_markup(label, -1, '_', NULL, &label2, NULL, NULL) && label2)
1375 accel = gtk_accelerator_name(key.accel_key, key.accel_mods);
1379 gtk_tree_store_append(accel_store, &iter, NULL);
1380 gtk_tree_store_set(accel_store, &iter,
1383 AE_TOOLTIP, tooltip ? tooltip : "",
1384 AE_ACCEL, accel_path,
1392 actions = actions->next;
1395 groups = groups->next;
1399 static void accel_store_cleared_cb(GtkCellRendererAccel *accel, gchar *path_string, gpointer user_data)
1404 static gboolean accel_remove_key_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1406 gchar *accel1 = data;
1411 gtk_tree_model_get(model, iter, AE_KEY, &accel2, -1);
1413 gtk_accelerator_parse(accel1, &key1.accel_key, &key1.accel_mods);
1414 gtk_accelerator_parse(accel2, &key2.accel_key, &key2.accel_mods);
1416 if (key1.accel_key == key2.accel_key && key1.accel_mods == key2.accel_mods)
1418 gtk_tree_store_set(accel_store, iter, AE_KEY, "", -1);
1419 DEBUG_1("accelerator key '%s' is already used, removing.", accel1);
1428 static void accel_store_edited_cb(GtkCellRendererAccel *accel, gchar *path_string, guint accel_key, GdkModifierType accel_mods, guint hardware_keycode, gpointer user_data)
1430 GtkTreeModel *model = (GtkTreeModel *)accel_store;
1434 GtkAccelKey old_key, key;
1435 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
1437 gtk_tree_model_get_iter(model, &iter, path);
1438 gtk_tree_model_get(model, &iter, AE_ACCEL, &accel_path, -1);
1440 /* test if the accelerator can be stored without conflicts*/
1441 gtk_accel_map_lookup_entry(accel_path, &old_key);
1443 /* change the key and read it back (change may fail on keys hardcoded in gtk)*/
1444 gtk_accel_map_change_entry(accel_path, accel_key, accel_mods, TRUE);
1445 gtk_accel_map_lookup_entry(accel_path, &key);
1447 /* restore the original for now, the key will be really changed when the changes are confirmed */
1448 gtk_accel_map_change_entry(accel_path, old_key.accel_key, old_key.accel_mods, TRUE);
1450 acc = gtk_accelerator_name(key.accel_key, key.accel_mods);
1451 gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_remove_key_cb, acc);
1453 gtk_tree_store_set(accel_store, &iter, AE_KEY, acc, -1);
1454 gtk_tree_path_free(path);
1458 static gboolean accel_default_scroll(GtkTreeView *data)
1462 GtkTreeViewColumn *column;
1464 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(accel_store), &iter);
1465 path = gtk_tree_model_get_path(GTK_TREE_MODEL(accel_store), &iter);
1466 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data),0);
1468 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1472 gtk_tree_path_free(path);
1477 static void accel_default_cb(GtkWidget *widget, gpointer data)
1479 accel_store_populate();
1481 g_idle_add((GSourceFunc)accel_default_scroll, data);
1484 void accel_remove_selection(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1486 gtk_tree_store_set(accel_store, iter, AE_KEY, "", -1);
1489 void accel_reset_selection(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1492 gchar *accel_path, *accel;
1494 gtk_tree_model_get(model, iter, AE_ACCEL, &accel_path, -1);
1495 gtk_accel_map_lookup_entry(accel_path, &key);
1496 accel = gtk_accelerator_name(key.accel_key, key.accel_mods);
1498 gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_remove_key_cb, accel);
1500 gtk_tree_store_set(accel_store, iter, AE_KEY, accel, -1);
1505 static void accel_reset_cb(GtkWidget *widget, gpointer data)
1507 GtkTreeSelection *selection;
1509 if (!accel_store) return;
1510 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data));
1511 gtk_tree_selection_selected_foreach(selection, &accel_reset_selection, NULL);
1516 static GtkWidget *scrolled_notebook_page(GtkWidget *notebook, const gchar *title)
1520 GtkWidget *scrolled;
1521 GtkWidget *viewport;
1523 scrolled = gtk_scrolled_window_new(NULL, NULL);
1524 gtk_container_set_border_width(GTK_CONTAINER(scrolled), PREF_PAD_BORDER);
1525 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
1526 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1527 label = gtk_label_new(title);
1528 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled, label);
1529 gtk_widget_show(scrolled);
1531 viewport = gtk_viewport_new(NULL, NULL);
1532 gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
1533 gtk_container_add(GTK_CONTAINER(scrolled), viewport);
1534 gtk_widget_show(viewport);
1536 vbox = gtk_vbox_new(FALSE, 0);
1537 gtk_container_add(GTK_CONTAINER(viewport), vbox);
1538 gtk_widget_show(vbox);
1543 static void cache_standard_cb(GtkWidget *widget, gpointer data)
1545 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1547 c_options->thumbnails.spec_standard =TRUE;
1548 c_options->thumbnails.cache_into_dirs = FALSE;
1552 c_options->thumbnails.spec_standard =FALSE;
1556 static void cache_geeqie_cb(GtkWidget *widget, gpointer data)
1558 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1560 c_options->thumbnails.spec_standard =TRUE;
1561 c_options->thumbnails.cache_into_dirs = FALSE;
1565 c_options->thumbnails.spec_standard =FALSE;
1569 static void cache_local_cb(GtkWidget *widget, gpointer data)
1571 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1573 c_options->thumbnails.cache_into_dirs = TRUE;
1574 c_options->thumbnails.spec_standard =FALSE;
1578 c_options->thumbnails.cache_into_dirs = FALSE;
1582 /* general options tab */
1583 static void config_tab_general(GtkWidget *notebook)
1588 GtkWidget *group_frame;
1589 GtkWidget *subgroup;
1591 GtkWidget *ct_button;
1594 gint hours, minutes, remainder;
1597 vbox = scrolled_notebook_page(notebook, _("General"));
1599 group = pref_group_new(vbox, FALSE, _("Thumbnails"), GTK_ORIENTATION_VERTICAL);
1601 table = pref_table_new(group, 2, 2, FALSE, FALSE);
1602 add_thumb_size_menu(table, 0, 0, _("Size:"));
1603 add_quality_menu(table, 0, 1, _("Quality:"), options->thumbnails.quality, &c_options->thumbnails.quality);
1605 ct_button = pref_checkbox_new_int(group, _("Cache thumbnails"),
1606 options->thumbnails.enable_caching, &c_options->thumbnails.enable_caching);
1608 subgroup = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1609 pref_checkbox_link_sensitivity(ct_button, subgroup);
1611 group_frame = pref_frame_new(subgroup, TRUE, _("Use Geeqie thumbnail style and cache"),
1612 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1613 button = pref_radiobutton_new(group_frame, NULL, get_thumbnails_cache_dir(),
1614 !options->thumbnails.spec_standard,
1615 G_CALLBACK(cache_geeqie_cb), NULL);
1617 group_frame = pref_frame_new(subgroup, TRUE,
1618 _("Store thumbnails local to image folder (non-standard)"),
1619 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1620 pref_radiobutton_new(group_frame, button, "*/.thumbnails",
1621 options->thumbnails.cache_into_dirs,
1622 G_CALLBACK(cache_local_cb), NULL);
1624 group_frame = pref_frame_new(subgroup, TRUE,
1625 _("Use standard thumbnail style and cache, shared with other applications"),
1626 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1627 pref_radiobutton_new(group_frame, button, get_thumbnails_standard_cache_dir(),
1628 options->thumbnails.spec_standard,
1629 G_CALLBACK(cache_standard_cb), NULL);
1631 pref_checkbox_new_int(group, _("Use EXIF thumbnails when available (EXIF thumbnails may be outdated)"),
1632 options->thumbnails.use_exif, &c_options->thumbnails.use_exif);
1634 #ifdef HAVE_FFMPEGTHUMBNAILER_METADATA
1635 pref_checkbox_new_int(group, _("Use embedded metadata in video files as thumbnails when available"),
1636 options->thumbnails.use_ft_metadata, &c_options->thumbnails.use_ft_metadata);
1638 // pref_checkbox_new_int(group, _("Ignore embedded metadata if size is too small"),
1639 // options->thumbnails.use_ft_metadata_small, &c_options->thumbnails.use_ft_metadata_small);
1642 group = pref_group_new(vbox, FALSE, _("Slide show"), GTK_ORIENTATION_VERTICAL);
1644 c_options->slideshow.delay = options->slideshow.delay;
1645 hours = options->slideshow.delay / (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1646 remainder = options->slideshow.delay % (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1647 minutes = remainder / (60 * SLIDESHOW_SUBSECOND_PRECISION);
1648 seconds = (gdouble)(remainder % (60 * SLIDESHOW_SUBSECOND_PRECISION)) /
1649 SLIDESHOW_SUBSECOND_PRECISION;
1651 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1653 spin = pref_spin_new(hbox, _("Delay between image change hrs:mins:secs.dec"), NULL,
1655 options->slideshow.delay ? hours : 0.0,
1656 G_CALLBACK(slideshow_delay_hours_cb), NULL);
1657 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1658 spin = pref_spin_new(hbox, ":" , NULL,
1660 options->slideshow.delay ? minutes: 0.0,
1661 G_CALLBACK(slideshow_delay_minutes_cb), NULL);
1662 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1663 spin = pref_spin_new(hbox, ":", NULL,
1664 SLIDESHOW_MIN_SECONDS, 59, 1.0, 1,
1665 options->slideshow.delay ? seconds : 10.0,
1666 G_CALLBACK(slideshow_delay_seconds_cb), NULL);
1667 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1669 pref_checkbox_new_int(group, _("Random"), options->slideshow.random, &c_options->slideshow.random);
1670 pref_checkbox_new_int(group, _("Repeat"), options->slideshow.repeat, &c_options->slideshow.repeat);
1672 group = pref_group_new(vbox, FALSE, _("Image loading and caching"), GTK_ORIENTATION_VERTICAL);
1674 pref_spin_new_int(group, _("Decoded image cache size (Mb):"), NULL,
1675 0, 99999, 1, options->image.image_cache_max, &c_options->image.image_cache_max);
1676 pref_checkbox_new_int(group, _("Preload next image"),
1677 options->image.enable_read_ahead, &c_options->image.enable_read_ahead);
1679 pref_checkbox_new_int(group, _("Refresh on file change"),
1680 options->update_on_time_change, &c_options->update_on_time_change);
1682 group = pref_group_new(vbox, FALSE, _("Info sidebar heights"), GTK_ORIENTATION_VERTICAL);
1683 pref_label_new(group, _("NOTE! Geeqie must be restarted for changes to take effect"));
1684 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1685 pref_spin_new_int(hbox, _("Keywords:"), NULL,
1687 options->info_keywords.height, &c_options->info_keywords.height);
1688 pref_spin_new_int(hbox, _("Title:"), NULL,
1690 options->info_title.height, &c_options->info_title.height);
1691 pref_spin_new_int(hbox, _("Comment:"), NULL,
1693 options->info_comment.height, &c_options->info_comment.height);
1694 pref_spin_new_int(hbox, _("Rating:"), NULL,
1696 options->info_rating.height, &c_options->info_rating.height);
1700 static void config_tab_image(GtkWidget *notebook)
1705 GtkWidget *ct_button;
1706 GtkWidget *enlargement_button;
1710 vbox = scrolled_notebook_page(notebook, _("Image"));
1712 group = pref_group_new(vbox, FALSE, _("Zoom"), GTK_ORIENTATION_VERTICAL);
1714 table = pref_table_new(group, 2, 1, FALSE, FALSE);
1715 add_quality_menu(table, 0, 0, _("Quality:"), options->image.zoom_quality, &c_options->image.zoom_quality);
1718 pref_checkbox_new_int(group, _("Use GPU acceleration via Clutter library"),
1719 options->image.use_clutter_renderer, &c_options->image.use_clutter_renderer);
1722 pref_checkbox_new_int(group, _("Two pass rendering (apply HQ zoom and color correction in second pass)"),
1723 options->image.zoom_2pass, &c_options->image.zoom_2pass);
1725 c_options->image.zoom_increment = options->image.zoom_increment;
1726 spin = pref_spin_new(group, _("Zoom increment:"), NULL,
1727 0.01, 4.0, 0.01, 2, (gdouble)options->image.zoom_increment / 100.0,
1728 G_CALLBACK(zoom_increment_cb), NULL);
1729 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1731 group = pref_group_new(vbox, FALSE, _("Fit image to window"), GTK_ORIENTATION_VERTICAL);
1733 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1734 enlargement_button = pref_checkbox_new_int(hbox, _("Allow enlargement of image (max. size in %)"),
1735 options->image.zoom_to_fit_allow_expand, &c_options->image.zoom_to_fit_allow_expand);
1736 spin = pref_spin_new_int(hbox, NULL, NULL,
1738 options->image.max_enlargement_size, &c_options->image.max_enlargement_size);
1739 pref_checkbox_link_sensitivity(enlargement_button, spin);
1740 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."));
1742 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1743 ct_button = pref_checkbox_new_int(hbox, _("Virtual window size (% of actual window):"),
1744 options->image.limit_autofit_size, &c_options->image.limit_autofit_size);
1745 spin = pref_spin_new_int(hbox, NULL, NULL,
1747 options->image.max_autofit_size, &c_options->image.max_autofit_size);
1748 pref_checkbox_link_sensitivity(ct_button, spin);
1749 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."));
1751 group = pref_group_new(vbox, FALSE, _("Appearance"), GTK_ORIENTATION_VERTICAL);
1753 pref_checkbox_new_int(group, _("Use custom border color in window mode"),
1754 options->image.use_custom_border_color, &c_options->image.use_custom_border_color);
1756 pref_checkbox_new_int(group, _("Use custom border color in fullscreen mode"),
1757 options->image.use_custom_border_color_in_fullscreen, &c_options->image.use_custom_border_color_in_fullscreen);
1759 pref_color_button_new(group, _("Border color"), &options->image.border_color,
1760 G_CALLBACK(pref_color_button_set_cb), &c_options->image.border_color);
1762 c_options->image.border_color = options->image.border_color;
1764 pref_color_button_new(group, _("Alpha channel color 1"), &options->image.alpha_color_1,
1765 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_1);
1767 pref_color_button_new(group, _("Alpha channel color 2"), &options->image.alpha_color_2,
1768 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_2);
1770 c_options->image.alpha_color_1 = options->image.alpha_color_1;
1771 c_options->image.alpha_color_2 = options->image.alpha_color_2;
1773 group = pref_group_new(vbox, FALSE, _("Convenience"), GTK_ORIENTATION_VERTICAL);
1775 pref_checkbox_new_int(group, _("Auto rotate proofs using Exif information"),
1776 options->image.exif_proof_rotate_enable, &c_options->image.exif_proof_rotate_enable);
1780 static void config_tab_windows(GtkWidget *notebook)
1786 GtkWidget *ct_button;
1788 GtkWidget *image_overlay_template_view;
1789 GtkWidget *scrolled;
1790 GtkTextBuffer *buffer;
1792 vbox = scrolled_notebook_page(notebook, _("Windows"));
1794 group = pref_group_new(vbox, FALSE, _("State"), GTK_ORIENTATION_VERTICAL);
1796 ct_button = pref_checkbox_new_int(group, _("Remember window positions"),
1797 options->save_window_positions, &c_options->save_window_positions);
1799 button = pref_checkbox_new_int(group, _("Use saved window positions also for new windows"),
1800 options->use_saved_window_positions_for_new_windows, &c_options->use_saved_window_positions_for_new_windows);
1801 pref_checkbox_link_sensitivity(ct_button, button);
1803 pref_checkbox_new_int(group, _("Remember tool state (float/hidden)"),
1804 options->tools_restore_state, &c_options->tools_restore_state);
1806 pref_checkbox_new_int(group, _("Remember dialog window positions"),
1807 options->save_dialog_window_positions, &c_options->save_dialog_window_positions);
1809 group = pref_group_new(vbox, FALSE, _("Size"), GTK_ORIENTATION_VERTICAL);
1811 pref_checkbox_new_int(group, _("Fit window to image when tools are hidden/floating"),
1812 options->image.fit_window_to_image, &c_options->image.fit_window_to_image);
1814 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1815 ct_button = pref_checkbox_new_int(hbox, _("Limit size when auto-sizing window (%):"),
1816 options->image.limit_window_size, &c_options->image.limit_window_size);
1817 spin = pref_spin_new_int(hbox, NULL, NULL,
1819 options->image.max_window_size, &c_options->image.max_window_size);
1820 pref_checkbox_link_sensitivity(ct_button, spin);
1822 group = pref_group_new(vbox, FALSE, _("Full screen"), GTK_ORIENTATION_VERTICAL);
1824 c_options->fullscreen.screen = options->fullscreen.screen;
1825 c_options->fullscreen.above = options->fullscreen.above;
1826 hbox = fullscreen_prefs_selection_new(_("Location:"), &c_options->fullscreen.screen, &c_options->fullscreen.above);
1827 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
1828 gtk_widget_show(hbox);
1830 pref_checkbox_new_int(group, _("Smooth image flip"),
1831 options->fullscreen.clean_flip, &c_options->fullscreen.clean_flip);
1832 pref_checkbox_new_int(group, _("Disable screen saver"),
1833 options->fullscreen.disable_saver, &c_options->fullscreen.disable_saver);
1836 group = pref_group_new(vbox, FALSE, _("Overlay Screen Display"), GTK_ORIENTATION_VERTICAL);
1838 pref_label_new(group, _("Image overlay template"));
1840 scrolled = gtk_scrolled_window_new(NULL, NULL);
1841 gtk_widget_set_size_request(scrolled, 200, 150);
1842 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
1843 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
1844 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1845 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 5);
1846 gtk_widget_show(scrolled);
1848 image_overlay_template_view = gtk_text_view_new();
1850 gtk_widget_set_tooltip_markup(image_overlay_template_view,
1851 _("<i>%name%</i> results in the filename of the picture.\n"
1852 "Also available: <i>%collection%</i>, <i>%number%</i>, <i>%total%</i>, <i>%date%</i>,\n"
1853 "<i>%size%</i> (filesize), <i>%width%</i>, <i>%height%</i>, <i>%res%</i> (resolution)\n"
1854 "To access exif data use the exif name, e. g. <i>%formatted.Camera%</i> is the formatted camera name,\n"
1855 "<i>%Exif.Photo.DateTimeOriginal%</i> the date of the original shot.\n"
1856 "<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"
1857 "If two or more variables are connected with the |-sign, it prints available variables with a separator.\n"
1858 "<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"
1859 "if there's no ISO information in the Exif data.\n"
1860 "If a line is empty, it is removed. This allows one to add lines that totally disappear when no data is available.\n"
1862 gtk_container_add(GTK_CONTAINER(scrolled), image_overlay_template_view);
1863 gtk_widget_show(image_overlay_template_view);
1865 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
1867 #if GTK_CHECK_VERSION(3,4,0)
1868 button = pref_button_new(NULL, GTK_STOCK_SELECT_FONT, _("Font"), FALSE,
1869 G_CALLBACK(image_overlay_set_font_cb), notebook);
1871 button = gtk_font_button_new();
1872 gtk_font_button_set_title(GTK_FONT_BUTTON(button), "Image Overlay Font");
1873 gtk_font_button_set_font_name(GTK_FONT_BUTTON(button), options->image_overlay.font);
1874 g_signal_connect(G_OBJECT(button), "font-set",
1875 G_CALLBACK(image_overlay_set_font_cb),NULL);
1877 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1878 gtk_widget_show(button);
1880 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Text"), FALSE,
1881 G_CALLBACK(image_overlay_set_text_colour_cb), NULL);
1882 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1883 gtk_widget_show(button);
1885 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Background"), FALSE,
1886 G_CALLBACK(image_overlay_set_background_colour_cb), NULL);
1887 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1888 gtk_widget_show(button);
1889 image_overlay_set_text_colours();
1891 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
1892 G_CALLBACK(image_overlay_default_template_cb), image_overlay_template_view);
1893 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1894 gtk_widget_show(button);
1896 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
1897 G_CALLBACK(image_overlay_help_cb), NULL);
1898 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1899 gtk_widget_show(button);
1901 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(image_overlay_template_view));
1902 if (options->image_overlay.template_string) gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
1903 g_signal_connect(G_OBJECT(buffer), "changed",
1904 G_CALLBACK(image_overlay_template_view_changed_cb), image_overlay_template_view);
1909 static GtkTreeModel *create_class_model(void)
1911 GtkListStore *model;
1915 /* create list store */
1916 model = gtk_list_store_new(1, G_TYPE_STRING);
1917 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
1919 gtk_list_store_append(model, &iter);
1920 gtk_list_store_set(model, &iter, 0, _(format_class_list[i]), -1);
1922 return GTK_TREE_MODEL (model);
1927 static void config_tab_files(GtkWidget *notebook)
1934 GtkWidget *ct_button;
1935 GtkWidget *scrolled;
1936 GtkWidget *filter_view;
1937 GtkCellRenderer *renderer;
1938 GtkTreeSelection *selection;
1939 GtkTreeViewColumn *column;
1941 vbox = scrolled_notebook_page(notebook, _("Files"));
1943 group = pref_box_new(vbox, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1945 pref_checkbox_new_int(group, _("Show hidden files or folders"),
1946 options->file_filter.show_hidden_files, &c_options->file_filter.show_hidden_files);
1947 pref_checkbox_new_int(group, _("Show parent folder (..)"),
1948 options->file_filter.show_parent_directory, &c_options->file_filter.show_parent_directory);
1949 pref_checkbox_new_int(group, _("Case sensitive sort"),
1950 options->file_sort.case_sensitive, &c_options->file_sort.case_sensitive);
1951 pref_checkbox_new_int(group, _("Natural sort order"),
1952 options->file_sort.natural, &c_options->file_sort.natural);
1953 pref_checkbox_new_int(group, _("Disable file extension checks"),
1954 options->file_filter.disable_file_extension_checks, &c_options->file_filter.disable_file_extension_checks);
1956 ct_button = pref_checkbox_new_int(group, _("Disable File Filtering"),
1957 options->file_filter.disable, &c_options->file_filter.disable);
1960 group = pref_group_new(vbox, FALSE, _("Grouping sidecar extensions"), GTK_ORIENTATION_VERTICAL);
1962 sidecar_ext_entry = gtk_entry_new();
1963 gtk_entry_set_text(GTK_ENTRY(sidecar_ext_entry), options->sidecar.ext);
1964 gtk_box_pack_start(GTK_BOX(group), sidecar_ext_entry, FALSE, FALSE, 0);
1965 gtk_widget_show(sidecar_ext_entry);
1967 group = pref_group_new(vbox, TRUE, _("File types"), GTK_ORIENTATION_VERTICAL);
1969 frame = pref_group_parent(group);
1970 g_signal_connect(G_OBJECT(ct_button), "toggled",
1971 G_CALLBACK(filter_disable_cb), frame);
1972 gtk_widget_set_sensitive(frame, !options->file_filter.disable);
1974 scrolled = gtk_scrolled_window_new(NULL, NULL);
1975 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
1976 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
1977 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
1978 gtk_widget_show(scrolled);
1980 filter_store = gtk_list_store_new(1, G_TYPE_POINTER);
1981 filter_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(filter_store));
1982 g_object_unref(filter_store);
1983 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
1984 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_SINGLE);
1986 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(filter_view), FALSE);
1988 column = gtk_tree_view_column_new();
1989 gtk_tree_view_column_set_title(column, _("Filter"));
1990 gtk_tree_view_column_set_resizable(column, TRUE);
1992 renderer = gtk_cell_renderer_toggle_new();
1993 g_signal_connect(G_OBJECT(renderer), "toggled",
1994 G_CALLBACK(filter_store_enable_cb), filter_store);
1995 gtk_tree_view_column_pack_start(column, renderer, FALSE);
1996 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
1997 GINT_TO_POINTER(FE_ENABLE), NULL);
1999 renderer = gtk_cell_renderer_text_new();
2000 g_signal_connect(G_OBJECT(renderer), "edited",
2001 G_CALLBACK(filter_store_ext_edit_cb), filter_store);
2002 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2003 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2004 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2005 GINT_TO_POINTER(FE_EXTENSION), NULL);
2006 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2008 column = gtk_tree_view_column_new();
2009 gtk_tree_view_column_set_title(column, _("Description"));
2010 gtk_tree_view_column_set_resizable(column, TRUE);
2011 gtk_tree_view_column_set_fixed_width(column, 200);
2012 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
2014 renderer = gtk_cell_renderer_text_new();
2015 g_signal_connect(G_OBJECT(renderer), "edited",
2016 G_CALLBACK(filter_store_desc_edit_cb), filter_store);
2017 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2018 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2019 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2020 GINT_TO_POINTER(FE_DESCRIPTION), NULL);
2021 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2023 column = gtk_tree_view_column_new();
2024 gtk_tree_view_column_set_title(column, _("Class"));
2025 gtk_tree_view_column_set_resizable(column, TRUE);
2026 renderer = gtk_cell_renderer_combo_new();
2027 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE,
2028 "model", create_class_model(),
2033 g_signal_connect(G_OBJECT(renderer), "edited",
2034 G_CALLBACK(filter_store_class_edit_cb), filter_store);
2035 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2036 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2037 GINT_TO_POINTER(FE_CLASS), NULL);
2038 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2040 column = gtk_tree_view_column_new();
2041 gtk_tree_view_column_set_title(column, _("Writable"));
2042 gtk_tree_view_column_set_resizable(column, FALSE);
2043 renderer = gtk_cell_renderer_toggle_new();
2044 g_signal_connect(G_OBJECT(renderer), "toggled",
2045 G_CALLBACK(filter_store_writable_cb), filter_store);
2046 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2047 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2048 GINT_TO_POINTER(FE_WRITABLE), NULL);
2049 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2051 column = gtk_tree_view_column_new();
2052 gtk_tree_view_column_set_title(column, _("Sidecar is allowed"));
2053 gtk_tree_view_column_set_resizable(column, FALSE);
2054 renderer = gtk_cell_renderer_toggle_new();
2055 g_signal_connect(G_OBJECT(renderer), "toggled",
2056 G_CALLBACK(filter_store_sidecar_cb), filter_store);
2057 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2058 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2059 GINT_TO_POINTER(FE_ALLOW_SIDECAR), NULL);
2060 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2063 filter_store_populate();
2064 gtk_container_add(GTK_CONTAINER(scrolled), filter_view);
2065 gtk_widget_show(filter_view);
2067 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2069 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2070 G_CALLBACK(filter_default_cb), filter_view);
2071 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2072 gtk_widget_show(button);
2074 button = pref_button_new(NULL, GTK_STOCK_REMOVE, NULL, FALSE,
2075 G_CALLBACK(filter_remove_cb), filter_view);
2076 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2077 gtk_widget_show(button);
2079 button = pref_button_new(NULL, GTK_STOCK_ADD, NULL, FALSE,
2080 G_CALLBACK(filter_add_cb), filter_view);
2081 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2082 gtk_widget_show(button);
2086 static void config_tab_metadata(GtkWidget *notebook)
2091 GtkWidget *ct_button;
2095 vbox = scrolled_notebook_page(notebook, _("Metadata"));
2098 group = pref_group_new(vbox, FALSE, _("Metadata writing process"), GTK_ORIENTATION_VERTICAL);
2100 label = pref_label_new(group, _("Warning: Geeqie is built without Exiv2. Some options are disabled."));
2102 label = pref_label_new(group, _("Metadata are written in the following order. The process ends after first success."));
2103 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2105 ct_button = pref_checkbox_new_int(group, _("1) Save metadata in image files, or sidecar files, according to the XMP standard"),
2106 options->metadata.save_in_image_file, &c_options->metadata.save_in_image_file);
2108 gtk_widget_set_sensitive(ct_button, FALSE);
2111 pref_checkbox_new_int(group, _("2) Save metadata in '.metadata' folder, local to image folder (non-standard)"),
2112 options->metadata.enable_metadata_dirs, &c_options->metadata.enable_metadata_dirs);
2114 text = g_strdup_printf(_("3) Save metadata in Geeqie private directory '%s'"), get_metadata_cache_dir());
2115 label = pref_label_new(group, text);
2116 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2117 gtk_misc_set_padding(GTK_MISC(label), 22, 0);
2120 group = pref_group_new(vbox, FALSE, _("Step 1: Write to image files"), GTK_ORIENTATION_VERTICAL);
2122 gtk_widget_set_sensitive(group, FALSE);
2125 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2126 pref_checkbox_link_sensitivity(ct_button, hbox);
2128 pref_checkbox_new_int(hbox, _("Store metadata also in legacy IPTC tags (converted according to IPTC4XMP standard)"),
2129 options->metadata.save_legacy_IPTC, &c_options->metadata.save_legacy_IPTC);
2131 pref_checkbox_new_int(hbox, _("Warn if the image files are unwritable"),
2132 options->metadata.warn_on_write_problems, &c_options->metadata.warn_on_write_problems);
2134 pref_checkbox_new_int(hbox, _("Ask before writing to image files"),
2135 options->metadata.confirm_write, &c_options->metadata.confirm_write);
2137 pref_checkbox_new_int(hbox, _("Create sidecar files named image.ext.xmp (as opposed to image.xmp)"),
2138 options->metadata.sidecar_extended_name, &c_options->metadata.sidecar_extended_name);
2140 group = pref_group_new(vbox, FALSE, _("Step 2 and 3: write to Geeqie private files"), GTK_ORIENTATION_VERTICAL);
2142 gtk_widget_set_sensitive(group, FALSE);
2145 pref_checkbox_new_int(group, _("Use GQview legacy metadata format (supports only keywords and comments) instead of XMP"),
2146 options->metadata.save_legacy_format, &c_options->metadata.save_legacy_format);
2149 group = pref_group_new(vbox, FALSE, _("Miscellaneous"), GTK_ORIENTATION_VERTICAL);
2150 pref_checkbox_new_int(group, _("Write the same description tags (keywords, comment, etc.) to all grouped sidecars"),
2151 options->metadata.sync_grouped_files, &c_options->metadata.sync_grouped_files);
2153 pref_checkbox_new_int(group, _("Allow keywords to differ only in case"),
2154 options->metadata.keywords_case_sensitive, &c_options->metadata.keywords_case_sensitive);
2156 ct_button = pref_checkbox_new_int(group, _("Write altered image orientation to the metadata"),
2157 options->metadata.write_orientation, &c_options->metadata.write_orientation);
2159 gtk_widget_set_sensitive(ct_button, FALSE);
2162 group = pref_group_new(vbox, FALSE, _("Auto-save options"), GTK_ORIENTATION_VERTICAL);
2164 ct_button = pref_checkbox_new_int(group, _("Write metadata after timeout"),
2165 options->metadata.confirm_after_timeout, &c_options->metadata.confirm_after_timeout);
2167 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2168 pref_checkbox_link_sensitivity(ct_button, hbox);
2170 pref_spin_new_int(hbox, _("Timeout (seconds):"), NULL, 0, 900, 1,
2171 options->metadata.confirm_timeout, &c_options->metadata.confirm_timeout);
2173 pref_checkbox_new_int(group, _("Write metadata on image change"),
2174 options->metadata.confirm_on_image_change, &c_options->metadata.confirm_on_image_change);
2176 pref_checkbox_new_int(group, _("Write metadata on directory change"),
2177 options->metadata.confirm_on_dir_change, &c_options->metadata.confirm_on_dir_change);
2182 static void intent_menu_cb(GtkWidget *combo, gpointer data)
2184 gint *option = data;
2186 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
2190 *option = INTENT_PERCEPTUAL;
2193 *option = INTENT_RELATIVE_COLORIMETRIC;
2196 *option = INTENT_SATURATION;
2199 *option = INTENT_ABSOLUTE_COLORIMETRIC;
2204 static void add_intent_menu(GtkWidget *table, gint column, gint row, const gchar *text,
2205 gint option, gint *option_c)
2212 pref_table_label(table, column, row, text, 0.0);
2214 combo = gtk_combo_box_text_new();
2216 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Perceptual"));
2217 if (option == INTENT_PERCEPTUAL) current = 0;
2218 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Relative Colorimetric"));
2219 if (option == INTENT_RELATIVE_COLORIMETRIC) current = 1;
2220 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Saturation"));
2221 if (option == INTENT_SATURATION) current = 2;
2222 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Absolute Colorimetric"));
2223 if (option == INTENT_ABSOLUTE_COLORIMETRIC) current = 3;
2225 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
2227 gtk_widget_set_tooltip_text(combo,"Refer to the lcms documentation for the defaults used when the selected Intent is not available");
2229 g_signal_connect(G_OBJECT(combo), "changed",
2230 G_CALLBACK(intent_menu_cb), option_c);
2232 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
2233 GTK_EXPAND | GTK_FILL, 0, 0, 0);
2234 gtk_widget_show(combo);
2238 static void config_tab_color(GtkWidget *notebook)
2247 vbox = scrolled_notebook_page(notebook, _("Color management"));
2249 group = pref_group_new(vbox, FALSE, _("Input profiles"), GTK_ORIENTATION_VERTICAL);
2251 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
2254 table = pref_table_new(group, 3, COLOR_PROFILE_INPUTS + 1, FALSE, FALSE);
2255 gtk_table_set_col_spacings(GTK_TABLE(table), PREF_PAD_GAP);
2257 label = pref_table_label(table, 0, 0, _("Type"), 0.0);
2258 pref_label_bold(label, TRUE, FALSE);
2260 label = pref_table_label(table, 1, 0, _("Menu name"), 0.0);
2261 pref_label_bold(label, TRUE, FALSE);
2263 label = pref_table_label(table, 2, 0, _("File"), 0.0);
2264 pref_label_bold(label, TRUE, FALSE);
2266 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
2271 buf = g_strdup_printf(_("Input %d:"), i + COLOR_PROFILE_FILE);
2272 pref_table_label(table, 0, i + 1, buf, 1.0);
2275 entry = gtk_entry_new();
2276 gtk_entry_set_max_length(GTK_ENTRY(entry), EDITOR_NAME_MAX_LENGTH);
2277 if (options->color_profile.input_name[i])
2279 gtk_entry_set_text(GTK_ENTRY(entry), options->color_profile.input_name[i]);
2281 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, i + 1, i + 2,
2282 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2283 gtk_widget_show(entry);
2284 color_profile_input_name_entry[i] = entry;
2286 tabcomp = tab_completion_new(&entry, options->color_profile.input_file[i], NULL, NULL);
2287 tab_completion_add_select_button(entry, _("Select color profile"), FALSE);
2288 gtk_widget_set_size_request(entry, 160, -1);
2289 gtk_table_attach(GTK_TABLE(table), tabcomp, 2, 3, i + 1, i + 2,
2290 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2291 gtk_widget_show(tabcomp);
2292 color_profile_input_file_entry[i] = entry;
2295 group = pref_group_new(vbox, FALSE, _("Screen profile"), GTK_ORIENTATION_VERTICAL);
2297 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
2299 pref_checkbox_new_int(group, _("Use system screen profile if available"),
2300 options->color_profile.use_x11_screen_profile, &c_options->color_profile.use_x11_screen_profile);
2302 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2304 pref_table_label(table, 0, 0, _("Screen:"), 1.0);
2305 tabcomp = tab_completion_new(&color_profile_screen_file_entry,
2306 options->color_profile.screen_file, NULL, NULL);
2307 tab_completion_add_select_button(color_profile_screen_file_entry, _("Select color profile"), FALSE);
2308 gtk_widget_set_size_request(color_profile_screen_file_entry, 160, -1);
2310 add_intent_menu(table, 0, 1, _("Render Intent:"), options->color_profile.render_intent, &c_options->color_profile.render_intent);
2312 gtk_table_attach(GTK_TABLE(table), tabcomp, 1, 2,
2314 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2316 gtk_widget_show(tabcomp);
2319 /* advanced entry tab */
2320 static void config_tab_behavior(GtkWidget *notebook)
2327 GtkWidget *ct_button;
2331 vbox = scrolled_notebook_page(notebook, _("Behavior"));
2333 group = pref_group_new(vbox, FALSE, _("Delete"), GTK_ORIENTATION_VERTICAL);
2335 pref_checkbox_new_int(group, _("Confirm file delete"),
2336 options->file_ops.confirm_delete, &c_options->file_ops.confirm_delete);
2337 pref_checkbox_new_int(group, _("Enable Delete key"),
2338 options->file_ops.enable_delete_key, &c_options->file_ops.enable_delete_key);
2340 ct_button = pref_checkbox_new_int(group, _("Safe delete"),
2341 options->file_ops.safe_delete_enable, &c_options->file_ops.safe_delete_enable);
2343 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2344 pref_checkbox_link_sensitivity(ct_button, hbox);
2346 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_SPACE);
2347 pref_label_new(hbox, _("Folder:"));
2349 tabcomp = tab_completion_new(&safe_delete_path_entry, options->file_ops.safe_delete_path, NULL, NULL);
2350 tab_completion_add_select_button(safe_delete_path_entry, NULL, TRUE);
2351 gtk_box_pack_start(GTK_BOX(hbox), tabcomp, TRUE, TRUE, 0);
2352 gtk_widget_show(tabcomp);
2354 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2355 pref_checkbox_link_sensitivity(ct_button, hbox);
2357 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_GAP);
2358 spin = pref_spin_new_int(hbox, _("Maximum size:"), _("MB"),
2359 0, 2048, 1, options->file_ops.safe_delete_folder_maxsize, &c_options->file_ops.safe_delete_folder_maxsize);
2360 gtk_widget_set_tooltip_markup(spin, _("Set to 0 for unlimited size"));
2361 button = pref_button_new(NULL, NULL, _("View"), FALSE,
2362 G_CALLBACK(safe_delete_view_cb), NULL);
2363 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2364 gtk_widget_show(button);
2366 button = pref_button_new(NULL, GTK_STOCK_CLEAR, NULL, FALSE,
2367 G_CALLBACK(safe_delete_clear_cb), NULL);
2368 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2369 gtk_widget_show(button);
2372 group = pref_group_new(vbox, FALSE, _("Behavior"), GTK_ORIENTATION_VERTICAL);
2374 pref_checkbox_new_int(group, _("Descend folders in tree view"),
2375 options->tree_descend_subdirs, &c_options->tree_descend_subdirs);
2377 pref_checkbox_new_int(group, _("In place renaming"),
2378 options->file_ops.enable_in_place_rename, &c_options->file_ops.enable_in_place_rename);
2380 pref_checkbox_new_int(group, _("List directory view uses single click to enter"),
2381 options->view_dir_list_single_click_enter, &c_options->view_dir_list_single_click_enter);
2383 pref_spin_new_int(group, _("Recent folder list maximum size"), NULL,
2384 1, 50, 1, options->open_recent_list_maxsize, &c_options->open_recent_list_maxsize);
2386 pref_spin_new_int(group, _("Drag'n drop icon size"), NULL,
2387 16, 256, 16, options->dnd_icon_size, &c_options->dnd_icon_size);
2389 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2390 add_clipboard_selection_menu(table, 0, 0, _("Copy path clipboard selection:"), options->clipboard_selection, &c_options->clipboard_selection);
2392 group = pref_group_new(vbox, FALSE, _("Navigation"), GTK_ORIENTATION_VERTICAL);
2394 pref_checkbox_new_int(group, _("Progressive keyboard scrolling"),
2395 options->progressive_key_scrolling, &c_options->progressive_key_scrolling);
2396 pref_spin_new_int(group, _("Keyboard scrolling step multiplier:"), NULL,
2397 1, 32, 1, options->keyboard_scroll_step, (int *)&c_options->keyboard_scroll_step);
2398 pref_checkbox_new_int(group, _("Mouse wheel scrolls image"),
2399 options->mousewheel_scrolls, &c_options->mousewheel_scrolls);
2400 pref_checkbox_new_int(group, _("Navigation by left or middle click on image"),
2401 options->image_lm_click_nav, &c_options->image_lm_click_nav);
2402 pref_checkbox_new_int(group, _("Play video by left click on image"),
2403 options->image_l_click_video, &c_options->image_l_click_video);
2404 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2405 add_video_menu(table, 0, 0, _("Play with:"), options->image_l_click_video_editor, &c_options->image_l_click_video_editor);
2409 group = pref_group_new(vbox, FALSE, _("Debugging"), GTK_ORIENTATION_VERTICAL);
2411 pref_spin_new_int(group, _("Debug level:"), NULL,
2412 DEBUG_LEVEL_MIN, DEBUG_LEVEL_MAX, 1, get_debug_level(), &debug_c);
2414 pref_checkbox_new_int(group, _("Timer data"),
2415 options->log_window.timer_data, &c_options->log_window.timer_data);
2417 pref_spin_new_int(group, _("Log Window max. lines:"), NULL,
2418 1, 99999, 1, options->log_window_lines, &options->log_window_lines);
2422 /* accelerators tab */
2423 static void config_tab_accelerators(GtkWidget *notebook)
2429 GtkWidget *scrolled;
2430 GtkWidget *accel_view;
2431 GtkCellRenderer *renderer;
2432 GtkTreeSelection *selection;
2433 GtkTreeViewColumn *column;
2435 vbox = scrolled_notebook_page(notebook, _("Keyboard"));
2437 group = pref_group_new(vbox, TRUE, _("Accelerators"), GTK_ORIENTATION_VERTICAL);
2439 scrolled = gtk_scrolled_window_new(NULL, NULL);
2440 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2441 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2442 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2443 gtk_widget_show(scrolled);
2445 accel_store = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
2447 accel_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(accel_store));
2448 g_object_unref(accel_store);
2449 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(accel_view));
2450 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_MULTIPLE);
2452 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(accel_view), FALSE);
2454 renderer = gtk_cell_renderer_text_new();
2456 column = gtk_tree_view_column_new_with_attributes(_("Action"),
2461 gtk_tree_view_column_set_sort_column_id(column, AE_ACTION);
2462 gtk_tree_view_column_set_resizable(column, TRUE);
2463 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2466 renderer = gtk_cell_renderer_accel_new();
2467 g_signal_connect(G_OBJECT(renderer), "accel-cleared",
2468 G_CALLBACK(accel_store_cleared_cb), accel_store);
2469 g_signal_connect(G_OBJECT(renderer), "accel-edited",
2470 G_CALLBACK(accel_store_edited_cb), accel_store);
2473 g_object_set (renderer,
2475 "accel-mode", GTK_CELL_RENDERER_ACCEL_MODE_OTHER,
2478 column = gtk_tree_view_column_new_with_attributes(_("KEY"),
2483 gtk_tree_view_column_set_sort_column_id(column, AE_KEY);
2484 gtk_tree_view_column_set_resizable(column, TRUE);
2485 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2487 renderer = gtk_cell_renderer_text_new();
2489 column = gtk_tree_view_column_new_with_attributes(_("Tooltip"),
2494 gtk_tree_view_column_set_sort_column_id(column, AE_TOOLTIP);
2495 gtk_tree_view_column_set_resizable(column, TRUE);
2496 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2498 renderer = gtk_cell_renderer_text_new();
2500 column = gtk_tree_view_column_new_with_attributes("Accel",
2505 gtk_tree_view_column_set_sort_column_id(column, AE_ACCEL);
2506 gtk_tree_view_column_set_resizable(column, TRUE);
2507 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2509 accel_store_populate();
2510 gtk_container_add(GTK_CONTAINER(scrolled), accel_view);
2511 gtk_widget_show(accel_view);
2513 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2515 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2516 G_CALLBACK(accel_default_cb), accel_view);
2517 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2518 gtk_widget_show(button);
2520 button = pref_button_new(NULL, NULL, _("Reset selected"), FALSE,
2521 G_CALLBACK(accel_reset_cb), accel_view);
2522 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2523 gtk_widget_show(button);
2527 static void config_tab_toolbar(GtkWidget *notebook)
2530 GtkWidget *toolbardata;
2533 lw = layout_window_list->data;
2535 vbox = scrolled_notebook_page(notebook, _("Toolbar"));
2537 toolbardata = toolbar_select_new(lw);
2538 gtk_box_pack_start(GTK_BOX(vbox), toolbardata, TRUE, TRUE, 0);
2539 gtk_widget_show(vbox);
2543 static void config_tab_stereo(GtkWidget *notebook)
2551 GtkWidget *fs_button;
2552 vbox = scrolled_notebook_page(notebook, _("Stereo"));
2554 group = pref_group_new(vbox, FALSE, _("Windowed stereo mode"), GTK_ORIENTATION_VERTICAL);
2556 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2557 add_stereo_mode_menu(table, 0, 0, _("Windowed stereo mode"), options->stereo.mode, &c_options->stereo.mode, FALSE);
2559 table = pref_table_new(group, 2, 2, TRUE, FALSE);
2560 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2561 pref_checkbox_new_int(box, _("Mirror left image"),
2562 options->stereo.mode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.mirror_left);
2563 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2564 pref_checkbox_new_int(box, _("Flip left image"),
2565 options->stereo.mode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.flip_left);
2566 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2567 pref_checkbox_new_int(box, _("Mirror right image"),
2568 options->stereo.mode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.mirror_right);
2569 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2570 pref_checkbox_new_int(box, _("Flip right image"),
2571 options->stereo.mode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.flip_right);
2572 pref_checkbox_new_int(group, _("Swap left and right images"),
2573 options->stereo.mode & PR_STEREO_SWAP, &c_options->stereo.tmp.swap);
2574 pref_checkbox_new_int(group, _("Disable stereo mode on single image source"),
2575 options->stereo.mode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.temp_disable);
2577 group = pref_group_new(vbox, FALSE, _("Fullscreen stereo mode"), GTK_ORIENTATION_VERTICAL);
2578 fs_button = pref_checkbox_new_int(group, _("Use different settings for fullscreen"),
2579 options->stereo.enable_fsmode, &c_options->stereo.enable_fsmode);
2580 box2 = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2581 pref_checkbox_link_sensitivity(fs_button, box2);
2582 table = pref_table_new(box2, 2, 1, FALSE, FALSE);
2583 add_stereo_mode_menu(table, 0, 0, _("Fullscreen stereo mode"), options->stereo.fsmode, &c_options->stereo.fsmode, TRUE);
2584 table = pref_table_new(box2, 2, 2, TRUE, FALSE);
2585 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2586 pref_checkbox_new_int(box, _("Mirror left image"),
2587 options->stereo.fsmode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.fs_mirror_left);
2588 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2589 pref_checkbox_new_int(box, _("Flip left image"),
2590 options->stereo.fsmode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.fs_flip_left);
2591 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2592 pref_checkbox_new_int(box, _("Mirror right image"),
2593 options->stereo.fsmode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.fs_mirror_right);
2594 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2595 pref_checkbox_new_int(box, _("Flip right image"),
2596 options->stereo.fsmode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.fs_flip_right);
2597 pref_checkbox_new_int(box2, _("Swap left and right images"),
2598 options->stereo.fsmode & PR_STEREO_SWAP, &c_options->stereo.tmp.fs_swap);
2599 pref_checkbox_new_int(box2, _("Disable stereo mode on single image source"),
2600 options->stereo.fsmode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.fs_temp_disable);
2602 group2 = pref_group_new(box2, FALSE, _("Fixed position"), GTK_ORIENTATION_VERTICAL);
2603 table = pref_table_new(group2, 5, 3, FALSE, FALSE);
2604 pref_table_spin_new_int(table, 0, 0, _("Width"), NULL,
2605 1, 5000, 1, options->stereo.fixed_w, &c_options->stereo.fixed_w);
2606 pref_table_spin_new_int(table, 3, 0, _("Height"), NULL,
2607 1, 5000, 1, options->stereo.fixed_h, &c_options->stereo.fixed_h);
2608 pref_table_spin_new_int(table, 0, 1, _("Left X"), NULL,
2609 0, 5000, 1, options->stereo.fixed_x1, &c_options->stereo.fixed_x1);
2610 pref_table_spin_new_int(table, 3, 1, _("Left Y"), NULL,
2611 0, 5000, 1, options->stereo.fixed_y1, &c_options->stereo.fixed_y1);
2612 pref_table_spin_new_int(table, 0, 2, _("Right X"), NULL,
2613 0, 5000, 1, options->stereo.fixed_x2, &c_options->stereo.fixed_x2);
2614 pref_table_spin_new_int(table, 3, 2, _("Right Y"), NULL,
2615 0, 5000, 1, options->stereo.fixed_y2, &c_options->stereo.fixed_y2);
2619 /* Main preferences window */
2620 static void config_window_create(void)
2622 GtkWidget *win_vbox;
2624 GtkWidget *notebook;
2626 GtkWidget *ct_button;
2628 if (!c_options) c_options = init_options(NULL);
2630 configwindow = window_new(GTK_WINDOW_TOPLEVEL, "preferences", PIXBUF_INLINE_ICON_CONFIG, NULL, _("Preferences"));
2631 gtk_window_set_type_hint(GTK_WINDOW(configwindow), GDK_WINDOW_TYPE_HINT_DIALOG);
2632 g_signal_connect(G_OBJECT(configwindow), "delete_event",
2633 G_CALLBACK(config_window_delete), NULL);
2634 gtk_window_set_default_size(GTK_WINDOW(configwindow), CONFIG_WINDOW_DEF_WIDTH, CONFIG_WINDOW_DEF_HEIGHT);
2635 gtk_window_set_resizable(GTK_WINDOW(configwindow), TRUE);
2636 gtk_container_set_border_width(GTK_CONTAINER(configwindow), PREF_PAD_BORDER);
2638 win_vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE);
2639 gtk_container_add(GTK_CONTAINER(configwindow), win_vbox);
2640 gtk_widget_show(win_vbox);
2642 notebook = gtk_notebook_new();
2643 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
2644 gtk_box_pack_start(GTK_BOX(win_vbox), notebook, TRUE, TRUE, 0);
2646 config_tab_general(notebook);
2647 config_tab_image(notebook);
2648 config_tab_windows(notebook);
2649 config_tab_accelerators(notebook);
2650 config_tab_files(notebook);
2651 config_tab_metadata(notebook);
2652 config_tab_color(notebook);
2653 config_tab_stereo(notebook);
2654 config_tab_behavior(notebook);
2655 config_tab_toolbar(notebook);
2657 hbox = gtk_hbutton_box_new();
2658 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
2659 gtk_box_set_spacing(GTK_BOX(hbox), PREF_PAD_BUTTON_GAP);
2660 gtk_box_pack_end(GTK_BOX(win_vbox), hbox, FALSE, FALSE, 0);
2661 gtk_widget_show(hbox);
2663 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
2664 G_CALLBACK(config_window_help_cb), notebook);
2665 gtk_container_add(GTK_CONTAINER(hbox), button);
2666 gtk_widget_set_can_default(button, TRUE);
2667 gtk_widget_show(button);
2669 button = pref_button_new(NULL, GTK_STOCK_OK, NULL, FALSE,
2670 G_CALLBACK(config_window_ok_cb), NULL);
2671 gtk_container_add(GTK_CONTAINER(hbox), button);
2672 gtk_widget_set_can_default(button, TRUE);
2673 gtk_widget_grab_default(button);
2674 gtk_widget_show(button);
2678 button = pref_button_new(NULL, GTK_STOCK_SAVE, NULL, FALSE,
2679 G_CALLBACK(config_window_save_cb), NULL);
2680 gtk_container_add(GTK_CONTAINER(hbox), button);
2681 gtk_widget_set_can_default(button, TRUE);
2682 gtk_widget_show(button);
2684 button = pref_button_new(NULL, GTK_STOCK_APPLY, NULL, FALSE,
2685 G_CALLBACK(config_window_apply_cb), NULL);
2686 gtk_container_add(GTK_CONTAINER(hbox), button);
2687 gtk_widget_set_can_default(button, TRUE);
2688 gtk_widget_show(button);
2690 button = pref_button_new(NULL, GTK_STOCK_CANCEL, NULL, FALSE,
2691 G_CALLBACK(config_window_close_cb), NULL);
2692 gtk_container_add(GTK_CONTAINER(hbox), button);
2693 gtk_widget_set_can_default(button, TRUE);
2694 gtk_widget_show(button);
2696 if (!generic_dialog_get_alternative_button_order(configwindow))
2698 gtk_box_reorder_child(GTK_BOX(hbox), ct_button, -1);
2701 gtk_widget_show(notebook);
2703 gtk_widget_show(configwindow);
2707 *-----------------------------------------------------------------------------
2708 * config window show (public)
2709 *-----------------------------------------------------------------------------
2712 void show_config_window(void)
2716 gtk_window_present(GTK_WINDOW(configwindow));
2720 config_window_create();
2729 void show_about_window(LayoutWindow *lw)
2731 GdkPixbuf *pixbuf_logo;
2732 GdkPixbuf *pixbuf_icon;
2733 gchar *authors[1000];
2738 #define LINE_LENGTH 1000
2739 gchar line[LINE_LENGTH];
2741 #if !GTK_CHECK_VERSION(3,0,0)
2744 copyright = g_string_new(NULL);
2745 path = g_build_filename(GQ_HELPDIR, "COPYING", NULL);
2746 fp = fopen(path, "r");
2749 while(fgets(line, LINE_LENGTH, fp))
2751 copyright = g_string_append(copyright, line);
2759 path = g_build_filename(GQ_HELPDIR, "AUTHORS", NULL);
2760 fp = fopen(path, "r");
2763 while(fgets(line, LINE_LENGTH, fp))
2765 /* get rid of ending \n from fgets */
2766 line[strlen(line) - 1] = '\0';
2767 authors[i_authors] = g_strdup(line);
2770 authors[i_authors] = NULL;
2775 comment = g_strconcat("Development and bug reports:\n", GQ_EMAIL_ADDRESS,
2776 "\nhttps://github.com/BestImageViewer/geeqie/issues",NULL);
2778 pixbuf_logo = pixbuf_inline(PIXBUF_INLINE_LOGO);
2779 pixbuf_icon = pixbuf_inline(PIXBUF_INLINE_ICON);
2780 gtk_show_about_dialog(GTK_WINDOW(lw->window),
2781 "title", _("About Geeqie"),
2783 "program-name", GQ_APPNAME,
2785 "logo", pixbuf_logo,
2786 "icon", pixbuf_icon,
2787 "website", GQ_WEBSITE,
2788 "website-label", "Website",
2789 "comments", comment,
2791 "translator-credits", _("translator-credits"),
2792 #if GTK_CHECK_VERSION(3,0,0)
2793 "license-type", GTK_LICENSE_GPL_2_0,
2795 "license", copyright->str,
2799 #if !GTK_CHECK_VERSION(3,0,0)
2800 g_string_free(copyright, TRUE);
2803 while(n < i_authors)
2813 static void image_overlay_set_text_colours()
2815 c_options->image_overlay.text_red = options->image_overlay.text_red;
2816 c_options->image_overlay.text_green = options->image_overlay.text_green;
2817 c_options->image_overlay.text_blue = options->image_overlay.text_blue;
2818 c_options->image_overlay.text_alpha = options->image_overlay.text_alpha;
2819 c_options->image_overlay.background_red = options->image_overlay.background_red;
2820 c_options->image_overlay.background_green = options->image_overlay.background_green;
2821 c_options->image_overlay.background_blue = options->image_overlay.background_blue;
2822 c_options->image_overlay.background_alpha = options->image_overlay.background_alpha;
2824 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */