2 * Copyright (C) 2006 John Ellis
3 * Copyright (C) 2008 - 2016 The Geeqie Team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "preferences.h"
27 #include "cache_maint.h"
31 #include "filefilter.h"
32 #include "fullscreen.h"
34 #include "image-overlay.h"
35 #include "color-man.h"
37 #include "layout_config.h"
38 #include "layout_util.h"
39 #include "pixbuf_util.h"
40 #include "slideshow.h"
44 #include "ui_fileops.h"
46 #include "ui_tabcomp.h"
47 #include "ui_utildlg.h"
49 #include "zonedetect.h"
61 #define EDITOR_NAME_MAX_LENGTH 32
62 #define EDITOR_COMMAND_MAX_LENGTH 1024
64 static void image_overlay_set_text_colours();
66 typedef struct _ThumbSize ThumbSize;
73 static ThumbSize thumb_size_list[] =
107 gchar *format_class_list[] = {
116 /* config memory values */
117 static ConfOptions *c_options = NULL;
124 static GtkWidget *configwindow = NULL;
125 static GtkListStore *filter_store = NULL;
126 static GtkTreeStore *accel_store = NULL;
128 static GtkWidget *safe_delete_path_entry;
130 static GtkWidget *color_profile_input_file_entry[COLOR_PROFILE_INPUTS];
131 static GtkWidget *color_profile_input_name_entry[COLOR_PROFILE_INPUTS];
132 static GtkWidget *color_profile_screen_file_entry;
134 static GtkWidget *sidecar_ext_entry;
135 static GtkWidget *help_search_engine_entry;
138 #define CONFIG_WINDOW_DEF_WIDTH 700
139 #define CONFIG_WINDOW_DEF_HEIGHT 600
142 *-----------------------------------------------------------------------------
143 * option widget callbacks (private)
144 *-----------------------------------------------------------------------------
147 static void zoom_increment_cb(GtkWidget *spin, gpointer data)
149 c_options->image.zoom_increment = (gint)(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) * 100.0 + 0.01);
152 static void slideshow_delay_hours_cb(GtkWidget *spin, gpointer data)
154 gint mins_secs_tenths, delay;
156 mins_secs_tenths = c_options->slideshow.delay %
157 (3600 * SLIDESHOW_SUBSECOND_PRECISION);
159 delay = (gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
160 (3600 * SLIDESHOW_SUBSECOND_PRECISION) +
163 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
164 SLIDESHOW_SUBSECOND_PRECISION;
167 static void slideshow_delay_minutes_cb(GtkWidget *spin, gpointer data)
169 gint hours, secs_tenths, delay;
171 hours = c_options->slideshow.delay / (3600 * SLIDESHOW_SUBSECOND_PRECISION);
172 secs_tenths = c_options->slideshow.delay % (60 * SLIDESHOW_SUBSECOND_PRECISION);
174 delay = hours * (3600 * SLIDESHOW_SUBSECOND_PRECISION) +
175 (gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
176 (60 * SLIDESHOW_SUBSECOND_PRECISION) + secs_tenths);
178 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
179 SLIDESHOW_SUBSECOND_PRECISION;
182 static void slideshow_delay_seconds_cb(GtkWidget *spin, gpointer data)
184 gint hours_mins, delay;
186 hours_mins = c_options->slideshow.delay / (60 * SLIDESHOW_SUBSECOND_PRECISION);
188 delay = (hours_mins * (60 * SLIDESHOW_SUBSECOND_PRECISION)) +
189 (gint)(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
190 (gdouble)(SLIDESHOW_SUBSECOND_PRECISION) + 0.01);
192 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
193 SLIDESHOW_SUBSECOND_PRECISION;
197 *-----------------------------------------------------------------------------
198 * sync progam to config window routine (private)
199 *-----------------------------------------------------------------------------
202 void config_entry_to_option(GtkWidget *entry, gchar **option, gchar *(*func)(const gchar *))
208 buf = gtk_entry_get_text(GTK_ENTRY(entry));
209 if (buf && strlen(buf) > 0)
214 *option = g_strdup(buf);
219 static gboolean accel_apply_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
221 gchar *accel_path, *accel;
223 gtk_tree_model_get(model, iter, AE_ACCEL, &accel_path, AE_KEY, &accel, -1);
225 if (accel_path && accel_path[0])
228 gtk_accelerator_parse(accel, &key.accel_key, &key.accel_mods);
229 gtk_accel_map_change_entry(accel_path, key.accel_key, key.accel_mods, TRUE);
239 static void config_window_apply(void)
242 gboolean refresh = FALSE;
244 config_entry_to_option(safe_delete_path_entry, &options->file_ops.safe_delete_path, remove_trailing_slash);
246 if (options->file_filter.show_hidden_files != c_options->file_filter.show_hidden_files) refresh = TRUE;
247 if (options->file_filter.show_parent_directory != c_options->file_filter.show_parent_directory) refresh = TRUE;
248 if (options->file_filter.show_dot_directory != c_options->file_filter.show_dot_directory) refresh = TRUE;
249 if (options->file_sort.case_sensitive != c_options->file_sort.case_sensitive) refresh = TRUE;
250 if (options->file_sort.natural != c_options->file_sort.natural) refresh = TRUE;
251 if (options->file_filter.disable_file_extension_checks != c_options->file_filter.disable_file_extension_checks) refresh = TRUE;
252 if (options->file_filter.disable != c_options->file_filter.disable) refresh = TRUE;
254 options->file_ops.confirm_delete = c_options->file_ops.confirm_delete;
255 options->file_ops.enable_delete_key = c_options->file_ops.enable_delete_key;
256 options->file_ops.safe_delete_enable = c_options->file_ops.safe_delete_enable;
257 options->file_ops.safe_delete_folder_maxsize = c_options->file_ops.safe_delete_folder_maxsize;
258 options->tools_restore_state = c_options->tools_restore_state;
259 options->save_window_positions = c_options->save_window_positions;
260 options->use_saved_window_positions_for_new_windows = c_options->use_saved_window_positions_for_new_windows;
261 options->save_dialog_window_positions = c_options->save_dialog_window_positions;
262 options->show_window_ids = c_options->show_window_ids;
263 options->image.scroll_reset_method = c_options->image.scroll_reset_method;
264 options->image.zoom_2pass = c_options->image.zoom_2pass;
265 options->image.fit_window_to_image = c_options->image.fit_window_to_image;
266 options->image.limit_window_size = c_options->image.limit_window_size;
267 options->image.zoom_to_fit_allow_expand = c_options->image.zoom_to_fit_allow_expand;
268 options->image.max_window_size = c_options->image.max_window_size;
269 options->image.limit_autofit_size = c_options->image.limit_autofit_size;
270 options->image.max_autofit_size = c_options->image.max_autofit_size;
271 options->image.max_enlargement_size = c_options->image.max_enlargement_size;
272 options->image.use_clutter_renderer = c_options->image.use_clutter_renderer;
273 options->progressive_key_scrolling = c_options->progressive_key_scrolling;
274 options->keyboard_scroll_step = c_options->keyboard_scroll_step;
276 if (options->thumbnails.max_width != c_options->thumbnails.max_width
277 || options->thumbnails.max_height != c_options->thumbnails.max_height
278 || options->thumbnails.quality != c_options->thumbnails.quality)
280 thumb_format_changed = TRUE;
282 options->thumbnails.max_width = c_options->thumbnails.max_width;
283 options->thumbnails.max_height = c_options->thumbnails.max_height;
284 options->thumbnails.quality = c_options->thumbnails.quality;
286 options->thumbnails.enable_caching = c_options->thumbnails.enable_caching;
287 options->thumbnails.cache_into_dirs = c_options->thumbnails.cache_into_dirs;
288 options->thumbnails.use_exif = c_options->thumbnails.use_exif;
289 options->thumbnails.use_ft_metadata = c_options->thumbnails.use_ft_metadata;
290 // options->thumbnails.use_ft_metadata_small = c_options->thumbnails.use_ft_metadata_small;
291 options->thumbnails.spec_standard = c_options->thumbnails.spec_standard;
292 options->metadata.enable_metadata_dirs = c_options->metadata.enable_metadata_dirs;
293 options->file_filter.show_hidden_files = c_options->file_filter.show_hidden_files;
294 options->file_filter.show_parent_directory = c_options->file_filter.show_parent_directory;
295 options->file_filter.show_dot_directory = c_options->file_filter.show_dot_directory;
296 options->file_filter.disable_file_extension_checks = c_options->file_filter.disable_file_extension_checks;
298 options->file_sort.case_sensitive = c_options->file_sort.case_sensitive;
299 options->file_sort.natural = c_options->file_sort.natural;
300 options->file_filter.disable = c_options->file_filter.disable;
302 config_entry_to_option(sidecar_ext_entry, &options->sidecar.ext, NULL);
303 sidecar_ext_parse(options->sidecar.ext);
305 options->slideshow.random = c_options->slideshow.random;
306 options->slideshow.repeat = c_options->slideshow.repeat;
307 options->slideshow.delay = c_options->slideshow.delay;
309 options->mousewheel_scrolls = c_options->mousewheel_scrolls;
310 options->image_lm_click_nav = c_options->image_lm_click_nav;
311 options->image_l_click_video = c_options->image_l_click_video;
312 options->image_l_click_video_editor = c_options->image_l_click_video_editor;
314 options->file_ops.enable_in_place_rename = c_options->file_ops.enable_in_place_rename;
316 options->image.tile_cache_max = c_options->image.tile_cache_max;
317 options->image.image_cache_max = c_options->image.image_cache_max;
319 options->image.zoom_quality = c_options->image.zoom_quality;
321 options->image.zoom_increment = c_options->image.zoom_increment;
323 options->image.enable_read_ahead = c_options->image.enable_read_ahead;
326 if (options->image.use_custom_border_color != c_options->image.use_custom_border_color
327 || options->image.use_custom_border_color_in_fullscreen != c_options->image.use_custom_border_color_in_fullscreen
328 || !gdk_color_equal(&options->image.border_color, &c_options->image.border_color))
330 options->image.use_custom_border_color_in_fullscreen = c_options->image.use_custom_border_color_in_fullscreen;
331 options->image.use_custom_border_color = c_options->image.use_custom_border_color;
332 options->image.border_color = c_options->image.border_color;
333 layout_colors_update();
334 view_window_colors_update();
337 options->image.alpha_color_1 = c_options->image.alpha_color_1;
338 options->image.alpha_color_2 = c_options->image.alpha_color_2;
340 options->fullscreen.screen = c_options->fullscreen.screen;
341 options->fullscreen.clean_flip = c_options->fullscreen.clean_flip;
342 options->fullscreen.disable_saver = c_options->fullscreen.disable_saver;
343 options->fullscreen.above = c_options->fullscreen.above;
344 if (c_options->image_overlay.template_string)
345 set_image_overlay_template_string(&options->image_overlay.template_string,
346 c_options->image_overlay.template_string);
347 if (c_options->image_overlay.font)
348 set_image_overlay_font_string(&options->image_overlay.font,
349 c_options->image_overlay.font);
350 options->image_overlay.text_red = c_options->image_overlay.text_red;
351 options->image_overlay.text_green = c_options->image_overlay.text_green;
352 options->image_overlay.text_blue = c_options->image_overlay.text_blue;
353 options->image_overlay.text_alpha = c_options->image_overlay.text_alpha;
354 options->image_overlay.background_red = c_options->image_overlay.background_red;
355 options->image_overlay.background_green = c_options->image_overlay.background_green;
356 options->image_overlay.background_blue = c_options->image_overlay.background_blue;
357 options->image_overlay.background_alpha = c_options->image_overlay.background_alpha;
358 options->update_on_time_change = c_options->update_on_time_change;
359 options->image.exif_proof_rotate_enable = c_options->image.exif_proof_rotate_enable;
361 options->duplicates_similarity_threshold = c_options->duplicates_similarity_threshold;
362 options->rot_invariant_sim = c_options->rot_invariant_sim;
364 options->tree_descend_subdirs = c_options->tree_descend_subdirs;
366 options->view_dir_list_single_click_enter = c_options->view_dir_list_single_click_enter;
368 options->open_recent_list_maxsize = c_options->open_recent_list_maxsize;
369 options->dnd_icon_size = c_options->dnd_icon_size;
370 options->clipboard_selection = c_options->clipboard_selection;
372 options->metadata.save_in_image_file = c_options->metadata.save_in_image_file;
373 options->metadata.save_legacy_IPTC = c_options->metadata.save_legacy_IPTC;
374 options->metadata.warn_on_write_problems = c_options->metadata.warn_on_write_problems;
375 options->metadata.save_legacy_format = c_options->metadata.save_legacy_format;
376 options->metadata.sync_grouped_files = c_options->metadata.sync_grouped_files;
377 options->metadata.confirm_write = c_options->metadata.confirm_write;
378 options->metadata.sidecar_extended_name = c_options->metadata.sidecar_extended_name;
379 options->metadata.confirm_timeout = c_options->metadata.confirm_timeout;
380 options->metadata.confirm_after_timeout = c_options->metadata.confirm_after_timeout;
381 options->metadata.confirm_on_image_change = c_options->metadata.confirm_on_image_change;
382 options->metadata.confirm_on_dir_change = c_options->metadata.confirm_on_dir_change;
383 options->metadata.keywords_case_sensitive = c_options->metadata.keywords_case_sensitive;
384 options->metadata.write_orientation = c_options->metadata.write_orientation;
385 options->stereo.mode = (c_options->stereo.mode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
386 (c_options->stereo.tmp.mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
387 (c_options->stereo.tmp.flip_right ? PR_STEREO_FLIP_RIGHT : 0) |
388 (c_options->stereo.tmp.mirror_left ? PR_STEREO_MIRROR_LEFT : 0) |
389 (c_options->stereo.tmp.flip_left ? PR_STEREO_FLIP_LEFT : 0) |
390 (c_options->stereo.tmp.swap ? PR_STEREO_SWAP : 0) |
391 (c_options->stereo.tmp.temp_disable ? PR_STEREO_TEMP_DISABLE : 0);
392 options->stereo.fsmode = (c_options->stereo.fsmode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
393 (c_options->stereo.tmp.fs_mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
394 (c_options->stereo.tmp.fs_flip_right ? PR_STEREO_FLIP_RIGHT : 0) |
395 (c_options->stereo.tmp.fs_mirror_left ? PR_STEREO_MIRROR_LEFT : 0) |
396 (c_options->stereo.tmp.fs_flip_left ? PR_STEREO_FLIP_LEFT : 0) |
397 (c_options->stereo.tmp.fs_swap ? PR_STEREO_SWAP : 0) |
398 (c_options->stereo.tmp.fs_temp_disable ? PR_STEREO_TEMP_DISABLE : 0);
399 options->stereo.enable_fsmode = c_options->stereo.enable_fsmode;
400 options->stereo.fixed_w = c_options->stereo.fixed_w;
401 options->stereo.fixed_h = c_options->stereo.fixed_h;
402 options->stereo.fixed_x1 = c_options->stereo.fixed_x1;
403 options->stereo.fixed_y1 = c_options->stereo.fixed_y1;
404 options->stereo.fixed_x2 = c_options->stereo.fixed_x2;
405 options->stereo.fixed_y2 = c_options->stereo.fixed_y2;
407 options->info_keywords.height = c_options->info_keywords.height;
408 options->info_title.height = c_options->info_title.height;
409 options->info_comment.height = c_options->info_comment.height;
410 options->info_rating.height = c_options->info_rating.height;
412 options->marks_save = c_options->marks_save;
413 options->with_rename = c_options->with_rename;
414 options->collections_on_top = c_options->collections_on_top;
415 config_entry_to_option(help_search_engine_entry, &options->help_search_engine, NULL);
417 options->read_metadata_in_idle = c_options->read_metadata_in_idle;
419 options->star_rating.star = c_options->star_rating.star;
420 options->star_rating.rejected = c_options->star_rating.rejected;
422 set_debug_level(debug_c);
426 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
428 config_entry_to_option(color_profile_input_name_entry[i], &options->color_profile.input_name[i], NULL);
429 config_entry_to_option(color_profile_input_file_entry[i], &options->color_profile.input_file[i], NULL);
431 config_entry_to_option(color_profile_screen_file_entry, &options->color_profile.screen_file, NULL);
432 options->color_profile.use_x11_screen_profile = c_options->color_profile.use_x11_screen_profile;
433 if (options->color_profile.render_intent != c_options->color_profile.render_intent)
435 options->color_profile.render_intent = c_options->color_profile.render_intent;
440 image_options_sync();
445 layout_refresh(NULL);
448 if (accel_store) gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_apply_cb, NULL);
454 *-----------------------------------------------------------------------------
455 * config window main button callbacks (private)
456 *-----------------------------------------------------------------------------
459 static void config_window_close_cb(GtkWidget *widget, gpointer data)
461 gtk_widget_destroy(configwindow);
466 static void config_window_help_cb(GtkWidget *widget, gpointer data)
468 GtkWidget *notebook = data;
471 static gchar *html_section[] =
473 "GuideOptionsGeneral.html",
474 "GuideOptionsImage.html",
475 "GuideOptionsWindow.html",
476 "GuideOptionsKeyboard.html",
477 "GuideOptionsFiltering.html",
478 "GuideOptionsMetadata.html",
479 "GuideOptionsColor.html",
480 "GuideOptionsStereo.html",
481 "GuideOptionsBehavior.html",
482 "GuideOptionsToolbar.html"
485 i = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
486 help_window_show(html_section[i]);
489 static gboolean config_window_delete(GtkWidget *widget, GdkEventAny *event, gpointer data)
491 config_window_close_cb(NULL, NULL);
495 static void config_window_ok_cb(GtkWidget *widget, gpointer data)
497 config_window_apply();
498 config_window_close_cb(NULL, NULL);
501 static void config_window_apply_cb(GtkWidget *widget, gpointer data)
504 lw = layout_window_list->data;
506 config_window_apply();
507 layout_util_sync(lw);
510 static void config_window_save_cb(GtkWidget *widget, gpointer data)
512 config_window_apply();
513 save_options(options);
517 *-----------------------------------------------------------------------------
518 * config window setup (private)
519 *-----------------------------------------------------------------------------
522 static void quality_menu_cb(GtkWidget *combo, gpointer data)
526 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
530 *option = GDK_INTERP_NEAREST;
533 *option = GDK_INTERP_TILES;
536 *option = GDK_INTERP_BILINEAR;
539 *option = GDK_INTERP_HYPER;
544 static void clipboard_selection_menu_cb(GtkWidget *combo, gpointer data)
548 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
560 static void add_quality_menu(GtkWidget *table, gint column, gint row, const gchar *text,
561 guint option, guint *option_c)
568 pref_table_label(table, column, row, text, 0.0);
570 combo = gtk_combo_box_text_new();
572 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Nearest (worst, but fastest)"));
573 if (option == GDK_INTERP_NEAREST) current = 0;
574 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Tiles"));
575 if (option == GDK_INTERP_TILES) current = 1;
576 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Bilinear"));
577 if (option == GDK_INTERP_BILINEAR) current = 2;
578 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Hyper (best, but slowest)"));
579 if (option == GDK_INTERP_HYPER) current = 3;
581 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
583 g_signal_connect(G_OBJECT(combo), "changed",
584 G_CALLBACK(quality_menu_cb), option_c);
586 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
587 GTK_EXPAND | GTK_FILL, 0, 0, 0);
588 gtk_widget_show(combo);
591 static void add_clipboard_selection_menu(GtkWidget *table, gint column, gint row, const gchar *text,
592 gint option, gint *option_c)
599 pref_table_label(table, column, row, text, 0.0);
601 combo = gtk_combo_box_text_new();
603 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("PRIMARY"));
604 if (option == PRIMARY) current = 0;
605 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("CLIPBOARD"));
606 if (option == CLIPBOARD) current = 1;
608 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
610 g_signal_connect(G_OBJECT(combo), "changed",
611 G_CALLBACK(clipboard_selection_menu_cb), option_c);
613 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
614 GTK_EXPAND | GTK_FILL, 0, 0, 0);
615 gtk_widget_show(combo);
618 static void thumb_size_menu_cb(GtkWidget *combo, gpointer data)
622 n = gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
625 if ((guint) n < sizeof(thumb_size_list) / sizeof(ThumbSize))
627 c_options->thumbnails.max_width = thumb_size_list[n].w;
628 c_options->thumbnails.max_height = thumb_size_list[n].h;
632 c_options->thumbnails.max_width = options->thumbnails.max_width;
633 c_options->thumbnails.max_height = options->thumbnails.max_height;
637 static void add_thumb_size_menu(GtkWidget *table, gint column, gint row, gchar *text)
643 c_options->thumbnails.max_width = options->thumbnails.max_width;
644 c_options->thumbnails.max_height = options->thumbnails.max_height;
646 pref_table_label(table, column, row, text, 0.0);
648 combo = gtk_combo_box_text_new();
651 for (i = 0; (guint) i < sizeof(thumb_size_list) / sizeof(ThumbSize); i++)
656 w = thumb_size_list[i].w;
657 h = thumb_size_list[i].h;
659 buf = g_strdup_printf("%d x %d", w, h);
660 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf);
663 if (w == options->thumbnails.max_width && h == options->thumbnails.max_height) current = i;
670 buf = g_strdup_printf("%s %d x %d", _("Custom"), options->thumbnails.max_width, options->thumbnails.max_height);
671 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf);
677 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
678 g_signal_connect(G_OBJECT(combo), "changed",
679 G_CALLBACK(thumb_size_menu_cb), NULL);
681 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
682 GTK_EXPAND | GTK_FILL, 0, 0, 0);
683 gtk_widget_show(combo);
686 static void stereo_mode_menu_cb(GtkWidget *combo, gpointer data)
690 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
694 *option = PR_STEREO_NONE;
697 *option = PR_STEREO_ANAGLYPH_RC;
700 *option = PR_STEREO_ANAGLYPH_GM;
703 *option = PR_STEREO_ANAGLYPH_YB;
706 *option = PR_STEREO_ANAGLYPH_GRAY_RC;
709 *option = PR_STEREO_ANAGLYPH_GRAY_GM;
712 *option = PR_STEREO_ANAGLYPH_GRAY_YB;
715 *option = PR_STEREO_ANAGLYPH_DB_RC;
718 *option = PR_STEREO_ANAGLYPH_DB_GM;
721 *option = PR_STEREO_ANAGLYPH_DB_YB;
724 *option = PR_STEREO_HORIZ;
727 *option = PR_STEREO_HORIZ | PR_STEREO_HALF;
730 *option = PR_STEREO_VERT;
733 *option = PR_STEREO_VERT | PR_STEREO_HALF;
736 *option = PR_STEREO_FIXED;
741 static void add_stereo_mode_menu(GtkWidget *table, gint column, gint row, const gchar *text,
742 gint option, gint *option_c, gboolean add_fixed)
749 pref_table_label(table, column, row, text, 0.0);
751 combo = gtk_combo_box_text_new();
753 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Single image"));
755 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Red-Cyan"));
756 if (option & PR_STEREO_ANAGLYPH_RC) current = 1;
757 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Green-Magenta"));
758 if (option & PR_STEREO_ANAGLYPH_GM) current = 2;
759 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Yellow-Blue"));
760 if (option & PR_STEREO_ANAGLYPH_YB) current = 3;
761 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Red-Cyan"));
762 if (option & PR_STEREO_ANAGLYPH_GRAY_RC) current = 4;
763 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Green-Magenta"));
764 if (option & PR_STEREO_ANAGLYPH_GRAY_GM) current = 5;
765 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Yellow-Blue"));
766 if (option & PR_STEREO_ANAGLYPH_GRAY_YB) current = 6;
767 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Red-Cyan"));
768 if (option & PR_STEREO_ANAGLYPH_DB_RC) current = 7;
769 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Green-Magenta"));
770 if (option & PR_STEREO_ANAGLYPH_DB_GM) current = 8;
771 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Yellow-Blue"));
772 if (option & PR_STEREO_ANAGLYPH_DB_YB) current = 9;
774 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Side by Side"));
775 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Side by Side Half size"));
776 if (option & PR_STEREO_HORIZ)
779 if (option & PR_STEREO_HALF) current = 11;
782 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Top - Bottom"));
783 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Top - Bottom Half size"));
784 if (option & PR_STEREO_VERT)
787 if (option & PR_STEREO_HALF) current = 13;
792 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Fixed position"));
793 if (option & PR_STEREO_FIXED) current = 14;
796 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
798 g_signal_connect(G_OBJECT(combo), "changed",
799 G_CALLBACK(stereo_mode_menu_cb), option_c);
801 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
802 GTK_EXPAND | GTK_FILL, 0, 0, 0);
803 gtk_widget_show(combo);
806 static void video_menu_cb(GtkWidget *combo, gpointer data)
808 gchar **option = data;
810 EditorDescription *ed = g_list_nth_data(editor_list_get(), gtk_combo_box_get_active(GTK_COMBO_BOX(combo)));
814 static void video_menu_populate(gpointer data, gpointer user_data)
816 GtkWidget *combo = user_data;
817 EditorDescription *ed = data;
819 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), ed->name);
822 static void add_video_menu(GtkWidget *table, gint column, gint row, const gchar *text,
823 gchar *option, gchar **option_c)
827 /* use lists since they are sorted */
828 GList *eds = editor_list_get();
832 pref_table_label(table, column, row, text, 0.0);
834 combo = gtk_combo_box_text_new();
835 g_list_foreach(eds,video_menu_populate,(gpointer)combo);
836 current = option ? g_list_index(eds,g_hash_table_lookup(editors,option)): -1;
838 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
840 g_signal_connect(G_OBJECT(combo), "changed",
841 G_CALLBACK(video_menu_cb), option_c);
843 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
844 GTK_EXPAND | GTK_FILL, 0, 0, 0);
845 gtk_widget_show(combo);
848 static void filter_store_populate(void)
852 if (!filter_store) return;
854 gtk_list_store_clear(filter_store);
856 work = filter_get_list();
865 gtk_list_store_append(filter_store, &iter);
866 gtk_list_store_set(filter_store, &iter, 0, fe, -1);
870 static void filter_store_ext_edit_cb(GtkCellRendererText *cell, gchar *path_str,
871 gchar *new_text, gpointer data)
873 GtkWidget *model = data;
874 FilterEntry *fe = data;
878 if (!new_text || strlen(new_text) < 1) return;
880 tpath = gtk_tree_path_new_from_string(path_str);
881 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
882 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
884 g_free(fe->extensions);
885 fe->extensions = g_strdup(new_text);
887 gtk_tree_path_free(tpath);
891 static void filter_store_class_edit_cb(GtkCellRendererText *cell, gchar *path_str,
892 gchar *new_text, gpointer data)
894 GtkWidget *model = data;
895 FilterEntry *fe = data;
900 if (!new_text || !new_text[0]) return;
902 tpath = gtk_tree_path_new_from_string(path_str);
903 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
904 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
906 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
908 if (strcmp(new_text, _(format_class_list[i])) == 0)
915 gtk_tree_path_free(tpath);
919 static void filter_store_desc_edit_cb(GtkCellRendererText *cell, gchar *path_str,
920 gchar *new_text, gpointer data)
922 GtkWidget *model = data;
927 if (!new_text || !new_text[0]) return;
929 tpath = gtk_tree_path_new_from_string(path_str);
930 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
931 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
933 g_free(fe->description);
934 fe->description = g_strdup(new_text);
936 gtk_tree_path_free(tpath);
939 static void filter_store_enable_cb(GtkCellRendererToggle *renderer,
940 gchar *path_str, gpointer data)
942 GtkWidget *model = data;
947 tpath = gtk_tree_path_new_from_string(path_str);
948 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
949 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
951 fe->enabled = !fe->enabled;
953 gtk_tree_path_free(tpath);
957 static void filter_store_writable_cb(GtkCellRendererToggle *renderer,
958 gchar *path_str, gpointer data)
960 GtkWidget *model = data;
965 tpath = gtk_tree_path_new_from_string(path_str);
966 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
967 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
969 fe->writable = !fe->writable;
970 if (fe->writable) fe->allow_sidecar = FALSE;
972 gtk_tree_path_free(tpath);
976 static void filter_store_sidecar_cb(GtkCellRendererToggle *renderer,
977 gchar *path_str, gpointer data)
979 GtkWidget *model = data;
984 tpath = gtk_tree_path_new_from_string(path_str);
985 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
986 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
988 fe->allow_sidecar = !fe->allow_sidecar;
989 if (fe->allow_sidecar) fe->writable = FALSE;
991 gtk_tree_path_free(tpath);
995 static void filter_set_func(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell,
996 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
1000 gtk_tree_model_get(tree_model, iter, 0, &fe, -1);
1002 switch (GPOINTER_TO_INT(data))
1005 g_object_set(GTK_CELL_RENDERER(cell),
1006 "active", fe->enabled, NULL);
1009 g_object_set(GTK_CELL_RENDERER(cell),
1010 "text", fe->extensions, NULL);
1012 case FE_DESCRIPTION:
1013 g_object_set(GTK_CELL_RENDERER(cell),
1014 "text", fe->description, NULL);
1017 g_object_set(GTK_CELL_RENDERER(cell),
1018 "text", _(format_class_list[fe->file_class]), NULL);
1021 g_object_set(GTK_CELL_RENDERER(cell),
1022 "active", fe->writable, NULL);
1024 case FE_ALLOW_SIDECAR:
1025 g_object_set(GTK_CELL_RENDERER(cell),
1026 "active", fe->allow_sidecar, NULL);
1031 static gboolean filter_add_scroll(gpointer data)
1035 GtkCellRenderer *cell;
1036 GtkTreeViewColumn *column;
1037 GList *list_columns;
1042 rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(filter_store), NULL);
1043 path = gtk_tree_path_new_from_indices(rows-1, -1);
1045 list_columns = gtk_tree_view_get_columns(GTK_TREE_VIEW(data));
1047 column = g_list_nth(list_columns,i)->data;
1048 title = gtk_tree_view_column_get_title(GTK_TREE_VIEW_COLUMN(column));
1050 } while (strcmp(title, "Filter") !=0 );
1052 list_cells = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(column));
1053 cell = g_list_last(list_cells)->data;
1055 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1056 path, column, FALSE, 0.0, 0.0 );
1057 gtk_tree_view_set_cursor_on_cell(GTK_TREE_VIEW(data),
1058 path, column, cell, TRUE);
1060 gtk_tree_path_free(path);
1061 g_list_free(list_cells);
1062 g_list_free(list_columns);
1067 static void filter_add_cb(GtkWidget *widget, gpointer data)
1069 filter_add_unique("description", ".new", FORMAT_CLASS_IMAGE, TRUE, FALSE, TRUE);
1070 filter_store_populate();
1072 g_idle_add((GSourceFunc)filter_add_scroll, data);
1075 static void filter_remove_cb(GtkWidget *widget, gpointer data)
1077 GtkWidget *filter_view = data;
1078 GtkTreeSelection *selection;
1082 if (!filter_store) return;
1083 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
1084 if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) return;
1085 gtk_tree_model_get(GTK_TREE_MODEL(filter_store), &iter, 0, &fe, -1);
1088 filter_remove_entry(fe);
1090 filter_store_populate();
1093 static gboolean filter_default_ok_scroll(GtkTreeView *data)
1097 GtkTreeViewColumn *column;
1099 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(filter_store), &iter);
1100 path = gtk_tree_model_get_path(GTK_TREE_MODEL(filter_store), &iter);
1101 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data),0);
1103 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1107 gtk_tree_path_free(path);
1112 static void filter_default_ok_cb(GenericDialog *gd, gpointer data)
1115 filter_add_defaults();
1117 filter_store_populate();
1119 g_idle_add((GSourceFunc)filter_default_ok_scroll, gd->data);
1122 static void dummy_cancel_cb(GenericDialog *gd, gpointer data)
1124 /* no op, only so cancel button appears */
1127 static void filter_default_cb(GtkWidget *widget, gpointer data)
1131 gd = generic_dialog_new(_("Reset filters"),
1132 "reset_filter", widget, TRUE,
1133 dummy_cancel_cb, data);
1134 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Reset filters"),
1135 _("This will reset the file filters to the defaults.\nContinue?"), TRUE);
1136 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, filter_default_ok_cb, TRUE);
1137 gtk_widget_show(gd->dialog);
1140 static void filter_disable_cb(GtkWidget *widget, gpointer data)
1142 GtkWidget *frame = data;
1144 gtk_widget_set_sensitive(frame,
1145 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
1148 static void safe_delete_view_cb(GtkWidget *widget, gpointer data)
1150 layout_set_path(NULL, gtk_entry_get_text(GTK_ENTRY(safe_delete_path_entry)));
1153 static void safe_delete_clear_ok_cb(GenericDialog *gd, gpointer data)
1155 file_util_trash_clear();
1158 static void safe_delete_clear_cb(GtkWidget *widget, gpointer data)
1162 gd = generic_dialog_new(_("Clear trash"),
1163 "clear_trash", widget, TRUE,
1164 dummy_cancel_cb, NULL);
1165 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Clear trash"),
1166 _("This will remove the trash contents."), FALSE);
1167 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, safe_delete_clear_ok_cb, TRUE);
1168 entry = gtk_entry_new();
1169 gtk_widget_set_can_focus(entry, FALSE);
1170 gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
1171 if (options->file_ops.safe_delete_path) gtk_entry_set_text(GTK_ENTRY(entry), options->file_ops.safe_delete_path);
1172 gtk_box_pack_start(GTK_BOX(gd->vbox), entry, FALSE, FALSE, 0);
1173 gtk_widget_show(entry);
1174 gtk_widget_show(gd->dialog);
1177 static void image_overlay_template_view_changed_cb(GtkWidget *widget, gpointer data)
1179 GtkWidget *pTextView;
1180 GtkTextBuffer *pTextBuffer;
1184 pTextView = GTK_WIDGET(data);
1186 pTextBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pTextView));
1187 gtk_text_buffer_get_start_iter(pTextBuffer, &iStart);
1188 gtk_text_buffer_get_end_iter(pTextBuffer, &iEnd);
1190 set_image_overlay_template_string(&c_options->image_overlay.template_string,
1191 gtk_text_buffer_get_text(pTextBuffer, &iStart, &iEnd, TRUE));
1194 static void image_overlay_default_template_ok_cb(GenericDialog *gd, gpointer data)
1196 GtkTextView *text_view = data;
1197 GtkTextBuffer *buffer;
1199 set_default_image_overlay_template_string(&options->image_overlay.template_string);
1200 if (!configwindow) return;
1202 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
1203 gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
1206 static void image_overlay_default_template_cb(GtkWidget *widget, gpointer data)
1210 gd = generic_dialog_new(_("Reset image overlay template string"),
1211 "reset_image_overlay_template_string", widget, TRUE,
1212 dummy_cancel_cb, data);
1213 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Reset image overlay template string"),
1214 _("This will reset the image overlay template string to the default.\nContinue?"), TRUE);
1215 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, image_overlay_default_template_ok_cb, TRUE);
1216 gtk_widget_show(gd->dialog);
1219 static void image_overlay_help_cb(GtkWidget *widget, gpointer data)
1221 help_window_show("GuideOptionsWindow.html#OverlayScreenDisplay");
1224 static void image_overlay_set_font_cb(GtkWidget *widget, gpointer data)
1226 #if GTK_CHECK_VERSION(3,4,0)
1229 PangoFontDescription *font_desc;
1231 dialog = gtk_font_chooser_dialog_new("Image Overlay Font", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1232 gtk_font_chooser_set_font(GTK_FONT_CHOOSER(dialog), options->image_overlay.font);
1234 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1236 font_desc = gtk_font_chooser_get_font_desc(GTK_FONT_CHOOSER(dialog));
1237 font = pango_font_description_to_string(font_desc);
1238 g_free(c_options->image_overlay.font);
1239 c_options->image_overlay.font = g_strdup(font);
1243 gtk_widget_destroy(dialog);
1247 font = gtk_font_button_get_font_name(GTK_FONT_BUTTON(widget));
1248 c_options->image_overlay.font = g_strdup(font);
1252 static void image_overlay_set_text_colour_cb(GtkWidget *widget, gpointer data)
1255 #if GTK_CHECK_VERSION(3,4,0)
1258 dialog = gtk_color_chooser_dialog_new("Image Overlay Text Colour", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1259 colour.red = options->image_overlay.text_red;
1260 colour.green = options->image_overlay.text_green;
1261 colour.blue = options->image_overlay.text_blue;
1262 colour.alpha = options->image_overlay.text_alpha;
1263 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1264 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(dialog), TRUE);
1266 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1268 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1269 c_options->image_overlay.text_red = colour.red*255;
1270 c_options->image_overlay.text_green = colour.green*255;
1271 c_options->image_overlay.text_blue = colour.blue*255;
1272 c_options->image_overlay.text_alpha = colour.alpha*255;
1274 gtk_widget_destroy(dialog);
1277 GtkColorSelection *colorsel;
1279 dialog = gtk_color_selection_dialog_new("Image Overlay Text Colour");
1280 gtk_window_set_keep_above(GTK_WINDOW(dialog),TRUE);
1281 colour.red = options->image_overlay.text_red*257;
1282 colour.green = options->image_overlay.text_green*257;
1283 colour.blue = options->image_overlay.text_blue*257;
1284 colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)));
1285 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
1286 gtk_color_selection_set_current_color(colorsel, &colour);
1287 gtk_color_selection_set_current_alpha(colorsel, options->image_overlay.text_alpha*257);
1289 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
1291 gtk_color_selection_get_current_color(colorsel, &colour);
1292 c_options->image_overlay.text_red = colour.red/257;
1293 c_options->image_overlay.text_green = colour.green/257;
1294 c_options->image_overlay.text_blue = colour.blue/257;
1295 c_options->image_overlay.text_alpha = gtk_color_selection_get_current_alpha(colorsel)/257;
1297 gtk_widget_destroy (dialog);
1302 static void image_overlay_set_background_colour_cb(GtkWidget *widget, gpointer data)
1305 #if GTK_CHECK_VERSION(3,4,0)
1308 dialog = gtk_color_chooser_dialog_new("Image Overlay Background Colour", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1309 colour.red = options->image_overlay.background_red;
1310 colour.green = options->image_overlay.background_green;
1311 colour.blue = options->image_overlay.background_blue;
1312 colour.alpha = options->image_overlay.background_alpha;
1313 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1314 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(dialog), TRUE);
1316 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1318 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1319 c_options->image_overlay.background_red = colour.red*255;
1320 c_options->image_overlay.background_green = colour.green*255;
1321 c_options->image_overlay.background_blue = colour.blue*255;
1322 c_options->image_overlay.background_alpha = colour.alpha*255;
1324 gtk_widget_destroy(dialog);
1327 GtkColorSelection *colorsel;
1329 dialog = gtk_color_selection_dialog_new("Image Overlay Background Colour");
1330 gtk_window_set_keep_above(GTK_WINDOW(dialog),TRUE);
1331 colour.red = options->image_overlay.background_red*257;
1332 colour.green = options->image_overlay.background_green*257;
1333 colour.blue = options->image_overlay.background_blue*257;
1334 colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)));
1335 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
1336 gtk_color_selection_set_current_color(colorsel, &colour);
1337 gtk_color_selection_set_current_alpha(colorsel, options->image_overlay.background_alpha*257);
1339 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
1341 gtk_color_selection_get_current_color(colorsel, &colour);
1342 c_options->image_overlay.background_red = colour.red/257;
1343 c_options->image_overlay.background_green = colour.green/257;
1344 c_options->image_overlay.background_blue = colour.blue/257;
1345 c_options->image_overlay.background_alpha = gtk_color_selection_get_current_alpha(colorsel)/257;
1347 gtk_widget_destroy(dialog);
1351 static void accel_store_populate(void)
1354 GList *groups, *actions;
1356 const gchar *accel_path;
1360 if (!accel_store || !layout_window_list || !layout_window_list->data) return;
1362 gtk_tree_store_clear(accel_store);
1363 lw = layout_window_list->data; /* get the actions from the first window, it should not matter, they should be the same in all windows */
1365 g_assert(lw && lw->ui_manager);
1366 groups = gtk_ui_manager_get_action_groups(lw->ui_manager);
1369 actions = gtk_action_group_list_actions(GTK_ACTION_GROUP(groups->data));
1372 action = GTK_ACTION(actions->data);
1373 accel_path = gtk_action_get_accel_path(action);
1374 if (accel_path && gtk_accel_map_lookup_entry(accel_path, &key))
1376 gchar *label, *label2, *tooltip, *accel;
1377 g_object_get(action,
1378 "tooltip", &tooltip,
1382 if (pango_parse_markup(label, -1, '_', NULL, &label2, NULL, NULL) && label2)
1388 accel = gtk_accelerator_name(key.accel_key, key.accel_mods);
1392 gtk_tree_store_append(accel_store, &iter, NULL);
1393 gtk_tree_store_set(accel_store, &iter,
1396 AE_TOOLTIP, tooltip ? tooltip : "",
1397 AE_ACCEL, accel_path,
1405 actions = actions->next;
1408 groups = groups->next;
1412 static void accel_store_cleared_cb(GtkCellRendererAccel *accel, gchar *path_string, gpointer user_data)
1417 static gboolean accel_remove_key_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1419 gchar *accel1 = data;
1424 gtk_tree_model_get(model, iter, AE_KEY, &accel2, -1);
1426 gtk_accelerator_parse(accel1, &key1.accel_key, &key1.accel_mods);
1427 gtk_accelerator_parse(accel2, &key2.accel_key, &key2.accel_mods);
1429 if (key1.accel_key == key2.accel_key && key1.accel_mods == key2.accel_mods)
1431 gtk_tree_store_set(accel_store, iter, AE_KEY, "", -1);
1432 DEBUG_1("accelerator key '%s' is already used, removing.", accel1);
1441 static void accel_store_edited_cb(GtkCellRendererAccel *accel, gchar *path_string, guint accel_key, GdkModifierType accel_mods, guint hardware_keycode, gpointer user_data)
1443 GtkTreeModel *model = (GtkTreeModel *)accel_store;
1447 GtkAccelKey old_key, key;
1448 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
1450 gtk_tree_model_get_iter(model, &iter, path);
1451 gtk_tree_model_get(model, &iter, AE_ACCEL, &accel_path, -1);
1453 /* test if the accelerator can be stored without conflicts*/
1454 gtk_accel_map_lookup_entry(accel_path, &old_key);
1456 /* change the key and read it back (change may fail on keys hardcoded in gtk)*/
1457 gtk_accel_map_change_entry(accel_path, accel_key, accel_mods, TRUE);
1458 gtk_accel_map_lookup_entry(accel_path, &key);
1460 /* restore the original for now, the key will be really changed when the changes are confirmed */
1461 gtk_accel_map_change_entry(accel_path, old_key.accel_key, old_key.accel_mods, TRUE);
1463 acc = gtk_accelerator_name(key.accel_key, key.accel_mods);
1464 gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_remove_key_cb, acc);
1466 gtk_tree_store_set(accel_store, &iter, AE_KEY, acc, -1);
1467 gtk_tree_path_free(path);
1471 static gboolean accel_default_scroll(GtkTreeView *data)
1475 GtkTreeViewColumn *column;
1477 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(accel_store), &iter);
1478 path = gtk_tree_model_get_path(GTK_TREE_MODEL(accel_store), &iter);
1479 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data),0);
1481 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1485 gtk_tree_path_free(path);
1490 static void accel_default_cb(GtkWidget *widget, gpointer data)
1492 accel_store_populate();
1494 g_idle_add((GSourceFunc)accel_default_scroll, data);
1497 void accel_remove_selection(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1499 gtk_tree_store_set(accel_store, iter, AE_KEY, "", -1);
1502 void accel_reset_selection(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1505 gchar *accel_path, *accel;
1507 gtk_tree_model_get(model, iter, AE_ACCEL, &accel_path, -1);
1508 gtk_accel_map_lookup_entry(accel_path, &key);
1509 accel = gtk_accelerator_name(key.accel_key, key.accel_mods);
1511 gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_remove_key_cb, accel);
1513 gtk_tree_store_set(accel_store, iter, AE_KEY, accel, -1);
1518 static void accel_reset_cb(GtkWidget *widget, gpointer data)
1520 GtkTreeSelection *selection;
1522 if (!accel_store) return;
1523 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data));
1524 gtk_tree_selection_selected_foreach(selection, &accel_reset_selection, NULL);
1529 static GtkWidget *scrolled_notebook_page(GtkWidget *notebook, const gchar *title)
1533 GtkWidget *scrolled;
1534 GtkWidget *viewport;
1536 scrolled = gtk_scrolled_window_new(NULL, NULL);
1537 gtk_container_set_border_width(GTK_CONTAINER(scrolled), PREF_PAD_BORDER);
1538 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
1539 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1540 label = gtk_label_new(title);
1541 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled, label);
1542 gtk_widget_show(scrolled);
1544 viewport = gtk_viewport_new(NULL, NULL);
1545 gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
1546 gtk_container_add(GTK_CONTAINER(scrolled), viewport);
1547 gtk_widget_show(viewport);
1549 vbox = gtk_vbox_new(FALSE, 0);
1550 gtk_container_add(GTK_CONTAINER(viewport), vbox);
1551 gtk_widget_show(vbox);
1556 static void cache_standard_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_geeqie_cb(GtkWidget *widget, gpointer data)
1571 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1573 c_options->thumbnails.spec_standard =TRUE;
1574 c_options->thumbnails.cache_into_dirs = FALSE;
1578 c_options->thumbnails.spec_standard =FALSE;
1582 static void cache_local_cb(GtkWidget *widget, gpointer data)
1584 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1586 c_options->thumbnails.cache_into_dirs = TRUE;
1587 c_options->thumbnails.spec_standard =FALSE;
1591 c_options->thumbnails.cache_into_dirs = FALSE;
1595 static void help_search_engine_entry_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1596 GdkEvent *event, gpointer userdata)
1598 if (pos == GTK_ENTRY_ICON_PRIMARY)
1600 gtk_entry_set_text(GTK_ENTRY(userdata), HELP_SEARCH_ENGINE);
1604 gtk_entry_set_text(GTK_ENTRY(userdata), "");
1608 static void star_rating_star_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1609 GdkEvent *event, gpointer userdata)
1611 gchar *rating_symbol;
1613 if (pos == GTK_ENTRY_ICON_PRIMARY)
1615 rating_symbol = g_strdup_printf("U+%X", STAR_RATING_STAR);
1616 gtk_entry_set_text(GTK_ENTRY(userdata), rating_symbol);
1617 g_free(rating_symbol);
1621 gtk_entry_set_text(GTK_ENTRY(userdata), "U+");
1622 gtk_widget_grab_focus(GTK_WIDGET(userdata));
1623 gtk_editable_select_region(GTK_EDITABLE(userdata), 2, 2);
1627 static void star_rating_rejected_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1628 GdkEvent *event, gpointer userdata)
1630 gchar *rating_symbol;
1632 if (pos == GTK_ENTRY_ICON_PRIMARY)
1634 rating_symbol = g_strdup_printf("U+%X", STAR_RATING_REJECTED);
1635 gtk_entry_set_text(GTK_ENTRY(userdata), rating_symbol);
1636 g_free(rating_symbol);
1640 gtk_entry_set_text(GTK_ENTRY(userdata), "U+");
1641 gtk_widget_grab_focus(GTK_WIDGET(userdata));
1642 gtk_editable_select_region(GTK_EDITABLE(userdata), 2, 2);
1646 static guint star_rating_symbol_test(GtkWidget *widget, gpointer data)
1648 GtkContainer *hbox = data;
1649 GString *str = g_string_new(NULL);
1650 GtkEntry *hex_code_entry;
1651 gchar *hex_code_full;
1654 guint64 hex_value = 0;
1656 list = gtk_container_get_children(hbox);
1658 hex_code_entry = g_list_nth_data(list, 2);
1659 hex_code_full = g_strdup(gtk_entry_get_text(hex_code_entry));
1661 hex_code = g_strsplit(hex_code_full, "+", 2);
1662 if (hex_code[0] && hex_code[1])
1664 hex_value = strtoull(hex_code[1], NULL, 16);
1666 if (!hex_value || hex_value > 0x10FFFF)
1668 hex_value = 0x003F; // Unicode 'Question Mark'
1670 str = g_string_append_unichar(str, (gunichar)hex_value);
1671 gtk_label_set_text(g_list_nth_data(list, 1), str->str);
1673 g_strfreev(hex_code);
1674 g_string_free(str, TRUE);
1675 g_free(hex_code_full);
1680 static void star_rating_star_test_cb(GtkWidget *widget, gpointer data)
1682 guint64 star_symbol;
1684 star_symbol = star_rating_symbol_test(widget, data);
1685 c_options->star_rating.star = star_symbol;
1688 static void star_rating_rejected_test_cb(GtkWidget *widget, gpointer data)
1690 guint64 rejected_symbol;
1692 rejected_symbol = star_rating_symbol_test(widget, data);
1693 c_options->star_rating.rejected = rejected_symbol;
1696 /* general options tab */
1697 static void config_tab_general(GtkWidget *notebook)
1702 GtkWidget *group_frame;
1703 GtkWidget *subgroup;
1705 GtkWidget *ct_button;
1708 gint hours, minutes, remainder;
1710 GtkWidget *star_rating_entry;
1712 gchar *rating_symbol;
1714 vbox = scrolled_notebook_page(notebook, _("General"));
1716 group = pref_group_new(vbox, FALSE, _("Thumbnails"), GTK_ORIENTATION_VERTICAL);
1718 table = pref_table_new(group, 2, 2, FALSE, FALSE);
1719 add_thumb_size_menu(table, 0, 0, _("Size:"));
1720 add_quality_menu(table, 0, 1, _("Quality:"), options->thumbnails.quality, &c_options->thumbnails.quality);
1722 ct_button = pref_checkbox_new_int(group, _("Cache thumbnails"),
1723 options->thumbnails.enable_caching, &c_options->thumbnails.enable_caching);
1725 subgroup = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1726 pref_checkbox_link_sensitivity(ct_button, subgroup);
1728 group_frame = pref_frame_new(subgroup, TRUE, _("Use Geeqie thumbnail style and cache"),
1729 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1730 button = pref_radiobutton_new(group_frame, NULL, get_thumbnails_cache_dir(),
1731 !options->thumbnails.spec_standard,
1732 G_CALLBACK(cache_geeqie_cb), NULL);
1734 group_frame = pref_frame_new(subgroup, TRUE,
1735 _("Store thumbnails local to image folder (non-standard)"),
1736 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1737 pref_radiobutton_new(group_frame, button, "*/.thumbnails",
1738 options->thumbnails.cache_into_dirs,
1739 G_CALLBACK(cache_local_cb), NULL);
1741 group_frame = pref_frame_new(subgroup, TRUE,
1742 _("Use standard thumbnail style and cache, shared with other applications"),
1743 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1744 pref_radiobutton_new(group_frame, button, get_thumbnails_standard_cache_dir(),
1745 options->thumbnails.spec_standard,
1746 G_CALLBACK(cache_standard_cb), NULL);
1748 pref_checkbox_new_int(group, _("Use EXIF thumbnails when available (EXIF thumbnails may be outdated)"),
1749 options->thumbnails.use_exif, &c_options->thumbnails.use_exif);
1751 #ifdef HAVE_FFMPEGTHUMBNAILER_METADATA
1752 pref_checkbox_new_int(group, _("Use embedded metadata in video files as thumbnails when available"),
1753 options->thumbnails.use_ft_metadata, &c_options->thumbnails.use_ft_metadata);
1755 // pref_checkbox_new_int(group, _("Ignore embedded metadata if size is too small"),
1756 // options->thumbnails.use_ft_metadata_small, &c_options->thumbnails.use_ft_metadata_small);
1759 group = pref_group_new(vbox, FALSE, _("Star Rating"), GTK_ORIENTATION_VERTICAL);
1761 c_options->star_rating.star = options->star_rating.star;
1762 c_options->star_rating.rejected = options->star_rating.rejected;
1764 str = g_string_new(NULL);
1765 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1766 pref_label_new(hbox, "Star character: ");
1767 str = g_string_append_unichar(str, options->star_rating.star);
1768 pref_label_new(hbox, g_strdup(str->str));
1769 rating_symbol = g_strdup_printf("U+%X", options->star_rating.star);
1770 star_rating_entry = gtk_entry_new();
1771 gtk_entry_set_text(GTK_ENTRY(star_rating_entry), rating_symbol);
1772 gtk_box_pack_start(GTK_BOX(hbox), star_rating_entry, FALSE, FALSE, 0);
1773 gtk_entry_set_width_chars(GTK_ENTRY(star_rating_entry), 15);
1774 gtk_widget_show(star_rating_entry);
1775 button = pref_button_new(NULL, NULL, _("Set"), FALSE,
1776 G_CALLBACK(star_rating_star_test_cb), hbox);
1777 gtk_widget_set_tooltip_text(button, _("Display selected character"));
1778 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1779 gtk_widget_show(button);
1780 gtk_widget_set_tooltip_text(star_rating_entry, _("Hexadecimal representation of a Unicode character. A list of all Unicode characters may be found on the Internet."));
1781 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1782 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1783 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1784 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1785 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1786 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1787 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1788 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1789 g_signal_connect(GTK_ENTRY(star_rating_entry), "icon-press",
1790 G_CALLBACK(star_rating_star_icon_cb),
1793 g_string_free(str, TRUE);
1794 g_free(rating_symbol);
1796 str = g_string_new(NULL);
1797 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1798 pref_label_new(hbox, "Rejected character: ");
1799 str = g_string_append_unichar(str, options->star_rating.rejected);
1800 pref_label_new(hbox, g_strdup(str->str));
1801 rating_symbol = g_strdup_printf("U+%X", options->star_rating.rejected);
1802 star_rating_entry = gtk_entry_new();
1803 gtk_entry_set_text(GTK_ENTRY(star_rating_entry), rating_symbol);
1804 gtk_box_pack_start(GTK_BOX(hbox), star_rating_entry, FALSE, FALSE, 0);
1805 gtk_entry_set_width_chars(GTK_ENTRY(star_rating_entry), 15);
1806 gtk_widget_show(star_rating_entry);
1807 button = pref_button_new(NULL, NULL, _("Set"), FALSE,
1808 G_CALLBACK(star_rating_rejected_test_cb), hbox);
1809 gtk_widget_set_tooltip_text(button, _("Display selected character"));
1810 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1811 gtk_widget_show(button);
1812 gtk_widget_set_tooltip_text(star_rating_entry, _("Hexadecimal representation of a Unicode character. A list of all Unicode characters may be found on the Internet."));
1813 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1814 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1815 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1816 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1817 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1818 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1819 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1820 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1821 g_signal_connect(GTK_ENTRY(star_rating_entry), "icon-press",
1822 G_CALLBACK(star_rating_rejected_icon_cb),
1825 g_string_free(str, TRUE);
1826 g_free(rating_symbol);
1828 group = pref_group_new(vbox, FALSE, _("Slide show"), GTK_ORIENTATION_VERTICAL);
1830 c_options->slideshow.delay = options->slideshow.delay;
1831 hours = options->slideshow.delay / (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1832 remainder = options->slideshow.delay % (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1833 minutes = remainder / (60 * SLIDESHOW_SUBSECOND_PRECISION);
1834 seconds = (gdouble)(remainder % (60 * SLIDESHOW_SUBSECOND_PRECISION)) /
1835 SLIDESHOW_SUBSECOND_PRECISION;
1837 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1839 spin = pref_spin_new(hbox, _("Delay between image change hrs:mins:secs.dec"), NULL,
1841 options->slideshow.delay ? hours : 0.0,
1842 G_CALLBACK(slideshow_delay_hours_cb), NULL);
1843 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1844 spin = pref_spin_new(hbox, ":" , NULL,
1846 options->slideshow.delay ? minutes: 0.0,
1847 G_CALLBACK(slideshow_delay_minutes_cb), NULL);
1848 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1849 spin = pref_spin_new(hbox, ":", NULL,
1850 SLIDESHOW_MIN_SECONDS, 59, 1.0, 1,
1851 options->slideshow.delay ? seconds : 10.0,
1852 G_CALLBACK(slideshow_delay_seconds_cb), NULL);
1853 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1855 pref_checkbox_new_int(group, _("Random"), options->slideshow.random, &c_options->slideshow.random);
1856 pref_checkbox_new_int(group, _("Repeat"), options->slideshow.repeat, &c_options->slideshow.repeat);
1858 group = pref_group_new(vbox, FALSE, _("Image loading and caching"), GTK_ORIENTATION_VERTICAL);
1860 pref_spin_new_int(group, _("Decoded image cache size (Mb):"), NULL,
1861 0, 99999, 1, options->image.image_cache_max, &c_options->image.image_cache_max);
1862 pref_checkbox_new_int(group, _("Preload next image"),
1863 options->image.enable_read_ahead, &c_options->image.enable_read_ahead);
1865 pref_checkbox_new_int(group, _("Refresh on file change"),
1866 options->update_on_time_change, &c_options->update_on_time_change);
1868 group = pref_group_new(vbox, FALSE, _("Info sidebar heights"), GTK_ORIENTATION_VERTICAL);
1869 pref_label_new(group, _("NOTE! Geeqie must be restarted for changes to take effect"));
1870 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1871 pref_spin_new_int(hbox, _("Keywords:"), NULL,
1873 options->info_keywords.height, &c_options->info_keywords.height);
1874 pref_spin_new_int(hbox, _("Title:"), NULL,
1876 options->info_title.height, &c_options->info_title.height);
1877 pref_spin_new_int(hbox, _("Comment:"), NULL,
1879 options->info_comment.height, &c_options->info_comment.height);
1880 pref_spin_new_int(hbox, _("Rating:"), NULL,
1882 options->info_rating.height, &c_options->info_rating.height);
1884 group = pref_group_new(vbox, FALSE, _("On-line help search engine"), GTK_ORIENTATION_VERTICAL);
1886 help_search_engine_entry = gtk_entry_new();
1887 gtk_entry_set_text(GTK_ENTRY(help_search_engine_entry), options->help_search_engine);
1888 gtk_box_pack_start(GTK_BOX(group), help_search_engine_entry, FALSE, FALSE, 0);
1889 gtk_widget_show(help_search_engine_entry);
1891 gtk_widget_set_tooltip_text(help_search_engine_entry, _("The format varies between search engines, e.g the format may be:\nhttps://www.search_engine.com/search?q=site:geeqie.org/help\nhttps://www.search_engine.com/?q=site:geeqie.org/help"));
1893 gtk_entry_set_icon_from_stock(GTK_ENTRY(help_search_engine_entry),
1894 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1895 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(help_search_engine_entry),
1896 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1897 gtk_entry_set_icon_from_stock(GTK_ENTRY(help_search_engine_entry),
1898 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1899 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(help_search_engine_entry),
1900 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1901 g_signal_connect(GTK_ENTRY(help_search_engine_entry), "icon-press",
1902 G_CALLBACK(help_search_engine_entry_icon_cb),
1903 help_search_engine_entry);
1907 static void config_tab_image(GtkWidget *notebook)
1912 GtkWidget *ct_button;
1913 GtkWidget *enlargement_button;
1917 vbox = scrolled_notebook_page(notebook, _("Image"));
1919 group = pref_group_new(vbox, FALSE, _("Zoom"), GTK_ORIENTATION_VERTICAL);
1921 table = pref_table_new(group, 2, 1, FALSE, FALSE);
1922 add_quality_menu(table, 0, 0, _("Quality:"), options->image.zoom_quality, &c_options->image.zoom_quality);
1925 pref_checkbox_new_int(group, _("Use GPU acceleration via Clutter library"),
1926 options->image.use_clutter_renderer, &c_options->image.use_clutter_renderer);
1929 pref_checkbox_new_int(group, _("Two pass rendering (apply HQ zoom and color correction in second pass)"),
1930 options->image.zoom_2pass, &c_options->image.zoom_2pass);
1932 c_options->image.zoom_increment = options->image.zoom_increment;
1933 spin = pref_spin_new(group, _("Zoom increment:"), NULL,
1934 0.01, 4.0, 0.01, 2, (gdouble)options->image.zoom_increment / 100.0,
1935 G_CALLBACK(zoom_increment_cb), NULL);
1936 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1938 group = pref_group_new(vbox, FALSE, _("Fit image to window"), GTK_ORIENTATION_VERTICAL);
1940 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1941 enlargement_button = pref_checkbox_new_int(hbox, _("Allow enlargement of image (max. size in %)"),
1942 options->image.zoom_to_fit_allow_expand, &c_options->image.zoom_to_fit_allow_expand);
1943 spin = pref_spin_new_int(hbox, NULL, NULL,
1945 options->image.max_enlargement_size, &c_options->image.max_enlargement_size);
1946 pref_checkbox_link_sensitivity(enlargement_button, spin);
1947 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."));
1949 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1950 ct_button = pref_checkbox_new_int(hbox, _("Virtual window size (% of actual window):"),
1951 options->image.limit_autofit_size, &c_options->image.limit_autofit_size);
1952 spin = pref_spin_new_int(hbox, NULL, NULL,
1954 options->image.max_autofit_size, &c_options->image.max_autofit_size);
1955 pref_checkbox_link_sensitivity(ct_button, spin);
1956 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."));
1958 group = pref_group_new(vbox, FALSE, _("Appearance"), GTK_ORIENTATION_VERTICAL);
1960 pref_checkbox_new_int(group, _("Use custom border color in window mode"),
1961 options->image.use_custom_border_color, &c_options->image.use_custom_border_color);
1963 pref_checkbox_new_int(group, _("Use custom border color in fullscreen mode"),
1964 options->image.use_custom_border_color_in_fullscreen, &c_options->image.use_custom_border_color_in_fullscreen);
1966 pref_color_button_new(group, _("Border color"), &options->image.border_color,
1967 G_CALLBACK(pref_color_button_set_cb), &c_options->image.border_color);
1969 c_options->image.border_color = options->image.border_color;
1971 pref_color_button_new(group, _("Alpha channel color 1"), &options->image.alpha_color_1,
1972 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_1);
1974 pref_color_button_new(group, _("Alpha channel color 2"), &options->image.alpha_color_2,
1975 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_2);
1977 c_options->image.alpha_color_1 = options->image.alpha_color_1;
1978 c_options->image.alpha_color_2 = options->image.alpha_color_2;
1980 group = pref_group_new(vbox, FALSE, _("Convenience"), GTK_ORIENTATION_VERTICAL);
1982 pref_checkbox_new_int(group, _("Auto rotate proofs using Exif information"),
1983 options->image.exif_proof_rotate_enable, &c_options->image.exif_proof_rotate_enable);
1987 static void config_tab_windows(GtkWidget *notebook)
1993 GtkWidget *ct_button;
1995 GtkWidget *image_overlay_template_view;
1996 GtkWidget *scrolled;
1997 GtkTextBuffer *buffer;
1999 vbox = scrolled_notebook_page(notebook, _("Windows"));
2001 group = pref_group_new(vbox, FALSE, _("State"), GTK_ORIENTATION_VERTICAL);
2003 ct_button = pref_checkbox_new_int(group, _("Remember window positions"),
2004 options->save_window_positions, &c_options->save_window_positions);
2006 button = pref_checkbox_new_int(group, _("Use saved window positions also for new windows"),
2007 options->use_saved_window_positions_for_new_windows, &c_options->use_saved_window_positions_for_new_windows);
2008 pref_checkbox_link_sensitivity(ct_button, button);
2010 pref_checkbox_new_int(group, _("Remember tool state (float/hidden)"),
2011 options->tools_restore_state, &c_options->tools_restore_state);
2013 pref_checkbox_new_int(group, _("Remember dialog window positions"),
2014 options->save_dialog_window_positions, &c_options->save_dialog_window_positions);
2016 pref_checkbox_new_int(group, _("Show window IDs"),
2017 options->show_window_ids, &c_options->show_window_ids);
2019 group = pref_group_new(vbox, FALSE, _("Size"), GTK_ORIENTATION_VERTICAL);
2021 pref_checkbox_new_int(group, _("Fit window to image when tools are hidden/floating"),
2022 options->image.fit_window_to_image, &c_options->image.fit_window_to_image);
2024 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2025 ct_button = pref_checkbox_new_int(hbox, _("Limit size when auto-sizing window (%):"),
2026 options->image.limit_window_size, &c_options->image.limit_window_size);
2027 spin = pref_spin_new_int(hbox, NULL, NULL,
2029 options->image.max_window_size, &c_options->image.max_window_size);
2030 pref_checkbox_link_sensitivity(ct_button, spin);
2032 group = pref_group_new(vbox, FALSE, _("Full screen"), GTK_ORIENTATION_VERTICAL);
2034 c_options->fullscreen.screen = options->fullscreen.screen;
2035 c_options->fullscreen.above = options->fullscreen.above;
2036 hbox = fullscreen_prefs_selection_new(_("Location:"), &c_options->fullscreen.screen, &c_options->fullscreen.above);
2037 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2038 gtk_widget_show(hbox);
2040 pref_checkbox_new_int(group, _("Smooth image flip"),
2041 options->fullscreen.clean_flip, &c_options->fullscreen.clean_flip);
2042 pref_checkbox_new_int(group, _("Disable screen saver"),
2043 options->fullscreen.disable_saver, &c_options->fullscreen.disable_saver);
2046 group = pref_group_new(vbox, FALSE, _("Overlay Screen Display"), GTK_ORIENTATION_VERTICAL);
2048 pref_label_new(group, _("Image overlay template"));
2050 scrolled = gtk_scrolled_window_new(NULL, NULL);
2051 gtk_widget_set_size_request(scrolled, 200, 150);
2052 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2053 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
2054 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2055 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 5);
2056 gtk_widget_show(scrolled);
2058 image_overlay_template_view = gtk_text_view_new();
2060 gtk_widget_set_tooltip_markup(image_overlay_template_view,
2061 _("<i>%name%</i> results in the filename of the picture.\n"
2062 "Also available: <i>%collection%</i>, <i>%number%</i>, <i>%total%</i>, <i>%date%</i>,\n"
2063 "<i>%size%</i> (filesize), <i>%width%</i>, <i>%height%</i>, <i>%res%</i> (resolution),\n"
2064 "<i>%rating%</i>, <i>%keywords%</i>, <i>%comment%</i> (XMP), <i>%imagecomment%</i> (JPEG)\n"
2065 "To access exif data use the exif name, e. g. <i>%formatted.Camera%</i> is the formatted camera name,\n"
2066 "<i>%Exif.Photo.DateTimeOriginal%</i> the date of the original shot.\n"
2067 "<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"
2068 "If two or more variables are connected with the |-sign, it prints available variables with a separator.\n"
2069 "<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"
2070 "if there's no ISO information in the Exif data.\n"
2071 "If a line is empty, it is removed. This allows one to add lines that totally disappear when no data is available.\n"
2073 gtk_container_add(GTK_CONTAINER(scrolled), image_overlay_template_view);
2074 gtk_widget_show(image_overlay_template_view);
2076 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2078 #if GTK_CHECK_VERSION(3,4,0)
2079 button = pref_button_new(NULL, GTK_STOCK_SELECT_FONT, _("Font"), FALSE,
2080 G_CALLBACK(image_overlay_set_font_cb), notebook);
2082 button = gtk_font_button_new();
2083 gtk_font_button_set_title(GTK_FONT_BUTTON(button), "Image Overlay Font");
2084 gtk_font_button_set_font_name(GTK_FONT_BUTTON(button), options->image_overlay.font);
2085 g_signal_connect(G_OBJECT(button), "font-set",
2086 G_CALLBACK(image_overlay_set_font_cb),NULL);
2088 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2089 gtk_widget_show(button);
2091 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Text"), FALSE,
2092 G_CALLBACK(image_overlay_set_text_colour_cb), NULL);
2093 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2094 gtk_widget_show(button);
2096 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Background"), FALSE,
2097 G_CALLBACK(image_overlay_set_background_colour_cb), NULL);
2098 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2099 gtk_widget_show(button);
2100 image_overlay_set_text_colours();
2102 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2103 G_CALLBACK(image_overlay_default_template_cb), image_overlay_template_view);
2104 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2105 gtk_widget_show(button);
2107 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
2108 G_CALLBACK(image_overlay_help_cb), NULL);
2109 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2110 gtk_widget_show(button);
2112 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(image_overlay_template_view));
2113 if (options->image_overlay.template_string) gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
2114 g_signal_connect(G_OBJECT(buffer), "changed",
2115 G_CALLBACK(image_overlay_template_view_changed_cb), image_overlay_template_view);
2120 static GtkTreeModel *create_class_model(void)
2122 GtkListStore *model;
2126 /* create list store */
2127 model = gtk_list_store_new(1, G_TYPE_STRING);
2128 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
2130 gtk_list_store_append(model, &iter);
2131 gtk_list_store_set(model, &iter, 0, _(format_class_list[i]), -1);
2133 return GTK_TREE_MODEL (model);
2138 static void config_tab_files(GtkWidget *notebook)
2145 GtkWidget *ct_button;
2146 GtkWidget *scrolled;
2147 GtkWidget *filter_view;
2148 GtkCellRenderer *renderer;
2149 GtkTreeSelection *selection;
2150 GtkTreeViewColumn *column;
2152 vbox = scrolled_notebook_page(notebook, _("Files"));
2154 group = pref_box_new(vbox, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
2156 pref_checkbox_new_int(group, _("Show hidden files or folders"),
2157 options->file_filter.show_hidden_files, &c_options->file_filter.show_hidden_files);
2158 pref_checkbox_new_int(group, _("Show parent folder (..)"),
2159 options->file_filter.show_parent_directory, &c_options->file_filter.show_parent_directory);
2160 pref_checkbox_new_int(group, _("Case sensitive sort"),
2161 options->file_sort.case_sensitive, &c_options->file_sort.case_sensitive);
2162 pref_checkbox_new_int(group, _("Natural sort order"),
2163 options->file_sort.natural, &c_options->file_sort.natural);
2164 pref_checkbox_new_int(group, _("Disable file extension checks"),
2165 options->file_filter.disable_file_extension_checks, &c_options->file_filter.disable_file_extension_checks);
2167 ct_button = pref_checkbox_new_int(group, _("Disable File Filtering"),
2168 options->file_filter.disable, &c_options->file_filter.disable);
2171 group = pref_group_new(vbox, FALSE, _("Grouping sidecar extensions"), GTK_ORIENTATION_VERTICAL);
2173 sidecar_ext_entry = gtk_entry_new();
2174 gtk_entry_set_text(GTK_ENTRY(sidecar_ext_entry), options->sidecar.ext);
2175 gtk_box_pack_start(GTK_BOX(group), sidecar_ext_entry, FALSE, FALSE, 0);
2176 gtk_widget_show(sidecar_ext_entry);
2178 group = pref_group_new(vbox, TRUE, _("File types"), GTK_ORIENTATION_VERTICAL);
2180 frame = pref_group_parent(group);
2181 g_signal_connect(G_OBJECT(ct_button), "toggled",
2182 G_CALLBACK(filter_disable_cb), frame);
2183 gtk_widget_set_sensitive(frame, !options->file_filter.disable);
2185 scrolled = gtk_scrolled_window_new(NULL, NULL);
2186 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2187 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2188 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2189 gtk_widget_show(scrolled);
2191 filter_store = gtk_list_store_new(1, G_TYPE_POINTER);
2192 filter_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(filter_store));
2193 g_object_unref(filter_store);
2194 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
2195 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_SINGLE);
2197 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(filter_view), FALSE);
2199 column = gtk_tree_view_column_new();
2200 gtk_tree_view_column_set_title(column, _("Filter"));
2201 gtk_tree_view_column_set_resizable(column, TRUE);
2203 renderer = gtk_cell_renderer_toggle_new();
2204 g_signal_connect(G_OBJECT(renderer), "toggled",
2205 G_CALLBACK(filter_store_enable_cb), filter_store);
2206 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2207 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2208 GINT_TO_POINTER(FE_ENABLE), NULL);
2210 renderer = gtk_cell_renderer_text_new();
2211 g_signal_connect(G_OBJECT(renderer), "edited",
2212 G_CALLBACK(filter_store_ext_edit_cb), filter_store);
2213 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2214 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2215 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2216 GINT_TO_POINTER(FE_EXTENSION), NULL);
2217 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2219 column = gtk_tree_view_column_new();
2220 gtk_tree_view_column_set_title(column, _("Description"));
2221 gtk_tree_view_column_set_resizable(column, TRUE);
2222 gtk_tree_view_column_set_fixed_width(column, 200);
2223 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
2225 renderer = gtk_cell_renderer_text_new();
2226 g_signal_connect(G_OBJECT(renderer), "edited",
2227 G_CALLBACK(filter_store_desc_edit_cb), filter_store);
2228 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2229 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2230 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2231 GINT_TO_POINTER(FE_DESCRIPTION), NULL);
2232 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2234 column = gtk_tree_view_column_new();
2235 gtk_tree_view_column_set_title(column, _("Class"));
2236 gtk_tree_view_column_set_resizable(column, TRUE);
2237 renderer = gtk_cell_renderer_combo_new();
2238 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE,
2239 "model", create_class_model(),
2244 g_signal_connect(G_OBJECT(renderer), "edited",
2245 G_CALLBACK(filter_store_class_edit_cb), filter_store);
2246 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2247 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2248 GINT_TO_POINTER(FE_CLASS), NULL);
2249 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2251 column = gtk_tree_view_column_new();
2252 gtk_tree_view_column_set_title(column, _("Writable"));
2253 gtk_tree_view_column_set_resizable(column, FALSE);
2254 renderer = gtk_cell_renderer_toggle_new();
2255 g_signal_connect(G_OBJECT(renderer), "toggled",
2256 G_CALLBACK(filter_store_writable_cb), filter_store);
2257 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2258 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2259 GINT_TO_POINTER(FE_WRITABLE), NULL);
2260 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2262 column = gtk_tree_view_column_new();
2263 gtk_tree_view_column_set_title(column, _("Sidecar is allowed"));
2264 gtk_tree_view_column_set_resizable(column, FALSE);
2265 renderer = gtk_cell_renderer_toggle_new();
2266 g_signal_connect(G_OBJECT(renderer), "toggled",
2267 G_CALLBACK(filter_store_sidecar_cb), filter_store);
2268 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2269 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2270 GINT_TO_POINTER(FE_ALLOW_SIDECAR), NULL);
2271 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2274 filter_store_populate();
2275 gtk_container_add(GTK_CONTAINER(scrolled), filter_view);
2276 gtk_widget_show(filter_view);
2278 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2280 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2281 G_CALLBACK(filter_default_cb), filter_view);
2282 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2283 gtk_widget_show(button);
2285 button = pref_button_new(NULL, GTK_STOCK_REMOVE, NULL, FALSE,
2286 G_CALLBACK(filter_remove_cb), filter_view);
2287 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2288 gtk_widget_show(button);
2290 button = pref_button_new(NULL, GTK_STOCK_ADD, NULL, FALSE,
2291 G_CALLBACK(filter_add_cb), filter_view);
2292 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2293 gtk_widget_show(button);
2297 static void config_tab_metadata(GtkWidget *notebook)
2302 GtkWidget *ct_button;
2306 vbox = scrolled_notebook_page(notebook, _("Metadata"));
2309 group = pref_group_new(vbox, FALSE, _("Metadata writing process"), GTK_ORIENTATION_VERTICAL);
2311 label = pref_label_new(group, _("Warning: Geeqie is built without Exiv2. Some options are disabled."));
2313 label = pref_label_new(group, _("Metadata are written in the following order. The process ends after first success."));
2314 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2316 ct_button = pref_checkbox_new_int(group, _("1) Save metadata in image files, or sidecar files, according to the XMP standard"),
2317 options->metadata.save_in_image_file, &c_options->metadata.save_in_image_file);
2319 gtk_widget_set_sensitive(ct_button, FALSE);
2322 pref_checkbox_new_int(group, _("2) Save metadata in '.metadata' folder, local to image folder (non-standard)"),
2323 options->metadata.enable_metadata_dirs, &c_options->metadata.enable_metadata_dirs);
2325 text = g_strdup_printf(_("3) Save metadata in Geeqie private directory '%s'"), get_metadata_cache_dir());
2326 label = pref_label_new(group, text);
2327 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2328 gtk_misc_set_padding(GTK_MISC(label), 22, 0);
2331 group = pref_group_new(vbox, FALSE, _("Step 1: Write to image files"), GTK_ORIENTATION_VERTICAL);
2333 gtk_widget_set_sensitive(group, FALSE);
2336 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2337 pref_checkbox_link_sensitivity(ct_button, hbox);
2339 pref_checkbox_new_int(hbox, _("Store metadata also in legacy IPTC tags (converted according to IPTC4XMP standard)"),
2340 options->metadata.save_legacy_IPTC, &c_options->metadata.save_legacy_IPTC);
2342 pref_checkbox_new_int(hbox, _("Warn if the image files are unwritable"),
2343 options->metadata.warn_on_write_problems, &c_options->metadata.warn_on_write_problems);
2345 pref_checkbox_new_int(hbox, _("Ask before writing to image files"),
2346 options->metadata.confirm_write, &c_options->metadata.confirm_write);
2348 pref_checkbox_new_int(hbox, _("Create sidecar files named image.ext.xmp (as opposed to image.xmp)"),
2349 options->metadata.sidecar_extended_name, &c_options->metadata.sidecar_extended_name);
2351 group = pref_group_new(vbox, FALSE, _("Step 2 and 3: write to Geeqie private files"), GTK_ORIENTATION_VERTICAL);
2353 gtk_widget_set_sensitive(group, FALSE);
2356 pref_checkbox_new_int(group, _("Use GQview legacy metadata format (supports only keywords and comments) instead of XMP"),
2357 options->metadata.save_legacy_format, &c_options->metadata.save_legacy_format);
2360 group = pref_group_new(vbox, FALSE, _("Miscellaneous"), GTK_ORIENTATION_VERTICAL);
2361 pref_checkbox_new_int(group, _("Write the same description tags (keywords, comment, etc.) to all grouped sidecars"),
2362 options->metadata.sync_grouped_files, &c_options->metadata.sync_grouped_files);
2364 pref_checkbox_new_int(group, _("Allow keywords to differ only in case"),
2365 options->metadata.keywords_case_sensitive, &c_options->metadata.keywords_case_sensitive);
2367 ct_button = pref_checkbox_new_int(group, _("Write altered image orientation to the metadata"),
2368 options->metadata.write_orientation, &c_options->metadata.write_orientation);
2370 gtk_widget_set_sensitive(ct_button, FALSE);
2373 group = pref_group_new(vbox, FALSE, _("Auto-save options"), GTK_ORIENTATION_VERTICAL);
2375 ct_button = pref_checkbox_new_int(group, _("Write metadata after timeout"),
2376 options->metadata.confirm_after_timeout, &c_options->metadata.confirm_after_timeout);
2378 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2379 pref_checkbox_link_sensitivity(ct_button, hbox);
2381 pref_spin_new_int(hbox, _("Timeout (seconds):"), NULL, 0, 900, 1,
2382 options->metadata.confirm_timeout, &c_options->metadata.confirm_timeout);
2384 pref_checkbox_new_int(group, _("Write metadata on image change"),
2385 options->metadata.confirm_on_image_change, &c_options->metadata.confirm_on_image_change);
2387 pref_checkbox_new_int(group, _("Write metadata on directory change"),
2388 options->metadata.confirm_on_dir_change, &c_options->metadata.confirm_on_dir_change);
2390 group = pref_group_new(vbox, FALSE, _("Pre-load metadata"), GTK_ORIENTATION_VERTICAL);
2392 ct_button = pref_checkbox_new_int(group, _("Read metadata in background"),
2393 options->read_metadata_in_idle, &c_options->read_metadata_in_idle);
2394 gtk_widget_set_tooltip_text(ct_button,"On folder change, read DateTimeOriginal, DateTimeDigitized and Star Rating in the idle loop.\nIf this is not selected, initial loading of the folder will be faster but sorting on these items will be slower");
2399 static void intent_menu_cb(GtkWidget *combo, gpointer data)
2401 gint *option = data;
2403 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
2407 *option = INTENT_PERCEPTUAL;
2410 *option = INTENT_RELATIVE_COLORIMETRIC;
2413 *option = INTENT_SATURATION;
2416 *option = INTENT_ABSOLUTE_COLORIMETRIC;
2421 static void add_intent_menu(GtkWidget *table, gint column, gint row, const gchar *text,
2422 gint option, gint *option_c)
2429 pref_table_label(table, column, row, text, 0.0);
2431 combo = gtk_combo_box_text_new();
2433 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Perceptual"));
2434 if (option == INTENT_PERCEPTUAL) current = 0;
2435 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Relative Colorimetric"));
2436 if (option == INTENT_RELATIVE_COLORIMETRIC) current = 1;
2437 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Saturation"));
2438 if (option == INTENT_SATURATION) current = 2;
2439 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Absolute Colorimetric"));
2440 if (option == INTENT_ABSOLUTE_COLORIMETRIC) current = 3;
2442 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
2444 gtk_widget_set_tooltip_text(combo,"Refer to the lcms documentation for the defaults used when the selected Intent is not available");
2446 g_signal_connect(G_OBJECT(combo), "changed",
2447 G_CALLBACK(intent_menu_cb), option_c);
2449 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
2450 GTK_EXPAND | GTK_FILL, 0, 0, 0);
2451 gtk_widget_show(combo);
2455 static void config_tab_color(GtkWidget *notebook)
2464 vbox = scrolled_notebook_page(notebook, _("Color management"));
2466 group = pref_group_new(vbox, FALSE, _("Input profiles"), GTK_ORIENTATION_VERTICAL);
2468 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
2471 table = pref_table_new(group, 3, COLOR_PROFILE_INPUTS + 1, FALSE, FALSE);
2472 gtk_table_set_col_spacings(GTK_TABLE(table), PREF_PAD_GAP);
2474 label = pref_table_label(table, 0, 0, _("Type"), 0.0);
2475 pref_label_bold(label, TRUE, FALSE);
2477 label = pref_table_label(table, 1, 0, _("Menu name"), 0.0);
2478 pref_label_bold(label, TRUE, FALSE);
2480 label = pref_table_label(table, 2, 0, _("File"), 0.0);
2481 pref_label_bold(label, TRUE, FALSE);
2483 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
2488 buf = g_strdup_printf(_("Input %d:"), i + COLOR_PROFILE_FILE);
2489 pref_table_label(table, 0, i + 1, buf, 1.0);
2492 entry = gtk_entry_new();
2493 gtk_entry_set_max_length(GTK_ENTRY(entry), EDITOR_NAME_MAX_LENGTH);
2494 if (options->color_profile.input_name[i])
2496 gtk_entry_set_text(GTK_ENTRY(entry), options->color_profile.input_name[i]);
2498 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, i + 1, i + 2,
2499 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2500 gtk_widget_show(entry);
2501 color_profile_input_name_entry[i] = entry;
2503 tabcomp = tab_completion_new(&entry, options->color_profile.input_file[i], NULL, ".icc", "ICC Files", NULL);
2504 tab_completion_add_select_button(entry, _("Select color profile"), FALSE);
2505 gtk_widget_set_size_request(entry, 160, -1);
2506 gtk_table_attach(GTK_TABLE(table), tabcomp, 2, 3, i + 1, i + 2,
2507 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2508 gtk_widget_show(tabcomp);
2509 color_profile_input_file_entry[i] = entry;
2512 group = pref_group_new(vbox, FALSE, _("Screen profile"), GTK_ORIENTATION_VERTICAL);
2514 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
2516 pref_checkbox_new_int(group, _("Use system screen profile if available"),
2517 options->color_profile.use_x11_screen_profile, &c_options->color_profile.use_x11_screen_profile);
2519 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2521 pref_table_label(table, 0, 0, _("Screen:"), 1.0);
2522 tabcomp = tab_completion_new(&color_profile_screen_file_entry,
2523 options->color_profile.screen_file, NULL, ".icc", "ICC Files", NULL);
2524 tab_completion_add_select_button(color_profile_screen_file_entry, _("Select color profile"), FALSE);
2525 gtk_widget_set_size_request(color_profile_screen_file_entry, 160, -1);
2527 add_intent_menu(table, 0, 1, _("Render Intent:"), options->color_profile.render_intent, &c_options->color_profile.render_intent);
2529 gtk_table_attach(GTK_TABLE(table), tabcomp, 1, 2,
2531 GTK_FILL | GTK_EXPAND, 0, 0, 0);
2533 gtk_widget_show(tabcomp);
2536 /* advanced entry tab */
2537 static void config_tab_behavior(GtkWidget *notebook)
2544 GtkWidget *ct_button;
2548 GtkWidget *with_rename;
2549 GtkWidget *collections_on_top;
2551 vbox = scrolled_notebook_page(notebook, _("Behavior"));
2553 group = pref_group_new(vbox, FALSE, _("Delete"), GTK_ORIENTATION_VERTICAL);
2555 pref_checkbox_new_int(group, _("Confirm file delete"),
2556 options->file_ops.confirm_delete, &c_options->file_ops.confirm_delete);
2557 pref_checkbox_new_int(group, _("Enable Delete key"),
2558 options->file_ops.enable_delete_key, &c_options->file_ops.enable_delete_key);
2560 ct_button = pref_checkbox_new_int(group, _("Safe delete"),
2561 options->file_ops.safe_delete_enable, &c_options->file_ops.safe_delete_enable);
2563 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2564 pref_checkbox_link_sensitivity(ct_button, hbox);
2566 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_SPACE);
2567 pref_label_new(hbox, _("Folder:"));
2569 tabcomp = tab_completion_new(&safe_delete_path_entry, options->file_ops.safe_delete_path, NULL, NULL, NULL, NULL);
2570 tab_completion_add_select_button(safe_delete_path_entry, NULL, TRUE);
2571 gtk_box_pack_start(GTK_BOX(hbox), tabcomp, TRUE, TRUE, 0);
2572 gtk_widget_show(tabcomp);
2574 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2575 pref_checkbox_link_sensitivity(ct_button, hbox);
2577 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_GAP);
2578 spin = pref_spin_new_int(hbox, _("Maximum size:"), _("MB"),
2579 0, 2048, 1, options->file_ops.safe_delete_folder_maxsize, &c_options->file_ops.safe_delete_folder_maxsize);
2580 gtk_widget_set_tooltip_markup(spin, _("Set to 0 for unlimited size"));
2581 button = pref_button_new(NULL, NULL, _("View"), FALSE,
2582 G_CALLBACK(safe_delete_view_cb), NULL);
2583 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2584 gtk_widget_show(button);
2586 button = pref_button_new(NULL, GTK_STOCK_CLEAR, NULL, FALSE,
2587 G_CALLBACK(safe_delete_clear_cb), NULL);
2588 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2589 gtk_widget_show(button);
2592 group = pref_group_new(vbox, FALSE, _("Behavior"), GTK_ORIENTATION_VERTICAL);
2594 pref_checkbox_new_int(group, _("Descend folders in tree view"),
2595 options->tree_descend_subdirs, &c_options->tree_descend_subdirs);
2597 pref_checkbox_new_int(group, _("In place renaming"),
2598 options->file_ops.enable_in_place_rename, &c_options->file_ops.enable_in_place_rename);
2600 pref_checkbox_new_int(group, _("List directory view uses single click to enter"),
2601 options->view_dir_list_single_click_enter, &c_options->view_dir_list_single_click_enter);
2603 marks = pref_checkbox_new_int(group, _("Save marks on exit"),
2604 options->marks_save, &c_options->marks_save);
2605 gtk_widget_set_tooltip_text(marks,"Note that marks linked to a keyword will be saved irrespective of this setting");
2607 with_rename = pref_checkbox_new_int(group, _("Use \"With Rename\" as default for Copy/Move dialogs"),
2608 options->with_rename, &c_options->with_rename);
2609 gtk_widget_set_tooltip_text(with_rename,"Change the default button for Copy/Move dialogs");
2611 collections_on_top = pref_checkbox_new_int(group, _("Open collections on top"),
2612 options->collections_on_top, &c_options->collections_on_top);
2613 gtk_widget_set_tooltip_text(collections_on_top,"Open collections window on top");
2615 pref_spin_new_int(group, _("Recent folder list maximum size"), NULL,
2616 1, 50, 1, options->open_recent_list_maxsize, &c_options->open_recent_list_maxsize);
2618 pref_spin_new_int(group, _("Drag'n drop icon size"), NULL,
2619 16, 256, 16, options->dnd_icon_size, &c_options->dnd_icon_size);
2621 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2622 add_clipboard_selection_menu(table, 0, 0, _("Copy path clipboard selection:"), options->clipboard_selection, &c_options->clipboard_selection);
2624 group = pref_group_new(vbox, FALSE, _("Navigation"), GTK_ORIENTATION_VERTICAL);
2626 pref_checkbox_new_int(group, _("Progressive keyboard scrolling"),
2627 options->progressive_key_scrolling, &c_options->progressive_key_scrolling);
2628 pref_spin_new_int(group, _("Keyboard scrolling step multiplier:"), NULL,
2629 1, 32, 1, options->keyboard_scroll_step, (int *)&c_options->keyboard_scroll_step);
2630 pref_checkbox_new_int(group, _("Mouse wheel scrolls image"),
2631 options->mousewheel_scrolls, &c_options->mousewheel_scrolls);
2632 pref_checkbox_new_int(group, _("Navigation by left or middle click on image"),
2633 options->image_lm_click_nav, &c_options->image_lm_click_nav);
2634 pref_checkbox_new_int(group, _("Play video by left click on image"),
2635 options->image_l_click_video, &c_options->image_l_click_video);
2636 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2637 add_video_menu(table, 0, 0, _("Play with:"), options->image_l_click_video_editor, &c_options->image_l_click_video_editor);
2641 group = pref_group_new(vbox, FALSE, _("Debugging"), GTK_ORIENTATION_VERTICAL);
2643 pref_spin_new_int(group, _("Debug level:"), NULL,
2644 DEBUG_LEVEL_MIN, DEBUG_LEVEL_MAX, 1, get_debug_level(), &debug_c);
2646 pref_checkbox_new_int(group, _("Timer data"),
2647 options->log_window.timer_data, &c_options->log_window.timer_data);
2649 pref_spin_new_int(group, _("Log Window max. lines:"), NULL,
2650 1, 99999, 1, options->log_window_lines, &options->log_window_lines);
2654 /* accelerators tab */
2655 static void config_tab_accelerators(GtkWidget *notebook)
2661 GtkWidget *scrolled;
2662 GtkWidget *accel_view;
2663 GtkCellRenderer *renderer;
2664 GtkTreeSelection *selection;
2665 GtkTreeViewColumn *column;
2667 vbox = scrolled_notebook_page(notebook, _("Keyboard"));
2669 group = pref_group_new(vbox, TRUE, _("Accelerators"), GTK_ORIENTATION_VERTICAL);
2671 scrolled = gtk_scrolled_window_new(NULL, NULL);
2672 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2673 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2674 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2675 gtk_widget_show(scrolled);
2677 accel_store = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
2679 accel_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(accel_store));
2680 g_object_unref(accel_store);
2681 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(accel_view));
2682 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_MULTIPLE);
2684 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(accel_view), FALSE);
2686 renderer = gtk_cell_renderer_text_new();
2688 column = gtk_tree_view_column_new_with_attributes(_("Action"),
2693 gtk_tree_view_column_set_sort_column_id(column, AE_ACTION);
2694 gtk_tree_view_column_set_resizable(column, TRUE);
2695 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2698 renderer = gtk_cell_renderer_accel_new();
2699 g_signal_connect(G_OBJECT(renderer), "accel-cleared",
2700 G_CALLBACK(accel_store_cleared_cb), accel_store);
2701 g_signal_connect(G_OBJECT(renderer), "accel-edited",
2702 G_CALLBACK(accel_store_edited_cb), accel_store);
2705 g_object_set (renderer,
2707 "accel-mode", GTK_CELL_RENDERER_ACCEL_MODE_OTHER,
2710 column = gtk_tree_view_column_new_with_attributes(_("KEY"),
2715 gtk_tree_view_column_set_sort_column_id(column, AE_KEY);
2716 gtk_tree_view_column_set_resizable(column, TRUE);
2717 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2719 renderer = gtk_cell_renderer_text_new();
2721 column = gtk_tree_view_column_new_with_attributes(_("Tooltip"),
2726 gtk_tree_view_column_set_sort_column_id(column, AE_TOOLTIP);
2727 gtk_tree_view_column_set_resizable(column, TRUE);
2728 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2730 renderer = gtk_cell_renderer_text_new();
2732 column = gtk_tree_view_column_new_with_attributes("Accel",
2737 gtk_tree_view_column_set_sort_column_id(column, AE_ACCEL);
2738 gtk_tree_view_column_set_resizable(column, TRUE);
2739 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
2741 accel_store_populate();
2742 gtk_container_add(GTK_CONTAINER(scrolled), accel_view);
2743 gtk_widget_show(accel_view);
2745 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2747 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2748 G_CALLBACK(accel_default_cb), accel_view);
2749 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2750 gtk_widget_show(button);
2752 button = pref_button_new(NULL, NULL, _("Reset selected"), FALSE,
2753 G_CALLBACK(accel_reset_cb), accel_view);
2754 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2755 gtk_widget_show(button);
2759 static void config_tab_toolbar(GtkWidget *notebook)
2762 GtkWidget *toolbardata;
2765 lw = layout_window_list->data;
2767 vbox = scrolled_notebook_page(notebook, _("Toolbar"));
2769 toolbardata = toolbar_select_new(lw);
2770 gtk_box_pack_start(GTK_BOX(vbox), toolbardata, TRUE, TRUE, 0);
2771 gtk_widget_show(vbox);
2775 static void config_tab_stereo(GtkWidget *notebook)
2783 GtkWidget *fs_button;
2784 vbox = scrolled_notebook_page(notebook, _("Stereo"));
2786 group = pref_group_new(vbox, FALSE, _("Windowed stereo mode"), GTK_ORIENTATION_VERTICAL);
2788 table = pref_table_new(group, 2, 1, FALSE, FALSE);
2789 add_stereo_mode_menu(table, 0, 0, _("Windowed stereo mode"), options->stereo.mode, &c_options->stereo.mode, FALSE);
2791 table = pref_table_new(group, 2, 2, TRUE, FALSE);
2792 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2793 pref_checkbox_new_int(box, _("Mirror left image"),
2794 options->stereo.mode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.mirror_left);
2795 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2796 pref_checkbox_new_int(box, _("Flip left image"),
2797 options->stereo.mode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.flip_left);
2798 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2799 pref_checkbox_new_int(box, _("Mirror right image"),
2800 options->stereo.mode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.mirror_right);
2801 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2802 pref_checkbox_new_int(box, _("Flip right image"),
2803 options->stereo.mode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.flip_right);
2804 pref_checkbox_new_int(group, _("Swap left and right images"),
2805 options->stereo.mode & PR_STEREO_SWAP, &c_options->stereo.tmp.swap);
2806 pref_checkbox_new_int(group, _("Disable stereo mode on single image source"),
2807 options->stereo.mode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.temp_disable);
2809 group = pref_group_new(vbox, FALSE, _("Fullscreen stereo mode"), GTK_ORIENTATION_VERTICAL);
2810 fs_button = pref_checkbox_new_int(group, _("Use different settings for fullscreen"),
2811 options->stereo.enable_fsmode, &c_options->stereo.enable_fsmode);
2812 box2 = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2813 pref_checkbox_link_sensitivity(fs_button, box2);
2814 table = pref_table_new(box2, 2, 1, FALSE, FALSE);
2815 add_stereo_mode_menu(table, 0, 0, _("Fullscreen stereo mode"), options->stereo.fsmode, &c_options->stereo.fsmode, TRUE);
2816 table = pref_table_new(box2, 2, 2, TRUE, FALSE);
2817 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2818 pref_checkbox_new_int(box, _("Mirror left image"),
2819 options->stereo.fsmode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.fs_mirror_left);
2820 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
2821 pref_checkbox_new_int(box, _("Flip left image"),
2822 options->stereo.fsmode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.fs_flip_left);
2823 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2824 pref_checkbox_new_int(box, _("Mirror right image"),
2825 options->stereo.fsmode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.fs_mirror_right);
2826 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
2827 pref_checkbox_new_int(box, _("Flip right image"),
2828 options->stereo.fsmode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.fs_flip_right);
2829 pref_checkbox_new_int(box2, _("Swap left and right images"),
2830 options->stereo.fsmode & PR_STEREO_SWAP, &c_options->stereo.tmp.fs_swap);
2831 pref_checkbox_new_int(box2, _("Disable stereo mode on single image source"),
2832 options->stereo.fsmode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.fs_temp_disable);
2834 group2 = pref_group_new(box2, FALSE, _("Fixed position"), GTK_ORIENTATION_VERTICAL);
2835 table = pref_table_new(group2, 5, 3, FALSE, FALSE);
2836 pref_table_spin_new_int(table, 0, 0, _("Width"), NULL,
2837 1, 5000, 1, options->stereo.fixed_w, &c_options->stereo.fixed_w);
2838 pref_table_spin_new_int(table, 3, 0, _("Height"), NULL,
2839 1, 5000, 1, options->stereo.fixed_h, &c_options->stereo.fixed_h);
2840 pref_table_spin_new_int(table, 0, 1, _("Left X"), NULL,
2841 0, 5000, 1, options->stereo.fixed_x1, &c_options->stereo.fixed_x1);
2842 pref_table_spin_new_int(table, 3, 1, _("Left Y"), NULL,
2843 0, 5000, 1, options->stereo.fixed_y1, &c_options->stereo.fixed_y1);
2844 pref_table_spin_new_int(table, 0, 2, _("Right X"), NULL,
2845 0, 5000, 1, options->stereo.fixed_x2, &c_options->stereo.fixed_x2);
2846 pref_table_spin_new_int(table, 3, 2, _("Right Y"), NULL,
2847 0, 5000, 1, options->stereo.fixed_y2, &c_options->stereo.fixed_y2);
2851 /* Main preferences window */
2852 static void config_window_create(void)
2854 GtkWidget *win_vbox;
2856 GtkWidget *notebook;
2858 GtkWidget *ct_button;
2860 if (!c_options) c_options = init_options(NULL);
2862 configwindow = window_new(GTK_WINDOW_TOPLEVEL, "preferences", PIXBUF_INLINE_ICON_CONFIG, NULL, _("Preferences"));
2863 gtk_window_set_type_hint(GTK_WINDOW(configwindow), GDK_WINDOW_TYPE_HINT_DIALOG);
2864 g_signal_connect(G_OBJECT(configwindow), "delete_event",
2865 G_CALLBACK(config_window_delete), NULL);
2866 gtk_window_set_default_size(GTK_WINDOW(configwindow), CONFIG_WINDOW_DEF_WIDTH, CONFIG_WINDOW_DEF_HEIGHT);
2867 gtk_window_set_resizable(GTK_WINDOW(configwindow), TRUE);
2868 gtk_container_set_border_width(GTK_CONTAINER(configwindow), PREF_PAD_BORDER);
2870 win_vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE);
2871 gtk_container_add(GTK_CONTAINER(configwindow), win_vbox);
2872 gtk_widget_show(win_vbox);
2874 notebook = gtk_notebook_new();
2875 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
2876 gtk_box_pack_start(GTK_BOX(win_vbox), notebook, TRUE, TRUE, 0);
2878 config_tab_general(notebook);
2879 config_tab_image(notebook);
2880 config_tab_windows(notebook);
2881 config_tab_accelerators(notebook);
2882 config_tab_files(notebook);
2883 config_tab_metadata(notebook);
2884 config_tab_color(notebook);
2885 config_tab_stereo(notebook);
2886 config_tab_behavior(notebook);
2887 config_tab_toolbar(notebook);
2889 hbox = gtk_hbutton_box_new();
2890 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
2891 gtk_box_set_spacing(GTK_BOX(hbox), PREF_PAD_BUTTON_GAP);
2892 gtk_box_pack_end(GTK_BOX(win_vbox), hbox, FALSE, FALSE, 0);
2893 gtk_widget_show(hbox);
2895 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
2896 G_CALLBACK(config_window_help_cb), notebook);
2897 gtk_container_add(GTK_CONTAINER(hbox), button);
2898 gtk_widget_set_can_default(button, TRUE);
2899 gtk_widget_show(button);
2901 button = pref_button_new(NULL, GTK_STOCK_OK, NULL, FALSE,
2902 G_CALLBACK(config_window_ok_cb), NULL);
2903 gtk_container_add(GTK_CONTAINER(hbox), button);
2904 gtk_widget_set_can_default(button, TRUE);
2905 gtk_widget_grab_default(button);
2906 gtk_widget_show(button);
2910 button = pref_button_new(NULL, GTK_STOCK_SAVE, NULL, FALSE,
2911 G_CALLBACK(config_window_save_cb), NULL);
2912 gtk_container_add(GTK_CONTAINER(hbox), button);
2913 gtk_widget_set_can_default(button, TRUE);
2914 gtk_widget_show(button);
2916 button = pref_button_new(NULL, GTK_STOCK_APPLY, NULL, FALSE,
2917 G_CALLBACK(config_window_apply_cb), NULL);
2918 gtk_container_add(GTK_CONTAINER(hbox), button);
2919 gtk_widget_set_can_default(button, TRUE);
2920 gtk_widget_show(button);
2922 button = pref_button_new(NULL, GTK_STOCK_CANCEL, NULL, FALSE,
2923 G_CALLBACK(config_window_close_cb), NULL);
2924 gtk_container_add(GTK_CONTAINER(hbox), button);
2925 gtk_widget_set_can_default(button, TRUE);
2926 gtk_widget_show(button);
2928 if (!generic_dialog_get_alternative_button_order(configwindow))
2930 gtk_box_reorder_child(GTK_BOX(hbox), ct_button, -1);
2933 gtk_widget_show(notebook);
2935 gtk_widget_show(configwindow);
2939 *-----------------------------------------------------------------------------
2940 * config window show (public)
2941 *-----------------------------------------------------------------------------
2944 void show_config_window(void)
2948 gtk_window_present(GTK_WINDOW(configwindow));
2952 config_window_create();
2961 void show_about_window(LayoutWindow *lw)
2963 GdkPixbuf *pixbuf_logo;
2964 GdkPixbuf *pixbuf_icon;
2965 gchar *authors[1000];
2973 #define LINE_LENGTH 1000
2974 gchar line[LINE_LENGTH];
2976 copyright = g_string_new(NULL);
2977 copyright = g_string_append(copyright, "This program comes with absolutely no warranty.\nGNU General Public License, version 2 or later.\nSee https://www.gnu.org/licenses/old-licenses/gpl-2.0.html\n\n");
2979 zd_path = g_build_filename(GQ_BIN_DIR, TIMEZONE_DATABASE, NULL);
2980 cd = ZDOpenDatabase(zd_path);
2983 copyright = g_string_append(copyright, ZDGetNotice(cd));
2985 ZDCloseDatabase(cd);
2989 path = g_build_filename(GQ_HELPDIR, "AUTHORS", NULL);
2990 fp = fopen(path, "r");
2993 while(fgets(line, LINE_LENGTH, fp))
2995 /* get rid of ending \n from fgets */
2996 line[strlen(line) - 1] = '\0';
2997 authors[i_authors] = g_strdup(line);
3000 authors[i_authors] = NULL;
3005 comment = g_strconcat("Development and bug reports:\n", GQ_EMAIL_ADDRESS,
3006 "\nhttps://github.com/BestImageViewer/geeqie/issues",NULL);
3008 pixbuf_logo = pixbuf_inline(PIXBUF_INLINE_LOGO);
3009 pixbuf_icon = pixbuf_inline(PIXBUF_INLINE_ICON);
3010 gtk_show_about_dialog(GTK_WINDOW(lw->window),
3011 "title", _("About Geeqie"),
3013 "program-name", GQ_APPNAME,
3015 "logo", pixbuf_logo,
3016 "icon", pixbuf_icon,
3017 "website", GQ_WEBSITE,
3018 "website-label", "Website",
3019 "comments", comment,
3021 "translator-credits", _("translator-credits"),
3022 "wrap-license", TRUE,
3023 "license", copyright->str,
3026 g_string_free(copyright, TRUE);
3029 while(n < i_authors)
3039 static void image_overlay_set_text_colours()
3041 c_options->image_overlay.text_red = options->image_overlay.text_red;
3042 c_options->image_overlay.text_green = options->image_overlay.text_green;
3043 c_options->image_overlay.text_blue = options->image_overlay.text_blue;
3044 c_options->image_overlay.text_alpha = options->image_overlay.text_alpha;
3045 c_options->image_overlay.background_red = options->image_overlay.background_red;
3046 c_options->image_overlay.background_green = options->image_overlay.background_green;
3047 c_options->image_overlay.background_blue = options->image_overlay.background_blue;
3048 c_options->image_overlay.background_alpha = options->image_overlay.background_alpha;
3050 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */