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 "<i>%rating%</i>, <i>%keywords%</i>, <i>%comment%</i> (XMP), <i>%imagecomment%</i> (JPEG)\n"
1855 "To access exif data use the exif name, e. g. <i>%formatted.Camera%</i> is the formatted camera name,\n"
1856 "<i>%Exif.Photo.DateTimeOriginal%</i> the date of the original shot.\n"
1857 "<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"
1858 "If two or more variables are connected with the |-sign, it prints available variables with a separator.\n"
1859 "<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"
1860 "if there's no ISO information in the Exif data.\n"
1861 "If a line is empty, it is removed. This allows one to add lines that totally disappear when no data is available.\n"
1863 gtk_container_add(GTK_CONTAINER(scrolled), image_overlay_template_view);
1864 gtk_widget_show(image_overlay_template_view);
1866 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
1868 #if GTK_CHECK_VERSION(3,4,0)
1869 button = pref_button_new(NULL, GTK_STOCK_SELECT_FONT, _("Font"), FALSE,
1870 G_CALLBACK(image_overlay_set_font_cb), notebook);
1872 button = gtk_font_button_new();
1873 gtk_font_button_set_title(GTK_FONT_BUTTON(button), "Image Overlay Font");
1874 gtk_font_button_set_font_name(GTK_FONT_BUTTON(button), options->image_overlay.font);
1875 g_signal_connect(G_OBJECT(button), "font-set",
1876 G_CALLBACK(image_overlay_set_font_cb),NULL);
1878 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1879 gtk_widget_show(button);
1881 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Text"), FALSE,
1882 G_CALLBACK(image_overlay_set_text_colour_cb), NULL);
1883 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1884 gtk_widget_show(button);
1886 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Background"), FALSE,
1887 G_CALLBACK(image_overlay_set_background_colour_cb), NULL);
1888 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1889 gtk_widget_show(button);
1890 image_overlay_set_text_colours();
1892 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
1893 G_CALLBACK(image_overlay_default_template_cb), image_overlay_template_view);
1894 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1895 gtk_widget_show(button);
1897 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
1898 G_CALLBACK(image_overlay_help_cb), NULL);
1899 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1900 gtk_widget_show(button);
1902 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(image_overlay_template_view));
1903 if (options->image_overlay.template_string) gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
1904 g_signal_connect(G_OBJECT(buffer), "changed",
1905 G_CALLBACK(image_overlay_template_view_changed_cb), image_overlay_template_view);
1910 static GtkTreeModel *create_class_model(void)
1912 GtkListStore *model;
1916 /* create list store */
1917 model = gtk_list_store_new(1, G_TYPE_STRING);
1918 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
1920 gtk_list_store_append(model, &iter);
1921 gtk_list_store_set(model, &iter, 0, _(format_class_list[i]), -1);
1923 return GTK_TREE_MODEL (model);
1928 static void config_tab_files(GtkWidget *notebook)
1935 GtkWidget *ct_button;
1936 GtkWidget *scrolled;
1937 GtkWidget *filter_view;
1938 GtkCellRenderer *renderer;
1939 GtkTreeSelection *selection;
1940 GtkTreeViewColumn *column;
1942 vbox = scrolled_notebook_page(notebook, _("Files"));
1944 group = pref_box_new(vbox, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1946 pref_checkbox_new_int(group, _("Show hidden files or folders"),
1947 options->file_filter.show_hidden_files, &c_options->file_filter.show_hidden_files);
1948 pref_checkbox_new_int(group, _("Show parent folder (..)"),
1949 options->file_filter.show_parent_directory, &c_options->file_filter.show_parent_directory);
1950 pref_checkbox_new_int(group, _("Case sensitive sort"),
1951 options->file_sort.case_sensitive, &c_options->file_sort.case_sensitive);
1952 pref_checkbox_new_int(group, _("Natural sort order"),
1953 options->file_sort.natural, &c_options->file_sort.natural);
1954 pref_checkbox_new_int(group, _("Disable file extension checks"),
1955 options->file_filter.disable_file_extension_checks, &c_options->file_filter.disable_file_extension_checks);
1957 ct_button = pref_checkbox_new_int(group, _("Disable File Filtering"),
1958 options->file_filter.disable, &c_options->file_filter.disable);
1961 group = pref_group_new(vbox, FALSE, _("Grouping sidecar extensions"), GTK_ORIENTATION_VERTICAL);
1963 sidecar_ext_entry = gtk_entry_new();
1964 gtk_entry_set_text(GTK_ENTRY(sidecar_ext_entry), options->sidecar.ext);
1965 gtk_box_pack_start(GTK_BOX(group), sidecar_ext_entry, FALSE, FALSE, 0);
1966 gtk_widget_show(sidecar_ext_entry);
1968 group = pref_group_new(vbox, TRUE, _("File types"), GTK_ORIENTATION_VERTICAL);
1970 frame = pref_group_parent(group);
1971 g_signal_connect(G_OBJECT(ct_button), "toggled",
1972 G_CALLBACK(filter_disable_cb), frame);
1973 gtk_widget_set_sensitive(frame, !options->file_filter.disable);
1975 scrolled = gtk_scrolled_window_new(NULL, NULL);
1976 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
1977 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
1978 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
1979 gtk_widget_show(scrolled);
1981 filter_store = gtk_list_store_new(1, G_TYPE_POINTER);
1982 filter_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(filter_store));
1983 g_object_unref(filter_store);
1984 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
1985 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_SINGLE);
1987 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(filter_view), FALSE);
1989 column = gtk_tree_view_column_new();
1990 gtk_tree_view_column_set_title(column, _("Filter"));
1991 gtk_tree_view_column_set_resizable(column, TRUE);
1993 renderer = gtk_cell_renderer_toggle_new();
1994 g_signal_connect(G_OBJECT(renderer), "toggled",
1995 G_CALLBACK(filter_store_enable_cb), filter_store);
1996 gtk_tree_view_column_pack_start(column, renderer, FALSE);
1997 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
1998 GINT_TO_POINTER(FE_ENABLE), NULL);
2000 renderer = gtk_cell_renderer_text_new();
2001 g_signal_connect(G_OBJECT(renderer), "edited",
2002 G_CALLBACK(filter_store_ext_edit_cb), filter_store);
2003 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2004 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2005 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2006 GINT_TO_POINTER(FE_EXTENSION), NULL);
2007 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2009 column = gtk_tree_view_column_new();
2010 gtk_tree_view_column_set_title(column, _("Description"));
2011 gtk_tree_view_column_set_resizable(column, TRUE);
2012 gtk_tree_view_column_set_fixed_width(column, 200);
2013 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
2015 renderer = gtk_cell_renderer_text_new();
2016 g_signal_connect(G_OBJECT(renderer), "edited",
2017 G_CALLBACK(filter_store_desc_edit_cb), filter_store);
2018 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2019 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2020 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2021 GINT_TO_POINTER(FE_DESCRIPTION), NULL);
2022 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2024 column = gtk_tree_view_column_new();
2025 gtk_tree_view_column_set_title(column, _("Class"));
2026 gtk_tree_view_column_set_resizable(column, TRUE);
2027 renderer = gtk_cell_renderer_combo_new();
2028 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE,
2029 "model", create_class_model(),
2034 g_signal_connect(G_OBJECT(renderer), "edited",
2035 G_CALLBACK(filter_store_class_edit_cb), filter_store);
2036 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2037 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2038 GINT_TO_POINTER(FE_CLASS), NULL);
2039 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2041 column = gtk_tree_view_column_new();
2042 gtk_tree_view_column_set_title(column, _("Writable"));
2043 gtk_tree_view_column_set_resizable(column, FALSE);
2044 renderer = gtk_cell_renderer_toggle_new();
2045 g_signal_connect(G_OBJECT(renderer), "toggled",
2046 G_CALLBACK(filter_store_writable_cb), filter_store);
2047 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2048 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2049 GINT_TO_POINTER(FE_WRITABLE), NULL);
2050 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2052 column = gtk_tree_view_column_new();
2053 gtk_tree_view_column_set_title(column, _("Sidecar is allowed"));
2054 gtk_tree_view_column_set_resizable(column, FALSE);
2055 renderer = gtk_cell_renderer_toggle_new();
2056 g_signal_connect(G_OBJECT(renderer), "toggled",
2057 G_CALLBACK(filter_store_sidecar_cb), filter_store);
2058 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2059 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2060 GINT_TO_POINTER(FE_ALLOW_SIDECAR), NULL);
2061 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2064 filter_store_populate();
2065 gtk_container_add(GTK_CONTAINER(scrolled), filter_view);
2066 gtk_widget_show(filter_view);
2068 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2070 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2071 G_CALLBACK(filter_default_cb), filter_view);
2072 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2073 gtk_widget_show(button);
2075 button = pref_button_new(NULL, GTK_STOCK_REMOVE, NULL, FALSE,
2076 G_CALLBACK(filter_remove_cb), filter_view);
2077 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2078 gtk_widget_show(button);
2080 button = pref_button_new(NULL, GTK_STOCK_ADD, NULL, FALSE,
2081 G_CALLBACK(filter_add_cb), filter_view);
2082 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2083 gtk_widget_show(button);
2087 static void config_tab_metadata(GtkWidget *notebook)
2092 GtkWidget *ct_button;
2096 vbox = scrolled_notebook_page(notebook, _("Metadata"));
2099 group = pref_group_new(vbox, FALSE, _("Metadata writing process"), GTK_ORIENTATION_VERTICAL);
2101 label = pref_label_new(group, _("Warning: Geeqie is built without Exiv2. Some options are disabled."));
2103 label = pref_label_new(group, _("Metadata are written in the following order. The process ends after first success."));
2104 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2106 ct_button = pref_checkbox_new_int(group, _("1) Save metadata in image files, or sidecar files, according to the XMP standard"),
2107 options->metadata.save_in_image_file, &c_options->metadata.save_in_image_file);
2109 gtk_widget_set_sensitive(ct_button, FALSE);
2112 pref_checkbox_new_int(group, _("2) Save metadata in '.metadata' folder, local to image folder (non-standard)"),
2113 options->metadata.enable_metadata_dirs, &c_options->metadata.enable_metadata_dirs);
2115 text = g_strdup_printf(_("3) Save metadata in Geeqie private directory '%s'"), get_metadata_cache_dir());
2116 label = pref_label_new(group, text);
2117 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2118 gtk_misc_set_padding(GTK_MISC(label), 22, 0);
2121 group = pref_group_new(vbox, FALSE, _("Step 1: Write to image files"), GTK_ORIENTATION_VERTICAL);
2123 gtk_widget_set_sensitive(group, FALSE);
2126 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2127 pref_checkbox_link_sensitivity(ct_button, hbox);
2129 pref_checkbox_new_int(hbox, _("Store metadata also in legacy IPTC tags (converted according to IPTC4XMP standard)"),
2130 options->metadata.save_legacy_IPTC, &c_options->metadata.save_legacy_IPTC);
2132 pref_checkbox_new_int(hbox, _("Warn if the image files are unwritable"),
2133 options->metadata.warn_on_write_problems, &c_options->metadata.warn_on_write_problems);
2135 pref_checkbox_new_int(hbox, _("Ask before writing to image files"),
2136 options->metadata.confirm_write, &c_options->metadata.confirm_write);
2138 pref_checkbox_new_int(hbox, _("Create sidecar files named image.ext.xmp (as opposed to image.xmp)"),
2139 options->metadata.sidecar_extended_name, &c_options->metadata.sidecar_extended_name);
2141 group = pref_group_new(vbox, FALSE, _("Step 2 and 3: write to Geeqie private files"), GTK_ORIENTATION_VERTICAL);
2143 gtk_widget_set_sensitive(group, FALSE);
2146 pref_checkbox_new_int(group, _("Use GQview legacy metadata format (supports only keywords and comments) instead of XMP"),
2147 options->metadata.save_legacy_format, &c_options->metadata.save_legacy_format);
2150 group = pref_group_new(vbox, FALSE, _("Miscellaneous"), GTK_ORIENTATION_VERTICAL);
2151 pref_checkbox_new_int(group, _("Write the same description tags (keywords, comment, etc.) to all grouped sidecars"),
2152 options->metadata.sync_grouped_files, &c_options->metadata.sync_grouped_files);
2154 pref_checkbox_new_int(group, _("Allow keywords to differ only in case"),
2155 options->metadata.keywords_case_sensitive, &c_options->metadata.keywords_case_sensitive);
2157 ct_button = pref_checkbox_new_int(group, _("Write altered image orientation to the metadata"),
2158 options->metadata.write_orientation, &c_options->metadata.write_orientation);
2160 gtk_widget_set_sensitive(ct_button, FALSE);
2163 group = pref_group_new(vbox, FALSE, _("Auto-save options"), GTK_ORIENTATION_VERTICAL);
2165 ct_button = pref_checkbox_new_int(group, _("Write metadata after timeout"),
2166 options->metadata.confirm_after_timeout, &c_options->metadata.confirm_after_timeout);
2168 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2169 pref_checkbox_link_sensitivity(ct_button, hbox);
2171 pref_spin_new_int(hbox, _("Timeout (seconds):"), NULL, 0, 900, 1,
2172 options->metadata.confirm_timeout, &c_options->metadata.confirm_timeout);
2174 pref_checkbox_new_int(group, _("Write metadata on image change"),
2175 options->metadata.confirm_on_image_change, &c_options->metadata.confirm_on_image_change);
2177 pref_checkbox_new_int(group, _("Write metadata on directory change"),
2178 options->metadata.confirm_on_dir_change, &c_options->metadata.confirm_on_dir_change);
2183 static void intent_menu_cb(GtkWidget *combo, gpointer data)
2185 gint *option = data;
2187 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
2191 *option = INTENT_PERCEPTUAL;
2194 *option = INTENT_RELATIVE_COLORIMETRIC;
2197 *option = INTENT_SATURATION;
2200 *option = INTENT_ABSOLUTE_COLORIMETRIC;
2205 static void add_intent_menu(GtkWidget *table, gint column, gint row, const gchar *text,
2206 gint option, gint *option_c)
2213 pref_table_label(table, column, row, text, 0.0);
2215 combo = gtk_combo_box_text_new();
2217 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Perceptual"));
2218 if (option == INTENT_PERCEPTUAL) current = 0;
2219 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Relative Colorimetric"));
2220 if (option == INTENT_RELATIVE_COLORIMETRIC) current = 1;
2221 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Saturation"));
2222 if (option == INTENT_SATURATION) current = 2;
2223 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Absolute Colorimetric"));
2224 if (option == INTENT_ABSOLUTE_COLORIMETRIC) current = 3;
2226 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
2228 gtk_widget_set_tooltip_text(combo,"Refer to the lcms documentation for the defaults used when the selected Intent is not available");
2230 g_signal_connect(G_OBJECT(combo), "changed",
2231 G_CALLBACK(intent_menu_cb), option_c);
2233 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
2234 GTK_EXPAND | GTK_FILL, 0, 0, 0);
2235 gtk_widget_show(combo);
2239 static void config_tab_color(GtkWidget *notebook)
2248 vbox = scrolled_notebook_page(notebook, _("Color management"));
2250 group = pref_group_new(vbox, FALSE, _("Input profiles"), GTK_ORIENTATION_VERTICAL);
2252 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
2255 table = pref_table_new(group, 3, COLOR_PROFILE_INPUTS + 1, FALSE, FALSE);
2256 gtk_table_set_col_spacings(GTK_TABLE(table), PREF_PAD_GAP);
2258 label = pref_table_label(table, 0, 0, _("Type"), 0.0);
2259 pref_label_bold(label, TRUE, FALSE);
2261 label = pref_table_label(table, 1, 0, _("Menu name"), 0.0);
2262 pref_label_bold(label, TRUE, FALSE);
2264 label = pref_table_label(table, 2, 0, _("File"), 0.0);
2265 pref_label_bold(label, TRUE, FALSE);
2267 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
2272 buf = g_strdup_printf(_("Input %d:"), i + COLOR_PROFILE_FILE);
2273 pref_table_label(table, 0, i + 1, buf, 1.0);
2276 entry = gtk_entry_new();
2277 gtk_entry_set_max_length(GTK_ENTRY(entry), EDITOR_NAME_MAX_LENGTH);
2278 if (options->color_profile.input_name[i])
2280 gtk_entry_set_text(GTK_ENTRY(entry), options->color_profile.input_name[i]);
2282 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, i + 1, i + 2,
2283 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2284 gtk_widget_show(entry);
2285 color_profile_input_name_entry[i] = entry;
2287 tabcomp = tab_completion_new(&entry, options->color_profile.input_file[i], NULL, ".icc", "ICC Files", NULL);
2288 tab_completion_add_select_button(entry, _("Select color profile"), FALSE);
2289 gtk_widget_set_size_request(entry, 160, -1);
2290 gtk_table_attach(GTK_TABLE(table), tabcomp, 2, 3, i + 1, i + 2,
2291 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2292 gtk_widget_show(tabcomp);
2293 color_profile_input_file_entry[i] = entry;
2296 group = pref_group_new(vbox, FALSE, _("Screen profile"), GTK_ORIENTATION_VERTICAL);
2298 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
2300 pref_checkbox_new_int(group, _("Use system screen profile if available"),
2301 options->color_profile.use_x11_screen_profile, &c_options->color_profile.use_x11_screen_profile);
2303 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2305 pref_table_label(table, 0, 0, _("Screen:"), 1.0);
2306 tabcomp = tab_completion_new(&color_profile_screen_file_entry,
2307 options->color_profile.screen_file, NULL, ".icc", "ICC Files", NULL);
2308 tab_completion_add_select_button(color_profile_screen_file_entry, _("Select color profile"), FALSE);
2309 gtk_widget_set_size_request(color_profile_screen_file_entry, 160, -1);
2311 add_intent_menu(table, 0, 1, _("Render Intent:"), options->color_profile.render_intent, &c_options->color_profile.render_intent);
2313 gtk_table_attach(GTK_TABLE(table), tabcomp, 1, 2,
2315 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2317 gtk_widget_show(tabcomp);
2320 /* advanced entry tab */
2321 static void config_tab_behavior(GtkWidget *notebook)
2328 GtkWidget *ct_button;
2332 vbox = scrolled_notebook_page(notebook, _("Behavior"));
2334 group = pref_group_new(vbox, FALSE, _("Delete"), GTK_ORIENTATION_VERTICAL);
2336 pref_checkbox_new_int(group, _("Confirm file delete"),
2337 options->file_ops.confirm_delete, &c_options->file_ops.confirm_delete);
2338 pref_checkbox_new_int(group, _("Enable Delete key"),
2339 options->file_ops.enable_delete_key, &c_options->file_ops.enable_delete_key);
2341 ct_button = pref_checkbox_new_int(group, _("Safe delete"),
2342 options->file_ops.safe_delete_enable, &c_options->file_ops.safe_delete_enable);
2344 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2345 pref_checkbox_link_sensitivity(ct_button, hbox);
2347 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_SPACE);
2348 pref_label_new(hbox, _("Folder:"));
2350 tabcomp = tab_completion_new(&safe_delete_path_entry, options->file_ops.safe_delete_path, NULL, NULL, NULL, NULL);
2351 tab_completion_add_select_button(safe_delete_path_entry, NULL, TRUE);
2352 gtk_box_pack_start(GTK_BOX(hbox), tabcomp, TRUE, TRUE, 0);
2353 gtk_widget_show(tabcomp);
2355 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2356 pref_checkbox_link_sensitivity(ct_button, hbox);
2358 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_GAP);
2359 spin = pref_spin_new_int(hbox, _("Maximum size:"), _("MB"),
2360 0, 2048, 1, options->file_ops.safe_delete_folder_maxsize, &c_options->file_ops.safe_delete_folder_maxsize);
2361 gtk_widget_set_tooltip_markup(spin, _("Set to 0 for unlimited size"));
2362 button = pref_button_new(NULL, NULL, _("View"), FALSE,
2363 G_CALLBACK(safe_delete_view_cb), NULL);
2364 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2365 gtk_widget_show(button);
2367 button = pref_button_new(NULL, GTK_STOCK_CLEAR, NULL, FALSE,
2368 G_CALLBACK(safe_delete_clear_cb), NULL);
2369 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2370 gtk_widget_show(button);
2373 group = pref_group_new(vbox, FALSE, _("Behavior"), GTK_ORIENTATION_VERTICAL);
2375 pref_checkbox_new_int(group, _("Descend folders in tree view"),
2376 options->tree_descend_subdirs, &c_options->tree_descend_subdirs);
2378 pref_checkbox_new_int(group, _("In place renaming"),
2379 options->file_ops.enable_in_place_rename, &c_options->file_ops.enable_in_place_rename);
2381 pref_checkbox_new_int(group, _("List directory view uses single click to enter"),
2382 options->view_dir_list_single_click_enter, &c_options->view_dir_list_single_click_enter);
2384 pref_spin_new_int(group, _("Recent folder list maximum size"), NULL,
2385 1, 50, 1, options->open_recent_list_maxsize, &c_options->open_recent_list_maxsize);
2387 pref_spin_new_int(group, _("Drag'n drop icon size"), NULL,
2388 16, 256, 16, options->dnd_icon_size, &c_options->dnd_icon_size);
2390 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2391 add_clipboard_selection_menu(table, 0, 0, _("Copy path clipboard selection:"), options->clipboard_selection, &c_options->clipboard_selection);
2393 group = pref_group_new(vbox, FALSE, _("Navigation"), GTK_ORIENTATION_VERTICAL);
2395 pref_checkbox_new_int(group, _("Progressive keyboard scrolling"),
2396 options->progressive_key_scrolling, &c_options->progressive_key_scrolling);
2397 pref_spin_new_int(group, _("Keyboard scrolling step multiplier:"), NULL,
2398 1, 32, 1, options->keyboard_scroll_step, (int *)&c_options->keyboard_scroll_step);
2399 pref_checkbox_new_int(group, _("Mouse wheel scrolls image"),
2400 options->mousewheel_scrolls, &c_options->mousewheel_scrolls);
2401 pref_checkbox_new_int(group, _("Navigation by left or middle click on image"),
2402 options->image_lm_click_nav, &c_options->image_lm_click_nav);
2403 pref_checkbox_new_int(group, _("Play video by left click on image"),
2404 options->image_l_click_video, &c_options->image_l_click_video);
2405 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2406 add_video_menu(table, 0, 0, _("Play with:"), options->image_l_click_video_editor, &c_options->image_l_click_video_editor);
2410 group = pref_group_new(vbox, FALSE, _("Debugging"), GTK_ORIENTATION_VERTICAL);
2412 pref_spin_new_int(group, _("Debug level:"), NULL,
2413 DEBUG_LEVEL_MIN, DEBUG_LEVEL_MAX, 1, get_debug_level(), &debug_c);
2415 pref_checkbox_new_int(group, _("Timer data"),
2416 options->log_window.timer_data, &c_options->log_window.timer_data);
2418 pref_spin_new_int(group, _("Log Window max. lines:"), NULL,
2419 1, 99999, 1, options->log_window_lines, &options->log_window_lines);
2423 /* accelerators tab */
2424 static void config_tab_accelerators(GtkWidget *notebook)
2430 GtkWidget *scrolled;
2431 GtkWidget *accel_view;
2432 GtkCellRenderer *renderer;
2433 GtkTreeSelection *selection;
2434 GtkTreeViewColumn *column;
2436 vbox = scrolled_notebook_page(notebook, _("Keyboard"));
2438 group = pref_group_new(vbox, TRUE, _("Accelerators"), GTK_ORIENTATION_VERTICAL);
2440 scrolled = gtk_scrolled_window_new(NULL, NULL);
2441 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2442 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2443 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2444 gtk_widget_show(scrolled);
2446 accel_store = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
2448 accel_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(accel_store));
2449 g_object_unref(accel_store);
2450 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(accel_view));
2451 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_MULTIPLE);
2453 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(accel_view), FALSE);
2455 renderer = gtk_cell_renderer_text_new();
2457 column = gtk_tree_view_column_new_with_attributes(_("Action"),
2462 gtk_tree_view_column_set_sort_column_id(column, AE_ACTION);
2463 gtk_tree_view_column_set_resizable(column, TRUE);
2464 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2467 renderer = gtk_cell_renderer_accel_new();
2468 g_signal_connect(G_OBJECT(renderer), "accel-cleared",
2469 G_CALLBACK(accel_store_cleared_cb), accel_store);
2470 g_signal_connect(G_OBJECT(renderer), "accel-edited",
2471 G_CALLBACK(accel_store_edited_cb), accel_store);
2474 g_object_set (renderer,
2476 "accel-mode", GTK_CELL_RENDERER_ACCEL_MODE_OTHER,
2479 column = gtk_tree_view_column_new_with_attributes(_("KEY"),
2484 gtk_tree_view_column_set_sort_column_id(column, AE_KEY);
2485 gtk_tree_view_column_set_resizable(column, TRUE);
2486 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2488 renderer = gtk_cell_renderer_text_new();
2490 column = gtk_tree_view_column_new_with_attributes(_("Tooltip"),
2495 gtk_tree_view_column_set_sort_column_id(column, AE_TOOLTIP);
2496 gtk_tree_view_column_set_resizable(column, TRUE);
2497 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2499 renderer = gtk_cell_renderer_text_new();
2501 column = gtk_tree_view_column_new_with_attributes("Accel",
2506 gtk_tree_view_column_set_sort_column_id(column, AE_ACCEL);
2507 gtk_tree_view_column_set_resizable(column, TRUE);
2508 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2510 accel_store_populate();
2511 gtk_container_add(GTK_CONTAINER(scrolled), accel_view);
2512 gtk_widget_show(accel_view);
2514 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2516 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2517 G_CALLBACK(accel_default_cb), accel_view);
2518 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2519 gtk_widget_show(button);
2521 button = pref_button_new(NULL, NULL, _("Reset selected"), FALSE,
2522 G_CALLBACK(accel_reset_cb), accel_view);
2523 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2524 gtk_widget_show(button);
2528 static void config_tab_toolbar(GtkWidget *notebook)
2531 GtkWidget *toolbardata;
2534 lw = layout_window_list->data;
2536 vbox = scrolled_notebook_page(notebook, _("Toolbar"));
2538 toolbardata = toolbar_select_new(lw);
2539 gtk_box_pack_start(GTK_BOX(vbox), toolbardata, TRUE, TRUE, 0);
2540 gtk_widget_show(vbox);
2544 static void config_tab_stereo(GtkWidget *notebook)
2552 GtkWidget *fs_button;
2553 vbox = scrolled_notebook_page(notebook, _("Stereo"));
2555 group = pref_group_new(vbox, FALSE, _("Windowed stereo mode"), GTK_ORIENTATION_VERTICAL);
2557 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2558 add_stereo_mode_menu(table, 0, 0, _("Windowed stereo mode"), options->stereo.mode, &c_options->stereo.mode, FALSE);
2560 table = pref_table_new(group, 2, 2, TRUE, FALSE);
2561 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2562 pref_checkbox_new_int(box, _("Mirror left image"),
2563 options->stereo.mode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.mirror_left);
2564 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2565 pref_checkbox_new_int(box, _("Flip left image"),
2566 options->stereo.mode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.flip_left);
2567 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2568 pref_checkbox_new_int(box, _("Mirror right image"),
2569 options->stereo.mode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.mirror_right);
2570 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2571 pref_checkbox_new_int(box, _("Flip right image"),
2572 options->stereo.mode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.flip_right);
2573 pref_checkbox_new_int(group, _("Swap left and right images"),
2574 options->stereo.mode & PR_STEREO_SWAP, &c_options->stereo.tmp.swap);
2575 pref_checkbox_new_int(group, _("Disable stereo mode on single image source"),
2576 options->stereo.mode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.temp_disable);
2578 group = pref_group_new(vbox, FALSE, _("Fullscreen stereo mode"), GTK_ORIENTATION_VERTICAL);
2579 fs_button = pref_checkbox_new_int(group, _("Use different settings for fullscreen"),
2580 options->stereo.enable_fsmode, &c_options->stereo.enable_fsmode);
2581 box2 = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2582 pref_checkbox_link_sensitivity(fs_button, box2);
2583 table = pref_table_new(box2, 2, 1, FALSE, FALSE);
2584 add_stereo_mode_menu(table, 0, 0, _("Fullscreen stereo mode"), options->stereo.fsmode, &c_options->stereo.fsmode, TRUE);
2585 table = pref_table_new(box2, 2, 2, TRUE, FALSE);
2586 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2587 pref_checkbox_new_int(box, _("Mirror left image"),
2588 options->stereo.fsmode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.fs_mirror_left);
2589 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2590 pref_checkbox_new_int(box, _("Flip left image"),
2591 options->stereo.fsmode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.fs_flip_left);
2592 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2593 pref_checkbox_new_int(box, _("Mirror right image"),
2594 options->stereo.fsmode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.fs_mirror_right);
2595 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2596 pref_checkbox_new_int(box, _("Flip right image"),
2597 options->stereo.fsmode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.fs_flip_right);
2598 pref_checkbox_new_int(box2, _("Swap left and right images"),
2599 options->stereo.fsmode & PR_STEREO_SWAP, &c_options->stereo.tmp.fs_swap);
2600 pref_checkbox_new_int(box2, _("Disable stereo mode on single image source"),
2601 options->stereo.fsmode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.fs_temp_disable);
2603 group2 = pref_group_new(box2, FALSE, _("Fixed position"), GTK_ORIENTATION_VERTICAL);
2604 table = pref_table_new(group2, 5, 3, FALSE, FALSE);
2605 pref_table_spin_new_int(table, 0, 0, _("Width"), NULL,
2606 1, 5000, 1, options->stereo.fixed_w, &c_options->stereo.fixed_w);
2607 pref_table_spin_new_int(table, 3, 0, _("Height"), NULL,
2608 1, 5000, 1, options->stereo.fixed_h, &c_options->stereo.fixed_h);
2609 pref_table_spin_new_int(table, 0, 1, _("Left X"), NULL,
2610 0, 5000, 1, options->stereo.fixed_x1, &c_options->stereo.fixed_x1);
2611 pref_table_spin_new_int(table, 3, 1, _("Left Y"), NULL,
2612 0, 5000, 1, options->stereo.fixed_y1, &c_options->stereo.fixed_y1);
2613 pref_table_spin_new_int(table, 0, 2, _("Right X"), NULL,
2614 0, 5000, 1, options->stereo.fixed_x2, &c_options->stereo.fixed_x2);
2615 pref_table_spin_new_int(table, 3, 2, _("Right Y"), NULL,
2616 0, 5000, 1, options->stereo.fixed_y2, &c_options->stereo.fixed_y2);
2620 /* Main preferences window */
2621 static void config_window_create(void)
2623 GtkWidget *win_vbox;
2625 GtkWidget *notebook;
2627 GtkWidget *ct_button;
2629 if (!c_options) c_options = init_options(NULL);
2631 configwindow = window_new(GTK_WINDOW_TOPLEVEL, "preferences", PIXBUF_INLINE_ICON_CONFIG, NULL, _("Preferences"));
2632 gtk_window_set_type_hint(GTK_WINDOW(configwindow), GDK_WINDOW_TYPE_HINT_DIALOG);
2633 g_signal_connect(G_OBJECT(configwindow), "delete_event",
2634 G_CALLBACK(config_window_delete), NULL);
2635 gtk_window_set_default_size(GTK_WINDOW(configwindow), CONFIG_WINDOW_DEF_WIDTH, CONFIG_WINDOW_DEF_HEIGHT);
2636 gtk_window_set_resizable(GTK_WINDOW(configwindow), TRUE);
2637 gtk_container_set_border_width(GTK_CONTAINER(configwindow), PREF_PAD_BORDER);
2639 win_vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE);
2640 gtk_container_add(GTK_CONTAINER(configwindow), win_vbox);
2641 gtk_widget_show(win_vbox);
2643 notebook = gtk_notebook_new();
2644 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
2645 gtk_box_pack_start(GTK_BOX(win_vbox), notebook, TRUE, TRUE, 0);
2647 config_tab_general(notebook);
2648 config_tab_image(notebook);
2649 config_tab_windows(notebook);
2650 config_tab_accelerators(notebook);
2651 config_tab_files(notebook);
2652 config_tab_metadata(notebook);
2653 config_tab_color(notebook);
2654 config_tab_stereo(notebook);
2655 config_tab_behavior(notebook);
2656 config_tab_toolbar(notebook);
2658 hbox = gtk_hbutton_box_new();
2659 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
2660 gtk_box_set_spacing(GTK_BOX(hbox), PREF_PAD_BUTTON_GAP);
2661 gtk_box_pack_end(GTK_BOX(win_vbox), hbox, FALSE, FALSE, 0);
2662 gtk_widget_show(hbox);
2664 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
2665 G_CALLBACK(config_window_help_cb), notebook);
2666 gtk_container_add(GTK_CONTAINER(hbox), button);
2667 gtk_widget_set_can_default(button, TRUE);
2668 gtk_widget_show(button);
2670 button = pref_button_new(NULL, GTK_STOCK_OK, NULL, FALSE,
2671 G_CALLBACK(config_window_ok_cb), NULL);
2672 gtk_container_add(GTK_CONTAINER(hbox), button);
2673 gtk_widget_set_can_default(button, TRUE);
2674 gtk_widget_grab_default(button);
2675 gtk_widget_show(button);
2679 button = pref_button_new(NULL, GTK_STOCK_SAVE, NULL, FALSE,
2680 G_CALLBACK(config_window_save_cb), NULL);
2681 gtk_container_add(GTK_CONTAINER(hbox), button);
2682 gtk_widget_set_can_default(button, TRUE);
2683 gtk_widget_show(button);
2685 button = pref_button_new(NULL, GTK_STOCK_APPLY, NULL, FALSE,
2686 G_CALLBACK(config_window_apply_cb), NULL);
2687 gtk_container_add(GTK_CONTAINER(hbox), button);
2688 gtk_widget_set_can_default(button, TRUE);
2689 gtk_widget_show(button);
2691 button = pref_button_new(NULL, GTK_STOCK_CANCEL, NULL, FALSE,
2692 G_CALLBACK(config_window_close_cb), NULL);
2693 gtk_container_add(GTK_CONTAINER(hbox), button);
2694 gtk_widget_set_can_default(button, TRUE);
2695 gtk_widget_show(button);
2697 if (!generic_dialog_get_alternative_button_order(configwindow))
2699 gtk_box_reorder_child(GTK_BOX(hbox), ct_button, -1);
2702 gtk_widget_show(notebook);
2704 gtk_widget_show(configwindow);
2708 *-----------------------------------------------------------------------------
2709 * config window show (public)
2710 *-----------------------------------------------------------------------------
2713 void show_config_window(void)
2717 gtk_window_present(GTK_WINDOW(configwindow));
2721 config_window_create();
2730 void show_about_window(LayoutWindow *lw)
2732 GdkPixbuf *pixbuf_logo;
2733 GdkPixbuf *pixbuf_icon;
2734 gchar *authors[1000];
2739 #define LINE_LENGTH 1000
2740 gchar line[LINE_LENGTH];
2742 #if !GTK_CHECK_VERSION(3,0,0)
2745 copyright = g_string_new(NULL);
2746 path = g_build_filename(GQ_HELPDIR, "COPYING", NULL);
2747 fp = fopen(path, "r");
2750 while(fgets(line, LINE_LENGTH, fp))
2752 copyright = g_string_append(copyright, line);
2760 path = g_build_filename(GQ_HELPDIR, "AUTHORS", NULL);
2761 fp = fopen(path, "r");
2764 while(fgets(line, LINE_LENGTH, fp))
2766 /* get rid of ending \n from fgets */
2767 line[strlen(line) - 1] = '\0';
2768 authors[i_authors] = g_strdup(line);
2771 authors[i_authors] = NULL;
2776 comment = g_strconcat("Development and bug reports:\n", GQ_EMAIL_ADDRESS,
2777 "\nhttps://github.com/BestImageViewer/geeqie/issues",NULL);
2779 pixbuf_logo = pixbuf_inline(PIXBUF_INLINE_LOGO);
2780 pixbuf_icon = pixbuf_inline(PIXBUF_INLINE_ICON);
2781 gtk_show_about_dialog(GTK_WINDOW(lw->window),
2782 "title", _("About Geeqie"),
2784 "program-name", GQ_APPNAME,
2786 "logo", pixbuf_logo,
2787 "icon", pixbuf_icon,
2788 "website", GQ_WEBSITE,
2789 "website-label", "Website",
2790 "comments", comment,
2792 "translator-credits", _("translator-credits"),
2793 #if GTK_CHECK_VERSION(3,0,0)
2794 "license-type", GTK_LICENSE_GPL_2_0,
2796 "license", copyright->str,
2800 #if !GTK_CHECK_VERSION(3,0,0)
2801 g_string_free(copyright, TRUE);
2804 while(n < i_authors)
2814 static void image_overlay_set_text_colours()
2816 c_options->image_overlay.text_red = options->image_overlay.text_red;
2817 c_options->image_overlay.text_green = options->image_overlay.text_green;
2818 c_options->image_overlay.text_blue = options->image_overlay.text_blue;
2819 c_options->image_overlay.text_alpha = options->image_overlay.text_alpha;
2820 c_options->image_overlay.background_red = options->image_overlay.background_red;
2821 c_options->image_overlay.background_green = options->image_overlay.background_green;
2822 c_options->image_overlay.background_blue = options->image_overlay.background_blue;
2823 c_options->image_overlay.background_alpha = options->image_overlay.background_alpha;
2825 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */