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"
26 #include "bar_keywords.h"
28 #include "cache_maint.h"
33 #include "filefilter.h"
34 #include "fullscreen.h"
36 #include "image-overlay.h"
37 #include "color-man.h"
39 #include "layout_config.h"
40 #include "layout_util.h"
42 #include "pixbuf_util.h"
43 #include "slideshow.h"
47 #include "ui_fileops.h"
49 #include "ui_spinner.h"
50 #include "ui_tabcomp.h"
51 #include "ui_utildlg.h"
53 #include "zonedetect.h"
65 #define EDITOR_NAME_MAX_LENGTH 32
66 #define EDITOR_COMMAND_MAX_LENGTH 1024
68 static void image_overlay_set_text_colours();
70 GtkWidget *keyword_text;
71 static void config_tab_keywords_save();
73 typedef struct _ThumbSize ThumbSize;
80 static ThumbSize thumb_size_list[] =
114 gchar *format_class_list[] = {
124 /* config memory values */
125 static ConfOptions *c_options = NULL;
132 static GtkWidget *configwindow = NULL;
133 static GtkListStore *filter_store = NULL;
134 static GtkTreeStore *accel_store = NULL;
136 static GtkWidget *safe_delete_path_entry;
138 static GtkWidget *color_profile_input_file_entry[COLOR_PROFILE_INPUTS];
139 static GtkWidget *color_profile_input_name_entry[COLOR_PROFILE_INPUTS];
140 static GtkWidget *color_profile_screen_file_entry;
142 static GtkWidget *sidecar_ext_entry;
143 static GtkWidget *help_search_engine_entry;
146 #define CONFIG_WINDOW_DEF_WIDTH 700
147 #define CONFIG_WINDOW_DEF_HEIGHT 600
150 *-----------------------------------------------------------------------------
151 * option widget callbacks (private)
152 *-----------------------------------------------------------------------------
155 static void zoom_increment_cb(GtkWidget *spin, gpointer data)
157 c_options->image.zoom_increment = (gint)(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) * 100.0 + 0.01);
160 static void slideshow_delay_hours_cb(GtkWidget *spin, gpointer data)
162 gint mins_secs_tenths, delay;
164 mins_secs_tenths = c_options->slideshow.delay %
165 (3600 * SLIDESHOW_SUBSECOND_PRECISION);
167 delay = (gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
168 (3600 * SLIDESHOW_SUBSECOND_PRECISION) +
171 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
172 SLIDESHOW_SUBSECOND_PRECISION;
175 static void slideshow_delay_minutes_cb(GtkWidget *spin, gpointer data)
177 gint hours, secs_tenths, delay;
179 hours = c_options->slideshow.delay / (3600 * SLIDESHOW_SUBSECOND_PRECISION);
180 secs_tenths = c_options->slideshow.delay % (60 * SLIDESHOW_SUBSECOND_PRECISION);
182 delay = hours * (3600 * SLIDESHOW_SUBSECOND_PRECISION) +
183 (gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
184 (60 * SLIDESHOW_SUBSECOND_PRECISION) + secs_tenths);
186 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
187 SLIDESHOW_SUBSECOND_PRECISION;
190 static void slideshow_delay_seconds_cb(GtkWidget *spin, gpointer data)
192 gint hours_mins, delay;
194 hours_mins = c_options->slideshow.delay / (60 * SLIDESHOW_SUBSECOND_PRECISION);
196 delay = (hours_mins * (60 * SLIDESHOW_SUBSECOND_PRECISION)) +
197 (gint)(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)) *
198 (gdouble)(SLIDESHOW_SUBSECOND_PRECISION) + 0.01);
200 c_options->slideshow.delay = delay > 0 ? delay : SLIDESHOW_MIN_SECONDS *
201 SLIDESHOW_SUBSECOND_PRECISION;
205 *-----------------------------------------------------------------------------
206 * sync progam to config window routine (private)
207 *-----------------------------------------------------------------------------
210 void config_entry_to_option(GtkWidget *entry, gchar **option, gchar *(*func)(const gchar *))
216 buf = gtk_entry_get_text(GTK_ENTRY(entry));
217 if (buf && strlen(buf) > 0)
222 *option = g_strdup(buf);
227 static gboolean accel_apply_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
229 gchar *accel_path, *accel;
231 gtk_tree_model_get(model, iter, AE_ACCEL, &accel_path, AE_KEY, &accel, -1);
233 if (accel_path && accel_path[0])
236 gtk_accelerator_parse(accel, &key.accel_key, &key.accel_mods);
237 gtk_accel_map_change_entry(accel_path, key.accel_key, key.accel_mods, TRUE);
247 static void config_window_apply(void)
250 gboolean refresh = FALSE;
252 config_entry_to_option(safe_delete_path_entry, &options->file_ops.safe_delete_path, remove_trailing_slash);
254 if (options->file_filter.show_hidden_files != c_options->file_filter.show_hidden_files) refresh = TRUE;
255 if (options->file_filter.show_parent_directory != c_options->file_filter.show_parent_directory) refresh = TRUE;
256 if (options->file_filter.show_dot_directory != c_options->file_filter.show_dot_directory) refresh = TRUE;
257 if (options->file_sort.case_sensitive != c_options->file_sort.case_sensitive) refresh = TRUE;
258 if (options->file_sort.natural != c_options->file_sort.natural) refresh = TRUE;
259 if (options->file_filter.disable_file_extension_checks != c_options->file_filter.disable_file_extension_checks) refresh = TRUE;
260 if (options->file_filter.disable != c_options->file_filter.disable) refresh = TRUE;
262 options->file_ops.confirm_delete = c_options->file_ops.confirm_delete;
263 options->file_ops.enable_delete_key = c_options->file_ops.enable_delete_key;
264 options->file_ops.confirm_move_to_trash = c_options->file_ops.confirm_move_to_trash;
265 options->file_ops.use_system_trash = c_options->file_ops.use_system_trash;
266 options->file_ops.safe_delete_folder_maxsize = c_options->file_ops.safe_delete_folder_maxsize;
267 options->tools_restore_state = c_options->tools_restore_state;
268 options->save_window_positions = c_options->save_window_positions;
269 options->use_saved_window_positions_for_new_windows = c_options->use_saved_window_positions_for_new_windows;
270 options->save_dialog_window_positions = c_options->save_dialog_window_positions;
271 options->show_window_ids = c_options->show_window_ids;
272 options->image.scroll_reset_method = c_options->image.scroll_reset_method;
273 options->image.zoom_2pass = c_options->image.zoom_2pass;
274 options->image.fit_window_to_image = c_options->image.fit_window_to_image;
275 options->image.limit_window_size = c_options->image.limit_window_size;
276 options->image.zoom_to_fit_allow_expand = c_options->image.zoom_to_fit_allow_expand;
277 options->image.max_window_size = c_options->image.max_window_size;
278 options->image.limit_autofit_size = c_options->image.limit_autofit_size;
279 options->image.max_autofit_size = c_options->image.max_autofit_size;
280 options->image.max_enlargement_size = c_options->image.max_enlargement_size;
281 options->image.use_clutter_renderer = c_options->image.use_clutter_renderer;
282 options->progressive_key_scrolling = c_options->progressive_key_scrolling;
283 options->keyboard_scroll_step = c_options->keyboard_scroll_step;
285 if (options->thumbnails.max_width != c_options->thumbnails.max_width
286 || options->thumbnails.max_height != c_options->thumbnails.max_height
287 || options->thumbnails.quality != c_options->thumbnails.quality)
289 thumb_format_changed = TRUE;
291 options->thumbnails.max_width = c_options->thumbnails.max_width;
292 options->thumbnails.max_height = c_options->thumbnails.max_height;
293 options->thumbnails.quality = c_options->thumbnails.quality;
295 options->thumbnails.enable_caching = c_options->thumbnails.enable_caching;
296 options->thumbnails.cache_into_dirs = c_options->thumbnails.cache_into_dirs;
297 options->thumbnails.use_exif = c_options->thumbnails.use_exif;
298 options->thumbnails.collection_preview = c_options->thumbnails.collection_preview;
299 options->thumbnails.use_ft_metadata = c_options->thumbnails.use_ft_metadata;
300 // options->thumbnails.use_ft_metadata_small = c_options->thumbnails.use_ft_metadata_small;
301 options->thumbnails.spec_standard = c_options->thumbnails.spec_standard;
302 options->metadata.enable_metadata_dirs = c_options->metadata.enable_metadata_dirs;
303 options->file_filter.show_hidden_files = c_options->file_filter.show_hidden_files;
304 options->file_filter.show_parent_directory = c_options->file_filter.show_parent_directory;
305 options->file_filter.show_dot_directory = c_options->file_filter.show_dot_directory;
306 options->file_filter.disable_file_extension_checks = c_options->file_filter.disable_file_extension_checks;
308 options->file_sort.case_sensitive = c_options->file_sort.case_sensitive;
309 options->file_sort.natural = c_options->file_sort.natural;
310 options->file_filter.disable = c_options->file_filter.disable;
312 config_entry_to_option(sidecar_ext_entry, &options->sidecar.ext, NULL);
313 sidecar_ext_parse(options->sidecar.ext);
315 options->slideshow.random = c_options->slideshow.random;
316 options->slideshow.repeat = c_options->slideshow.repeat;
317 options->slideshow.delay = c_options->slideshow.delay;
319 options->mousewheel_scrolls = c_options->mousewheel_scrolls;
320 options->image_lm_click_nav = c_options->image_lm_click_nav;
321 options->image_l_click_video = c_options->image_l_click_video;
322 options->image_l_click_video_editor = c_options->image_l_click_video_editor;
324 options->file_ops.enable_in_place_rename = c_options->file_ops.enable_in_place_rename;
326 options->image.tile_cache_max = c_options->image.tile_cache_max;
327 options->image.image_cache_max = c_options->image.image_cache_max;
329 options->image.zoom_quality = c_options->image.zoom_quality;
331 options->image.zoom_increment = c_options->image.zoom_increment;
333 options->image.enable_read_ahead = c_options->image.enable_read_ahead;
336 if (options->image.use_custom_border_color != c_options->image.use_custom_border_color
337 || options->image.use_custom_border_color_in_fullscreen != c_options->image.use_custom_border_color_in_fullscreen
338 || !gdk_color_equal(&options->image.border_color, &c_options->image.border_color))
340 options->image.use_custom_border_color_in_fullscreen = c_options->image.use_custom_border_color_in_fullscreen;
341 options->image.use_custom_border_color = c_options->image.use_custom_border_color;
342 options->image.border_color = c_options->image.border_color;
343 layout_colors_update();
344 view_window_colors_update();
347 options->image.alpha_color_1 = c_options->image.alpha_color_1;
348 options->image.alpha_color_2 = c_options->image.alpha_color_2;
350 options->fullscreen.screen = c_options->fullscreen.screen;
351 options->fullscreen.clean_flip = c_options->fullscreen.clean_flip;
352 options->fullscreen.disable_saver = c_options->fullscreen.disable_saver;
353 options->fullscreen.above = c_options->fullscreen.above;
354 if (c_options->image_overlay.template_string)
355 set_image_overlay_template_string(&options->image_overlay.template_string,
356 c_options->image_overlay.template_string);
357 if (c_options->image_overlay.font)
358 set_image_overlay_font_string(&options->image_overlay.font,
359 c_options->image_overlay.font);
360 options->image_overlay.text_red = c_options->image_overlay.text_red;
361 options->image_overlay.text_green = c_options->image_overlay.text_green;
362 options->image_overlay.text_blue = c_options->image_overlay.text_blue;
363 options->image_overlay.text_alpha = c_options->image_overlay.text_alpha;
364 options->image_overlay.background_red = c_options->image_overlay.background_red;
365 options->image_overlay.background_green = c_options->image_overlay.background_green;
366 options->image_overlay.background_blue = c_options->image_overlay.background_blue;
367 options->image_overlay.background_alpha = c_options->image_overlay.background_alpha;
368 options->update_on_time_change = c_options->update_on_time_change;
369 options->image.exif_proof_rotate_enable = c_options->image.exif_proof_rotate_enable;
371 options->duplicates_similarity_threshold = c_options->duplicates_similarity_threshold;
372 options->rot_invariant_sim = c_options->rot_invariant_sim;
374 options->tree_descend_subdirs = c_options->tree_descend_subdirs;
376 options->view_dir_list_single_click_enter = c_options->view_dir_list_single_click_enter;
378 options->open_recent_list_maxsize = c_options->open_recent_list_maxsize;
379 options->dnd_icon_size = c_options->dnd_icon_size;
380 options->clipboard_selection = c_options->clipboard_selection;
382 options->metadata.save_in_image_file = c_options->metadata.save_in_image_file;
383 options->metadata.save_legacy_IPTC = c_options->metadata.save_legacy_IPTC;
384 options->metadata.warn_on_write_problems = c_options->metadata.warn_on_write_problems;
385 options->metadata.save_legacy_format = c_options->metadata.save_legacy_format;
386 options->metadata.sync_grouped_files = c_options->metadata.sync_grouped_files;
387 options->metadata.confirm_write = c_options->metadata.confirm_write;
388 options->metadata.sidecar_extended_name = c_options->metadata.sidecar_extended_name;
389 options->metadata.confirm_timeout = c_options->metadata.confirm_timeout;
390 options->metadata.confirm_after_timeout = c_options->metadata.confirm_after_timeout;
391 options->metadata.confirm_on_image_change = c_options->metadata.confirm_on_image_change;
392 options->metadata.confirm_on_dir_change = c_options->metadata.confirm_on_dir_change;
393 options->metadata.keywords_case_sensitive = c_options->metadata.keywords_case_sensitive;
394 options->metadata.write_orientation = c_options->metadata.write_orientation;
395 options->stereo.mode = (c_options->stereo.mode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
396 (c_options->stereo.tmp.mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
397 (c_options->stereo.tmp.flip_right ? PR_STEREO_FLIP_RIGHT : 0) |
398 (c_options->stereo.tmp.mirror_left ? PR_STEREO_MIRROR_LEFT : 0) |
399 (c_options->stereo.tmp.flip_left ? PR_STEREO_FLIP_LEFT : 0) |
400 (c_options->stereo.tmp.swap ? PR_STEREO_SWAP : 0) |
401 (c_options->stereo.tmp.temp_disable ? PR_STEREO_TEMP_DISABLE : 0);
402 options->stereo.fsmode = (c_options->stereo.fsmode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
403 (c_options->stereo.tmp.fs_mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
404 (c_options->stereo.tmp.fs_flip_right ? PR_STEREO_FLIP_RIGHT : 0) |
405 (c_options->stereo.tmp.fs_mirror_left ? PR_STEREO_MIRROR_LEFT : 0) |
406 (c_options->stereo.tmp.fs_flip_left ? PR_STEREO_FLIP_LEFT : 0) |
407 (c_options->stereo.tmp.fs_swap ? PR_STEREO_SWAP : 0) |
408 (c_options->stereo.tmp.fs_temp_disable ? PR_STEREO_TEMP_DISABLE : 0);
409 options->stereo.enable_fsmode = c_options->stereo.enable_fsmode;
410 options->stereo.fixed_w = c_options->stereo.fixed_w;
411 options->stereo.fixed_h = c_options->stereo.fixed_h;
412 options->stereo.fixed_x1 = c_options->stereo.fixed_x1;
413 options->stereo.fixed_y1 = c_options->stereo.fixed_y1;
414 options->stereo.fixed_x2 = c_options->stereo.fixed_x2;
415 options->stereo.fixed_y2 = c_options->stereo.fixed_y2;
417 options->info_keywords.height = c_options->info_keywords.height;
418 options->info_title.height = c_options->info_title.height;
419 options->info_comment.height = c_options->info_comment.height;
420 options->info_rating.height = c_options->info_rating.height;
422 options->show_predefined_keyword_tree = c_options->show_predefined_keyword_tree;
424 options->marks_save = c_options->marks_save;
425 options->with_rename = c_options->with_rename;
426 options->collections_on_top = c_options->collections_on_top;
427 config_entry_to_option(help_search_engine_entry, &options->help_search_engine, NULL);
429 options->read_metadata_in_idle = c_options->read_metadata_in_idle;
431 options->star_rating.star = c_options->star_rating.star;
432 options->star_rating.rejected = c_options->star_rating.rejected;
434 set_debug_level(debug_c);
438 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
440 config_entry_to_option(color_profile_input_name_entry[i], &options->color_profile.input_name[i], NULL);
441 config_entry_to_option(color_profile_input_file_entry[i], &options->color_profile.input_file[i], NULL);
443 config_entry_to_option(color_profile_screen_file_entry, &options->color_profile.screen_file, NULL);
444 options->color_profile.use_x11_screen_profile = c_options->color_profile.use_x11_screen_profile;
445 if (options->color_profile.render_intent != c_options->color_profile.render_intent)
447 options->color_profile.render_intent = c_options->color_profile.render_intent;
452 config_tab_keywords_save();
454 image_options_sync();
459 layout_refresh(NULL);
462 if (accel_store) gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_apply_cb, NULL);
468 *-----------------------------------------------------------------------------
469 * config window main button callbacks (private)
470 *-----------------------------------------------------------------------------
473 static void config_window_close_cb(GtkWidget *widget, gpointer data)
475 gtk_widget_destroy(configwindow);
480 static void config_window_help_cb(GtkWidget *widget, gpointer data)
482 GtkWidget *notebook = data;
485 static gchar *html_section[] =
487 "GuideOptionsGeneral.html",
488 "GuideOptionsImage.html",
489 "GuideOptionsOSD.html",
490 "GuideOptionsWindow.html",
491 "GuideOptionsKeyboard.html",
492 "GuideOptionsFiltering.html",
493 "GuideOptionsMetadata.html",
494 "GuideOptionsKeywords.html",
495 "GuideOptionsColor.html",
496 "GuideOptionsStereo.html",
497 "GuideOptionsBehavior.html",
498 "GuideOptionsToolbar.html"
501 i = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
502 help_window_show(html_section[i]);
505 static gboolean config_window_delete(GtkWidget *widget, GdkEventAny *event, gpointer data)
507 config_window_close_cb(NULL, NULL);
511 static void config_window_ok_cb(GtkWidget *widget, gpointer data)
513 config_window_apply();
514 config_window_close_cb(NULL, NULL);
517 static void config_window_apply_cb(GtkWidget *widget, gpointer data)
520 lw = layout_window_list->data;
522 config_window_apply();
523 layout_util_sync(lw);
526 static void config_window_save_cb(GtkWidget *widget, gpointer data)
528 config_window_apply();
529 save_options(options);
533 *-----------------------------------------------------------------------------
534 * config window setup (private)
535 *-----------------------------------------------------------------------------
538 static void quality_menu_cb(GtkWidget *combo, gpointer data)
542 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
546 *option = GDK_INTERP_NEAREST;
549 *option = GDK_INTERP_TILES;
552 *option = GDK_INTERP_BILINEAR;
555 *option = GDK_INTERP_HYPER;
560 static void clipboard_selection_menu_cb(GtkWidget *combo, gpointer data)
564 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
576 static void add_quality_menu(GtkWidget *table, gint column, gint row, const gchar *text,
577 guint option, guint *option_c)
584 pref_table_label(table, column, row, text, 0.0);
586 combo = gtk_combo_box_text_new();
588 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Nearest (worst, but fastest)"));
589 if (option == GDK_INTERP_NEAREST) current = 0;
590 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Tiles"));
591 if (option == GDK_INTERP_TILES) current = 1;
592 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Bilinear"));
593 if (option == GDK_INTERP_BILINEAR) current = 2;
594 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Hyper (best, but slowest)"));
595 if (option == GDK_INTERP_HYPER) current = 3;
597 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
599 g_signal_connect(G_OBJECT(combo), "changed",
600 G_CALLBACK(quality_menu_cb), option_c);
602 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
603 GTK_EXPAND | GTK_FILL, 0, 0, 0);
604 gtk_widget_show(combo);
607 static void add_clipboard_selection_menu(GtkWidget *table, gint column, gint row, const gchar *text,
608 gint option, gint *option_c)
615 pref_table_label(table, column, row, text, 0.0);
617 combo = gtk_combo_box_text_new();
619 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("PRIMARY"));
620 if (option == PRIMARY) current = 0;
621 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("CLIPBOARD"));
622 if (option == CLIPBOARD) current = 1;
624 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
626 g_signal_connect(G_OBJECT(combo), "changed",
627 G_CALLBACK(clipboard_selection_menu_cb), option_c);
629 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
630 GTK_EXPAND | GTK_FILL, 0, 0, 0);
631 gtk_widget_show(combo);
634 static void thumb_size_menu_cb(GtkWidget *combo, gpointer data)
638 n = gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
641 if ((guint) n < sizeof(thumb_size_list) / sizeof(ThumbSize))
643 c_options->thumbnails.max_width = thumb_size_list[n].w;
644 c_options->thumbnails.max_height = thumb_size_list[n].h;
648 c_options->thumbnails.max_width = options->thumbnails.max_width;
649 c_options->thumbnails.max_height = options->thumbnails.max_height;
653 static void add_thumb_size_menu(GtkWidget *table, gint column, gint row, gchar *text)
659 c_options->thumbnails.max_width = options->thumbnails.max_width;
660 c_options->thumbnails.max_height = options->thumbnails.max_height;
662 pref_table_label(table, column, row, text, 0.0);
664 combo = gtk_combo_box_text_new();
667 for (i = 0; (guint) i < sizeof(thumb_size_list) / sizeof(ThumbSize); i++)
672 w = thumb_size_list[i].w;
673 h = thumb_size_list[i].h;
675 buf = g_strdup_printf("%d x %d", w, h);
676 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf);
679 if (w == options->thumbnails.max_width && h == options->thumbnails.max_height) current = i;
686 buf = g_strdup_printf("%s %d x %d", _("Custom"), options->thumbnails.max_width, options->thumbnails.max_height);
687 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf);
693 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
694 g_signal_connect(G_OBJECT(combo), "changed",
695 G_CALLBACK(thumb_size_menu_cb), NULL);
697 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
698 GTK_EXPAND | GTK_FILL, 0, 0, 0);
699 gtk_widget_show(combo);
702 static void stereo_mode_menu_cb(GtkWidget *combo, gpointer data)
706 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
710 *option = PR_STEREO_NONE;
713 *option = PR_STEREO_ANAGLYPH_RC;
716 *option = PR_STEREO_ANAGLYPH_GM;
719 *option = PR_STEREO_ANAGLYPH_YB;
722 *option = PR_STEREO_ANAGLYPH_GRAY_RC;
725 *option = PR_STEREO_ANAGLYPH_GRAY_GM;
728 *option = PR_STEREO_ANAGLYPH_GRAY_YB;
731 *option = PR_STEREO_ANAGLYPH_DB_RC;
734 *option = PR_STEREO_ANAGLYPH_DB_GM;
737 *option = PR_STEREO_ANAGLYPH_DB_YB;
740 *option = PR_STEREO_HORIZ;
743 *option = PR_STEREO_HORIZ | PR_STEREO_HALF;
746 *option = PR_STEREO_VERT;
749 *option = PR_STEREO_VERT | PR_STEREO_HALF;
752 *option = PR_STEREO_FIXED;
757 static void add_stereo_mode_menu(GtkWidget *table, gint column, gint row, const gchar *text,
758 gint option, gint *option_c, gboolean add_fixed)
765 pref_table_label(table, column, row, text, 0.0);
767 combo = gtk_combo_box_text_new();
769 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Single image"));
771 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Red-Cyan"));
772 if (option & PR_STEREO_ANAGLYPH_RC) current = 1;
773 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Green-Magenta"));
774 if (option & PR_STEREO_ANAGLYPH_GM) current = 2;
775 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Yellow-Blue"));
776 if (option & PR_STEREO_ANAGLYPH_YB) current = 3;
777 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Red-Cyan"));
778 if (option & PR_STEREO_ANAGLYPH_GRAY_RC) current = 4;
779 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Green-Magenta"));
780 if (option & PR_STEREO_ANAGLYPH_GRAY_GM) current = 5;
781 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Yellow-Blue"));
782 if (option & PR_STEREO_ANAGLYPH_GRAY_YB) current = 6;
783 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Red-Cyan"));
784 if (option & PR_STEREO_ANAGLYPH_DB_RC) current = 7;
785 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Green-Magenta"));
786 if (option & PR_STEREO_ANAGLYPH_DB_GM) current = 8;
787 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Yellow-Blue"));
788 if (option & PR_STEREO_ANAGLYPH_DB_YB) current = 9;
790 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Side by Side"));
791 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Side by Side Half size"));
792 if (option & PR_STEREO_HORIZ)
795 if (option & PR_STEREO_HALF) current = 11;
798 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Top - Bottom"));
799 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Top - Bottom Half size"));
800 if (option & PR_STEREO_VERT)
803 if (option & PR_STEREO_HALF) current = 13;
808 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Fixed position"));
809 if (option & PR_STEREO_FIXED) current = 14;
812 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
814 g_signal_connect(G_OBJECT(combo), "changed",
815 G_CALLBACK(stereo_mode_menu_cb), option_c);
817 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
818 GTK_EXPAND | GTK_FILL, 0, 0, 0);
819 gtk_widget_show(combo);
822 static void video_menu_cb(GtkWidget *combo, gpointer data)
824 gchar **option = data;
826 EditorDescription *ed = g_list_nth_data(editor_list_get(), gtk_combo_box_get_active(GTK_COMBO_BOX(combo)));
830 static void video_menu_populate(gpointer data, gpointer user_data)
832 GtkWidget *combo = user_data;
833 EditorDescription *ed = data;
835 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), ed->name);
838 static void add_video_menu(GtkWidget *table, gint column, gint row, const gchar *text,
839 gchar *option, gchar **option_c)
843 /* use lists since they are sorted */
844 GList *eds = editor_list_get();
848 pref_table_label(table, column, row, text, 0.0);
850 combo = gtk_combo_box_text_new();
851 g_list_foreach(eds,video_menu_populate,(gpointer)combo);
852 current = option ? g_list_index(eds,g_hash_table_lookup(editors,option)): -1;
854 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
856 g_signal_connect(G_OBJECT(combo), "changed",
857 G_CALLBACK(video_menu_cb), option_c);
859 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
860 GTK_EXPAND | GTK_FILL, 0, 0, 0);
861 gtk_widget_show(combo);
864 static void filter_store_populate(void)
868 if (!filter_store) return;
870 gtk_list_store_clear(filter_store);
872 work = filter_get_list();
881 gtk_list_store_append(filter_store, &iter);
882 gtk_list_store_set(filter_store, &iter, 0, fe, -1);
886 static void filter_store_ext_edit_cb(GtkCellRendererText *cell, gchar *path_str,
887 gchar *new_text, gpointer data)
889 GtkWidget *model = data;
890 FilterEntry *fe = data;
894 if (!new_text || strlen(new_text) < 1) return;
896 tpath = gtk_tree_path_new_from_string(path_str);
897 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
898 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
900 g_free(fe->extensions);
901 fe->extensions = g_strdup(new_text);
903 gtk_tree_path_free(tpath);
907 static void filter_store_class_edit_cb(GtkCellRendererText *cell, gchar *path_str,
908 gchar *new_text, gpointer data)
910 GtkWidget *model = data;
911 FilterEntry *fe = data;
916 if (!new_text || !new_text[0]) return;
918 tpath = gtk_tree_path_new_from_string(path_str);
919 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
920 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
922 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
924 if (strcmp(new_text, _(format_class_list[i])) == 0)
931 gtk_tree_path_free(tpath);
935 static void filter_store_desc_edit_cb(GtkCellRendererText *cell, gchar *path_str,
936 gchar *new_text, gpointer data)
938 GtkWidget *model = data;
943 if (!new_text || !new_text[0]) return;
945 tpath = gtk_tree_path_new_from_string(path_str);
946 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
947 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
949 g_free(fe->description);
950 fe->description = g_strdup(new_text);
952 gtk_tree_path_free(tpath);
955 static void filter_store_enable_cb(GtkCellRendererToggle *renderer,
956 gchar *path_str, gpointer data)
958 GtkWidget *model = data;
963 tpath = gtk_tree_path_new_from_string(path_str);
964 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
965 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
967 fe->enabled = !fe->enabled;
969 gtk_tree_path_free(tpath);
973 static void filter_store_writable_cb(GtkCellRendererToggle *renderer,
974 gchar *path_str, gpointer data)
976 GtkWidget *model = data;
981 tpath = gtk_tree_path_new_from_string(path_str);
982 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
983 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
985 fe->writable = !fe->writable;
986 if (fe->writable) fe->allow_sidecar = FALSE;
988 gtk_tree_path_free(tpath);
992 static void filter_store_sidecar_cb(GtkCellRendererToggle *renderer,
993 gchar *path_str, gpointer data)
995 GtkWidget *model = data;
1000 tpath = gtk_tree_path_new_from_string(path_str);
1001 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
1002 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
1004 fe->allow_sidecar = !fe->allow_sidecar;
1005 if (fe->allow_sidecar) fe->writable = FALSE;
1007 gtk_tree_path_free(tpath);
1011 static void filter_set_func(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell,
1012 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
1016 gtk_tree_model_get(tree_model, iter, 0, &fe, -1);
1018 switch (GPOINTER_TO_INT(data))
1021 g_object_set(GTK_CELL_RENDERER(cell),
1022 "active", fe->enabled, NULL);
1025 g_object_set(GTK_CELL_RENDERER(cell),
1026 "text", fe->extensions, NULL);
1028 case FE_DESCRIPTION:
1029 g_object_set(GTK_CELL_RENDERER(cell),
1030 "text", fe->description, NULL);
1033 g_object_set(GTK_CELL_RENDERER(cell),
1034 "text", _(format_class_list[fe->file_class]), NULL);
1037 g_object_set(GTK_CELL_RENDERER(cell),
1038 "active", fe->writable, NULL);
1040 case FE_ALLOW_SIDECAR:
1041 g_object_set(GTK_CELL_RENDERER(cell),
1042 "active", fe->allow_sidecar, NULL);
1047 static gboolean filter_add_scroll(gpointer data)
1051 GtkCellRenderer *cell;
1052 GtkTreeViewColumn *column;
1053 GList *list_columns;
1058 rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(filter_store), NULL);
1059 path = gtk_tree_path_new_from_indices(rows-1, -1);
1061 list_columns = gtk_tree_view_get_columns(GTK_TREE_VIEW(data));
1063 column = g_list_nth(list_columns,i)->data;
1064 title = gtk_tree_view_column_get_title(GTK_TREE_VIEW_COLUMN(column));
1066 } while (strcmp(title, "Filter") !=0 );
1068 list_cells = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(column));
1069 cell = g_list_last(list_cells)->data;
1071 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1072 path, column, FALSE, 0.0, 0.0 );
1073 gtk_tree_view_set_cursor_on_cell(GTK_TREE_VIEW(data),
1074 path, column, cell, TRUE);
1076 gtk_tree_path_free(path);
1077 g_list_free(list_cells);
1078 g_list_free(list_columns);
1083 static void filter_add_cb(GtkWidget *widget, gpointer data)
1085 filter_add_unique("description", ".new", FORMAT_CLASS_IMAGE, TRUE, FALSE, TRUE);
1086 filter_store_populate();
1088 g_idle_add((GSourceFunc)filter_add_scroll, data);
1091 static void filter_remove_cb(GtkWidget *widget, gpointer data)
1093 GtkWidget *filter_view = data;
1094 GtkTreeSelection *selection;
1098 if (!filter_store) return;
1099 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
1100 if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) return;
1101 gtk_tree_model_get(GTK_TREE_MODEL(filter_store), &iter, 0, &fe, -1);
1104 filter_remove_entry(fe);
1106 filter_store_populate();
1109 static gboolean filter_default_ok_scroll(GtkTreeView *data)
1113 GtkTreeViewColumn *column;
1115 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(filter_store), &iter);
1116 path = gtk_tree_model_get_path(GTK_TREE_MODEL(filter_store), &iter);
1117 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data),0);
1119 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1123 gtk_tree_path_free(path);
1128 static void filter_default_ok_cb(GenericDialog *gd, gpointer data)
1131 filter_add_defaults();
1133 filter_store_populate();
1135 g_idle_add((GSourceFunc)filter_default_ok_scroll, gd->data);
1138 static void dummy_cancel_cb(GenericDialog *gd, gpointer data)
1140 /* no op, only so cancel button appears */
1143 static void filter_default_cb(GtkWidget *widget, gpointer data)
1147 gd = generic_dialog_new(_("Reset filters"),
1148 "reset_filter", widget, TRUE,
1149 dummy_cancel_cb, data);
1150 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Reset filters"),
1151 _("This will reset the file filters to the defaults.\nContinue?"), TRUE);
1152 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, filter_default_ok_cb, TRUE);
1153 gtk_widget_show(gd->dialog);
1156 static void filter_disable_cb(GtkWidget *widget, gpointer data)
1158 GtkWidget *frame = data;
1160 gtk_widget_set_sensitive(frame,
1161 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
1164 static void safe_delete_view_cb(GtkWidget *widget, gpointer data)
1166 layout_set_path(NULL, gtk_entry_get_text(GTK_ENTRY(safe_delete_path_entry)));
1169 static void safe_delete_clear_ok_cb(GenericDialog *gd, gpointer data)
1171 file_util_trash_clear();
1174 static void safe_delete_clear_cb(GtkWidget *widget, gpointer data)
1178 gd = generic_dialog_new(_("Clear trash"),
1179 "clear_trash", widget, TRUE,
1180 dummy_cancel_cb, NULL);
1181 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Clear trash"),
1182 _("This will remove the trash contents."), FALSE);
1183 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, safe_delete_clear_ok_cb, TRUE);
1184 entry = gtk_entry_new();
1185 gtk_widget_set_can_focus(entry, FALSE);
1186 gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
1187 if (options->file_ops.safe_delete_path) gtk_entry_set_text(GTK_ENTRY(entry), options->file_ops.safe_delete_path);
1188 gtk_box_pack_start(GTK_BOX(gd->vbox), entry, FALSE, FALSE, 0);
1189 gtk_widget_show(entry);
1190 gtk_widget_show(gd->dialog);
1193 static void image_overlay_template_view_changed_cb(GtkWidget *widget, gpointer data)
1195 GtkWidget *pTextView;
1196 GtkTextBuffer *pTextBuffer;
1200 pTextView = GTK_WIDGET(data);
1202 pTextBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pTextView));
1203 gtk_text_buffer_get_start_iter(pTextBuffer, &iStart);
1204 gtk_text_buffer_get_end_iter(pTextBuffer, &iEnd);
1206 set_image_overlay_template_string(&c_options->image_overlay.template_string,
1207 gtk_text_buffer_get_text(pTextBuffer, &iStart, &iEnd, TRUE));
1210 static void image_overlay_default_template_ok_cb(GenericDialog *gd, gpointer data)
1212 GtkTextView *text_view = data;
1213 GtkTextBuffer *buffer;
1215 set_default_image_overlay_template_string(&options->image_overlay.template_string);
1216 if (!configwindow) return;
1218 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
1219 gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
1222 static void image_overlay_default_template_cb(GtkWidget *widget, gpointer data)
1226 gd = generic_dialog_new(_("Reset image overlay template string"),
1227 "reset_image_overlay_template_string", widget, TRUE,
1228 dummy_cancel_cb, data);
1229 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Reset image overlay template string"),
1230 _("This will reset the image overlay template string to the default.\nContinue?"), TRUE);
1231 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, image_overlay_default_template_ok_cb, TRUE);
1232 gtk_widget_show(gd->dialog);
1235 static void image_overlay_help_cb(GtkWidget *widget, gpointer data)
1237 help_window_show("GuideOptionsOSD.html");
1240 static void image_overlay_set_font_cb(GtkWidget *widget, gpointer data)
1242 #if GTK_CHECK_VERSION(3,4,0)
1245 PangoFontDescription *font_desc;
1247 dialog = gtk_font_chooser_dialog_new("Image Overlay Font", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1248 gtk_font_chooser_set_font(GTK_FONT_CHOOSER(dialog), options->image_overlay.font);
1250 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1252 font_desc = gtk_font_chooser_get_font_desc(GTK_FONT_CHOOSER(dialog));
1253 font = pango_font_description_to_string(font_desc);
1254 g_free(c_options->image_overlay.font);
1255 c_options->image_overlay.font = g_strdup(font);
1259 gtk_widget_destroy(dialog);
1263 font = gtk_font_button_get_font_name(GTK_FONT_BUTTON(widget));
1264 c_options->image_overlay.font = g_strdup(font);
1268 static void image_overlay_set_text_colour_cb(GtkWidget *widget, gpointer data)
1271 #if GTK_CHECK_VERSION(3,4,0)
1274 dialog = gtk_color_chooser_dialog_new("Image Overlay Text Colour", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1275 colour.red = options->image_overlay.text_red;
1276 colour.green = options->image_overlay.text_green;
1277 colour.blue = options->image_overlay.text_blue;
1278 colour.alpha = options->image_overlay.text_alpha;
1279 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1280 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(dialog), TRUE);
1282 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1284 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1285 c_options->image_overlay.text_red = colour.red*255;
1286 c_options->image_overlay.text_green = colour.green*255;
1287 c_options->image_overlay.text_blue = colour.blue*255;
1288 c_options->image_overlay.text_alpha = colour.alpha*255;
1290 gtk_widget_destroy(dialog);
1293 GtkColorSelection *colorsel;
1295 dialog = gtk_color_selection_dialog_new("Image Overlay Text Colour");
1296 gtk_window_set_keep_above(GTK_WINDOW(dialog),TRUE);
1297 colour.red = options->image_overlay.text_red*257;
1298 colour.green = options->image_overlay.text_green*257;
1299 colour.blue = options->image_overlay.text_blue*257;
1300 colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)));
1301 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
1302 gtk_color_selection_set_current_color(colorsel, &colour);
1303 gtk_color_selection_set_current_alpha(colorsel, options->image_overlay.text_alpha*257);
1305 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
1307 gtk_color_selection_get_current_color(colorsel, &colour);
1308 c_options->image_overlay.text_red = colour.red/257;
1309 c_options->image_overlay.text_green = colour.green/257;
1310 c_options->image_overlay.text_blue = colour.blue/257;
1311 c_options->image_overlay.text_alpha = gtk_color_selection_get_current_alpha(colorsel)/257;
1313 gtk_widget_destroy (dialog);
1318 static void image_overlay_set_background_colour_cb(GtkWidget *widget, gpointer data)
1321 #if GTK_CHECK_VERSION(3,4,0)
1324 dialog = gtk_color_chooser_dialog_new("Image Overlay Background Colour", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1325 colour.red = options->image_overlay.background_red;
1326 colour.green = options->image_overlay.background_green;
1327 colour.blue = options->image_overlay.background_blue;
1328 colour.alpha = options->image_overlay.background_alpha;
1329 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1330 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(dialog), TRUE);
1332 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1334 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1335 c_options->image_overlay.background_red = colour.red*255;
1336 c_options->image_overlay.background_green = colour.green*255;
1337 c_options->image_overlay.background_blue = colour.blue*255;
1338 c_options->image_overlay.background_alpha = colour.alpha*255;
1340 gtk_widget_destroy(dialog);
1343 GtkColorSelection *colorsel;
1345 dialog = gtk_color_selection_dialog_new("Image Overlay Background Colour");
1346 gtk_window_set_keep_above(GTK_WINDOW(dialog),TRUE);
1347 colour.red = options->image_overlay.background_red*257;
1348 colour.green = options->image_overlay.background_green*257;
1349 colour.blue = options->image_overlay.background_blue*257;
1350 colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)));
1351 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
1352 gtk_color_selection_set_current_color(colorsel, &colour);
1353 gtk_color_selection_set_current_alpha(colorsel, options->image_overlay.background_alpha*257);
1355 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
1357 gtk_color_selection_get_current_color(colorsel, &colour);
1358 c_options->image_overlay.background_red = colour.red/257;
1359 c_options->image_overlay.background_green = colour.green/257;
1360 c_options->image_overlay.background_blue = colour.blue/257;
1361 c_options->image_overlay.background_alpha = gtk_color_selection_get_current_alpha(colorsel)/257;
1363 gtk_widget_destroy(dialog);
1367 static void accel_store_populate(void)
1370 GList *groups, *actions;
1372 const gchar *accel_path;
1376 if (!accel_store || !layout_window_list || !layout_window_list->data) return;
1378 gtk_tree_store_clear(accel_store);
1379 lw = layout_window_list->data; /* get the actions from the first window, it should not matter, they should be the same in all windows */
1381 g_assert(lw && lw->ui_manager);
1382 groups = gtk_ui_manager_get_action_groups(lw->ui_manager);
1385 actions = gtk_action_group_list_actions(GTK_ACTION_GROUP(groups->data));
1388 action = GTK_ACTION(actions->data);
1389 accel_path = gtk_action_get_accel_path(action);
1390 if (accel_path && gtk_accel_map_lookup_entry(accel_path, &key))
1392 gchar *label, *label2, *tooltip, *accel;
1393 g_object_get(action,
1394 "tooltip", &tooltip,
1398 if (pango_parse_markup(label, -1, '_', NULL, &label2, NULL, NULL) && label2)
1404 accel = gtk_accelerator_name(key.accel_key, key.accel_mods);
1408 gtk_tree_store_append(accel_store, &iter, NULL);
1409 gtk_tree_store_set(accel_store, &iter,
1412 AE_TOOLTIP, tooltip ? tooltip : "",
1413 AE_ACCEL, accel_path,
1421 actions = actions->next;
1424 groups = groups->next;
1428 static void accel_store_cleared_cb(GtkCellRendererAccel *accel, gchar *path_string, gpointer user_data)
1433 static gboolean accel_remove_key_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1435 gchar *accel1 = data;
1440 gtk_tree_model_get(model, iter, AE_KEY, &accel2, -1);
1442 gtk_accelerator_parse(accel1, &key1.accel_key, &key1.accel_mods);
1443 gtk_accelerator_parse(accel2, &key2.accel_key, &key2.accel_mods);
1445 if (key1.accel_key == key2.accel_key && key1.accel_mods == key2.accel_mods)
1447 gtk_tree_store_set(accel_store, iter, AE_KEY, "", -1);
1448 DEBUG_1("accelerator key '%s' is already used, removing.", accel1);
1457 static void accel_store_edited_cb(GtkCellRendererAccel *accel, gchar *path_string, guint accel_key, GdkModifierType accel_mods, guint hardware_keycode, gpointer user_data)
1459 GtkTreeModel *model = (GtkTreeModel *)accel_store;
1463 GtkAccelKey old_key, key;
1464 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
1466 gtk_tree_model_get_iter(model, &iter, path);
1467 gtk_tree_model_get(model, &iter, AE_ACCEL, &accel_path, -1);
1469 /* test if the accelerator can be stored without conflicts*/
1470 gtk_accel_map_lookup_entry(accel_path, &old_key);
1472 /* change the key and read it back (change may fail on keys hardcoded in gtk)*/
1473 gtk_accel_map_change_entry(accel_path, accel_key, accel_mods, TRUE);
1474 gtk_accel_map_lookup_entry(accel_path, &key);
1476 /* restore the original for now, the key will be really changed when the changes are confirmed */
1477 gtk_accel_map_change_entry(accel_path, old_key.accel_key, old_key.accel_mods, TRUE);
1479 acc = gtk_accelerator_name(key.accel_key, key.accel_mods);
1480 gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_remove_key_cb, acc);
1482 gtk_tree_store_set(accel_store, &iter, AE_KEY, acc, -1);
1483 gtk_tree_path_free(path);
1487 static gboolean accel_default_scroll(GtkTreeView *data)
1491 GtkTreeViewColumn *column;
1493 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(accel_store), &iter);
1494 path = gtk_tree_model_get_path(GTK_TREE_MODEL(accel_store), &iter);
1495 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data),0);
1497 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1501 gtk_tree_path_free(path);
1506 static void accel_default_cb(GtkWidget *widget, gpointer data)
1508 accel_store_populate();
1510 g_idle_add((GSourceFunc)accel_default_scroll, data);
1513 void accel_remove_selection(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1515 gtk_tree_store_set(accel_store, iter, AE_KEY, "", -1);
1518 void accel_reset_selection(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1521 gchar *accel_path, *accel;
1523 gtk_tree_model_get(model, iter, AE_ACCEL, &accel_path, -1);
1524 gtk_accel_map_lookup_entry(accel_path, &key);
1525 accel = gtk_accelerator_name(key.accel_key, key.accel_mods);
1527 gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_remove_key_cb, accel);
1529 gtk_tree_store_set(accel_store, iter, AE_KEY, accel, -1);
1534 static void accel_reset_cb(GtkWidget *widget, gpointer data)
1536 GtkTreeSelection *selection;
1538 if (!accel_store) return;
1539 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data));
1540 gtk_tree_selection_selected_foreach(selection, &accel_reset_selection, NULL);
1545 static GtkWidget *scrolled_notebook_page(GtkWidget *notebook, const gchar *title)
1549 GtkWidget *scrolled;
1550 GtkWidget *viewport;
1552 scrolled = gtk_scrolled_window_new(NULL, NULL);
1553 gtk_container_set_border_width(GTK_CONTAINER(scrolled), PREF_PAD_BORDER);
1554 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
1555 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1556 label = gtk_label_new(title);
1557 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled, label);
1558 gtk_widget_show(scrolled);
1560 viewport = gtk_viewport_new(NULL, NULL);
1561 gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
1562 gtk_container_add(GTK_CONTAINER(scrolled), viewport);
1563 gtk_widget_show(viewport);
1565 vbox = gtk_vbox_new(FALSE, 0);
1566 gtk_container_add(GTK_CONTAINER(viewport), vbox);
1567 gtk_widget_show(vbox);
1572 static void cache_standard_cb(GtkWidget *widget, gpointer data)
1574 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1576 c_options->thumbnails.spec_standard =TRUE;
1577 c_options->thumbnails.cache_into_dirs = FALSE;
1581 static void cache_geeqie_cb(GtkWidget *widget, gpointer data)
1583 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1585 c_options->thumbnails.spec_standard =FALSE;
1586 c_options->thumbnails.cache_into_dirs = FALSE;
1590 static void cache_local_cb(GtkWidget *widget, gpointer data)
1592 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1594 c_options->thumbnails.cache_into_dirs = TRUE;
1595 c_options->thumbnails.spec_standard =FALSE;
1599 static void help_search_engine_entry_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1600 GdkEvent *event, gpointer userdata)
1602 if (pos == GTK_ENTRY_ICON_PRIMARY)
1604 gtk_entry_set_text(GTK_ENTRY(userdata), HELP_SEARCH_ENGINE);
1608 gtk_entry_set_text(GTK_ENTRY(userdata), "");
1612 static void star_rating_star_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1613 GdkEvent *event, gpointer userdata)
1615 gchar *rating_symbol;
1617 if (pos == GTK_ENTRY_ICON_PRIMARY)
1619 rating_symbol = g_strdup_printf("U+%X", STAR_RATING_STAR);
1620 gtk_entry_set_text(GTK_ENTRY(userdata), rating_symbol);
1621 g_free(rating_symbol);
1625 gtk_entry_set_text(GTK_ENTRY(userdata), "U+");
1626 gtk_widget_grab_focus(GTK_WIDGET(userdata));
1627 gtk_editable_select_region(GTK_EDITABLE(userdata), 2, 2);
1631 static void star_rating_rejected_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1632 GdkEvent *event, gpointer userdata)
1634 gchar *rating_symbol;
1636 if (pos == GTK_ENTRY_ICON_PRIMARY)
1638 rating_symbol = g_strdup_printf("U+%X", STAR_RATING_REJECTED);
1639 gtk_entry_set_text(GTK_ENTRY(userdata), rating_symbol);
1640 g_free(rating_symbol);
1644 gtk_entry_set_text(GTK_ENTRY(userdata), "U+");
1645 gtk_widget_grab_focus(GTK_WIDGET(userdata));
1646 gtk_editable_select_region(GTK_EDITABLE(userdata), 2, 2);
1650 static guint star_rating_symbol_test(GtkWidget *widget, gpointer data)
1652 GtkContainer *hbox = data;
1653 GString *str = g_string_new(NULL);
1654 GtkEntry *hex_code_entry;
1655 gchar *hex_code_full;
1658 guint64 hex_value = 0;
1660 list = gtk_container_get_children(hbox);
1662 hex_code_entry = g_list_nth_data(list, 2);
1663 hex_code_full = g_strdup(gtk_entry_get_text(hex_code_entry));
1665 hex_code = g_strsplit(hex_code_full, "+", 2);
1666 if (hex_code[0] && hex_code[1])
1668 hex_value = strtoull(hex_code[1], NULL, 16);
1670 if (!hex_value || hex_value > 0x10FFFF)
1672 hex_value = 0x003F; // Unicode 'Question Mark'
1674 str = g_string_append_unichar(str, (gunichar)hex_value);
1675 gtk_label_set_text(g_list_nth_data(list, 1), str->str);
1677 g_strfreev(hex_code);
1678 g_string_free(str, TRUE);
1679 g_free(hex_code_full);
1684 static void star_rating_star_test_cb(GtkWidget *widget, gpointer data)
1686 guint64 star_symbol;
1688 star_symbol = star_rating_symbol_test(widget, data);
1689 c_options->star_rating.star = star_symbol;
1692 static void star_rating_rejected_test_cb(GtkWidget *widget, gpointer data)
1694 guint64 rejected_symbol;
1696 rejected_symbol = star_rating_symbol_test(widget, data);
1697 c_options->star_rating.rejected = rejected_symbol;
1700 /* general options tab */
1701 static void config_tab_general(GtkWidget *notebook)
1706 GtkWidget *group_frame;
1707 GtkWidget *subgroup;
1709 GtkWidget *ct_button;
1712 gint hours, minutes, remainder;
1714 GtkWidget *star_rating_entry;
1716 gchar *rating_symbol;
1718 vbox = scrolled_notebook_page(notebook, _("General"));
1720 group = pref_group_new(vbox, FALSE, _("Thumbnails"), GTK_ORIENTATION_VERTICAL);
1722 table = pref_table_new(group, 2, 2, FALSE, FALSE);
1723 add_thumb_size_menu(table, 0, 0, _("Size:"));
1724 add_quality_menu(table, 0, 1, _("Quality:"), options->thumbnails.quality, &c_options->thumbnails.quality);
1726 ct_button = pref_checkbox_new_int(group, _("Cache thumbnails"),
1727 options->thumbnails.enable_caching, &c_options->thumbnails.enable_caching);
1729 subgroup = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1730 pref_checkbox_link_sensitivity(ct_button, subgroup);
1732 c_options->thumbnails.spec_standard = options->thumbnails.spec_standard;
1733 c_options->thumbnails.cache_into_dirs = options->thumbnails.cache_into_dirs;
1734 group_frame = pref_frame_new(subgroup, TRUE, _("Use Geeqie thumbnail style and cache"),
1735 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1736 button = pref_radiobutton_new(group_frame, NULL, get_thumbnails_cache_dir(),
1737 !options->thumbnails.spec_standard && !options->thumbnails.cache_into_dirs,
1738 G_CALLBACK(cache_geeqie_cb), NULL);
1740 group_frame = pref_frame_new(subgroup, TRUE,
1741 _("Store thumbnails local to image folder (non-standard)"),
1742 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1743 pref_radiobutton_new(group_frame, button, "*/.thumbnails",
1744 !options->thumbnails.spec_standard && options->thumbnails.cache_into_dirs,
1745 G_CALLBACK(cache_local_cb), NULL);
1747 group_frame = pref_frame_new(subgroup, TRUE,
1748 _("Use standard thumbnail style and cache, shared with other applications"),
1749 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1750 pref_radiobutton_new(group_frame, button, get_thumbnails_standard_cache_dir(),
1751 options->thumbnails.spec_standard && !options->thumbnails.cache_into_dirs,
1752 G_CALLBACK(cache_standard_cb), NULL);
1754 pref_checkbox_new_int(group, _("Use EXIF thumbnails when available (EXIF thumbnails may be outdated)"),
1755 options->thumbnails.use_exif, &c_options->thumbnails.use_exif);
1757 spin = pref_spin_new_int(group, _("Collection preview:"), NULL,
1759 options->thumbnails.collection_preview, &c_options->thumbnails.collection_preview);
1760 gtk_widget_set_tooltip_text(spin, _("The maximum number of thumbnails shown in a Collection preview montage"));
1762 #ifdef HAVE_FFMPEGTHUMBNAILER_METADATA
1763 pref_checkbox_new_int(group, _("Use embedded metadata in video files as thumbnails when available"),
1764 options->thumbnails.use_ft_metadata, &c_options->thumbnails.use_ft_metadata);
1766 // pref_checkbox_new_int(group, _("Ignore embedded metadata if size is too small"),
1767 // options->thumbnails.use_ft_metadata_small, &c_options->thumbnails.use_ft_metadata_small);
1770 group = pref_group_new(vbox, FALSE, _("Star Rating"), GTK_ORIENTATION_VERTICAL);
1772 c_options->star_rating.star = options->star_rating.star;
1773 c_options->star_rating.rejected = options->star_rating.rejected;
1775 str = g_string_new(NULL);
1776 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1777 pref_label_new(hbox, "Star character: ");
1778 str = g_string_append_unichar(str, options->star_rating.star);
1779 pref_label_new(hbox, g_strdup(str->str));
1780 rating_symbol = g_strdup_printf("U+%X", options->star_rating.star);
1781 star_rating_entry = gtk_entry_new();
1782 gtk_entry_set_text(GTK_ENTRY(star_rating_entry), rating_symbol);
1783 gtk_box_pack_start(GTK_BOX(hbox), star_rating_entry, FALSE, FALSE, 0);
1784 gtk_entry_set_width_chars(GTK_ENTRY(star_rating_entry), 15);
1785 gtk_widget_show(star_rating_entry);
1786 button = pref_button_new(NULL, NULL, _("Set"), FALSE,
1787 G_CALLBACK(star_rating_star_test_cb), hbox);
1788 gtk_widget_set_tooltip_text(button, _("Display selected character"));
1789 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1790 gtk_widget_show(button);
1791 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."));
1792 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1793 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1794 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1795 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1796 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1797 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1798 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1799 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1800 g_signal_connect(GTK_ENTRY(star_rating_entry), "icon-press",
1801 G_CALLBACK(star_rating_star_icon_cb),
1804 g_string_free(str, TRUE);
1805 g_free(rating_symbol);
1807 str = g_string_new(NULL);
1808 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1809 pref_label_new(hbox, "Rejected character: ");
1810 str = g_string_append_unichar(str, options->star_rating.rejected);
1811 pref_label_new(hbox, g_strdup(str->str));
1812 rating_symbol = g_strdup_printf("U+%X", options->star_rating.rejected);
1813 star_rating_entry = gtk_entry_new();
1814 gtk_entry_set_text(GTK_ENTRY(star_rating_entry), rating_symbol);
1815 gtk_box_pack_start(GTK_BOX(hbox), star_rating_entry, FALSE, FALSE, 0);
1816 gtk_entry_set_width_chars(GTK_ENTRY(star_rating_entry), 15);
1817 gtk_widget_show(star_rating_entry);
1818 button = pref_button_new(NULL, NULL, _("Set"), FALSE,
1819 G_CALLBACK(star_rating_rejected_test_cb), hbox);
1820 gtk_widget_set_tooltip_text(button, _("Display selected character"));
1821 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1822 gtk_widget_show(button);
1823 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."));
1824 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1825 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1826 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1827 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1828 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1829 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1830 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1831 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1832 g_signal_connect(GTK_ENTRY(star_rating_entry), "icon-press",
1833 G_CALLBACK(star_rating_rejected_icon_cb),
1836 g_string_free(str, TRUE);
1837 g_free(rating_symbol);
1839 group = pref_group_new(vbox, FALSE, _("Slide show"), GTK_ORIENTATION_VERTICAL);
1841 c_options->slideshow.delay = options->slideshow.delay;
1842 hours = options->slideshow.delay / (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1843 remainder = options->slideshow.delay % (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1844 minutes = remainder / (60 * SLIDESHOW_SUBSECOND_PRECISION);
1845 seconds = (gdouble)(remainder % (60 * SLIDESHOW_SUBSECOND_PRECISION)) /
1846 SLIDESHOW_SUBSECOND_PRECISION;
1848 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1850 spin = pref_spin_new(hbox, _("Delay between image change hrs:mins:secs.dec"), NULL,
1852 options->slideshow.delay ? hours : 0.0,
1853 G_CALLBACK(slideshow_delay_hours_cb), NULL);
1854 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1855 spin = pref_spin_new(hbox, ":" , NULL,
1857 options->slideshow.delay ? minutes: 0.0,
1858 G_CALLBACK(slideshow_delay_minutes_cb), NULL);
1859 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1860 spin = pref_spin_new(hbox, ":", NULL,
1861 SLIDESHOW_MIN_SECONDS, 59, 1.0, 1,
1862 options->slideshow.delay ? seconds : 10.0,
1863 G_CALLBACK(slideshow_delay_seconds_cb), NULL);
1864 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1866 pref_checkbox_new_int(group, _("Random"), options->slideshow.random, &c_options->slideshow.random);
1867 pref_checkbox_new_int(group, _("Repeat"), options->slideshow.repeat, &c_options->slideshow.repeat);
1869 group = pref_group_new(vbox, FALSE, _("Image loading and caching"), GTK_ORIENTATION_VERTICAL);
1871 pref_spin_new_int(group, _("Decoded image cache size (Mb):"), NULL,
1872 0, 99999, 1, options->image.image_cache_max, &c_options->image.image_cache_max);
1873 pref_checkbox_new_int(group, _("Preload next image"),
1874 options->image.enable_read_ahead, &c_options->image.enable_read_ahead);
1876 pref_checkbox_new_int(group, _("Refresh on file change"),
1877 options->update_on_time_change, &c_options->update_on_time_change);
1879 group = pref_group_new(vbox, FALSE, _("Info sidebar heights"), GTK_ORIENTATION_VERTICAL);
1880 pref_label_new(group, _("NOTE! Geeqie must be restarted for changes to take effect"));
1881 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1882 pref_spin_new_int(hbox, _("Keywords:"), NULL,
1884 options->info_keywords.height, &c_options->info_keywords.height);
1885 pref_spin_new_int(hbox, _("Title:"), NULL,
1887 options->info_title.height, &c_options->info_title.height);
1888 pref_spin_new_int(hbox, _("Comment:"), NULL,
1890 options->info_comment.height, &c_options->info_comment.height);
1891 pref_spin_new_int(hbox, _("Rating:"), NULL,
1893 options->info_rating.height, &c_options->info_rating.height);
1895 group = pref_group_new(vbox, FALSE, _("Show predefined keyword tree"), GTK_ORIENTATION_VERTICAL);
1897 pref_checkbox_new_int(group, _("Show predefined keyword tree (NOTE! Geeqie must be restarted for change to take effect)"),
1898 options->show_predefined_keyword_tree, &c_options->show_predefined_keyword_tree);
1900 group = pref_group_new(vbox, FALSE, _("On-line help search engine"), GTK_ORIENTATION_VERTICAL);
1902 help_search_engine_entry = gtk_entry_new();
1903 gtk_entry_set_text(GTK_ENTRY(help_search_engine_entry), options->help_search_engine);
1904 gtk_box_pack_start(GTK_BOX(group), help_search_engine_entry, FALSE, FALSE, 0);
1905 gtk_widget_show(help_search_engine_entry);
1907 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"));
1909 gtk_entry_set_icon_from_stock(GTK_ENTRY(help_search_engine_entry),
1910 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1911 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(help_search_engine_entry),
1912 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1913 gtk_entry_set_icon_from_stock(GTK_ENTRY(help_search_engine_entry),
1914 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1915 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(help_search_engine_entry),
1916 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1917 g_signal_connect(GTK_ENTRY(help_search_engine_entry), "icon-press",
1918 G_CALLBACK(help_search_engine_entry_icon_cb),
1919 help_search_engine_entry);
1923 static void config_tab_image(GtkWidget *notebook)
1928 GtkWidget *ct_button;
1929 GtkWidget *enlargement_button;
1933 vbox = scrolled_notebook_page(notebook, _("Image"));
1935 group = pref_group_new(vbox, FALSE, _("Zoom"), GTK_ORIENTATION_VERTICAL);
1937 table = pref_table_new(group, 2, 1, FALSE, FALSE);
1938 add_quality_menu(table, 0, 0, _("Quality:"), options->image.zoom_quality, &c_options->image.zoom_quality);
1941 pref_checkbox_new_int(group, _("Use GPU acceleration via Clutter library"),
1942 options->image.use_clutter_renderer, &c_options->image.use_clutter_renderer);
1945 pref_checkbox_new_int(group, _("Two pass rendering (apply HQ zoom and color correction in second pass)"),
1946 options->image.zoom_2pass, &c_options->image.zoom_2pass);
1948 c_options->image.zoom_increment = options->image.zoom_increment;
1949 spin = pref_spin_new(group, _("Zoom increment:"), NULL,
1950 0.01, 4.0, 0.01, 2, (gdouble)options->image.zoom_increment / 100.0,
1951 G_CALLBACK(zoom_increment_cb), NULL);
1952 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1954 group = pref_group_new(vbox, FALSE, _("Fit image to window"), GTK_ORIENTATION_VERTICAL);
1956 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1957 enlargement_button = pref_checkbox_new_int(hbox, _("Allow enlargement of image (max. size in %)"),
1958 options->image.zoom_to_fit_allow_expand, &c_options->image.zoom_to_fit_allow_expand);
1959 spin = pref_spin_new_int(hbox, NULL, NULL,
1961 options->image.max_enlargement_size, &c_options->image.max_enlargement_size);
1962 pref_checkbox_link_sensitivity(enlargement_button, spin);
1963 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."));
1965 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1966 ct_button = pref_checkbox_new_int(hbox, _("Virtual window size (% of actual window):"),
1967 options->image.limit_autofit_size, &c_options->image.limit_autofit_size);
1968 spin = pref_spin_new_int(hbox, NULL, NULL,
1970 options->image.max_autofit_size, &c_options->image.max_autofit_size);
1971 pref_checkbox_link_sensitivity(ct_button, spin);
1972 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."));
1974 group = pref_group_new(vbox, FALSE, _("Appearance"), GTK_ORIENTATION_VERTICAL);
1976 pref_checkbox_new_int(group, _("Use custom border color in window mode"),
1977 options->image.use_custom_border_color, &c_options->image.use_custom_border_color);
1979 pref_checkbox_new_int(group, _("Use custom border color in fullscreen mode"),
1980 options->image.use_custom_border_color_in_fullscreen, &c_options->image.use_custom_border_color_in_fullscreen);
1982 pref_color_button_new(group, _("Border color"), &options->image.border_color,
1983 G_CALLBACK(pref_color_button_set_cb), &c_options->image.border_color);
1985 c_options->image.border_color = options->image.border_color;
1987 pref_color_button_new(group, _("Alpha channel color 1"), &options->image.alpha_color_1,
1988 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_1);
1990 pref_color_button_new(group, _("Alpha channel color 2"), &options->image.alpha_color_2,
1991 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_2);
1993 c_options->image.alpha_color_1 = options->image.alpha_color_1;
1994 c_options->image.alpha_color_2 = options->image.alpha_color_2;
1996 group = pref_group_new(vbox, FALSE, _("Convenience"), GTK_ORIENTATION_VERTICAL);
1998 pref_checkbox_new_int(group, _("Auto rotate proofs using Exif information"),
1999 options->image.exif_proof_rotate_enable, &c_options->image.exif_proof_rotate_enable);
2003 static void config_tab_windows(GtkWidget *notebook)
2009 GtkWidget *ct_button;
2012 vbox = scrolled_notebook_page(notebook, _("Windows"));
2014 group = pref_group_new(vbox, FALSE, _("State"), GTK_ORIENTATION_VERTICAL);
2016 ct_button = pref_checkbox_new_int(group, _("Remember window positions"),
2017 options->save_window_positions, &c_options->save_window_positions);
2019 button = pref_checkbox_new_int(group, _("Use saved window positions also for new windows"),
2020 options->use_saved_window_positions_for_new_windows, &c_options->use_saved_window_positions_for_new_windows);
2021 pref_checkbox_link_sensitivity(ct_button, button);
2023 pref_checkbox_new_int(group, _("Remember tool state (float/hidden)"),
2024 options->tools_restore_state, &c_options->tools_restore_state);
2026 pref_checkbox_new_int(group, _("Remember dialog window positions"),
2027 options->save_dialog_window_positions, &c_options->save_dialog_window_positions);
2029 pref_checkbox_new_int(group, _("Show window IDs"),
2030 options->show_window_ids, &c_options->show_window_ids);
2032 group = pref_group_new(vbox, FALSE, _("Size"), GTK_ORIENTATION_VERTICAL);
2034 pref_checkbox_new_int(group, _("Fit window to image when tools are hidden/floating"),
2035 options->image.fit_window_to_image, &c_options->image.fit_window_to_image);
2037 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2038 ct_button = pref_checkbox_new_int(hbox, _("Limit size when auto-sizing window (%):"),
2039 options->image.limit_window_size, &c_options->image.limit_window_size);
2040 spin = pref_spin_new_int(hbox, NULL, NULL,
2042 options->image.max_window_size, &c_options->image.max_window_size);
2043 pref_checkbox_link_sensitivity(ct_button, spin);
2045 group = pref_group_new(vbox, FALSE, _("Full screen"), GTK_ORIENTATION_VERTICAL);
2047 c_options->fullscreen.screen = options->fullscreen.screen;
2048 c_options->fullscreen.above = options->fullscreen.above;
2049 hbox = fullscreen_prefs_selection_new(_("Location:"), &c_options->fullscreen.screen, &c_options->fullscreen.above);
2050 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2051 gtk_widget_show(hbox);
2053 pref_checkbox_new_int(group, _("Smooth image flip"),
2054 options->fullscreen.clean_flip, &c_options->fullscreen.clean_flip);
2055 pref_checkbox_new_int(group, _("Disable screen saver"),
2056 options->fullscreen.disable_saver, &c_options->fullscreen.disable_saver);
2059 /* overlay screen display tab */
2060 static const gchar *predefined_tags[][2] = {
2061 {"%name%", N_("Name")},
2062 {"%path:60%*", N_("Path")},
2063 {"%date%", N_("Date")},
2064 {"%size%", N_("Size")},
2065 {"%zoom%", N_("Zoom")},
2066 {"%dimensions%", N_("Dimensions")},
2067 {"%collection%", N_("Collection")},
2068 {"%number%", N_("Collection number")},
2069 {"%total%", N_("Collection total")},
2070 {"%file.ctime%", N_("File ctime")},
2071 {"%file.mode%", N_("File mode")},
2072 {"%file.owner%", N_("File owner")},
2073 {"%file.group%", N_("File group")},
2074 {"%file.link%", N_("File link")},
2075 {"%file.class%", N_("File class")},
2076 {"%formatted.DateTime%", N_("Image date")},
2077 {"%formatted.DateTimeDigitized%", N_("Date digitized")},
2078 {"%formatted.ShutterSpeed%", N_("ShutterSpeed")},
2079 {"%formatted.Aperture%", N_("Aperture")},
2080 {"%formatted.ExposureBias%", N_("Exposure bias")},
2081 {"%formatted.Resolution%", N_("Resolution")},
2082 {"%formatted.Camera%", N_("Camera")},
2083 {"%formatted.ShutterSpeed%", N_("Shutter speed")},
2084 {"%formatted.ISOSpeedRating%", N_("ISO")},
2085 {"%formatted.FocalLength%", N_("Focal length")},
2086 {"%formatted.FocalLength35mmFilm%", N_("Focal len. 35mm")},
2087 {"%formatted.SubjectDistance%", N_("Subject distance")},
2088 {"%formatted.Flash%", N_("Flash")},
2089 {"%formatted.ColorProfile%", N_("Color profile")},
2090 {"%formatted.GPSPosition%", N_("Lat, Long")},
2091 {"%formatted.GPSAltitude%", N_("Altitude")},
2092 {"%formatted.localtime%", N_("Local time")},
2093 {"%formatted.timezone%", N_("Timezone")},
2094 {"%formatted.countryname%", N_("Country name")},
2095 {"%formatted.countrycode%", N_("Country code")},
2096 {"%formatted.star_rating%", N_("Star rating")},
2099 static GtkTargetEntry osd_drag_types[] = {
2100 { "text/plain", GTK_TARGET_SAME_APP, TARGET_TEXT_PLAIN }
2103 typedef struct _TagData TagData;
2110 static void tag_button_cb(GtkWidget *widget, gpointer data)
2112 GtkTextView *image_overlay_template_view = data;
2113 GtkTextBuffer *buffer;
2116 buffer = gtk_text_view_get_buffer(image_overlay_template_view);
2117 td = g_object_get_data(G_OBJECT(widget), "tag_data");
2118 gtk_text_buffer_insert_at_cursor(GTK_TEXT_BUFFER(buffer), td->key, -1);
2120 gtk_widget_grab_focus(GTK_WIDGET(image_overlay_template_view));
2123 static void osd_dnd_get_cb(GtkWidget *btn, GdkDragContext *context,
2124 GtkSelectionData *selection_data, guint info,
2125 guint time, gpointer data)
2128 GtkTextView *image_overlay_template_view = data;
2130 td = g_object_get_data(G_OBJECT(btn), "tag_data");
2131 gtk_selection_data_set_text(selection_data, td->key, -1);
2133 gtk_widget_grab_focus(GTK_WIDGET(image_overlay_template_view));
2136 static void osd_btn_destroy_cb(GtkWidget *btn, GdkDragContext *context,
2137 GtkSelectionData *selection_data, guint info,
2138 guint time, gpointer data)
2142 td = g_object_get_data(G_OBJECT(btn), "tag_data");
2147 static void set_osd_button(GtkWidget *widget, const gchar *key, const gchar *title,
2148 GtkWidget *image_overlay_template_view)
2150 GtkWidget *new_button;
2153 new_button = pref_button_new(widget, NULL, _(title), TRUE,
2154 G_CALLBACK(tag_button_cb), image_overlay_template_view);
2156 td = g_new0(TagData, 1);
2157 td->key = g_strdup(key);
2158 td->title = g_strdup(title);
2160 g_object_set_data(G_OBJECT(new_button), "tag_data", td);
2162 gtk_drag_source_set(new_button, GDK_BUTTON1_MASK, osd_drag_types, 1, GDK_ACTION_COPY);
2163 g_signal_connect(G_OBJECT(new_button), "drag_data_get",
2164 G_CALLBACK(osd_dnd_get_cb), image_overlay_template_view);
2165 g_signal_connect(G_OBJECT(new_button), "destroy",
2166 G_CALLBACK(osd_btn_destroy_cb), new_button);
2169 static void config_tab_osd(GtkWidget *notebook)
2173 GtkWidget *vbox_buttons;
2176 GtkWidget *image_overlay_template_view;
2177 GtkWidget *scrolled;
2178 GtkTextBuffer *buffer;
2180 GtkWidget * subgroup;
2185 vbox = scrolled_notebook_page(notebook, _("OSD"));
2187 image_overlay_template_view = gtk_text_view_new();
2189 group = pref_group_new(vbox, FALSE, _("Overlay Screen Display"), GTK_ORIENTATION_VERTICAL);
2191 hbox = gtk_hbox_new(FALSE, 0);
2193 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2194 gtk_widget_show(hbox);
2196 pref_label_new(hbox, _("To include predefined tags in the template, click a button or drag-and-drop"));
2198 subgroup = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
2199 hbox = gtk_hbox_new(FALSE, 0);
2200 gtk_box_pack_start(GTK_BOX(subgroup), hbox, FALSE, FALSE, 0);
2201 gtk_widget_show(hbox);
2203 for (cols = 0; cols < 6; cols++)
2205 vbox_buttons = gtk_vbox_new(FALSE, 0);
2208 gtk_box_pack_start(GTK_BOX(hbox), vbox_buttons, FALSE, FALSE, 0);
2210 while (rows < 6 && predefined_tags[i][0])
2212 set_osd_button(vbox_buttons, predefined_tags[i][0], predefined_tags[i][1], image_overlay_template_view);
2216 gtk_widget_show(vbox_buttons);
2219 pref_line(group, PREF_PAD_GAP);
2221 pref_label_new(group, _("Image overlay template"));
2223 scrolled = gtk_scrolled_window_new(NULL, NULL);
2224 gtk_widget_set_size_request(scrolled, 200, 150);
2225 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2226 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
2227 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2228 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 5);
2229 gtk_widget_show(scrolled);
2231 gtk_widget_set_tooltip_markup(image_overlay_template_view,
2232 _("Extensive formatting options are shown in the Help file"));
2234 gtk_container_add(GTK_CONTAINER(scrolled), image_overlay_template_view);
2235 gtk_widget_show(image_overlay_template_view);
2237 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2239 #if GTK_CHECK_VERSION(3,4,0)
2240 button = pref_button_new(NULL, GTK_STOCK_SELECT_FONT, _("Font"), FALSE,
2241 G_CALLBACK(image_overlay_set_font_cb), notebook);
2243 button = gtk_font_button_new();
2244 gtk_font_button_set_title(GTK_FONT_BUTTON(button), "Image Overlay Font");
2245 gtk_font_button_set_font_name(GTK_FONT_BUTTON(button), options->image_overlay.font);
2246 g_signal_connect(G_OBJECT(button), "font-set",
2247 G_CALLBACK(image_overlay_set_font_cb),NULL);
2249 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2250 gtk_widget_show(button);
2252 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Text"), FALSE,
2253 G_CALLBACK(image_overlay_set_text_colour_cb), NULL);
2254 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2255 gtk_widget_show(button);
2257 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Background"), FALSE,
2258 G_CALLBACK(image_overlay_set_background_colour_cb), NULL);
2259 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2260 gtk_widget_show(button);
2261 image_overlay_set_text_colours();
2263 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2264 G_CALLBACK(image_overlay_default_template_cb), image_overlay_template_view);
2265 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2266 gtk_widget_show(button);
2268 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
2269 G_CALLBACK(image_overlay_help_cb), NULL);
2270 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2271 gtk_widget_show(button);
2273 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(image_overlay_template_view));
2274 if (options->image_overlay.template_string) gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
2275 g_signal_connect(G_OBJECT(buffer), "changed",
2276 G_CALLBACK(image_overlay_template_view_changed_cb), image_overlay_template_view);
2278 pref_line(group, PREF_PAD_GAP);
2280 group = pref_group_new(vbox, FALSE, _("Exif, XMP or IPTC tags"), GTK_ORIENTATION_VERTICAL);
2281 hbox = gtk_hbox_new(FALSE, 0);
2282 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2283 gtk_widget_show(hbox);
2284 label = gtk_label_new(_("%Exif.Image.Orientation%"));
2285 gtk_box_pack_start(GTK_BOX(hbox),label, FALSE,FALSE,0);
2286 gtk_widget_show(label);
2287 pref_spacer(group,TRUE);
2289 group = pref_group_new(vbox, FALSE, _("Field separators"), GTK_ORIENTATION_VERTICAL);
2290 hbox = gtk_hbox_new(FALSE, 0);
2291 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2292 gtk_widget_show(hbox);
2293 label = gtk_label_new(_("Separator shown only if both fields are non-null:\n%formatted.ShutterSpeed%|%formatted.ISOSpeedRating%"));
2294 gtk_box_pack_start(GTK_BOX(hbox),label, FALSE,FALSE,0);
2295 gtk_widget_show(label);
2296 pref_spacer(group,TRUE);
2298 group = pref_group_new(vbox, FALSE, _("Field maximum length"), GTK_ORIENTATION_VERTICAL);
2299 hbox = gtk_hbox_new(FALSE, 0);
2300 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2301 gtk_widget_show(hbox);
2302 label = gtk_label_new(_("%path:39%"));
2303 gtk_box_pack_start(GTK_BOX(hbox),label, FALSE,FALSE,0);
2304 gtk_widget_show(label);
2305 pref_spacer(group,TRUE);
2307 group = pref_group_new(vbox, FALSE, _("Pre- and post- text"), GTK_ORIENTATION_VERTICAL);
2308 hbox = gtk_hbox_new(FALSE, 0);
2309 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2310 gtk_widget_show(hbox);
2311 label = gtk_label_new(_("Text shown only if the field is non-null:\n%formatted.Aperture:F no. * setting%\n %formatted.Aperture:10:F no. * setting%"));
2312 gtk_box_pack_start(GTK_BOX(hbox),label, FALSE,FALSE,0);
2313 gtk_widget_show(label);
2314 pref_spacer(group,TRUE);
2316 group = pref_group_new(vbox, FALSE, _("Pango markup"), GTK_ORIENTATION_VERTICAL);
2317 hbox = gtk_hbox_new(FALSE, 0);
2318 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2319 gtk_widget_show(hbox);
2320 label = gtk_label_new(_("<b>bold</b>\n<u>underline</u>\n<i>italic</i>\n<s>strikethrough</s>"));
2321 gtk_box_pack_start(GTK_BOX(hbox),label, FALSE,FALSE,0);
2322 gtk_widget_show(label);
2325 static GtkTreeModel *create_class_model(void)
2327 GtkListStore *model;
2331 /* create list store */
2332 model = gtk_list_store_new(1, G_TYPE_STRING);
2333 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
2335 gtk_list_store_append(model, &iter);
2336 gtk_list_store_set(model, &iter, 0, _(format_class_list[i]), -1);
2338 return GTK_TREE_MODEL (model);
2343 static void config_tab_files(GtkWidget *notebook)
2350 GtkWidget *ct_button;
2351 GtkWidget *scrolled;
2352 GtkWidget *filter_view;
2353 GtkCellRenderer *renderer;
2354 GtkTreeSelection *selection;
2355 GtkTreeViewColumn *column;
2357 vbox = scrolled_notebook_page(notebook, _("Files"));
2359 group = pref_box_new(vbox, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
2361 pref_checkbox_new_int(group, _("Show hidden files or folders"),
2362 options->file_filter.show_hidden_files, &c_options->file_filter.show_hidden_files);
2363 pref_checkbox_new_int(group, _("Show parent folder (..)"),
2364 options->file_filter.show_parent_directory, &c_options->file_filter.show_parent_directory);
2365 pref_checkbox_new_int(group, _("Case sensitive sort"),
2366 options->file_sort.case_sensitive, &c_options->file_sort.case_sensitive);
2367 pref_checkbox_new_int(group, _("Natural sort order"),
2368 options->file_sort.natural, &c_options->file_sort.natural);
2369 pref_checkbox_new_int(group, _("Disable file extension checks"),
2370 options->file_filter.disable_file_extension_checks, &c_options->file_filter.disable_file_extension_checks);
2372 ct_button = pref_checkbox_new_int(group, _("Disable File Filtering"),
2373 options->file_filter.disable, &c_options->file_filter.disable);
2376 group = pref_group_new(vbox, FALSE, _("Grouping sidecar extensions"), GTK_ORIENTATION_VERTICAL);
2378 sidecar_ext_entry = gtk_entry_new();
2379 gtk_entry_set_text(GTK_ENTRY(sidecar_ext_entry), options->sidecar.ext);
2380 gtk_box_pack_start(GTK_BOX(group), sidecar_ext_entry, FALSE, FALSE, 0);
2381 gtk_widget_show(sidecar_ext_entry);
2383 group = pref_group_new(vbox, TRUE, _("File types"), GTK_ORIENTATION_VERTICAL);
2385 frame = pref_group_parent(group);
2386 g_signal_connect(G_OBJECT(ct_button), "toggled",
2387 G_CALLBACK(filter_disable_cb), frame);
2388 gtk_widget_set_sensitive(frame, !options->file_filter.disable);
2390 scrolled = gtk_scrolled_window_new(NULL, NULL);
2391 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2392 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2393 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2394 gtk_widget_show(scrolled);
2396 filter_store = gtk_list_store_new(1, G_TYPE_POINTER);
2397 filter_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(filter_store));
2398 g_object_unref(filter_store);
2399 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
2400 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_SINGLE);
2402 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(filter_view), FALSE);
2404 column = gtk_tree_view_column_new();
2405 gtk_tree_view_column_set_title(column, _("Filter"));
2406 gtk_tree_view_column_set_resizable(column, TRUE);
2408 renderer = gtk_cell_renderer_toggle_new();
2409 g_signal_connect(G_OBJECT(renderer), "toggled",
2410 G_CALLBACK(filter_store_enable_cb), filter_store);
2411 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2412 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2413 GINT_TO_POINTER(FE_ENABLE), NULL);
2415 renderer = gtk_cell_renderer_text_new();
2416 g_signal_connect(G_OBJECT(renderer), "edited",
2417 G_CALLBACK(filter_store_ext_edit_cb), filter_store);
2418 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2419 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2420 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2421 GINT_TO_POINTER(FE_EXTENSION), NULL);
2422 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2424 column = gtk_tree_view_column_new();
2425 gtk_tree_view_column_set_title(column, _("Description"));
2426 gtk_tree_view_column_set_resizable(column, TRUE);
2427 gtk_tree_view_column_set_fixed_width(column, 200);
2428 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
2430 renderer = gtk_cell_renderer_text_new();
2431 g_signal_connect(G_OBJECT(renderer), "edited",
2432 G_CALLBACK(filter_store_desc_edit_cb), filter_store);
2433 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2434 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2435 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2436 GINT_TO_POINTER(FE_DESCRIPTION), NULL);
2437 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2439 column = gtk_tree_view_column_new();
2440 gtk_tree_view_column_set_title(column, _("Class"));
2441 gtk_tree_view_column_set_resizable(column, TRUE);
2442 renderer = gtk_cell_renderer_combo_new();
2443 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE,
2444 "model", create_class_model(),
2449 g_signal_connect(G_OBJECT(renderer), "edited",
2450 G_CALLBACK(filter_store_class_edit_cb), filter_store);
2451 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2452 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2453 GINT_TO_POINTER(FE_CLASS), NULL);
2454 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2456 column = gtk_tree_view_column_new();
2457 gtk_tree_view_column_set_title(column, _("Writable"));
2458 gtk_tree_view_column_set_resizable(column, FALSE);
2459 renderer = gtk_cell_renderer_toggle_new();
2460 g_signal_connect(G_OBJECT(renderer), "toggled",
2461 G_CALLBACK(filter_store_writable_cb), filter_store);
2462 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2463 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2464 GINT_TO_POINTER(FE_WRITABLE), NULL);
2465 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2467 column = gtk_tree_view_column_new();
2468 gtk_tree_view_column_set_title(column, _("Sidecar is allowed"));
2469 gtk_tree_view_column_set_resizable(column, FALSE);
2470 renderer = gtk_cell_renderer_toggle_new();
2471 g_signal_connect(G_OBJECT(renderer), "toggled",
2472 G_CALLBACK(filter_store_sidecar_cb), filter_store);
2473 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2474 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2475 GINT_TO_POINTER(FE_ALLOW_SIDECAR), NULL);
2476 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2479 filter_store_populate();
2480 gtk_container_add(GTK_CONTAINER(scrolled), filter_view);
2481 gtk_widget_show(filter_view);
2483 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2485 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2486 G_CALLBACK(filter_default_cb), filter_view);
2487 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2488 gtk_widget_show(button);
2490 button = pref_button_new(NULL, GTK_STOCK_REMOVE, NULL, FALSE,
2491 G_CALLBACK(filter_remove_cb), filter_view);
2492 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2493 gtk_widget_show(button);
2495 button = pref_button_new(NULL, GTK_STOCK_ADD, NULL, FALSE,
2496 G_CALLBACK(filter_add_cb), filter_view);
2497 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2498 gtk_widget_show(button);
2502 static void config_tab_metadata(GtkWidget *notebook)
2507 GtkWidget *ct_button;
2511 vbox = scrolled_notebook_page(notebook, _("Metadata"));
2514 group = pref_group_new(vbox, FALSE, _("Metadata writing process"), GTK_ORIENTATION_VERTICAL);
2516 label = pref_label_new(group, _("Warning: Geeqie is built without Exiv2. Some options are disabled."));
2518 label = pref_label_new(group, _("Metadata are written in the following order. The process ends after first success."));
2519 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2521 ct_button = pref_checkbox_new_int(group, _("1) Save metadata in image files, or sidecar files, according to the XMP standard"),
2522 options->metadata.save_in_image_file, &c_options->metadata.save_in_image_file);
2524 gtk_widget_set_sensitive(ct_button, FALSE);
2527 pref_checkbox_new_int(group, _("2) Save metadata in '.metadata' folder, local to image folder (non-standard)"),
2528 options->metadata.enable_metadata_dirs, &c_options->metadata.enable_metadata_dirs);
2530 text = g_strdup_printf(_("3) Save metadata in Geeqie private directory '%s'"), get_metadata_cache_dir());
2531 label = pref_label_new(group, text);
2532 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2533 gtk_misc_set_padding(GTK_MISC(label), 22, 0);
2536 group = pref_group_new(vbox, FALSE, _("Step 1: Write to image files"), GTK_ORIENTATION_VERTICAL);
2538 gtk_widget_set_sensitive(group, FALSE);
2541 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2542 pref_checkbox_link_sensitivity(ct_button, hbox);
2544 pref_checkbox_new_int(hbox, _("Store metadata also in legacy IPTC tags (converted according to IPTC4XMP standard)"),
2545 options->metadata.save_legacy_IPTC, &c_options->metadata.save_legacy_IPTC);
2547 pref_checkbox_new_int(hbox, _("Warn if the image files are unwritable"),
2548 options->metadata.warn_on_write_problems, &c_options->metadata.warn_on_write_problems);
2550 pref_checkbox_new_int(hbox, _("Ask before writing to image files"),
2551 options->metadata.confirm_write, &c_options->metadata.confirm_write);
2553 pref_checkbox_new_int(hbox, _("Create sidecar files named image.ext.xmp (as opposed to image.xmp)"),
2554 options->metadata.sidecar_extended_name, &c_options->metadata.sidecar_extended_name);
2556 group = pref_group_new(vbox, FALSE, _("Step 2 and 3: write to Geeqie private files"), GTK_ORIENTATION_VERTICAL);
2558 gtk_widget_set_sensitive(group, FALSE);
2561 pref_checkbox_new_int(group, _("Use GQview legacy metadata format (supports only keywords and comments) instead of XMP"),
2562 options->metadata.save_legacy_format, &c_options->metadata.save_legacy_format);
2565 group = pref_group_new(vbox, FALSE, _("Miscellaneous"), GTK_ORIENTATION_VERTICAL);
2566 pref_checkbox_new_int(group, _("Write the same description tags (keywords, comment, etc.) to all grouped sidecars"),
2567 options->metadata.sync_grouped_files, &c_options->metadata.sync_grouped_files);
2569 pref_checkbox_new_int(group, _("Allow keywords to differ only in case"),
2570 options->metadata.keywords_case_sensitive, &c_options->metadata.keywords_case_sensitive);
2572 ct_button = pref_checkbox_new_int(group, _("Write altered image orientation to the metadata"),
2573 options->metadata.write_orientation, &c_options->metadata.write_orientation);
2575 gtk_widget_set_sensitive(ct_button, FALSE);
2578 group = pref_group_new(vbox, FALSE, _("Auto-save options"), GTK_ORIENTATION_VERTICAL);
2580 ct_button = pref_checkbox_new_int(group, _("Write metadata after timeout"),
2581 options->metadata.confirm_after_timeout, &c_options->metadata.confirm_after_timeout);
2583 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2584 pref_checkbox_link_sensitivity(ct_button, hbox);
2586 pref_spin_new_int(hbox, _("Timeout (seconds):"), NULL, 0, 900, 1,
2587 options->metadata.confirm_timeout, &c_options->metadata.confirm_timeout);
2589 pref_checkbox_new_int(group, _("Write metadata on image change"),
2590 options->metadata.confirm_on_image_change, &c_options->metadata.confirm_on_image_change);
2592 pref_checkbox_new_int(group, _("Write metadata on directory change"),
2593 options->metadata.confirm_on_dir_change, &c_options->metadata.confirm_on_dir_change);
2595 group = pref_group_new(vbox, FALSE, _("Pre-load metadata"), GTK_ORIENTATION_VERTICAL);
2597 ct_button = pref_checkbox_new_int(group, _("Read metadata in background"),
2598 options->read_metadata_in_idle, &c_options->read_metadata_in_idle);
2599 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");
2604 typedef struct _KeywordFindData KeywordFindData;
2605 struct _KeywordFindData
2612 GtkWidget *button_close;
2613 GtkWidget *button_stop;
2614 GtkWidget *button_start;
2615 GtkWidget *progress;
2623 guint idle_id; /* event source id */
2626 #define KEYWORD_DIALOG_WIDTH 400
2628 static void keywords_find_folder(KeywordFindData *kfd, FileData *dir_fd)
2630 GList *list_d = NULL;
2631 GList *list_f = NULL;
2635 filelist_read(dir_fd, &list_f, &list_d);
2639 filelist_read(dir_fd, &list_f, NULL);
2642 list_f = filelist_filter(list_f, FALSE);
2643 list_d = filelist_filter(list_d, TRUE);
2645 kfd->list = g_list_concat(list_f, kfd->list);
2646 kfd->list_dir = g_list_concat(list_d, kfd->list_dir);
2649 static void keywords_find_reset(KeywordFindData *kfd)
2651 filelist_free(kfd->list);
2654 filelist_free(kfd->list_dir);
2655 kfd->list_dir = NULL;
2658 static void keywords_find_close_cb(GenericDialog *fd, gpointer data)
2660 KeywordFindData *kfd = data;
2662 if (!gtk_widget_get_sensitive(kfd->button_close)) return;
2664 keywords_find_reset(kfd);
2665 generic_dialog_close(kfd->gd);
2669 static void keywords_find_finish(KeywordFindData *kfd)
2671 keywords_find_reset(kfd);
2673 gtk_entry_set_text(GTK_ENTRY(kfd->progress), _("done"));
2674 spinner_set_interval(kfd->spinner, -1);
2676 gtk_widget_set_sensitive(kfd->group, TRUE);
2677 gtk_widget_set_sensitive(kfd->button_start, TRUE);
2678 gtk_widget_set_sensitive(kfd->button_stop, FALSE);
2679 gtk_widget_set_sensitive(kfd->button_close, TRUE);
2682 static void keywords_find_stop_cb(GenericDialog *fd, gpointer data)
2684 KeywordFindData *kfd = data;
2686 g_idle_remove_by_data(kfd);
2688 keywords_find_finish(kfd);
2691 static gboolean keywords_find_file(gpointer data)
2693 KeywordFindData *kfd = data;
2695 GtkTextBuffer *buffer;
2703 fd = kfd->list->data;
2704 kfd->list = g_list_remove(kfd->list, fd);
2706 keywords = metadata_read_list(fd, KEYWORD_KEY, METADATA_PLAIN);
2707 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(keyword_text));
2711 gtk_text_buffer_get_end_iter(buffer, &iter);
2712 tmp = g_strconcat(keywords->data, "\n", NULL);
2713 gtk_text_buffer_insert(buffer, &iter, tmp, -1);
2715 keywords = keywords->next;
2718 gtk_entry_set_text(GTK_ENTRY(kfd->progress), fd->path);
2719 file_data_unref(fd);
2720 string_list_free(keywords);
2724 else if (kfd->list_dir)
2728 fd = kfd->list_dir->data;
2729 kfd->list_dir = g_list_remove(kfd->list_dir, fd);
2731 keywords_find_folder(kfd, fd);
2733 file_data_unref(fd);
2738 keywords_find_finish(kfd);
2743 static void keywords_find_start_cb(GenericDialog *fd, gpointer data)
2745 KeywordFindData *kfd = data;
2748 if (kfd->list || !gtk_widget_get_sensitive(kfd->button_start)) return;
2750 path = remove_trailing_slash((gtk_entry_get_text(GTK_ENTRY(kfd->entry))));
2751 parse_out_relatives(path);
2755 warning_dialog(_("Invalid folder"),
2756 _("The specified folder can not be found."),
2757 GTK_STOCK_DIALOG_WARNING, kfd->gd->dialog);
2763 gtk_widget_set_sensitive(kfd->group, FALSE);
2764 gtk_widget_set_sensitive(kfd->button_start, FALSE);
2765 gtk_widget_set_sensitive(kfd->button_stop, TRUE);
2766 gtk_widget_set_sensitive(kfd->button_close, FALSE);
2767 spinner_set_interval(kfd->spinner, SPINNER_SPEED);
2769 dir_fd = file_data_new_dir(path);
2770 keywords_find_folder(kfd, dir_fd);
2771 file_data_unref(dir_fd);
2772 kfd->idle_id = g_idle_add(keywords_find_file, kfd);
2778 static void keywords_find_dialog(GtkWidget *widget, const gchar *path)
2780 KeywordFindData *kfd;
2784 kfd = g_new0(KeywordFindData, 1);
2786 kfd->gd = generic_dialog_new(_("Search for keywords"),
2787 "search_for_keywords",
2790 gtk_window_set_default_size(GTK_WINDOW(kfd->gd->dialog), KEYWORD_DIALOG_WIDTH, -1);
2791 kfd->gd->cancel_cb = keywords_find_close_cb;
2792 kfd->button_close = generic_dialog_add_button(kfd->gd, GTK_STOCK_CLOSE, NULL,
2793 keywords_find_close_cb, FALSE);
2794 kfd->button_start = generic_dialog_add_button(kfd->gd, GTK_STOCK_OK, _("S_tart"),
2795 keywords_find_start_cb, FALSE);
2796 kfd->button_stop = generic_dialog_add_button(kfd->gd, GTK_STOCK_STOP, NULL,
2797 keywords_find_stop_cb, FALSE);
2798 gtk_widget_set_sensitive(kfd->button_stop, FALSE);
2800 generic_dialog_add_message(kfd->gd, NULL, _("Search for keywords"), NULL, FALSE);
2802 hbox = pref_box_new(kfd->gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, 0);
2803 pref_spacer(hbox, PREF_PAD_INDENT);
2804 kfd->group = pref_box_new(hbox, TRUE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
2806 hbox = pref_box_new(kfd->group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2807 pref_label_new(hbox, _("Folder:"));
2809 label = tab_completion_new(&kfd->entry, path, NULL, NULL, NULL, NULL);
2810 tab_completion_add_select_button(kfd->entry,_("Select folder") , TRUE);
2811 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
2812 gtk_widget_show(label);
2814 pref_checkbox_new_int(kfd->group, _("Include subfolders"), FALSE, &kfd->recurse);
2816 pref_line(kfd->gd->vbox, PREF_PAD_SPACE);
2817 hbox = pref_box_new(kfd->gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2819 kfd->progress = gtk_entry_new();
2820 gtk_widget_set_can_focus(kfd->progress, FALSE);
2821 gtk_editable_set_editable(GTK_EDITABLE(kfd->progress), FALSE);
2822 gtk_entry_set_text(GTK_ENTRY(kfd->progress), _("click start to begin"));
2823 gtk_box_pack_start(GTK_BOX(hbox), kfd->progress, TRUE, TRUE, 0);
2824 gtk_widget_show(kfd->progress);
2826 kfd->spinner = spinner_new(NULL, -1);
2827 gtk_box_pack_start(GTK_BOX(hbox), kfd->spinner, FALSE, FALSE, 0);
2828 gtk_widget_show(kfd->spinner);
2832 gtk_widget_show(kfd->gd->dialog);
2835 static void keywords_find_cb(GtkWidget *widget, gpointer data)
2837 const gchar *path = layout_get_path(NULL);
2839 if (!path || !*path) path = homedir();
2840 keywords_find_dialog(widget, path);
2843 static void config_tab_keywords_save()
2845 GtkTextIter start, end;
2846 GtkTextBuffer *buffer;
2847 GList *kw_list = NULL;
2853 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(keyword_text));
2854 gtk_text_buffer_get_bounds(buffer, &start, &end);
2856 buffer_text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
2858 kw_split = strtok(buffer_text, "\n");
2859 while (kw_split != NULL)
2865 if (g_strcmp0(work->data, kw_split) == 0)
2874 kw_list = g_list_append(kw_list, g_strdup(kw_split));
2876 kw_split = strtok(NULL, "\n");
2879 keyword_list_set(kw_list);
2881 string_list_free(kw_list);
2882 g_free(buffer_text);
2885 static void config_tab_keywords(GtkWidget *notebook)
2891 GtkWidget *scrolled;
2893 GtkTextBuffer *buffer;
2896 vbox = scrolled_notebook_page(notebook, _("Keywords"));
2898 group = pref_group_new(vbox, TRUE, _("Edit keywords autocompletion list"), GTK_ORIENTATION_VERTICAL);
2900 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2902 button = pref_button_new(hbox, GTK_STOCK_EXECUTE, _("Search"), FALSE,
2903 G_CALLBACK(keywords_find_cb), keyword_text);
2904 gtk_widget_set_tooltip_text(button, "Search for existing keywords");
2907 keyword_text = gtk_text_view_new();
2908 gtk_widget_set_size_request(keyword_text, 20, 20);
2909 scrolled = gtk_scrolled_window_new(NULL, NULL);
2910 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2911 gtk_widget_show(scrolled);
2913 gtk_container_add(GTK_CONTAINER(scrolled), keyword_text);
2914 gtk_widget_show(keyword_text);
2916 gtk_text_view_set_editable(GTK_TEXT_VIEW(keyword_text), TRUE);
2918 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(keyword_text));
2919 gtk_text_buffer_create_tag(buffer, "monospace",
2920 "family", "monospace", NULL);
2922 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(keyword_text), GTK_WRAP_WORD);
2923 gtk_text_buffer_get_start_iter(buffer, &iter);
2924 gtk_text_buffer_create_mark(buffer, "end", &iter, FALSE);
2927 path = g_build_filename(get_rc_dir(), "keywords", NULL);
2929 GList *kwl = keyword_list_get();
2930 kwl = g_list_first(kwl);
2933 gtk_text_buffer_get_end_iter (buffer, &iter);
2934 tmp = g_strconcat(kwl->data, "\n", NULL);
2935 gtk_text_buffer_insert(buffer, &iter, tmp, -1);
2940 gtk_text_buffer_set_modified(buffer, FALSE);
2947 static void intent_menu_cb(GtkWidget *combo, gpointer data)
2949 gint *option = data;
2951 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
2955 *option = INTENT_PERCEPTUAL;
2958 *option = INTENT_RELATIVE_COLORIMETRIC;
2961 *option = INTENT_SATURATION;
2964 *option = INTENT_ABSOLUTE_COLORIMETRIC;
2969 static void add_intent_menu(GtkWidget *table, gint column, gint row, const gchar *text,
2970 gint option, gint *option_c)
2977 pref_table_label(table, column, row, text, 0.0);
2979 combo = gtk_combo_box_text_new();
2981 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Perceptual"));
2982 if (option == INTENT_PERCEPTUAL) current = 0;
2983 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Relative Colorimetric"));
2984 if (option == INTENT_RELATIVE_COLORIMETRIC) current = 1;
2985 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Saturation"));
2986 if (option == INTENT_SATURATION) current = 2;
2987 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Absolute Colorimetric"));
2988 if (option == INTENT_ABSOLUTE_COLORIMETRIC) current = 3;
2990 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
2992 gtk_widget_set_tooltip_text(combo,"Refer to the lcms documentation for the defaults used when the selected Intent is not available");
2994 g_signal_connect(G_OBJECT(combo), "changed",
2995 G_CALLBACK(intent_menu_cb), option_c);
2997 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
2998 GTK_EXPAND | GTK_FILL, 0, 0, 0);
2999 gtk_widget_show(combo);
3003 static void config_tab_color(GtkWidget *notebook)
3012 vbox = scrolled_notebook_page(notebook, _("Color management"));
3014 group = pref_group_new(vbox, FALSE, _("Input profiles"), GTK_ORIENTATION_VERTICAL);
3016 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
3019 table = pref_table_new(group, 3, COLOR_PROFILE_INPUTS + 1, FALSE, FALSE);
3020 gtk_table_set_col_spacings(GTK_TABLE(table), PREF_PAD_GAP);
3022 label = pref_table_label(table, 0, 0, _("Type"), 0.0);
3023 pref_label_bold(label, TRUE, FALSE);
3025 label = pref_table_label(table, 1, 0, _("Menu name"), 0.0);
3026 pref_label_bold(label, TRUE, FALSE);
3028 label = pref_table_label(table, 2, 0, _("File"), 0.0);
3029 pref_label_bold(label, TRUE, FALSE);
3031 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
3036 buf = g_strdup_printf(_("Input %d:"), i + COLOR_PROFILE_FILE);
3037 pref_table_label(table, 0, i + 1, buf, 1.0);
3040 entry = gtk_entry_new();
3041 gtk_entry_set_max_length(GTK_ENTRY(entry), EDITOR_NAME_MAX_LENGTH);
3042 if (options->color_profile.input_name[i])
3044 gtk_entry_set_text(GTK_ENTRY(entry), options->color_profile.input_name[i]);
3046 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, i + 1, i + 2,
3047 GTK_FILL | GTK_EXPAND, 0, 0, 0);
3048 gtk_widget_show(entry);
3049 color_profile_input_name_entry[i] = entry;
3051 tabcomp = tab_completion_new(&entry, options->color_profile.input_file[i], NULL, ".icc", "ICC Files", NULL);
3052 tab_completion_add_select_button(entry, _("Select color profile"), FALSE);
3053 gtk_widget_set_size_request(entry, 160, -1);
3054 gtk_table_attach(GTK_TABLE(table), tabcomp, 2, 3, i + 1, i + 2,
3055 GTK_FILL | GTK_EXPAND, 0, 0, 0);
3056 gtk_widget_show(tabcomp);
3057 color_profile_input_file_entry[i] = entry;
3060 group = pref_group_new(vbox, FALSE, _("Screen profile"), GTK_ORIENTATION_VERTICAL);
3062 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
3064 pref_checkbox_new_int(group, _("Use system screen profile if available"),
3065 options->color_profile.use_x11_screen_profile, &c_options->color_profile.use_x11_screen_profile);
3067 table = pref_table_new(group, 2, 1, FALSE, FALSE);
3069 pref_table_label(table, 0, 0, _("Screen:"), 1.0);
3070 tabcomp = tab_completion_new(&color_profile_screen_file_entry,
3071 options->color_profile.screen_file, NULL, ".icc", "ICC Files", NULL);
3072 tab_completion_add_select_button(color_profile_screen_file_entry, _("Select color profile"), FALSE);
3073 gtk_widget_set_size_request(color_profile_screen_file_entry, 160, -1);
3075 add_intent_menu(table, 0, 1, _("Render Intent:"), options->color_profile.render_intent, &c_options->color_profile.render_intent);
3077 gtk_table_attach(GTK_TABLE(table), tabcomp, 1, 2,
3079 GTK_FILL | GTK_EXPAND, 0, 0, 0);
3081 gtk_widget_show(tabcomp);
3084 /* advanced entry tab */
3085 static void use_geeqie_trash_cb(GtkWidget *widget, gpointer data)
3087 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
3089 c_options->file_ops.use_system_trash = FALSE;
3093 static void use_system_trash_cb(GtkWidget *widget, gpointer data)
3095 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
3097 c_options->file_ops.use_system_trash = TRUE;
3101 static void config_tab_behavior(GtkWidget *notebook)
3108 GtkWidget *ct_button;
3112 GtkWidget *with_rename;
3113 GtkWidget *collections_on_top;
3115 vbox = scrolled_notebook_page(notebook, _("Behavior"));
3117 group = pref_group_new(vbox, FALSE, _("Delete"), GTK_ORIENTATION_VERTICAL);
3119 pref_checkbox_new_int(group, _("Confirm permanent file delete"),
3120 options->file_ops.confirm_delete, &c_options->file_ops.confirm_delete);
3121 pref_checkbox_new_int(group, _("Confirm move file to Trash"),
3122 options->file_ops.confirm_move_to_trash, &c_options->file_ops.confirm_move_to_trash);
3123 pref_checkbox_new_int(group, _("Enable Delete key"),
3124 options->file_ops.enable_delete_key, &c_options->file_ops.enable_delete_key);
3126 ct_button = pref_radiobutton_new(group, NULL, _("Use Geeqie trash location"),
3127 !options->file_ops.use_system_trash, G_CALLBACK(use_geeqie_trash_cb),NULL);
3129 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
3130 pref_checkbox_link_sensitivity(ct_button, hbox);
3132 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_SPACE);
3133 pref_label_new(hbox, _("Folder:"));
3135 tabcomp = tab_completion_new(&safe_delete_path_entry, options->file_ops.safe_delete_path, NULL, NULL, NULL, NULL);
3136 tab_completion_add_select_button(safe_delete_path_entry, NULL, TRUE);
3137 gtk_box_pack_start(GTK_BOX(hbox), tabcomp, TRUE, TRUE, 0);
3138 gtk_widget_show(tabcomp);
3140 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
3141 pref_checkbox_link_sensitivity(ct_button, hbox);
3143 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_GAP);
3144 spin = pref_spin_new_int(hbox, _("Maximum size:"), _("MB"),
3145 0, 2048, 1, options->file_ops.safe_delete_folder_maxsize, &c_options->file_ops.safe_delete_folder_maxsize);
3146 gtk_widget_set_tooltip_markup(spin, _("Set to 0 for unlimited size"));
3147 button = pref_button_new(NULL, NULL, _("View"), FALSE,
3148 G_CALLBACK(safe_delete_view_cb), NULL);
3149 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
3150 gtk_widget_show(button);
3152 button = pref_button_new(NULL, GTK_STOCK_CLEAR, NULL, FALSE,
3153 G_CALLBACK(safe_delete_clear_cb), NULL);
3154 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
3155 pref_radiobutton_new(group, ct_button, _("Use system Trash bin"),
3156 options->file_ops.use_system_trash, G_CALLBACK(use_system_trash_cb), NULL);
3157 gtk_widget_show(button);
3159 pref_spacer(group, PREF_PAD_GROUP);
3162 group = pref_group_new(vbox, FALSE, _("Behavior"), GTK_ORIENTATION_VERTICAL);
3164 pref_checkbox_new_int(group, _("Descend folders in tree view"),
3165 options->tree_descend_subdirs, &c_options->tree_descend_subdirs);
3167 pref_checkbox_new_int(group, _("In place renaming"),
3168 options->file_ops.enable_in_place_rename, &c_options->file_ops.enable_in_place_rename);
3170 pref_checkbox_new_int(group, _("List directory view uses single click to enter"),
3171 options->view_dir_list_single_click_enter, &c_options->view_dir_list_single_click_enter);
3173 marks = pref_checkbox_new_int(group, _("Save marks on exit"),
3174 options->marks_save, &c_options->marks_save);
3175 gtk_widget_set_tooltip_text(marks,"Note that marks linked to a keyword will be saved irrespective of this setting");
3177 with_rename = pref_checkbox_new_int(group, _("Use \"With Rename\" as default for Copy/Move dialogs"),
3178 options->with_rename, &c_options->with_rename);
3179 gtk_widget_set_tooltip_text(with_rename,"Change the default button for Copy/Move dialogs");
3181 collections_on_top = pref_checkbox_new_int(group, _("Open collections on top"),
3182 options->collections_on_top, &c_options->collections_on_top);
3183 gtk_widget_set_tooltip_text(collections_on_top,"Open collections window on top");
3185 pref_spin_new_int(group, _("Recent folder list maximum size"), NULL,
3186 1, 50, 1, options->open_recent_list_maxsize, &c_options->open_recent_list_maxsize);
3188 pref_spin_new_int(group, _("Drag'n drop icon size"), NULL,
3189 16, 256, 16, options->dnd_icon_size, &c_options->dnd_icon_size);
3191 table = pref_table_new(group, 2, 1, FALSE, FALSE);
3192 add_clipboard_selection_menu(table, 0, 0, _("Copy path clipboard selection:"), options->clipboard_selection, &c_options->clipboard_selection);
3194 pref_spacer(group, PREF_PAD_GROUP);
3196 group = pref_group_new(vbox, FALSE, _("Navigation"), GTK_ORIENTATION_VERTICAL);
3198 pref_checkbox_new_int(group, _("Progressive keyboard scrolling"),
3199 options->progressive_key_scrolling, &c_options->progressive_key_scrolling);
3200 pref_spin_new_int(group, _("Keyboard scrolling step multiplier:"), NULL,
3201 1, 32, 1, options->keyboard_scroll_step, (int *)&c_options->keyboard_scroll_step);
3202 pref_checkbox_new_int(group, _("Mouse wheel scrolls image"),
3203 options->mousewheel_scrolls, &c_options->mousewheel_scrolls);
3204 pref_checkbox_new_int(group, _("Navigation by left or middle click on image"),
3205 options->image_lm_click_nav, &c_options->image_lm_click_nav);
3206 pref_checkbox_new_int(group, _("Play video by left click on image"),
3207 options->image_l_click_video, &c_options->image_l_click_video);
3208 table = pref_table_new(group, 2, 1, FALSE, FALSE);
3209 add_video_menu(table, 0, 0, _("Play with:"), options->image_l_click_video_editor, &c_options->image_l_click_video_editor);
3213 pref_spacer(group, PREF_PAD_GROUP);
3215 group = pref_group_new(vbox, FALSE, _("Debugging"), GTK_ORIENTATION_VERTICAL);
3217 pref_spin_new_int(group, _("Debug level:"), NULL,
3218 DEBUG_LEVEL_MIN, DEBUG_LEVEL_MAX, 1, get_debug_level(), &debug_c);
3220 pref_checkbox_new_int(group, _("Timer data"),
3221 options->log_window.timer_data, &c_options->log_window.timer_data);
3223 pref_spin_new_int(group, _("Log Window max. lines:"), NULL,
3224 1, 99999, 1, options->log_window_lines, &options->log_window_lines);
3228 /* accelerators tab */
3229 static void config_tab_accelerators(GtkWidget *notebook)
3235 GtkWidget *scrolled;
3236 GtkWidget *accel_view;
3237 GtkCellRenderer *renderer;
3238 GtkTreeSelection *selection;
3239 GtkTreeViewColumn *column;
3241 vbox = scrolled_notebook_page(notebook, _("Keyboard"));
3243 group = pref_group_new(vbox, TRUE, _("Accelerators"), GTK_ORIENTATION_VERTICAL);
3245 scrolled = gtk_scrolled_window_new(NULL, NULL);
3246 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
3247 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
3248 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
3249 gtk_widget_show(scrolled);
3251 accel_store = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
3253 accel_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(accel_store));
3254 g_object_unref(accel_store);
3255 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(accel_view));
3256 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_MULTIPLE);
3258 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(accel_view), FALSE);
3260 renderer = gtk_cell_renderer_text_new();
3262 column = gtk_tree_view_column_new_with_attributes(_("Action"),
3267 gtk_tree_view_column_set_sort_column_id(column, AE_ACTION);
3268 gtk_tree_view_column_set_resizable(column, TRUE);
3269 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
3272 renderer = gtk_cell_renderer_accel_new();
3273 g_signal_connect(G_OBJECT(renderer), "accel-cleared",
3274 G_CALLBACK(accel_store_cleared_cb), accel_store);
3275 g_signal_connect(G_OBJECT(renderer), "accel-edited",
3276 G_CALLBACK(accel_store_edited_cb), accel_store);
3279 g_object_set (renderer,
3281 "accel-mode", GTK_CELL_RENDERER_ACCEL_MODE_OTHER,
3284 column = gtk_tree_view_column_new_with_attributes(_("KEY"),
3289 gtk_tree_view_column_set_sort_column_id(column, AE_KEY);
3290 gtk_tree_view_column_set_resizable(column, TRUE);
3291 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
3293 renderer = gtk_cell_renderer_text_new();
3295 column = gtk_tree_view_column_new_with_attributes(_("Tooltip"),
3300 gtk_tree_view_column_set_sort_column_id(column, AE_TOOLTIP);
3301 gtk_tree_view_column_set_resizable(column, TRUE);
3302 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
3304 renderer = gtk_cell_renderer_text_new();
3306 column = gtk_tree_view_column_new_with_attributes("Accel",
3311 gtk_tree_view_column_set_sort_column_id(column, AE_ACCEL);
3312 gtk_tree_view_column_set_resizable(column, TRUE);
3313 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
3315 accel_store_populate();
3316 gtk_container_add(GTK_CONTAINER(scrolled), accel_view);
3317 gtk_widget_show(accel_view);
3319 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
3321 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
3322 G_CALLBACK(accel_default_cb), accel_view);
3323 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
3324 gtk_widget_show(button);
3326 button = pref_button_new(NULL, NULL, _("Reset selected"), FALSE,
3327 G_CALLBACK(accel_reset_cb), accel_view);
3328 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
3329 gtk_widget_show(button);
3333 static void config_tab_toolbar(GtkWidget *notebook)
3336 GtkWidget *toolbardata;
3339 lw = layout_window_list->data;
3341 vbox = scrolled_notebook_page(notebook, _("Toolbar"));
3343 toolbardata = toolbar_select_new(lw);
3344 gtk_box_pack_start(GTK_BOX(vbox), toolbardata, TRUE, TRUE, 0);
3345 gtk_widget_show(vbox);
3349 static void config_tab_stereo(GtkWidget *notebook)
3357 GtkWidget *fs_button;
3358 vbox = scrolled_notebook_page(notebook, _("Stereo"));
3360 group = pref_group_new(vbox, FALSE, _("Windowed stereo mode"), GTK_ORIENTATION_VERTICAL);
3362 table = pref_table_new(group, 2, 1, FALSE, FALSE);
3363 add_stereo_mode_menu(table, 0, 0, _("Windowed stereo mode"), options->stereo.mode, &c_options->stereo.mode, FALSE);
3365 table = pref_table_new(group, 2, 2, TRUE, FALSE);
3366 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
3367 pref_checkbox_new_int(box, _("Mirror left image"),
3368 options->stereo.mode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.mirror_left);
3369 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
3370 pref_checkbox_new_int(box, _("Flip left image"),
3371 options->stereo.mode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.flip_left);
3372 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
3373 pref_checkbox_new_int(box, _("Mirror right image"),
3374 options->stereo.mode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.mirror_right);
3375 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
3376 pref_checkbox_new_int(box, _("Flip right image"),
3377 options->stereo.mode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.flip_right);
3378 pref_checkbox_new_int(group, _("Swap left and right images"),
3379 options->stereo.mode & PR_STEREO_SWAP, &c_options->stereo.tmp.swap);
3380 pref_checkbox_new_int(group, _("Disable stereo mode on single image source"),
3381 options->stereo.mode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.temp_disable);
3383 group = pref_group_new(vbox, FALSE, _("Fullscreen stereo mode"), GTK_ORIENTATION_VERTICAL);
3384 fs_button = pref_checkbox_new_int(group, _("Use different settings for fullscreen"),
3385 options->stereo.enable_fsmode, &c_options->stereo.enable_fsmode);
3386 box2 = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
3387 pref_checkbox_link_sensitivity(fs_button, box2);
3388 table = pref_table_new(box2, 2, 1, FALSE, FALSE);
3389 add_stereo_mode_menu(table, 0, 0, _("Fullscreen stereo mode"), options->stereo.fsmode, &c_options->stereo.fsmode, TRUE);
3390 table = pref_table_new(box2, 2, 2, TRUE, FALSE);
3391 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
3392 pref_checkbox_new_int(box, _("Mirror left image"),
3393 options->stereo.fsmode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.fs_mirror_left);
3394 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
3395 pref_checkbox_new_int(box, _("Flip left image"),
3396 options->stereo.fsmode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.fs_flip_left);
3397 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
3398 pref_checkbox_new_int(box, _("Mirror right image"),
3399 options->stereo.fsmode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.fs_mirror_right);
3400 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
3401 pref_checkbox_new_int(box, _("Flip right image"),
3402 options->stereo.fsmode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.fs_flip_right);
3403 pref_checkbox_new_int(box2, _("Swap left and right images"),
3404 options->stereo.fsmode & PR_STEREO_SWAP, &c_options->stereo.tmp.fs_swap);
3405 pref_checkbox_new_int(box2, _("Disable stereo mode on single image source"),
3406 options->stereo.fsmode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.fs_temp_disable);
3408 group2 = pref_group_new(box2, FALSE, _("Fixed position"), GTK_ORIENTATION_VERTICAL);
3409 table = pref_table_new(group2, 5, 3, FALSE, FALSE);
3410 pref_table_spin_new_int(table, 0, 0, _("Width"), NULL,
3411 1, 5000, 1, options->stereo.fixed_w, &c_options->stereo.fixed_w);
3412 pref_table_spin_new_int(table, 3, 0, _("Height"), NULL,
3413 1, 5000, 1, options->stereo.fixed_h, &c_options->stereo.fixed_h);
3414 pref_table_spin_new_int(table, 0, 1, _("Left X"), NULL,
3415 0, 5000, 1, options->stereo.fixed_x1, &c_options->stereo.fixed_x1);
3416 pref_table_spin_new_int(table, 3, 1, _("Left Y"), NULL,
3417 0, 5000, 1, options->stereo.fixed_y1, &c_options->stereo.fixed_y1);
3418 pref_table_spin_new_int(table, 0, 2, _("Right X"), NULL,
3419 0, 5000, 1, options->stereo.fixed_x2, &c_options->stereo.fixed_x2);
3420 pref_table_spin_new_int(table, 3, 2, _("Right Y"), NULL,
3421 0, 5000, 1, options->stereo.fixed_y2, &c_options->stereo.fixed_y2);
3425 /* Main preferences window */
3426 static void config_window_create(void)
3428 GtkWidget *win_vbox;
3430 GtkWidget *notebook;
3432 GtkWidget *ct_button;
3434 if (!c_options) c_options = init_options(NULL);
3436 configwindow = window_new(GTK_WINDOW_TOPLEVEL, "preferences", PIXBUF_INLINE_ICON_CONFIG, NULL, _("Preferences"));
3437 gtk_window_set_type_hint(GTK_WINDOW(configwindow), GDK_WINDOW_TYPE_HINT_DIALOG);
3438 g_signal_connect(G_OBJECT(configwindow), "delete_event",
3439 G_CALLBACK(config_window_delete), NULL);
3440 gtk_window_set_default_size(GTK_WINDOW(configwindow), CONFIG_WINDOW_DEF_WIDTH, CONFIG_WINDOW_DEF_HEIGHT);
3441 gtk_window_set_resizable(GTK_WINDOW(configwindow), TRUE);
3442 gtk_container_set_border_width(GTK_CONTAINER(configwindow), PREF_PAD_BORDER);
3444 win_vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE);
3445 gtk_container_add(GTK_CONTAINER(configwindow), win_vbox);
3446 gtk_widget_show(win_vbox);
3448 notebook = gtk_notebook_new();
3449 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
3450 gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), TRUE);
3451 gtk_box_pack_start(GTK_BOX(win_vbox), notebook, TRUE, TRUE, 0);
3453 config_tab_general(notebook);
3454 config_tab_image(notebook);
3455 config_tab_osd(notebook);
3456 config_tab_windows(notebook);
3457 config_tab_accelerators(notebook);
3458 config_tab_files(notebook);
3459 config_tab_metadata(notebook);
3460 config_tab_keywords(notebook);
3461 config_tab_color(notebook);
3462 config_tab_stereo(notebook);
3463 config_tab_behavior(notebook);
3464 config_tab_toolbar(notebook);
3466 hbox = gtk_hbutton_box_new();
3467 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
3468 gtk_box_set_spacing(GTK_BOX(hbox), PREF_PAD_BUTTON_GAP);
3469 gtk_box_pack_end(GTK_BOX(win_vbox), hbox, FALSE, FALSE, 0);
3470 gtk_widget_show(hbox);
3472 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
3473 G_CALLBACK(config_window_help_cb), notebook);
3474 gtk_container_add(GTK_CONTAINER(hbox), button);
3475 gtk_widget_set_can_default(button, TRUE);
3476 gtk_widget_show(button);
3478 button = pref_button_new(NULL, GTK_STOCK_OK, NULL, FALSE,
3479 G_CALLBACK(config_window_ok_cb), NULL);
3480 gtk_container_add(GTK_CONTAINER(hbox), button);
3481 gtk_widget_set_can_default(button, TRUE);
3482 gtk_widget_grab_default(button);
3483 gtk_widget_show(button);
3487 button = pref_button_new(NULL, GTK_STOCK_SAVE, NULL, FALSE,
3488 G_CALLBACK(config_window_save_cb), NULL);
3489 gtk_container_add(GTK_CONTAINER(hbox), button);
3490 gtk_widget_set_can_default(button, TRUE);
3491 gtk_widget_show(button);
3493 button = pref_button_new(NULL, GTK_STOCK_APPLY, NULL, FALSE,
3494 G_CALLBACK(config_window_apply_cb), NULL);
3495 gtk_container_add(GTK_CONTAINER(hbox), button);
3496 gtk_widget_set_can_default(button, TRUE);
3497 gtk_widget_show(button);
3499 button = pref_button_new(NULL, GTK_STOCK_CANCEL, NULL, FALSE,
3500 G_CALLBACK(config_window_close_cb), NULL);
3501 gtk_container_add(GTK_CONTAINER(hbox), button);
3502 gtk_widget_set_can_default(button, TRUE);
3503 gtk_widget_show(button);
3505 if (!generic_dialog_get_alternative_button_order(configwindow))
3507 gtk_box_reorder_child(GTK_BOX(hbox), ct_button, -1);
3510 gtk_widget_show(notebook);
3512 gtk_widget_show(configwindow);
3516 *-----------------------------------------------------------------------------
3517 * config window show (public)
3518 *-----------------------------------------------------------------------------
3521 void show_config_window(void)
3525 gtk_window_present(GTK_WINDOW(configwindow));
3529 config_window_create();
3538 void show_about_window(LayoutWindow *lw)
3540 GdkPixbuf *pixbuf_logo;
3541 GdkPixbuf *pixbuf_icon;
3542 gchar *authors[1000];
3550 #define LINE_LENGTH 1000
3551 gchar line[LINE_LENGTH];
3553 copyright = g_string_new(NULL);
3554 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");
3556 zd_path = g_build_filename(GQ_BIN_DIR, TIMEZONE_DATABASE, NULL);
3557 cd = ZDOpenDatabase(zd_path);
3560 copyright = g_string_append(copyright, ZDGetNotice(cd));
3562 ZDCloseDatabase(cd);
3566 path = g_build_filename(GQ_HELPDIR, "AUTHORS", NULL);
3567 fp = fopen(path, "r");
3570 while(fgets(line, LINE_LENGTH, fp))
3572 /* get rid of ending \n from fgets */
3573 line[strlen(line) - 1] = '\0';
3574 authors[i_authors] = g_strdup(line);
3577 authors[i_authors] = NULL;
3582 comment = g_strconcat("Development and bug reports:\n", GQ_EMAIL_ADDRESS,
3583 "\nhttps://github.com/BestImageViewer/geeqie/issues",NULL);
3585 pixbuf_logo = pixbuf_inline(PIXBUF_INLINE_LOGO);
3586 pixbuf_icon = pixbuf_inline(PIXBUF_INLINE_ICON);
3587 gtk_show_about_dialog(GTK_WINDOW(lw->window),
3588 "title", _("About Geeqie"),
3590 "program-name", GQ_APPNAME,
3592 "logo", pixbuf_logo,
3593 "icon", pixbuf_icon,
3594 "website", GQ_WEBSITE,
3595 "website-label", "Website",
3596 "comments", comment,
3598 "translator-credits", _("translator-credits"),
3599 "wrap-license", TRUE,
3600 "license", copyright->str,
3603 g_string_free(copyright, TRUE);
3606 while(n < i_authors)
3616 static void image_overlay_set_text_colours()
3618 c_options->image_overlay.text_red = options->image_overlay.text_red;
3619 c_options->image_overlay.text_green = options->image_overlay.text_green;
3620 c_options->image_overlay.text_blue = options->image_overlay.text_blue;
3621 c_options->image_overlay.text_alpha = options->image_overlay.text_alpha;
3622 c_options->image_overlay.background_red = options->image_overlay.background_red;
3623 c_options->image_overlay.background_green = options->image_overlay.background_green;
3624 c_options->image_overlay.background_blue = options->image_overlay.background_blue;
3625 c_options->image_overlay.background_alpha = options->image_overlay.background_alpha;
3627 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */