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.safe_delete_enable = c_options->file_ops.safe_delete_enable;
265 options->file_ops.safe_delete_folder_maxsize = c_options->file_ops.safe_delete_folder_maxsize;
266 options->tools_restore_state = c_options->tools_restore_state;
267 options->save_window_positions = c_options->save_window_positions;
268 options->use_saved_window_positions_for_new_windows = c_options->use_saved_window_positions_for_new_windows;
269 options->save_dialog_window_positions = c_options->save_dialog_window_positions;
270 options->show_window_ids = c_options->show_window_ids;
271 options->image.scroll_reset_method = c_options->image.scroll_reset_method;
272 options->image.zoom_2pass = c_options->image.zoom_2pass;
273 options->image.fit_window_to_image = c_options->image.fit_window_to_image;
274 options->image.limit_window_size = c_options->image.limit_window_size;
275 options->image.zoom_to_fit_allow_expand = c_options->image.zoom_to_fit_allow_expand;
276 options->image.max_window_size = c_options->image.max_window_size;
277 options->image.limit_autofit_size = c_options->image.limit_autofit_size;
278 options->image.max_autofit_size = c_options->image.max_autofit_size;
279 options->image.max_enlargement_size = c_options->image.max_enlargement_size;
280 options->image.use_clutter_renderer = c_options->image.use_clutter_renderer;
281 options->progressive_key_scrolling = c_options->progressive_key_scrolling;
282 options->keyboard_scroll_step = c_options->keyboard_scroll_step;
284 if (options->thumbnails.max_width != c_options->thumbnails.max_width
285 || options->thumbnails.max_height != c_options->thumbnails.max_height
286 || options->thumbnails.quality != c_options->thumbnails.quality)
288 thumb_format_changed = TRUE;
290 options->thumbnails.max_width = c_options->thumbnails.max_width;
291 options->thumbnails.max_height = c_options->thumbnails.max_height;
292 options->thumbnails.quality = c_options->thumbnails.quality;
294 options->thumbnails.enable_caching = c_options->thumbnails.enable_caching;
295 options->thumbnails.cache_into_dirs = c_options->thumbnails.cache_into_dirs;
296 options->thumbnails.use_exif = c_options->thumbnails.use_exif;
297 options->thumbnails.collection_preview = c_options->thumbnails.collection_preview;
298 options->thumbnails.use_ft_metadata = c_options->thumbnails.use_ft_metadata;
299 // options->thumbnails.use_ft_metadata_small = c_options->thumbnails.use_ft_metadata_small;
300 options->thumbnails.spec_standard = c_options->thumbnails.spec_standard;
301 options->metadata.enable_metadata_dirs = c_options->metadata.enable_metadata_dirs;
302 options->file_filter.show_hidden_files = c_options->file_filter.show_hidden_files;
303 options->file_filter.show_parent_directory = c_options->file_filter.show_parent_directory;
304 options->file_filter.show_dot_directory = c_options->file_filter.show_dot_directory;
305 options->file_filter.disable_file_extension_checks = c_options->file_filter.disable_file_extension_checks;
307 options->file_sort.case_sensitive = c_options->file_sort.case_sensitive;
308 options->file_sort.natural = c_options->file_sort.natural;
309 options->file_filter.disable = c_options->file_filter.disable;
311 config_entry_to_option(sidecar_ext_entry, &options->sidecar.ext, NULL);
312 sidecar_ext_parse(options->sidecar.ext);
314 options->slideshow.random = c_options->slideshow.random;
315 options->slideshow.repeat = c_options->slideshow.repeat;
316 options->slideshow.delay = c_options->slideshow.delay;
318 options->mousewheel_scrolls = c_options->mousewheel_scrolls;
319 options->image_lm_click_nav = c_options->image_lm_click_nav;
320 options->image_l_click_video = c_options->image_l_click_video;
321 options->image_l_click_video_editor = c_options->image_l_click_video_editor;
323 options->file_ops.enable_in_place_rename = c_options->file_ops.enable_in_place_rename;
325 options->image.tile_cache_max = c_options->image.tile_cache_max;
326 options->image.image_cache_max = c_options->image.image_cache_max;
328 options->image.zoom_quality = c_options->image.zoom_quality;
330 options->image.zoom_increment = c_options->image.zoom_increment;
332 options->image.enable_read_ahead = c_options->image.enable_read_ahead;
335 if (options->image.use_custom_border_color != c_options->image.use_custom_border_color
336 || options->image.use_custom_border_color_in_fullscreen != c_options->image.use_custom_border_color_in_fullscreen
337 || !gdk_color_equal(&options->image.border_color, &c_options->image.border_color))
339 options->image.use_custom_border_color_in_fullscreen = c_options->image.use_custom_border_color_in_fullscreen;
340 options->image.use_custom_border_color = c_options->image.use_custom_border_color;
341 options->image.border_color = c_options->image.border_color;
342 layout_colors_update();
343 view_window_colors_update();
346 options->image.alpha_color_1 = c_options->image.alpha_color_1;
347 options->image.alpha_color_2 = c_options->image.alpha_color_2;
349 options->fullscreen.screen = c_options->fullscreen.screen;
350 options->fullscreen.clean_flip = c_options->fullscreen.clean_flip;
351 options->fullscreen.disable_saver = c_options->fullscreen.disable_saver;
352 options->fullscreen.above = c_options->fullscreen.above;
353 if (c_options->image_overlay.template_string)
354 set_image_overlay_template_string(&options->image_overlay.template_string,
355 c_options->image_overlay.template_string);
356 if (c_options->image_overlay.font)
357 set_image_overlay_font_string(&options->image_overlay.font,
358 c_options->image_overlay.font);
359 options->image_overlay.text_red = c_options->image_overlay.text_red;
360 options->image_overlay.text_green = c_options->image_overlay.text_green;
361 options->image_overlay.text_blue = c_options->image_overlay.text_blue;
362 options->image_overlay.text_alpha = c_options->image_overlay.text_alpha;
363 options->image_overlay.background_red = c_options->image_overlay.background_red;
364 options->image_overlay.background_green = c_options->image_overlay.background_green;
365 options->image_overlay.background_blue = c_options->image_overlay.background_blue;
366 options->image_overlay.background_alpha = c_options->image_overlay.background_alpha;
367 options->update_on_time_change = c_options->update_on_time_change;
368 options->image.exif_proof_rotate_enable = c_options->image.exif_proof_rotate_enable;
370 options->duplicates_similarity_threshold = c_options->duplicates_similarity_threshold;
371 options->rot_invariant_sim = c_options->rot_invariant_sim;
373 options->tree_descend_subdirs = c_options->tree_descend_subdirs;
375 options->view_dir_list_single_click_enter = c_options->view_dir_list_single_click_enter;
377 options->open_recent_list_maxsize = c_options->open_recent_list_maxsize;
378 options->dnd_icon_size = c_options->dnd_icon_size;
379 options->clipboard_selection = c_options->clipboard_selection;
381 options->metadata.save_in_image_file = c_options->metadata.save_in_image_file;
382 options->metadata.save_legacy_IPTC = c_options->metadata.save_legacy_IPTC;
383 options->metadata.warn_on_write_problems = c_options->metadata.warn_on_write_problems;
384 options->metadata.save_legacy_format = c_options->metadata.save_legacy_format;
385 options->metadata.sync_grouped_files = c_options->metadata.sync_grouped_files;
386 options->metadata.confirm_write = c_options->metadata.confirm_write;
387 options->metadata.sidecar_extended_name = c_options->metadata.sidecar_extended_name;
388 options->metadata.confirm_timeout = c_options->metadata.confirm_timeout;
389 options->metadata.confirm_after_timeout = c_options->metadata.confirm_after_timeout;
390 options->metadata.confirm_on_image_change = c_options->metadata.confirm_on_image_change;
391 options->metadata.confirm_on_dir_change = c_options->metadata.confirm_on_dir_change;
392 options->metadata.keywords_case_sensitive = c_options->metadata.keywords_case_sensitive;
393 options->metadata.write_orientation = c_options->metadata.write_orientation;
394 options->stereo.mode = (c_options->stereo.mode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
395 (c_options->stereo.tmp.mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
396 (c_options->stereo.tmp.flip_right ? PR_STEREO_FLIP_RIGHT : 0) |
397 (c_options->stereo.tmp.mirror_left ? PR_STEREO_MIRROR_LEFT : 0) |
398 (c_options->stereo.tmp.flip_left ? PR_STEREO_FLIP_LEFT : 0) |
399 (c_options->stereo.tmp.swap ? PR_STEREO_SWAP : 0) |
400 (c_options->stereo.tmp.temp_disable ? PR_STEREO_TEMP_DISABLE : 0);
401 options->stereo.fsmode = (c_options->stereo.fsmode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
402 (c_options->stereo.tmp.fs_mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
403 (c_options->stereo.tmp.fs_flip_right ? PR_STEREO_FLIP_RIGHT : 0) |
404 (c_options->stereo.tmp.fs_mirror_left ? PR_STEREO_MIRROR_LEFT : 0) |
405 (c_options->stereo.tmp.fs_flip_left ? PR_STEREO_FLIP_LEFT : 0) |
406 (c_options->stereo.tmp.fs_swap ? PR_STEREO_SWAP : 0) |
407 (c_options->stereo.tmp.fs_temp_disable ? PR_STEREO_TEMP_DISABLE : 0);
408 options->stereo.enable_fsmode = c_options->stereo.enable_fsmode;
409 options->stereo.fixed_w = c_options->stereo.fixed_w;
410 options->stereo.fixed_h = c_options->stereo.fixed_h;
411 options->stereo.fixed_x1 = c_options->stereo.fixed_x1;
412 options->stereo.fixed_y1 = c_options->stereo.fixed_y1;
413 options->stereo.fixed_x2 = c_options->stereo.fixed_x2;
414 options->stereo.fixed_y2 = c_options->stereo.fixed_y2;
416 options->info_keywords.height = c_options->info_keywords.height;
417 options->info_title.height = c_options->info_title.height;
418 options->info_comment.height = c_options->info_comment.height;
419 options->info_rating.height = c_options->info_rating.height;
421 options->show_predefined_keyword_tree = c_options->show_predefined_keyword_tree;
423 options->marks_save = c_options->marks_save;
424 options->with_rename = c_options->with_rename;
425 options->collections_on_top = c_options->collections_on_top;
426 config_entry_to_option(help_search_engine_entry, &options->help_search_engine, NULL);
428 options->read_metadata_in_idle = c_options->read_metadata_in_idle;
430 options->star_rating.star = c_options->star_rating.star;
431 options->star_rating.rejected = c_options->star_rating.rejected;
433 set_debug_level(debug_c);
437 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
439 config_entry_to_option(color_profile_input_name_entry[i], &options->color_profile.input_name[i], NULL);
440 config_entry_to_option(color_profile_input_file_entry[i], &options->color_profile.input_file[i], NULL);
442 config_entry_to_option(color_profile_screen_file_entry, &options->color_profile.screen_file, NULL);
443 options->color_profile.use_x11_screen_profile = c_options->color_profile.use_x11_screen_profile;
444 if (options->color_profile.render_intent != c_options->color_profile.render_intent)
446 options->color_profile.render_intent = c_options->color_profile.render_intent;
451 config_tab_keywords_save();
453 image_options_sync();
458 layout_refresh(NULL);
461 if (accel_store) gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_apply_cb, NULL);
467 *-----------------------------------------------------------------------------
468 * config window main button callbacks (private)
469 *-----------------------------------------------------------------------------
472 static void config_window_close_cb(GtkWidget *widget, gpointer data)
474 gtk_widget_destroy(configwindow);
479 static void config_window_help_cb(GtkWidget *widget, gpointer data)
481 GtkWidget *notebook = data;
484 static gchar *html_section[] =
486 "GuideOptionsGeneral.html",
487 "GuideOptionsImage.html",
488 "GuideOptionsOSD.html",
489 "GuideOptionsWindow.html",
490 "GuideOptionsKeyboard.html",
491 "GuideOptionsFiltering.html",
492 "GuideOptionsMetadata.html",
493 "GuideOptionsKeywords.html",
494 "GuideOptionsColor.html",
495 "GuideOptionsStereo.html",
496 "GuideOptionsBehavior.html",
497 "GuideOptionsToolbar.html"
500 i = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
501 help_window_show(html_section[i]);
504 static gboolean config_window_delete(GtkWidget *widget, GdkEventAny *event, gpointer data)
506 config_window_close_cb(NULL, NULL);
510 static void config_window_ok_cb(GtkWidget *widget, gpointer data)
512 config_window_apply();
513 config_window_close_cb(NULL, NULL);
516 static void config_window_apply_cb(GtkWidget *widget, gpointer data)
519 lw = layout_window_list->data;
521 config_window_apply();
522 layout_util_sync(lw);
525 static void config_window_save_cb(GtkWidget *widget, gpointer data)
527 config_window_apply();
528 save_options(options);
532 *-----------------------------------------------------------------------------
533 * config window setup (private)
534 *-----------------------------------------------------------------------------
537 static void quality_menu_cb(GtkWidget *combo, gpointer data)
541 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
545 *option = GDK_INTERP_NEAREST;
548 *option = GDK_INTERP_TILES;
551 *option = GDK_INTERP_BILINEAR;
554 *option = GDK_INTERP_HYPER;
559 static void clipboard_selection_menu_cb(GtkWidget *combo, gpointer data)
563 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
575 static void add_quality_menu(GtkWidget *table, gint column, gint row, const gchar *text,
576 guint option, guint *option_c)
583 pref_table_label(table, column, row, text, 0.0);
585 combo = gtk_combo_box_text_new();
587 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Nearest (worst, but fastest)"));
588 if (option == GDK_INTERP_NEAREST) current = 0;
589 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Tiles"));
590 if (option == GDK_INTERP_TILES) current = 1;
591 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Bilinear"));
592 if (option == GDK_INTERP_BILINEAR) current = 2;
593 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Hyper (best, but slowest)"));
594 if (option == GDK_INTERP_HYPER) current = 3;
596 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
598 g_signal_connect(G_OBJECT(combo), "changed",
599 G_CALLBACK(quality_menu_cb), option_c);
601 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
602 GTK_EXPAND | GTK_FILL, 0, 0, 0);
603 gtk_widget_show(combo);
606 static void add_clipboard_selection_menu(GtkWidget *table, gint column, gint row, const gchar *text,
607 gint option, gint *option_c)
614 pref_table_label(table, column, row, text, 0.0);
616 combo = gtk_combo_box_text_new();
618 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("PRIMARY"));
619 if (option == PRIMARY) current = 0;
620 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("CLIPBOARD"));
621 if (option == CLIPBOARD) current = 1;
623 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
625 g_signal_connect(G_OBJECT(combo), "changed",
626 G_CALLBACK(clipboard_selection_menu_cb), option_c);
628 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
629 GTK_EXPAND | GTK_FILL, 0, 0, 0);
630 gtk_widget_show(combo);
633 static void thumb_size_menu_cb(GtkWidget *combo, gpointer data)
637 n = gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
640 if ((guint) n < sizeof(thumb_size_list) / sizeof(ThumbSize))
642 c_options->thumbnails.max_width = thumb_size_list[n].w;
643 c_options->thumbnails.max_height = thumb_size_list[n].h;
647 c_options->thumbnails.max_width = options->thumbnails.max_width;
648 c_options->thumbnails.max_height = options->thumbnails.max_height;
652 static void add_thumb_size_menu(GtkWidget *table, gint column, gint row, gchar *text)
658 c_options->thumbnails.max_width = options->thumbnails.max_width;
659 c_options->thumbnails.max_height = options->thumbnails.max_height;
661 pref_table_label(table, column, row, text, 0.0);
663 combo = gtk_combo_box_text_new();
666 for (i = 0; (guint) i < sizeof(thumb_size_list) / sizeof(ThumbSize); i++)
671 w = thumb_size_list[i].w;
672 h = thumb_size_list[i].h;
674 buf = g_strdup_printf("%d x %d", w, h);
675 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf);
678 if (w == options->thumbnails.max_width && h == options->thumbnails.max_height) current = i;
685 buf = g_strdup_printf("%s %d x %d", _("Custom"), options->thumbnails.max_width, options->thumbnails.max_height);
686 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf);
692 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
693 g_signal_connect(G_OBJECT(combo), "changed",
694 G_CALLBACK(thumb_size_menu_cb), NULL);
696 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
697 GTK_EXPAND | GTK_FILL, 0, 0, 0);
698 gtk_widget_show(combo);
701 static void stereo_mode_menu_cb(GtkWidget *combo, gpointer data)
705 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
709 *option = PR_STEREO_NONE;
712 *option = PR_STEREO_ANAGLYPH_RC;
715 *option = PR_STEREO_ANAGLYPH_GM;
718 *option = PR_STEREO_ANAGLYPH_YB;
721 *option = PR_STEREO_ANAGLYPH_GRAY_RC;
724 *option = PR_STEREO_ANAGLYPH_GRAY_GM;
727 *option = PR_STEREO_ANAGLYPH_GRAY_YB;
730 *option = PR_STEREO_ANAGLYPH_DB_RC;
733 *option = PR_STEREO_ANAGLYPH_DB_GM;
736 *option = PR_STEREO_ANAGLYPH_DB_YB;
739 *option = PR_STEREO_HORIZ;
742 *option = PR_STEREO_HORIZ | PR_STEREO_HALF;
745 *option = PR_STEREO_VERT;
748 *option = PR_STEREO_VERT | PR_STEREO_HALF;
751 *option = PR_STEREO_FIXED;
756 static void add_stereo_mode_menu(GtkWidget *table, gint column, gint row, const gchar *text,
757 gint option, gint *option_c, gboolean add_fixed)
764 pref_table_label(table, column, row, text, 0.0);
766 combo = gtk_combo_box_text_new();
768 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Single image"));
770 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Red-Cyan"));
771 if (option & PR_STEREO_ANAGLYPH_RC) current = 1;
772 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Green-Magenta"));
773 if (option & PR_STEREO_ANAGLYPH_GM) current = 2;
774 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Yellow-Blue"));
775 if (option & PR_STEREO_ANAGLYPH_YB) current = 3;
776 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Red-Cyan"));
777 if (option & PR_STEREO_ANAGLYPH_GRAY_RC) current = 4;
778 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Green-Magenta"));
779 if (option & PR_STEREO_ANAGLYPH_GRAY_GM) current = 5;
780 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Gray Yellow-Blue"));
781 if (option & PR_STEREO_ANAGLYPH_GRAY_YB) current = 6;
782 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Red-Cyan"));
783 if (option & PR_STEREO_ANAGLYPH_DB_RC) current = 7;
784 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Green-Magenta"));
785 if (option & PR_STEREO_ANAGLYPH_DB_GM) current = 8;
786 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Anaglyph Dubois Yellow-Blue"));
787 if (option & PR_STEREO_ANAGLYPH_DB_YB) current = 9;
789 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Side by Side"));
790 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Side by Side Half size"));
791 if (option & PR_STEREO_HORIZ)
794 if (option & PR_STEREO_HALF) current = 11;
797 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Top - Bottom"));
798 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Top - Bottom Half size"));
799 if (option & PR_STEREO_VERT)
802 if (option & PR_STEREO_HALF) current = 13;
807 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Fixed position"));
808 if (option & PR_STEREO_FIXED) current = 14;
811 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
813 g_signal_connect(G_OBJECT(combo), "changed",
814 G_CALLBACK(stereo_mode_menu_cb), option_c);
816 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
817 GTK_EXPAND | GTK_FILL, 0, 0, 0);
818 gtk_widget_show(combo);
821 static void video_menu_cb(GtkWidget *combo, gpointer data)
823 gchar **option = data;
825 EditorDescription *ed = g_list_nth_data(editor_list_get(), gtk_combo_box_get_active(GTK_COMBO_BOX(combo)));
829 static void video_menu_populate(gpointer data, gpointer user_data)
831 GtkWidget *combo = user_data;
832 EditorDescription *ed = data;
834 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), ed->name);
837 static void add_video_menu(GtkWidget *table, gint column, gint row, const gchar *text,
838 gchar *option, gchar **option_c)
842 /* use lists since they are sorted */
843 GList *eds = editor_list_get();
847 pref_table_label(table, column, row, text, 0.0);
849 combo = gtk_combo_box_text_new();
850 g_list_foreach(eds,video_menu_populate,(gpointer)combo);
851 current = option ? g_list_index(eds,g_hash_table_lookup(editors,option)): -1;
853 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
855 g_signal_connect(G_OBJECT(combo), "changed",
856 G_CALLBACK(video_menu_cb), option_c);
858 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
859 GTK_EXPAND | GTK_FILL, 0, 0, 0);
860 gtk_widget_show(combo);
863 static void filter_store_populate(void)
867 if (!filter_store) return;
869 gtk_list_store_clear(filter_store);
871 work = filter_get_list();
880 gtk_list_store_append(filter_store, &iter);
881 gtk_list_store_set(filter_store, &iter, 0, fe, -1);
885 static void filter_store_ext_edit_cb(GtkCellRendererText *cell, gchar *path_str,
886 gchar *new_text, gpointer data)
888 GtkWidget *model = data;
889 FilterEntry *fe = data;
893 if (!new_text || strlen(new_text) < 1) return;
895 tpath = gtk_tree_path_new_from_string(path_str);
896 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
897 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
899 g_free(fe->extensions);
900 fe->extensions = g_strdup(new_text);
902 gtk_tree_path_free(tpath);
906 static void filter_store_class_edit_cb(GtkCellRendererText *cell, gchar *path_str,
907 gchar *new_text, gpointer data)
909 GtkWidget *model = data;
910 FilterEntry *fe = data;
915 if (!new_text || !new_text[0]) return;
917 tpath = gtk_tree_path_new_from_string(path_str);
918 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
919 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
921 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
923 if (strcmp(new_text, _(format_class_list[i])) == 0)
930 gtk_tree_path_free(tpath);
934 static void filter_store_desc_edit_cb(GtkCellRendererText *cell, gchar *path_str,
935 gchar *new_text, gpointer data)
937 GtkWidget *model = data;
942 if (!new_text || !new_text[0]) return;
944 tpath = gtk_tree_path_new_from_string(path_str);
945 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
946 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
948 g_free(fe->description);
949 fe->description = g_strdup(new_text);
951 gtk_tree_path_free(tpath);
954 static void filter_store_enable_cb(GtkCellRendererToggle *renderer,
955 gchar *path_str, gpointer data)
957 GtkWidget *model = data;
962 tpath = gtk_tree_path_new_from_string(path_str);
963 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
964 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
966 fe->enabled = !fe->enabled;
968 gtk_tree_path_free(tpath);
972 static void filter_store_writable_cb(GtkCellRendererToggle *renderer,
973 gchar *path_str, gpointer data)
975 GtkWidget *model = data;
980 tpath = gtk_tree_path_new_from_string(path_str);
981 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
982 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
984 fe->writable = !fe->writable;
985 if (fe->writable) fe->allow_sidecar = FALSE;
987 gtk_tree_path_free(tpath);
991 static void filter_store_sidecar_cb(GtkCellRendererToggle *renderer,
992 gchar *path_str, gpointer data)
994 GtkWidget *model = data;
999 tpath = gtk_tree_path_new_from_string(path_str);
1000 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, tpath);
1001 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &fe, -1);
1003 fe->allow_sidecar = !fe->allow_sidecar;
1004 if (fe->allow_sidecar) fe->writable = FALSE;
1006 gtk_tree_path_free(tpath);
1010 static void filter_set_func(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell,
1011 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
1015 gtk_tree_model_get(tree_model, iter, 0, &fe, -1);
1017 switch (GPOINTER_TO_INT(data))
1020 g_object_set(GTK_CELL_RENDERER(cell),
1021 "active", fe->enabled, NULL);
1024 g_object_set(GTK_CELL_RENDERER(cell),
1025 "text", fe->extensions, NULL);
1027 case FE_DESCRIPTION:
1028 g_object_set(GTK_CELL_RENDERER(cell),
1029 "text", fe->description, NULL);
1032 g_object_set(GTK_CELL_RENDERER(cell),
1033 "text", _(format_class_list[fe->file_class]), NULL);
1036 g_object_set(GTK_CELL_RENDERER(cell),
1037 "active", fe->writable, NULL);
1039 case FE_ALLOW_SIDECAR:
1040 g_object_set(GTK_CELL_RENDERER(cell),
1041 "active", fe->allow_sidecar, NULL);
1046 static gboolean filter_add_scroll(gpointer data)
1050 GtkCellRenderer *cell;
1051 GtkTreeViewColumn *column;
1052 GList *list_columns;
1057 rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(filter_store), NULL);
1058 path = gtk_tree_path_new_from_indices(rows-1, -1);
1060 list_columns = gtk_tree_view_get_columns(GTK_TREE_VIEW(data));
1062 column = g_list_nth(list_columns,i)->data;
1063 title = gtk_tree_view_column_get_title(GTK_TREE_VIEW_COLUMN(column));
1065 } while (strcmp(title, "Filter") !=0 );
1067 list_cells = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(column));
1068 cell = g_list_last(list_cells)->data;
1070 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1071 path, column, FALSE, 0.0, 0.0 );
1072 gtk_tree_view_set_cursor_on_cell(GTK_TREE_VIEW(data),
1073 path, column, cell, TRUE);
1075 gtk_tree_path_free(path);
1076 g_list_free(list_cells);
1077 g_list_free(list_columns);
1082 static void filter_add_cb(GtkWidget *widget, gpointer data)
1084 filter_add_unique("description", ".new", FORMAT_CLASS_IMAGE, TRUE, FALSE, TRUE);
1085 filter_store_populate();
1087 g_idle_add((GSourceFunc)filter_add_scroll, data);
1090 static void filter_remove_cb(GtkWidget *widget, gpointer data)
1092 GtkWidget *filter_view = data;
1093 GtkTreeSelection *selection;
1097 if (!filter_store) return;
1098 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
1099 if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) return;
1100 gtk_tree_model_get(GTK_TREE_MODEL(filter_store), &iter, 0, &fe, -1);
1103 filter_remove_entry(fe);
1105 filter_store_populate();
1108 static gboolean filter_default_ok_scroll(GtkTreeView *data)
1112 GtkTreeViewColumn *column;
1114 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(filter_store), &iter);
1115 path = gtk_tree_model_get_path(GTK_TREE_MODEL(filter_store), &iter);
1116 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data),0);
1118 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1122 gtk_tree_path_free(path);
1127 static void filter_default_ok_cb(GenericDialog *gd, gpointer data)
1130 filter_add_defaults();
1132 filter_store_populate();
1134 g_idle_add((GSourceFunc)filter_default_ok_scroll, gd->data);
1137 static void dummy_cancel_cb(GenericDialog *gd, gpointer data)
1139 /* no op, only so cancel button appears */
1142 static void filter_default_cb(GtkWidget *widget, gpointer data)
1146 gd = generic_dialog_new(_("Reset filters"),
1147 "reset_filter", widget, TRUE,
1148 dummy_cancel_cb, data);
1149 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Reset filters"),
1150 _("This will reset the file filters to the defaults.\nContinue?"), TRUE);
1151 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, filter_default_ok_cb, TRUE);
1152 gtk_widget_show(gd->dialog);
1155 static void filter_disable_cb(GtkWidget *widget, gpointer data)
1157 GtkWidget *frame = data;
1159 gtk_widget_set_sensitive(frame,
1160 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
1163 static void safe_delete_view_cb(GtkWidget *widget, gpointer data)
1165 layout_set_path(NULL, gtk_entry_get_text(GTK_ENTRY(safe_delete_path_entry)));
1168 static void safe_delete_clear_ok_cb(GenericDialog *gd, gpointer data)
1170 file_util_trash_clear();
1173 static void safe_delete_clear_cb(GtkWidget *widget, gpointer data)
1177 gd = generic_dialog_new(_("Clear trash"),
1178 "clear_trash", widget, TRUE,
1179 dummy_cancel_cb, NULL);
1180 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Clear trash"),
1181 _("This will remove the trash contents."), FALSE);
1182 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, safe_delete_clear_ok_cb, TRUE);
1183 entry = gtk_entry_new();
1184 gtk_widget_set_can_focus(entry, FALSE);
1185 gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
1186 if (options->file_ops.safe_delete_path) gtk_entry_set_text(GTK_ENTRY(entry), options->file_ops.safe_delete_path);
1187 gtk_box_pack_start(GTK_BOX(gd->vbox), entry, FALSE, FALSE, 0);
1188 gtk_widget_show(entry);
1189 gtk_widget_show(gd->dialog);
1192 static void image_overlay_template_view_changed_cb(GtkWidget *widget, gpointer data)
1194 GtkWidget *pTextView;
1195 GtkTextBuffer *pTextBuffer;
1199 pTextView = GTK_WIDGET(data);
1201 pTextBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pTextView));
1202 gtk_text_buffer_get_start_iter(pTextBuffer, &iStart);
1203 gtk_text_buffer_get_end_iter(pTextBuffer, &iEnd);
1205 set_image_overlay_template_string(&c_options->image_overlay.template_string,
1206 gtk_text_buffer_get_text(pTextBuffer, &iStart, &iEnd, TRUE));
1209 static void image_overlay_default_template_ok_cb(GenericDialog *gd, gpointer data)
1211 GtkTextView *text_view = data;
1212 GtkTextBuffer *buffer;
1214 set_default_image_overlay_template_string(&options->image_overlay.template_string);
1215 if (!configwindow) return;
1217 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
1218 gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
1221 static void image_overlay_default_template_cb(GtkWidget *widget, gpointer data)
1225 gd = generic_dialog_new(_("Reset image overlay template string"),
1226 "reset_image_overlay_template_string", widget, TRUE,
1227 dummy_cancel_cb, data);
1228 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Reset image overlay template string"),
1229 _("This will reset the image overlay template string to the default.\nContinue?"), TRUE);
1230 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, image_overlay_default_template_ok_cb, TRUE);
1231 gtk_widget_show(gd->dialog);
1234 static void image_overlay_help_cb(GtkWidget *widget, gpointer data)
1236 help_window_show("GuideOptionsOSD.html");
1239 static void image_overlay_set_font_cb(GtkWidget *widget, gpointer data)
1241 #if GTK_CHECK_VERSION(3,4,0)
1244 PangoFontDescription *font_desc;
1246 dialog = gtk_font_chooser_dialog_new("Image Overlay Font", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1247 gtk_font_chooser_set_font(GTK_FONT_CHOOSER(dialog), options->image_overlay.font);
1249 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1251 font_desc = gtk_font_chooser_get_font_desc(GTK_FONT_CHOOSER(dialog));
1252 font = pango_font_description_to_string(font_desc);
1253 g_free(c_options->image_overlay.font);
1254 c_options->image_overlay.font = g_strdup(font);
1258 gtk_widget_destroy(dialog);
1262 font = gtk_font_button_get_font_name(GTK_FONT_BUTTON(widget));
1263 c_options->image_overlay.font = g_strdup(font);
1267 static void image_overlay_set_text_colour_cb(GtkWidget *widget, gpointer data)
1270 #if GTK_CHECK_VERSION(3,4,0)
1273 dialog = gtk_color_chooser_dialog_new("Image Overlay Text Colour", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1274 colour.red = options->image_overlay.text_red;
1275 colour.green = options->image_overlay.text_green;
1276 colour.blue = options->image_overlay.text_blue;
1277 colour.alpha = options->image_overlay.text_alpha;
1278 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1279 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(dialog), TRUE);
1281 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1283 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1284 c_options->image_overlay.text_red = colour.red*255;
1285 c_options->image_overlay.text_green = colour.green*255;
1286 c_options->image_overlay.text_blue = colour.blue*255;
1287 c_options->image_overlay.text_alpha = colour.alpha*255;
1289 gtk_widget_destroy(dialog);
1292 GtkColorSelection *colorsel;
1294 dialog = gtk_color_selection_dialog_new("Image Overlay Text Colour");
1295 gtk_window_set_keep_above(GTK_WINDOW(dialog),TRUE);
1296 colour.red = options->image_overlay.text_red*257;
1297 colour.green = options->image_overlay.text_green*257;
1298 colour.blue = options->image_overlay.text_blue*257;
1299 colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)));
1300 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
1301 gtk_color_selection_set_current_color(colorsel, &colour);
1302 gtk_color_selection_set_current_alpha(colorsel, options->image_overlay.text_alpha*257);
1304 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
1306 gtk_color_selection_get_current_color(colorsel, &colour);
1307 c_options->image_overlay.text_red = colour.red/257;
1308 c_options->image_overlay.text_green = colour.green/257;
1309 c_options->image_overlay.text_blue = colour.blue/257;
1310 c_options->image_overlay.text_alpha = gtk_color_selection_get_current_alpha(colorsel)/257;
1312 gtk_widget_destroy (dialog);
1317 static void image_overlay_set_background_colour_cb(GtkWidget *widget, gpointer data)
1320 #if GTK_CHECK_VERSION(3,4,0)
1323 dialog = gtk_color_chooser_dialog_new("Image Overlay Background Colour", GTK_WINDOW(gtk_widget_get_toplevel(widget)));
1324 colour.red = options->image_overlay.background_red;
1325 colour.green = options->image_overlay.background_green;
1326 colour.blue = options->image_overlay.background_blue;
1327 colour.alpha = options->image_overlay.background_alpha;
1328 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1329 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(dialog), TRUE);
1331 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL)
1333 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &colour);
1334 c_options->image_overlay.background_red = colour.red*255;
1335 c_options->image_overlay.background_green = colour.green*255;
1336 c_options->image_overlay.background_blue = colour.blue*255;
1337 c_options->image_overlay.background_alpha = colour.alpha*255;
1339 gtk_widget_destroy(dialog);
1342 GtkColorSelection *colorsel;
1344 dialog = gtk_color_selection_dialog_new("Image Overlay Background Colour");
1345 gtk_window_set_keep_above(GTK_WINDOW(dialog),TRUE);
1346 colour.red = options->image_overlay.background_red*257;
1347 colour.green = options->image_overlay.background_green*257;
1348 colour.blue = options->image_overlay.background_blue*257;
1349 colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)));
1350 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
1351 gtk_color_selection_set_current_color(colorsel, &colour);
1352 gtk_color_selection_set_current_alpha(colorsel, options->image_overlay.background_alpha*257);
1354 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
1356 gtk_color_selection_get_current_color(colorsel, &colour);
1357 c_options->image_overlay.background_red = colour.red/257;
1358 c_options->image_overlay.background_green = colour.green/257;
1359 c_options->image_overlay.background_blue = colour.blue/257;
1360 c_options->image_overlay.background_alpha = gtk_color_selection_get_current_alpha(colorsel)/257;
1362 gtk_widget_destroy(dialog);
1366 static void accel_store_populate(void)
1369 GList *groups, *actions;
1371 const gchar *accel_path;
1375 if (!accel_store || !layout_window_list || !layout_window_list->data) return;
1377 gtk_tree_store_clear(accel_store);
1378 lw = layout_window_list->data; /* get the actions from the first window, it should not matter, they should be the same in all windows */
1380 g_assert(lw && lw->ui_manager);
1381 groups = gtk_ui_manager_get_action_groups(lw->ui_manager);
1384 actions = gtk_action_group_list_actions(GTK_ACTION_GROUP(groups->data));
1387 action = GTK_ACTION(actions->data);
1388 accel_path = gtk_action_get_accel_path(action);
1389 if (accel_path && gtk_accel_map_lookup_entry(accel_path, &key))
1391 gchar *label, *label2, *tooltip, *accel;
1392 g_object_get(action,
1393 "tooltip", &tooltip,
1397 if (pango_parse_markup(label, -1, '_', NULL, &label2, NULL, NULL) && label2)
1403 accel = gtk_accelerator_name(key.accel_key, key.accel_mods);
1407 gtk_tree_store_append(accel_store, &iter, NULL);
1408 gtk_tree_store_set(accel_store, &iter,
1411 AE_TOOLTIP, tooltip ? tooltip : "",
1412 AE_ACCEL, accel_path,
1420 actions = actions->next;
1423 groups = groups->next;
1427 static void accel_store_cleared_cb(GtkCellRendererAccel *accel, gchar *path_string, gpointer user_data)
1432 static gboolean accel_remove_key_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1434 gchar *accel1 = data;
1439 gtk_tree_model_get(model, iter, AE_KEY, &accel2, -1);
1441 gtk_accelerator_parse(accel1, &key1.accel_key, &key1.accel_mods);
1442 gtk_accelerator_parse(accel2, &key2.accel_key, &key2.accel_mods);
1444 if (key1.accel_key == key2.accel_key && key1.accel_mods == key2.accel_mods)
1446 gtk_tree_store_set(accel_store, iter, AE_KEY, "", -1);
1447 DEBUG_1("accelerator key '%s' is already used, removing.", accel1);
1456 static void accel_store_edited_cb(GtkCellRendererAccel *accel, gchar *path_string, guint accel_key, GdkModifierType accel_mods, guint hardware_keycode, gpointer user_data)
1458 GtkTreeModel *model = (GtkTreeModel *)accel_store;
1462 GtkAccelKey old_key, key;
1463 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
1465 gtk_tree_model_get_iter(model, &iter, path);
1466 gtk_tree_model_get(model, &iter, AE_ACCEL, &accel_path, -1);
1468 /* test if the accelerator can be stored without conflicts*/
1469 gtk_accel_map_lookup_entry(accel_path, &old_key);
1471 /* change the key and read it back (change may fail on keys hardcoded in gtk)*/
1472 gtk_accel_map_change_entry(accel_path, accel_key, accel_mods, TRUE);
1473 gtk_accel_map_lookup_entry(accel_path, &key);
1475 /* restore the original for now, the key will be really changed when the changes are confirmed */
1476 gtk_accel_map_change_entry(accel_path, old_key.accel_key, old_key.accel_mods, TRUE);
1478 acc = gtk_accelerator_name(key.accel_key, key.accel_mods);
1479 gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_remove_key_cb, acc);
1481 gtk_tree_store_set(accel_store, &iter, AE_KEY, acc, -1);
1482 gtk_tree_path_free(path);
1486 static gboolean accel_default_scroll(GtkTreeView *data)
1490 GtkTreeViewColumn *column;
1492 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(accel_store), &iter);
1493 path = gtk_tree_model_get_path(GTK_TREE_MODEL(accel_store), &iter);
1494 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data),0);
1496 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(data),
1500 gtk_tree_path_free(path);
1505 static void accel_default_cb(GtkWidget *widget, gpointer data)
1507 accel_store_populate();
1509 g_idle_add((GSourceFunc)accel_default_scroll, data);
1512 void accel_remove_selection(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1514 gtk_tree_store_set(accel_store, iter, AE_KEY, "", -1);
1517 void accel_reset_selection(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
1520 gchar *accel_path, *accel;
1522 gtk_tree_model_get(model, iter, AE_ACCEL, &accel_path, -1);
1523 gtk_accel_map_lookup_entry(accel_path, &key);
1524 accel = gtk_accelerator_name(key.accel_key, key.accel_mods);
1526 gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_remove_key_cb, accel);
1528 gtk_tree_store_set(accel_store, iter, AE_KEY, accel, -1);
1533 static void accel_reset_cb(GtkWidget *widget, gpointer data)
1535 GtkTreeSelection *selection;
1537 if (!accel_store) return;
1538 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data));
1539 gtk_tree_selection_selected_foreach(selection, &accel_reset_selection, NULL);
1544 static GtkWidget *scrolled_notebook_page(GtkWidget *notebook, const gchar *title)
1548 GtkWidget *scrolled;
1549 GtkWidget *viewport;
1551 scrolled = gtk_scrolled_window_new(NULL, NULL);
1552 gtk_container_set_border_width(GTK_CONTAINER(scrolled), PREF_PAD_BORDER);
1553 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
1554 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1555 label = gtk_label_new(title);
1556 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled, label);
1557 gtk_widget_show(scrolled);
1559 viewport = gtk_viewport_new(NULL, NULL);
1560 gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
1561 gtk_container_add(GTK_CONTAINER(scrolled), viewport);
1562 gtk_widget_show(viewport);
1564 vbox = gtk_vbox_new(FALSE, 0);
1565 gtk_container_add(GTK_CONTAINER(viewport), vbox);
1566 gtk_widget_show(vbox);
1571 static void cache_standard_cb(GtkWidget *widget, gpointer data)
1573 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1575 c_options->thumbnails.spec_standard =TRUE;
1576 c_options->thumbnails.cache_into_dirs = FALSE;
1580 static void cache_geeqie_cb(GtkWidget *widget, gpointer data)
1582 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1584 c_options->thumbnails.spec_standard =FALSE;
1585 c_options->thumbnails.cache_into_dirs = FALSE;
1589 static void cache_local_cb(GtkWidget *widget, gpointer data)
1591 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
1593 c_options->thumbnails.cache_into_dirs = TRUE;
1594 c_options->thumbnails.spec_standard =FALSE;
1598 static void help_search_engine_entry_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1599 GdkEvent *event, gpointer userdata)
1601 if (pos == GTK_ENTRY_ICON_PRIMARY)
1603 gtk_entry_set_text(GTK_ENTRY(userdata), HELP_SEARCH_ENGINE);
1607 gtk_entry_set_text(GTK_ENTRY(userdata), "");
1611 static void star_rating_star_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1612 GdkEvent *event, gpointer userdata)
1614 gchar *rating_symbol;
1616 if (pos == GTK_ENTRY_ICON_PRIMARY)
1618 rating_symbol = g_strdup_printf("U+%X", STAR_RATING_STAR);
1619 gtk_entry_set_text(GTK_ENTRY(userdata), rating_symbol);
1620 g_free(rating_symbol);
1624 gtk_entry_set_text(GTK_ENTRY(userdata), "U+");
1625 gtk_widget_grab_focus(GTK_WIDGET(userdata));
1626 gtk_editable_select_region(GTK_EDITABLE(userdata), 2, 2);
1630 static void star_rating_rejected_icon_cb(GtkEntry *entry, GtkEntryIconPosition pos,
1631 GdkEvent *event, gpointer userdata)
1633 gchar *rating_symbol;
1635 if (pos == GTK_ENTRY_ICON_PRIMARY)
1637 rating_symbol = g_strdup_printf("U+%X", STAR_RATING_REJECTED);
1638 gtk_entry_set_text(GTK_ENTRY(userdata), rating_symbol);
1639 g_free(rating_symbol);
1643 gtk_entry_set_text(GTK_ENTRY(userdata), "U+");
1644 gtk_widget_grab_focus(GTK_WIDGET(userdata));
1645 gtk_editable_select_region(GTK_EDITABLE(userdata), 2, 2);
1649 static guint star_rating_symbol_test(GtkWidget *widget, gpointer data)
1651 GtkContainer *hbox = data;
1652 GString *str = g_string_new(NULL);
1653 GtkEntry *hex_code_entry;
1654 gchar *hex_code_full;
1657 guint64 hex_value = 0;
1659 list = gtk_container_get_children(hbox);
1661 hex_code_entry = g_list_nth_data(list, 2);
1662 hex_code_full = g_strdup(gtk_entry_get_text(hex_code_entry));
1664 hex_code = g_strsplit(hex_code_full, "+", 2);
1665 if (hex_code[0] && hex_code[1])
1667 hex_value = strtoull(hex_code[1], NULL, 16);
1669 if (!hex_value || hex_value > 0x10FFFF)
1671 hex_value = 0x003F; // Unicode 'Question Mark'
1673 str = g_string_append_unichar(str, (gunichar)hex_value);
1674 gtk_label_set_text(g_list_nth_data(list, 1), str->str);
1676 g_strfreev(hex_code);
1677 g_string_free(str, TRUE);
1678 g_free(hex_code_full);
1683 static void star_rating_star_test_cb(GtkWidget *widget, gpointer data)
1685 guint64 star_symbol;
1687 star_symbol = star_rating_symbol_test(widget, data);
1688 c_options->star_rating.star = star_symbol;
1691 static void star_rating_rejected_test_cb(GtkWidget *widget, gpointer data)
1693 guint64 rejected_symbol;
1695 rejected_symbol = star_rating_symbol_test(widget, data);
1696 c_options->star_rating.rejected = rejected_symbol;
1699 /* general options tab */
1700 static void config_tab_general(GtkWidget *notebook)
1705 GtkWidget *group_frame;
1706 GtkWidget *subgroup;
1708 GtkWidget *ct_button;
1711 gint hours, minutes, remainder;
1713 GtkWidget *star_rating_entry;
1715 gchar *rating_symbol;
1717 vbox = scrolled_notebook_page(notebook, _("General"));
1719 group = pref_group_new(vbox, FALSE, _("Thumbnails"), GTK_ORIENTATION_VERTICAL);
1721 table = pref_table_new(group, 2, 2, FALSE, FALSE);
1722 add_thumb_size_menu(table, 0, 0, _("Size:"));
1723 add_quality_menu(table, 0, 1, _("Quality:"), options->thumbnails.quality, &c_options->thumbnails.quality);
1725 ct_button = pref_checkbox_new_int(group, _("Cache thumbnails"),
1726 options->thumbnails.enable_caching, &c_options->thumbnails.enable_caching);
1728 subgroup = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1729 pref_checkbox_link_sensitivity(ct_button, subgroup);
1731 c_options->thumbnails.spec_standard = options->thumbnails.spec_standard;
1732 c_options->thumbnails.cache_into_dirs = options->thumbnails.cache_into_dirs;
1733 group_frame = pref_frame_new(subgroup, TRUE, _("Use Geeqie thumbnail style and cache"),
1734 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1735 button = pref_radiobutton_new(group_frame, NULL, get_thumbnails_cache_dir(),
1736 !options->thumbnails.spec_standard && !options->thumbnails.cache_into_dirs,
1737 G_CALLBACK(cache_geeqie_cb), NULL);
1739 group_frame = pref_frame_new(subgroup, TRUE,
1740 _("Store thumbnails local to image folder (non-standard)"),
1741 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1742 pref_radiobutton_new(group_frame, button, "*/.thumbnails",
1743 !options->thumbnails.spec_standard && options->thumbnails.cache_into_dirs,
1744 G_CALLBACK(cache_local_cb), NULL);
1746 group_frame = pref_frame_new(subgroup, TRUE,
1747 _("Use standard thumbnail style and cache, shared with other applications"),
1748 GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
1749 pref_radiobutton_new(group_frame, button, get_thumbnails_standard_cache_dir(),
1750 options->thumbnails.spec_standard && !options->thumbnails.cache_into_dirs,
1751 G_CALLBACK(cache_standard_cb), NULL);
1753 pref_checkbox_new_int(group, _("Use EXIF thumbnails when available (EXIF thumbnails may be outdated)"),
1754 options->thumbnails.use_exif, &c_options->thumbnails.use_exif);
1756 spin = pref_spin_new_int(group, _("Collection preview:"), NULL,
1758 options->thumbnails.collection_preview, &c_options->thumbnails.collection_preview);
1759 gtk_widget_set_tooltip_text(spin, _("The maximum number of thumbnails shown in a Collection preview montage"));
1761 #ifdef HAVE_FFMPEGTHUMBNAILER_METADATA
1762 pref_checkbox_new_int(group, _("Use embedded metadata in video files as thumbnails when available"),
1763 options->thumbnails.use_ft_metadata, &c_options->thumbnails.use_ft_metadata);
1765 // pref_checkbox_new_int(group, _("Ignore embedded metadata if size is too small"),
1766 // options->thumbnails.use_ft_metadata_small, &c_options->thumbnails.use_ft_metadata_small);
1769 group = pref_group_new(vbox, FALSE, _("Star Rating"), GTK_ORIENTATION_VERTICAL);
1771 c_options->star_rating.star = options->star_rating.star;
1772 c_options->star_rating.rejected = options->star_rating.rejected;
1774 str = g_string_new(NULL);
1775 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1776 pref_label_new(hbox, "Star character: ");
1777 str = g_string_append_unichar(str, options->star_rating.star);
1778 pref_label_new(hbox, g_strdup(str->str));
1779 rating_symbol = g_strdup_printf("U+%X", options->star_rating.star);
1780 star_rating_entry = gtk_entry_new();
1781 gtk_entry_set_text(GTK_ENTRY(star_rating_entry), rating_symbol);
1782 gtk_box_pack_start(GTK_BOX(hbox), star_rating_entry, FALSE, FALSE, 0);
1783 gtk_entry_set_width_chars(GTK_ENTRY(star_rating_entry), 15);
1784 gtk_widget_show(star_rating_entry);
1785 button = pref_button_new(NULL, NULL, _("Set"), FALSE,
1786 G_CALLBACK(star_rating_star_test_cb), hbox);
1787 gtk_widget_set_tooltip_text(button, _("Display selected character"));
1788 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1789 gtk_widget_show(button);
1790 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."));
1791 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1792 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1793 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1794 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1795 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1796 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1797 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1798 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1799 g_signal_connect(GTK_ENTRY(star_rating_entry), "icon-press",
1800 G_CALLBACK(star_rating_star_icon_cb),
1803 g_string_free(str, TRUE);
1804 g_free(rating_symbol);
1806 str = g_string_new(NULL);
1807 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1808 pref_label_new(hbox, "Rejected character: ");
1809 str = g_string_append_unichar(str, options->star_rating.rejected);
1810 pref_label_new(hbox, g_strdup(str->str));
1811 rating_symbol = g_strdup_printf("U+%X", options->star_rating.rejected);
1812 star_rating_entry = gtk_entry_new();
1813 gtk_entry_set_text(GTK_ENTRY(star_rating_entry), rating_symbol);
1814 gtk_box_pack_start(GTK_BOX(hbox), star_rating_entry, FALSE, FALSE, 0);
1815 gtk_entry_set_width_chars(GTK_ENTRY(star_rating_entry), 15);
1816 gtk_widget_show(star_rating_entry);
1817 button = pref_button_new(NULL, NULL, _("Set"), FALSE,
1818 G_CALLBACK(star_rating_rejected_test_cb), hbox);
1819 gtk_widget_set_tooltip_text(button, _("Display selected character"));
1820 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1821 gtk_widget_show(button);
1822 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."));
1823 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1824 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1825 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1826 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1827 gtk_entry_set_icon_from_stock(GTK_ENTRY(star_rating_entry),
1828 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1829 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(star_rating_entry),
1830 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1831 g_signal_connect(GTK_ENTRY(star_rating_entry), "icon-press",
1832 G_CALLBACK(star_rating_rejected_icon_cb),
1835 g_string_free(str, TRUE);
1836 g_free(rating_symbol);
1838 group = pref_group_new(vbox, FALSE, _("Slide show"), GTK_ORIENTATION_VERTICAL);
1840 c_options->slideshow.delay = options->slideshow.delay;
1841 hours = options->slideshow.delay / (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1842 remainder = options->slideshow.delay % (3600 * SLIDESHOW_SUBSECOND_PRECISION);
1843 minutes = remainder / (60 * SLIDESHOW_SUBSECOND_PRECISION);
1844 seconds = (gdouble)(remainder % (60 * SLIDESHOW_SUBSECOND_PRECISION)) /
1845 SLIDESHOW_SUBSECOND_PRECISION;
1847 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1849 spin = pref_spin_new(hbox, _("Delay between image change hrs:mins:secs.dec"), NULL,
1851 options->slideshow.delay ? hours : 0.0,
1852 G_CALLBACK(slideshow_delay_hours_cb), NULL);
1853 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1854 spin = pref_spin_new(hbox, ":" , NULL,
1856 options->slideshow.delay ? minutes: 0.0,
1857 G_CALLBACK(slideshow_delay_minutes_cb), NULL);
1858 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1859 spin = pref_spin_new(hbox, ":", NULL,
1860 SLIDESHOW_MIN_SECONDS, 59, 1.0, 1,
1861 options->slideshow.delay ? seconds : 10.0,
1862 G_CALLBACK(slideshow_delay_seconds_cb), NULL);
1863 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1865 pref_checkbox_new_int(group, _("Random"), options->slideshow.random, &c_options->slideshow.random);
1866 pref_checkbox_new_int(group, _("Repeat"), options->slideshow.repeat, &c_options->slideshow.repeat);
1868 group = pref_group_new(vbox, FALSE, _("Image loading and caching"), GTK_ORIENTATION_VERTICAL);
1870 pref_spin_new_int(group, _("Decoded image cache size (Mb):"), NULL,
1871 0, 99999, 1, options->image.image_cache_max, &c_options->image.image_cache_max);
1872 pref_checkbox_new_int(group, _("Preload next image"),
1873 options->image.enable_read_ahead, &c_options->image.enable_read_ahead);
1875 pref_checkbox_new_int(group, _("Refresh on file change"),
1876 options->update_on_time_change, &c_options->update_on_time_change);
1878 group = pref_group_new(vbox, FALSE, _("Info sidebar heights"), GTK_ORIENTATION_VERTICAL);
1879 pref_label_new(group, _("NOTE! Geeqie must be restarted for changes to take effect"));
1880 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1881 pref_spin_new_int(hbox, _("Keywords:"), NULL,
1883 options->info_keywords.height, &c_options->info_keywords.height);
1884 pref_spin_new_int(hbox, _("Title:"), NULL,
1886 options->info_title.height, &c_options->info_title.height);
1887 pref_spin_new_int(hbox, _("Comment:"), NULL,
1889 options->info_comment.height, &c_options->info_comment.height);
1890 pref_spin_new_int(hbox, _("Rating:"), NULL,
1892 options->info_rating.height, &c_options->info_rating.height);
1894 group = pref_group_new(vbox, FALSE, _("Show predefined keyword tree"), GTK_ORIENTATION_VERTICAL);
1896 pref_checkbox_new_int(group, _("Show predefined keyword tree (NOTE! Geeqie must be restarted for change to take effect)"),
1897 options->show_predefined_keyword_tree, &c_options->show_predefined_keyword_tree);
1899 group = pref_group_new(vbox, FALSE, _("On-line help search engine"), GTK_ORIENTATION_VERTICAL);
1901 help_search_engine_entry = gtk_entry_new();
1902 gtk_entry_set_text(GTK_ENTRY(help_search_engine_entry), options->help_search_engine);
1903 gtk_box_pack_start(GTK_BOX(group), help_search_engine_entry, FALSE, FALSE, 0);
1904 gtk_widget_show(help_search_engine_entry);
1906 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"));
1908 gtk_entry_set_icon_from_stock(GTK_ENTRY(help_search_engine_entry),
1909 GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1910 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(help_search_engine_entry),
1911 GTK_ENTRY_ICON_SECONDARY, _("Clear"));
1912 gtk_entry_set_icon_from_stock(GTK_ENTRY(help_search_engine_entry),
1913 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_REVERT_TO_SAVED);
1914 gtk_entry_set_icon_tooltip_text (GTK_ENTRY(help_search_engine_entry),
1915 GTK_ENTRY_ICON_PRIMARY, _("Default"));
1916 g_signal_connect(GTK_ENTRY(help_search_engine_entry), "icon-press",
1917 G_CALLBACK(help_search_engine_entry_icon_cb),
1918 help_search_engine_entry);
1922 static void config_tab_image(GtkWidget *notebook)
1927 GtkWidget *ct_button;
1928 GtkWidget *enlargement_button;
1932 vbox = scrolled_notebook_page(notebook, _("Image"));
1934 group = pref_group_new(vbox, FALSE, _("Zoom"), GTK_ORIENTATION_VERTICAL);
1936 table = pref_table_new(group, 2, 1, FALSE, FALSE);
1937 add_quality_menu(table, 0, 0, _("Quality:"), options->image.zoom_quality, &c_options->image.zoom_quality);
1940 pref_checkbox_new_int(group, _("Use GPU acceleration via Clutter library"),
1941 options->image.use_clutter_renderer, &c_options->image.use_clutter_renderer);
1944 pref_checkbox_new_int(group, _("Two pass rendering (apply HQ zoom and color correction in second pass)"),
1945 options->image.zoom_2pass, &c_options->image.zoom_2pass);
1947 c_options->image.zoom_increment = options->image.zoom_increment;
1948 spin = pref_spin_new(group, _("Zoom increment:"), NULL,
1949 0.01, 4.0, 0.01, 2, (gdouble)options->image.zoom_increment / 100.0,
1950 G_CALLBACK(zoom_increment_cb), NULL);
1951 gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
1953 group = pref_group_new(vbox, FALSE, _("Fit image to window"), GTK_ORIENTATION_VERTICAL);
1955 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1956 enlargement_button = pref_checkbox_new_int(hbox, _("Allow enlargement of image (max. size in %)"),
1957 options->image.zoom_to_fit_allow_expand, &c_options->image.zoom_to_fit_allow_expand);
1958 spin = pref_spin_new_int(hbox, NULL, NULL,
1960 options->image.max_enlargement_size, &c_options->image.max_enlargement_size);
1961 pref_checkbox_link_sensitivity(enlargement_button, spin);
1962 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."));
1964 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
1965 ct_button = pref_checkbox_new_int(hbox, _("Virtual window size (% of actual window):"),
1966 options->image.limit_autofit_size, &c_options->image.limit_autofit_size);
1967 spin = pref_spin_new_int(hbox, NULL, NULL,
1969 options->image.max_autofit_size, &c_options->image.max_autofit_size);
1970 pref_checkbox_link_sensitivity(ct_button, spin);
1971 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."));
1973 group = pref_group_new(vbox, FALSE, _("Appearance"), GTK_ORIENTATION_VERTICAL);
1975 pref_checkbox_new_int(group, _("Use custom border color in window mode"),
1976 options->image.use_custom_border_color, &c_options->image.use_custom_border_color);
1978 pref_checkbox_new_int(group, _("Use custom border color in fullscreen mode"),
1979 options->image.use_custom_border_color_in_fullscreen, &c_options->image.use_custom_border_color_in_fullscreen);
1981 pref_color_button_new(group, _("Border color"), &options->image.border_color,
1982 G_CALLBACK(pref_color_button_set_cb), &c_options->image.border_color);
1984 c_options->image.border_color = options->image.border_color;
1986 pref_color_button_new(group, _("Alpha channel color 1"), &options->image.alpha_color_1,
1987 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_1);
1989 pref_color_button_new(group, _("Alpha channel color 2"), &options->image.alpha_color_2,
1990 G_CALLBACK(pref_color_button_set_cb), &c_options->image.alpha_color_2);
1992 c_options->image.alpha_color_1 = options->image.alpha_color_1;
1993 c_options->image.alpha_color_2 = options->image.alpha_color_2;
1995 group = pref_group_new(vbox, FALSE, _("Convenience"), GTK_ORIENTATION_VERTICAL);
1997 pref_checkbox_new_int(group, _("Auto rotate proofs using Exif information"),
1998 options->image.exif_proof_rotate_enable, &c_options->image.exif_proof_rotate_enable);
2002 static void config_tab_windows(GtkWidget *notebook)
2008 GtkWidget *ct_button;
2011 vbox = scrolled_notebook_page(notebook, _("Windows"));
2013 group = pref_group_new(vbox, FALSE, _("State"), GTK_ORIENTATION_VERTICAL);
2015 ct_button = pref_checkbox_new_int(group, _("Remember window positions"),
2016 options->save_window_positions, &c_options->save_window_positions);
2018 button = pref_checkbox_new_int(group, _("Use saved window positions also for new windows"),
2019 options->use_saved_window_positions_for_new_windows, &c_options->use_saved_window_positions_for_new_windows);
2020 pref_checkbox_link_sensitivity(ct_button, button);
2022 pref_checkbox_new_int(group, _("Remember tool state (float/hidden)"),
2023 options->tools_restore_state, &c_options->tools_restore_state);
2025 pref_checkbox_new_int(group, _("Remember dialog window positions"),
2026 options->save_dialog_window_positions, &c_options->save_dialog_window_positions);
2028 pref_checkbox_new_int(group, _("Show window IDs"),
2029 options->show_window_ids, &c_options->show_window_ids);
2031 group = pref_group_new(vbox, FALSE, _("Size"), GTK_ORIENTATION_VERTICAL);
2033 pref_checkbox_new_int(group, _("Fit window to image when tools are hidden/floating"),
2034 options->image.fit_window_to_image, &c_options->image.fit_window_to_image);
2036 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2037 ct_button = pref_checkbox_new_int(hbox, _("Limit size when auto-sizing window (%):"),
2038 options->image.limit_window_size, &c_options->image.limit_window_size);
2039 spin = pref_spin_new_int(hbox, NULL, NULL,
2041 options->image.max_window_size, &c_options->image.max_window_size);
2042 pref_checkbox_link_sensitivity(ct_button, spin);
2044 group = pref_group_new(vbox, FALSE, _("Full screen"), GTK_ORIENTATION_VERTICAL);
2046 c_options->fullscreen.screen = options->fullscreen.screen;
2047 c_options->fullscreen.above = options->fullscreen.above;
2048 hbox = fullscreen_prefs_selection_new(_("Location:"), &c_options->fullscreen.screen, &c_options->fullscreen.above);
2049 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2050 gtk_widget_show(hbox);
2052 pref_checkbox_new_int(group, _("Smooth image flip"),
2053 options->fullscreen.clean_flip, &c_options->fullscreen.clean_flip);
2054 pref_checkbox_new_int(group, _("Disable screen saver"),
2055 options->fullscreen.disable_saver, &c_options->fullscreen.disable_saver);
2058 /* overlay screen display tab */
2059 static const gchar *predefined_tags[][2] = {
2060 {"%name%", N_("Name")},
2061 {"%path:60%*", N_("Path")},
2062 {"%date%", N_("Date")},
2063 {"%size%", N_("Size")},
2064 {"%zoom%", N_("Zoom")},
2065 {"%dimensions%", N_("Dimensions")},
2066 {"%collection%", N_("Collection")},
2067 {"%number%", N_("Collection number")},
2068 {"%total%", N_("Collection total")},
2069 {"%file.ctime%", N_("File ctime")},
2070 {"%file.mode%", N_("File mode")},
2071 {"%file.owner%", N_("File owner")},
2072 {"%file.group%", N_("File group")},
2073 {"%file.link%", N_("File link")},
2074 {"%file.class%", N_("File class")},
2075 {"%formatted.DateTime%", N_("Image date")},
2076 {"%formatted.DateTimeDigitized%", N_("Date digitized")},
2077 {"%formatted.ShutterSpeed%", N_("ShutterSpeed")},
2078 {"%formatted.Aperture%", N_("Aperture")},
2079 {"%formatted.ExposureBias%", N_("Exposure bias")},
2080 {"%formatted.Resolution%", N_("Resolution")},
2081 {"%formatted.Camera%", N_("Camera")},
2082 {"%formatted.ShutterSpeed%", N_("Shutter speed")},
2083 {"%formatted.ISOSpeedRating%", N_("ISO")},
2084 {"%formatted.FocalLength%", N_("Focal length")},
2085 {"%formatted.FocalLength35mmFilm%", N_("Focal len. 35mm")},
2086 {"%formatted.SubjectDistance%", N_("Subject distance")},
2087 {"%formatted.Flash%", N_("Flash")},
2088 {"%formatted.ColorProfile%", N_("Color profile")},
2089 {"%formatted.GPSPosition%", N_("Lat, Long")},
2090 {"%formatted.GPSAltitude%", N_("Altitude")},
2091 {"%formatted.localtime%", N_("Local time")},
2092 {"%formatted.timezone%", N_("Timezone")},
2093 {"%formatted.countryname%", N_("Country name")},
2094 {"%formatted.countrycode%", N_("Country code")},
2095 {"%formatted.star_rating%", N_("Star rating")},
2098 static GtkTargetEntry osd_drag_types[] = {
2099 { "text/plain", GTK_TARGET_SAME_APP, TARGET_TEXT_PLAIN }
2102 typedef struct _TagData TagData;
2109 static void tag_button_cb(GtkWidget *widget, gpointer data)
2111 GtkTextView *image_overlay_template_view = data;
2112 GtkTextBuffer *buffer;
2115 buffer = gtk_text_view_get_buffer(image_overlay_template_view);
2116 td = g_object_get_data(G_OBJECT(widget), "tag_data");
2117 gtk_text_buffer_insert_at_cursor(GTK_TEXT_BUFFER(buffer), td->key, -1);
2119 gtk_widget_grab_focus(GTK_WIDGET(image_overlay_template_view));
2122 static void osd_dnd_get_cb(GtkWidget *btn, GdkDragContext *context,
2123 GtkSelectionData *selection_data, guint info,
2124 guint time, gpointer data)
2127 GtkTextView *image_overlay_template_view = data;
2129 td = g_object_get_data(G_OBJECT(btn), "tag_data");
2130 gtk_selection_data_set_text(selection_data, td->key, -1);
2132 gtk_widget_grab_focus(GTK_WIDGET(image_overlay_template_view));
2135 static void osd_btn_destroy_cb(GtkWidget *btn, GdkDragContext *context,
2136 GtkSelectionData *selection_data, guint info,
2137 guint time, gpointer data)
2141 td = g_object_get_data(G_OBJECT(btn), "tag_data");
2146 static void set_osd_button(GtkWidget *widget, const gchar *key, const gchar *title,
2147 GtkWidget *image_overlay_template_view)
2149 GtkWidget *new_button;
2152 new_button = pref_button_new(widget, NULL, _(title), TRUE,
2153 G_CALLBACK(tag_button_cb), image_overlay_template_view);
2155 td = g_new0(TagData, 1);
2156 td->key = g_strdup(key);
2157 td->title = g_strdup(title);
2159 g_object_set_data(G_OBJECT(new_button), "tag_data", td);
2161 gtk_drag_source_set(new_button, GDK_BUTTON1_MASK, osd_drag_types, 1, GDK_ACTION_COPY);
2162 g_signal_connect(G_OBJECT(new_button), "drag_data_get",
2163 G_CALLBACK(osd_dnd_get_cb), image_overlay_template_view);
2164 g_signal_connect(G_OBJECT(new_button), "destroy",
2165 G_CALLBACK(osd_btn_destroy_cb), new_button);
2168 static void config_tab_osd(GtkWidget *notebook)
2172 GtkWidget *vbox_buttons;
2175 GtkWidget *image_overlay_template_view;
2176 GtkWidget *scrolled;
2177 GtkTextBuffer *buffer;
2179 GtkWidget * subgroup;
2184 vbox = scrolled_notebook_page(notebook, _("OSD"));
2186 image_overlay_template_view = gtk_text_view_new();
2188 group = pref_group_new(vbox, FALSE, _("Overlay Screen Display"), GTK_ORIENTATION_VERTICAL);
2190 hbox = gtk_hbox_new(FALSE, 0);
2192 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2193 gtk_widget_show(hbox);
2195 pref_label_new(hbox, _("To include predefined tags in the template, click a button or drag-and-drop"));
2197 subgroup = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
2198 hbox = gtk_hbox_new(FALSE, 0);
2199 gtk_box_pack_start(GTK_BOX(subgroup), hbox, FALSE, FALSE, 0);
2200 gtk_widget_show(hbox);
2202 for (cols = 0; cols < 6; cols++)
2204 vbox_buttons = gtk_vbox_new(FALSE, 0);
2207 gtk_box_pack_start(GTK_BOX(hbox), vbox_buttons, FALSE, FALSE, 0);
2209 while (rows < 6 && predefined_tags[i][0])
2211 set_osd_button(vbox_buttons, predefined_tags[i][0], predefined_tags[i][1], image_overlay_template_view);
2215 gtk_widget_show(vbox_buttons);
2218 pref_line(group, PREF_PAD_GAP);
2220 pref_label_new(group, _("Image overlay template"));
2222 scrolled = gtk_scrolled_window_new(NULL, NULL);
2223 gtk_widget_set_size_request(scrolled, 200, 150);
2224 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2225 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
2226 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2227 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 5);
2228 gtk_widget_show(scrolled);
2230 gtk_widget_set_tooltip_markup(image_overlay_template_view,
2231 _("Extensive formatting options are shown in the Help file"));
2233 gtk_container_add(GTK_CONTAINER(scrolled), image_overlay_template_view);
2234 gtk_widget_show(image_overlay_template_view);
2236 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2238 #if GTK_CHECK_VERSION(3,4,0)
2239 button = pref_button_new(NULL, GTK_STOCK_SELECT_FONT, _("Font"), FALSE,
2240 G_CALLBACK(image_overlay_set_font_cb), notebook);
2242 button = gtk_font_button_new();
2243 gtk_font_button_set_title(GTK_FONT_BUTTON(button), "Image Overlay Font");
2244 gtk_font_button_set_font_name(GTK_FONT_BUTTON(button), options->image_overlay.font);
2245 g_signal_connect(G_OBJECT(button), "font-set",
2246 G_CALLBACK(image_overlay_set_font_cb),NULL);
2248 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2249 gtk_widget_show(button);
2251 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Text"), FALSE,
2252 G_CALLBACK(image_overlay_set_text_colour_cb), NULL);
2253 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2254 gtk_widget_show(button);
2256 button = pref_button_new(NULL, GTK_STOCK_COLOR_PICKER, _("Background"), FALSE,
2257 G_CALLBACK(image_overlay_set_background_colour_cb), NULL);
2258 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2259 gtk_widget_show(button);
2260 image_overlay_set_text_colours();
2262 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2263 G_CALLBACK(image_overlay_default_template_cb), image_overlay_template_view);
2264 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2265 gtk_widget_show(button);
2267 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
2268 G_CALLBACK(image_overlay_help_cb), NULL);
2269 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2270 gtk_widget_show(button);
2272 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(image_overlay_template_view));
2273 if (options->image_overlay.template_string) gtk_text_buffer_set_text(buffer, options->image_overlay.template_string, -1);
2274 g_signal_connect(G_OBJECT(buffer), "changed",
2275 G_CALLBACK(image_overlay_template_view_changed_cb), image_overlay_template_view);
2277 pref_line(group, PREF_PAD_GAP);
2279 group = pref_group_new(vbox, FALSE, _("Exif, XMP or IPTC tags"), GTK_ORIENTATION_VERTICAL);
2280 hbox = gtk_hbox_new(FALSE, 0);
2281 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2282 gtk_widget_show(hbox);
2283 label = gtk_label_new(_("%Exif.Image.Orientation%"));
2284 gtk_box_pack_start(GTK_BOX(hbox),label, FALSE,FALSE,0);
2285 gtk_widget_show(label);
2286 pref_spacer(group,TRUE);
2288 group = pref_group_new(vbox, FALSE, _("Field separators"), GTK_ORIENTATION_VERTICAL);
2289 hbox = gtk_hbox_new(FALSE, 0);
2290 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2291 gtk_widget_show(hbox);
2292 label = gtk_label_new(_("Separator shown only if both fields are non-null:\n%formatted.ShutterSpeed%|%formatted.ISOSpeedRating%"));
2293 gtk_box_pack_start(GTK_BOX(hbox),label, FALSE,FALSE,0);
2294 gtk_widget_show(label);
2295 pref_spacer(group,TRUE);
2297 group = pref_group_new(vbox, FALSE, _("Field maximum length"), GTK_ORIENTATION_VERTICAL);
2298 hbox = gtk_hbox_new(FALSE, 0);
2299 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2300 gtk_widget_show(hbox);
2301 label = gtk_label_new(_("%path:39%"));
2302 gtk_box_pack_start(GTK_BOX(hbox),label, FALSE,FALSE,0);
2303 gtk_widget_show(label);
2304 pref_spacer(group,TRUE);
2306 group = pref_group_new(vbox, FALSE, _("Pre- and post- text"), GTK_ORIENTATION_VERTICAL);
2307 hbox = gtk_hbox_new(FALSE, 0);
2308 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2309 gtk_widget_show(hbox);
2310 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%"));
2311 gtk_box_pack_start(GTK_BOX(hbox),label, FALSE,FALSE,0);
2312 gtk_widget_show(label);
2313 pref_spacer(group,TRUE);
2315 group = pref_group_new(vbox, FALSE, _("Pango markup"), GTK_ORIENTATION_VERTICAL);
2316 hbox = gtk_hbox_new(FALSE, 0);
2317 gtk_box_pack_start(GTK_BOX(group), hbox, FALSE, FALSE, 0);
2318 gtk_widget_show(hbox);
2319 label = gtk_label_new(_("<b>bold</b>\n<u>underline</u>\n<i>italic</i>\n<s>strikethrough</s>"));
2320 gtk_box_pack_start(GTK_BOX(hbox),label, FALSE,FALSE,0);
2321 gtk_widget_show(label);
2324 static GtkTreeModel *create_class_model(void)
2326 GtkListStore *model;
2330 /* create list store */
2331 model = gtk_list_store_new(1, G_TYPE_STRING);
2332 for (i = 0; i < FILE_FORMAT_CLASSES; i++)
2334 gtk_list_store_append(model, &iter);
2335 gtk_list_store_set(model, &iter, 0, _(format_class_list[i]), -1);
2337 return GTK_TREE_MODEL (model);
2342 static void config_tab_files(GtkWidget *notebook)
2349 GtkWidget *ct_button;
2350 GtkWidget *scrolled;
2351 GtkWidget *filter_view;
2352 GtkCellRenderer *renderer;
2353 GtkTreeSelection *selection;
2354 GtkTreeViewColumn *column;
2356 vbox = scrolled_notebook_page(notebook, _("Files"));
2358 group = pref_box_new(vbox, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
2360 pref_checkbox_new_int(group, _("Show hidden files or folders"),
2361 options->file_filter.show_hidden_files, &c_options->file_filter.show_hidden_files);
2362 pref_checkbox_new_int(group, _("Show parent folder (..)"),
2363 options->file_filter.show_parent_directory, &c_options->file_filter.show_parent_directory);
2364 pref_checkbox_new_int(group, _("Case sensitive sort"),
2365 options->file_sort.case_sensitive, &c_options->file_sort.case_sensitive);
2366 pref_checkbox_new_int(group, _("Natural sort order"),
2367 options->file_sort.natural, &c_options->file_sort.natural);
2368 pref_checkbox_new_int(group, _("Disable file extension checks"),
2369 options->file_filter.disable_file_extension_checks, &c_options->file_filter.disable_file_extension_checks);
2371 ct_button = pref_checkbox_new_int(group, _("Disable File Filtering"),
2372 options->file_filter.disable, &c_options->file_filter.disable);
2375 group = pref_group_new(vbox, FALSE, _("Grouping sidecar extensions"), GTK_ORIENTATION_VERTICAL);
2377 sidecar_ext_entry = gtk_entry_new();
2378 gtk_entry_set_text(GTK_ENTRY(sidecar_ext_entry), options->sidecar.ext);
2379 gtk_box_pack_start(GTK_BOX(group), sidecar_ext_entry, FALSE, FALSE, 0);
2380 gtk_widget_show(sidecar_ext_entry);
2382 group = pref_group_new(vbox, TRUE, _("File types"), GTK_ORIENTATION_VERTICAL);
2384 frame = pref_group_parent(group);
2385 g_signal_connect(G_OBJECT(ct_button), "toggled",
2386 G_CALLBACK(filter_disable_cb), frame);
2387 gtk_widget_set_sensitive(frame, !options->file_filter.disable);
2389 scrolled = gtk_scrolled_window_new(NULL, NULL);
2390 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2391 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2392 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2393 gtk_widget_show(scrolled);
2395 filter_store = gtk_list_store_new(1, G_TYPE_POINTER);
2396 filter_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(filter_store));
2397 g_object_unref(filter_store);
2398 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(filter_view));
2399 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_SINGLE);
2401 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(filter_view), FALSE);
2403 column = gtk_tree_view_column_new();
2404 gtk_tree_view_column_set_title(column, _("Filter"));
2405 gtk_tree_view_column_set_resizable(column, TRUE);
2407 renderer = gtk_cell_renderer_toggle_new();
2408 g_signal_connect(G_OBJECT(renderer), "toggled",
2409 G_CALLBACK(filter_store_enable_cb), filter_store);
2410 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2411 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2412 GINT_TO_POINTER(FE_ENABLE), NULL);
2414 renderer = gtk_cell_renderer_text_new();
2415 g_signal_connect(G_OBJECT(renderer), "edited",
2416 G_CALLBACK(filter_store_ext_edit_cb), filter_store);
2417 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2418 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2419 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2420 GINT_TO_POINTER(FE_EXTENSION), NULL);
2421 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2423 column = gtk_tree_view_column_new();
2424 gtk_tree_view_column_set_title(column, _("Description"));
2425 gtk_tree_view_column_set_resizable(column, TRUE);
2426 gtk_tree_view_column_set_fixed_width(column, 200);
2427 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
2429 renderer = gtk_cell_renderer_text_new();
2430 g_signal_connect(G_OBJECT(renderer), "edited",
2431 G_CALLBACK(filter_store_desc_edit_cb), filter_store);
2432 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, NULL);
2433 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2434 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2435 GINT_TO_POINTER(FE_DESCRIPTION), NULL);
2436 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2438 column = gtk_tree_view_column_new();
2439 gtk_tree_view_column_set_title(column, _("Class"));
2440 gtk_tree_view_column_set_resizable(column, TRUE);
2441 renderer = gtk_cell_renderer_combo_new();
2442 g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE,
2443 "model", create_class_model(),
2448 g_signal_connect(G_OBJECT(renderer), "edited",
2449 G_CALLBACK(filter_store_class_edit_cb), filter_store);
2450 gtk_tree_view_column_pack_start(column, renderer, TRUE);
2451 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2452 GINT_TO_POINTER(FE_CLASS), NULL);
2453 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2455 column = gtk_tree_view_column_new();
2456 gtk_tree_view_column_set_title(column, _("Writable"));
2457 gtk_tree_view_column_set_resizable(column, FALSE);
2458 renderer = gtk_cell_renderer_toggle_new();
2459 g_signal_connect(G_OBJECT(renderer), "toggled",
2460 G_CALLBACK(filter_store_writable_cb), filter_store);
2461 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2462 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2463 GINT_TO_POINTER(FE_WRITABLE), NULL);
2464 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2466 column = gtk_tree_view_column_new();
2467 gtk_tree_view_column_set_title(column, _("Sidecar is allowed"));
2468 gtk_tree_view_column_set_resizable(column, FALSE);
2469 renderer = gtk_cell_renderer_toggle_new();
2470 g_signal_connect(G_OBJECT(renderer), "toggled",
2471 G_CALLBACK(filter_store_sidecar_cb), filter_store);
2472 gtk_tree_view_column_pack_start(column, renderer, FALSE);
2473 gtk_tree_view_column_set_cell_data_func(column, renderer, filter_set_func,
2474 GINT_TO_POINTER(FE_ALLOW_SIDECAR), NULL);
2475 gtk_tree_view_append_column(GTK_TREE_VIEW(filter_view), column);
2478 filter_store_populate();
2479 gtk_container_add(GTK_CONTAINER(scrolled), filter_view);
2480 gtk_widget_show(filter_view);
2482 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2484 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
2485 G_CALLBACK(filter_default_cb), filter_view);
2486 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2487 gtk_widget_show(button);
2489 button = pref_button_new(NULL, GTK_STOCK_REMOVE, NULL, FALSE,
2490 G_CALLBACK(filter_remove_cb), filter_view);
2491 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2492 gtk_widget_show(button);
2494 button = pref_button_new(NULL, GTK_STOCK_ADD, NULL, FALSE,
2495 G_CALLBACK(filter_add_cb), filter_view);
2496 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
2497 gtk_widget_show(button);
2501 static void config_tab_metadata(GtkWidget *notebook)
2506 GtkWidget *ct_button;
2510 vbox = scrolled_notebook_page(notebook, _("Metadata"));
2513 group = pref_group_new(vbox, FALSE, _("Metadata writing process"), GTK_ORIENTATION_VERTICAL);
2515 label = pref_label_new(group, _("Warning: Geeqie is built without Exiv2. Some options are disabled."));
2517 label = pref_label_new(group, _("Metadata are written in the following order. The process ends after first success."));
2518 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2520 ct_button = pref_checkbox_new_int(group, _("1) Save metadata in image files, or sidecar files, according to the XMP standard"),
2521 options->metadata.save_in_image_file, &c_options->metadata.save_in_image_file);
2523 gtk_widget_set_sensitive(ct_button, FALSE);
2526 pref_checkbox_new_int(group, _("2) Save metadata in '.metadata' folder, local to image folder (non-standard)"),
2527 options->metadata.enable_metadata_dirs, &c_options->metadata.enable_metadata_dirs);
2529 text = g_strdup_printf(_("3) Save metadata in Geeqie private directory '%s'"), get_metadata_cache_dir());
2530 label = pref_label_new(group, text);
2531 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
2532 gtk_misc_set_padding(GTK_MISC(label), 22, 0);
2535 group = pref_group_new(vbox, FALSE, _("Step 1: Write to image files"), GTK_ORIENTATION_VERTICAL);
2537 gtk_widget_set_sensitive(group, FALSE);
2540 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
2541 pref_checkbox_link_sensitivity(ct_button, hbox);
2543 pref_checkbox_new_int(hbox, _("Store metadata also in legacy IPTC tags (converted according to IPTC4XMP standard)"),
2544 options->metadata.save_legacy_IPTC, &c_options->metadata.save_legacy_IPTC);
2546 pref_checkbox_new_int(hbox, _("Warn if the image files are unwritable"),
2547 options->metadata.warn_on_write_problems, &c_options->metadata.warn_on_write_problems);
2549 pref_checkbox_new_int(hbox, _("Ask before writing to image files"),
2550 options->metadata.confirm_write, &c_options->metadata.confirm_write);
2552 pref_checkbox_new_int(hbox, _("Create sidecar files named image.ext.xmp (as opposed to image.xmp)"),
2553 options->metadata.sidecar_extended_name, &c_options->metadata.sidecar_extended_name);
2555 group = pref_group_new(vbox, FALSE, _("Step 2 and 3: write to Geeqie private files"), GTK_ORIENTATION_VERTICAL);
2557 gtk_widget_set_sensitive(group, FALSE);
2560 pref_checkbox_new_int(group, _("Use GQview legacy metadata format (supports only keywords and comments) instead of XMP"),
2561 options->metadata.save_legacy_format, &c_options->metadata.save_legacy_format);
2564 group = pref_group_new(vbox, FALSE, _("Miscellaneous"), GTK_ORIENTATION_VERTICAL);
2565 pref_checkbox_new_int(group, _("Write the same description tags (keywords, comment, etc.) to all grouped sidecars"),
2566 options->metadata.sync_grouped_files, &c_options->metadata.sync_grouped_files);
2568 pref_checkbox_new_int(group, _("Allow keywords to differ only in case"),
2569 options->metadata.keywords_case_sensitive, &c_options->metadata.keywords_case_sensitive);
2571 ct_button = pref_checkbox_new_int(group, _("Write altered image orientation to the metadata"),
2572 options->metadata.write_orientation, &c_options->metadata.write_orientation);
2574 gtk_widget_set_sensitive(ct_button, FALSE);
2577 group = pref_group_new(vbox, FALSE, _("Auto-save options"), GTK_ORIENTATION_VERTICAL);
2579 ct_button = pref_checkbox_new_int(group, _("Write metadata after timeout"),
2580 options->metadata.confirm_after_timeout, &c_options->metadata.confirm_after_timeout);
2582 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2583 pref_checkbox_link_sensitivity(ct_button, hbox);
2585 pref_spin_new_int(hbox, _("Timeout (seconds):"), NULL, 0, 900, 1,
2586 options->metadata.confirm_timeout, &c_options->metadata.confirm_timeout);
2588 pref_checkbox_new_int(group, _("Write metadata on image change"),
2589 options->metadata.confirm_on_image_change, &c_options->metadata.confirm_on_image_change);
2591 pref_checkbox_new_int(group, _("Write metadata on directory change"),
2592 options->metadata.confirm_on_dir_change, &c_options->metadata.confirm_on_dir_change);
2594 group = pref_group_new(vbox, FALSE, _("Pre-load metadata"), GTK_ORIENTATION_VERTICAL);
2596 ct_button = pref_checkbox_new_int(group, _("Read metadata in background"),
2597 options->read_metadata_in_idle, &c_options->read_metadata_in_idle);
2598 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");
2603 typedef struct _KeywordFindData KeywordFindData;
2604 struct _KeywordFindData
2611 GtkWidget *button_close;
2612 GtkWidget *button_stop;
2613 GtkWidget *button_start;
2614 GtkWidget *progress;
2622 guint idle_id; /* event source id */
2625 #define KEYWORD_DIALOG_WIDTH 400
2627 static void keywords_find_folder(KeywordFindData *kfd, FileData *dir_fd)
2629 GList *list_d = NULL;
2630 GList *list_f = NULL;
2634 filelist_read(dir_fd, &list_f, &list_d);
2638 filelist_read(dir_fd, &list_f, NULL);
2641 list_f = filelist_filter(list_f, FALSE);
2642 list_d = filelist_filter(list_d, TRUE);
2644 kfd->list = g_list_concat(list_f, kfd->list);
2645 kfd->list_dir = g_list_concat(list_d, kfd->list_dir);
2648 static void keywords_find_reset(KeywordFindData *kfd)
2650 filelist_free(kfd->list);
2653 filelist_free(kfd->list_dir);
2654 kfd->list_dir = NULL;
2657 static void keywords_find_close_cb(GenericDialog *fd, gpointer data)
2659 KeywordFindData *kfd = data;
2661 if (!gtk_widget_get_sensitive(kfd->button_close)) return;
2663 keywords_find_reset(kfd);
2664 generic_dialog_close(kfd->gd);
2668 static void keywords_find_finish(KeywordFindData *kfd)
2670 keywords_find_reset(kfd);
2672 gtk_entry_set_text(GTK_ENTRY(kfd->progress), _("done"));
2673 spinner_set_interval(kfd->spinner, -1);
2675 gtk_widget_set_sensitive(kfd->group, TRUE);
2676 gtk_widget_set_sensitive(kfd->button_start, TRUE);
2677 gtk_widget_set_sensitive(kfd->button_stop, FALSE);
2678 gtk_widget_set_sensitive(kfd->button_close, TRUE);
2681 static void keywords_find_stop_cb(GenericDialog *fd, gpointer data)
2683 KeywordFindData *kfd = data;
2685 g_idle_remove_by_data(kfd);
2687 keywords_find_finish(kfd);
2690 static gboolean keywords_find_file(gpointer data)
2692 KeywordFindData *kfd = data;
2694 GtkTextBuffer *buffer;
2702 fd = kfd->list->data;
2703 kfd->list = g_list_remove(kfd->list, fd);
2705 keywords = metadata_read_list(fd, KEYWORD_KEY, METADATA_PLAIN);
2706 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(keyword_text));
2710 gtk_text_buffer_get_end_iter(buffer, &iter);
2711 tmp = g_strconcat(keywords->data, "\n", NULL);
2712 gtk_text_buffer_insert(buffer, &iter, tmp, -1);
2714 keywords = keywords->next;
2717 gtk_entry_set_text(GTK_ENTRY(kfd->progress), fd->path);
2718 file_data_unref(fd);
2719 string_list_free(keywords);
2723 else if (kfd->list_dir)
2727 fd = kfd->list_dir->data;
2728 kfd->list_dir = g_list_remove(kfd->list_dir, fd);
2730 keywords_find_folder(kfd, fd);
2732 file_data_unref(fd);
2737 keywords_find_finish(kfd);
2742 static void keywords_find_start_cb(GenericDialog *fd, gpointer data)
2744 KeywordFindData *kfd = data;
2747 if (kfd->list || !gtk_widget_get_sensitive(kfd->button_start)) return;
2749 path = remove_trailing_slash((gtk_entry_get_text(GTK_ENTRY(kfd->entry))));
2750 parse_out_relatives(path);
2754 warning_dialog(_("Invalid folder"),
2755 _("The specified folder can not be found."),
2756 GTK_STOCK_DIALOG_WARNING, kfd->gd->dialog);
2762 gtk_widget_set_sensitive(kfd->group, FALSE);
2763 gtk_widget_set_sensitive(kfd->button_start, FALSE);
2764 gtk_widget_set_sensitive(kfd->button_stop, TRUE);
2765 gtk_widget_set_sensitive(kfd->button_close, FALSE);
2766 spinner_set_interval(kfd->spinner, SPINNER_SPEED);
2768 dir_fd = file_data_new_dir(path);
2769 keywords_find_folder(kfd, dir_fd);
2770 file_data_unref(dir_fd);
2771 kfd->idle_id = g_idle_add(keywords_find_file, kfd);
2777 static void keywords_find_dialog(GtkWidget *widget, const gchar *path)
2779 KeywordFindData *kfd;
2783 kfd = g_new0(KeywordFindData, 1);
2785 kfd->gd = generic_dialog_new(_("Search for keywords"),
2786 "search_for_keywords",
2789 gtk_window_set_default_size(GTK_WINDOW(kfd->gd->dialog), KEYWORD_DIALOG_WIDTH, -1);
2790 kfd->gd->cancel_cb = keywords_find_close_cb;
2791 kfd->button_close = generic_dialog_add_button(kfd->gd, GTK_STOCK_CLOSE, NULL,
2792 keywords_find_close_cb, FALSE);
2793 kfd->button_start = generic_dialog_add_button(kfd->gd, GTK_STOCK_OK, _("S_tart"),
2794 keywords_find_start_cb, FALSE);
2795 kfd->button_stop = generic_dialog_add_button(kfd->gd, GTK_STOCK_STOP, NULL,
2796 keywords_find_stop_cb, FALSE);
2797 gtk_widget_set_sensitive(kfd->button_stop, FALSE);
2799 generic_dialog_add_message(kfd->gd, NULL, _("Search for keywords"), NULL, FALSE);
2801 hbox = pref_box_new(kfd->gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, 0);
2802 pref_spacer(hbox, PREF_PAD_INDENT);
2803 kfd->group = pref_box_new(hbox, TRUE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
2805 hbox = pref_box_new(kfd->group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2806 pref_label_new(hbox, _("Folder:"));
2808 label = tab_completion_new(&kfd->entry, path, NULL, NULL, NULL, NULL);
2809 tab_completion_add_select_button(kfd->entry,_("Select folder") , TRUE);
2810 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
2811 gtk_widget_show(label);
2813 pref_checkbox_new_int(kfd->group, _("Include subfolders"), FALSE, &kfd->recurse);
2815 pref_line(kfd->gd->vbox, PREF_PAD_SPACE);
2816 hbox = pref_box_new(kfd->gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
2818 kfd->progress = gtk_entry_new();
2819 gtk_widget_set_can_focus(kfd->progress, FALSE);
2820 gtk_editable_set_editable(GTK_EDITABLE(kfd->progress), FALSE);
2821 gtk_entry_set_text(GTK_ENTRY(kfd->progress), _("click start to begin"));
2822 gtk_box_pack_start(GTK_BOX(hbox), kfd->progress, TRUE, TRUE, 0);
2823 gtk_widget_show(kfd->progress);
2825 kfd->spinner = spinner_new(NULL, -1);
2826 gtk_box_pack_start(GTK_BOX(hbox), kfd->spinner, FALSE, FALSE, 0);
2827 gtk_widget_show(kfd->spinner);
2831 gtk_widget_show(kfd->gd->dialog);
2834 static void keywords_find_cb(GtkWidget *widget, gpointer data)
2836 const gchar *path = layout_get_path(NULL);
2838 if (!path || !*path) path = homedir();
2839 keywords_find_dialog(widget, path);
2842 static void config_tab_keywords_save()
2844 GtkTextIter start, end;
2845 GtkTextBuffer *buffer;
2846 GList *kw_list = NULL;
2852 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(keyword_text));
2853 gtk_text_buffer_get_bounds(buffer, &start, &end);
2855 buffer_text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
2857 kw_split = strtok(buffer_text, "\n");
2858 while (kw_split != NULL)
2864 if (g_strcmp0(work->data, kw_split) == 0)
2873 kw_list = g_list_append(kw_list, g_strdup(kw_split));
2875 kw_split = strtok(NULL, "\n");
2878 keyword_list_set(kw_list);
2880 string_list_free(kw_list);
2881 g_free(buffer_text);
2884 static void config_tab_keywords(GtkWidget *notebook)
2890 GtkWidget *scrolled;
2892 GtkTextBuffer *buffer;
2895 vbox = scrolled_notebook_page(notebook, _("Keywords"));
2897 group = pref_group_new(vbox, TRUE, _("Edit keywords autocompletion list"), GTK_ORIENTATION_VERTICAL);
2899 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
2901 button = pref_button_new(hbox, GTK_STOCK_EXECUTE, _("Search"), FALSE,
2902 G_CALLBACK(keywords_find_cb), keyword_text);
2903 gtk_widget_set_tooltip_text(button, "Search for existing keywords");
2906 keyword_text = gtk_text_view_new();
2907 gtk_widget_set_size_request(keyword_text, 20, 20);
2908 scrolled = gtk_scrolled_window_new(NULL, NULL);
2909 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
2910 gtk_widget_show(scrolled);
2912 gtk_container_add(GTK_CONTAINER(scrolled), keyword_text);
2913 gtk_widget_show(keyword_text);
2915 gtk_text_view_set_editable(GTK_TEXT_VIEW(keyword_text), TRUE);
2917 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(keyword_text));
2918 gtk_text_buffer_create_tag(buffer, "monospace",
2919 "family", "monospace", NULL);
2921 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(keyword_text), GTK_WRAP_WORD);
2922 gtk_text_buffer_get_start_iter(buffer, &iter);
2923 gtk_text_buffer_create_mark(buffer, "end", &iter, FALSE);
2926 path = g_build_filename(get_rc_dir(), "keywords", NULL);
2928 GList *kwl = keyword_list_get();
2929 kwl = g_list_first(kwl);
2932 gtk_text_buffer_get_end_iter (buffer, &iter);
2933 tmp = g_strconcat(kwl->data, "\n", NULL);
2934 gtk_text_buffer_insert(buffer, &iter, tmp, -1);
2939 gtk_text_buffer_set_modified(buffer, FALSE);
2946 static void intent_menu_cb(GtkWidget *combo, gpointer data)
2948 gint *option = data;
2950 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
2954 *option = INTENT_PERCEPTUAL;
2957 *option = INTENT_RELATIVE_COLORIMETRIC;
2960 *option = INTENT_SATURATION;
2963 *option = INTENT_ABSOLUTE_COLORIMETRIC;
2968 static void add_intent_menu(GtkWidget *table, gint column, gint row, const gchar *text,
2969 gint option, gint *option_c)
2976 pref_table_label(table, column, row, text, 0.0);
2978 combo = gtk_combo_box_text_new();
2980 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Perceptual"));
2981 if (option == INTENT_PERCEPTUAL) current = 0;
2982 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Relative Colorimetric"));
2983 if (option == INTENT_RELATIVE_COLORIMETRIC) current = 1;
2984 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Saturation"));
2985 if (option == INTENT_SATURATION) current = 2;
2986 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Absolute Colorimetric"));
2987 if (option == INTENT_ABSOLUTE_COLORIMETRIC) current = 3;
2989 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
2991 gtk_widget_set_tooltip_text(combo,"Refer to the lcms documentation for the defaults used when the selected Intent is not available");
2993 g_signal_connect(G_OBJECT(combo), "changed",
2994 G_CALLBACK(intent_menu_cb), option_c);
2996 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1,
2997 GTK_EXPAND | GTK_FILL, 0, 0, 0);
2998 gtk_widget_show(combo);
3002 static void config_tab_color(GtkWidget *notebook)
3011 vbox = scrolled_notebook_page(notebook, _("Color management"));
3013 group = pref_group_new(vbox, FALSE, _("Input profiles"), GTK_ORIENTATION_VERTICAL);
3015 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
3018 table = pref_table_new(group, 3, COLOR_PROFILE_INPUTS + 1, FALSE, FALSE);
3019 gtk_table_set_col_spacings(GTK_TABLE(table), PREF_PAD_GAP);
3021 label = pref_table_label(table, 0, 0, _("Type"), 0.0);
3022 pref_label_bold(label, TRUE, FALSE);
3024 label = pref_table_label(table, 1, 0, _("Menu name"), 0.0);
3025 pref_label_bold(label, TRUE, FALSE);
3027 label = pref_table_label(table, 2, 0, _("File"), 0.0);
3028 pref_label_bold(label, TRUE, FALSE);
3030 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
3035 buf = g_strdup_printf(_("Input %d:"), i + COLOR_PROFILE_FILE);
3036 pref_table_label(table, 0, i + 1, buf, 1.0);
3039 entry = gtk_entry_new();
3040 gtk_entry_set_max_length(GTK_ENTRY(entry), EDITOR_NAME_MAX_LENGTH);
3041 if (options->color_profile.input_name[i])
3043 gtk_entry_set_text(GTK_ENTRY(entry), options->color_profile.input_name[i]);
3045 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, i + 1, i + 2,
3046 GTK_FILL | GTK_EXPAND, 0, 0, 0);
3047 gtk_widget_show(entry);
3048 color_profile_input_name_entry[i] = entry;
3050 tabcomp = tab_completion_new(&entry, options->color_profile.input_file[i], NULL, ".icc", "ICC Files", NULL);
3051 tab_completion_add_select_button(entry, _("Select color profile"), FALSE);
3052 gtk_widget_set_size_request(entry, 160, -1);
3053 gtk_table_attach(GTK_TABLE(table), tabcomp, 2, 3, i + 1, i + 2,
3054 GTK_FILL | GTK_EXPAND, 0, 0, 0);
3055 gtk_widget_show(tabcomp);
3056 color_profile_input_file_entry[i] = entry;
3059 group = pref_group_new(vbox, FALSE, _("Screen profile"), GTK_ORIENTATION_VERTICAL);
3061 gtk_widget_set_sensitive(pref_group_parent(group), FALSE);
3063 pref_checkbox_new_int(group, _("Use system screen profile if available"),
3064 options->color_profile.use_x11_screen_profile, &c_options->color_profile.use_x11_screen_profile);
3066 table = pref_table_new(group, 2, 1, FALSE, FALSE);
3068 pref_table_label(table, 0, 0, _("Screen:"), 1.0);
3069 tabcomp = tab_completion_new(&color_profile_screen_file_entry,
3070 options->color_profile.screen_file, NULL, ".icc", "ICC Files", NULL);
3071 tab_completion_add_select_button(color_profile_screen_file_entry, _("Select color profile"), FALSE);
3072 gtk_widget_set_size_request(color_profile_screen_file_entry, 160, -1);
3074 add_intent_menu(table, 0, 1, _("Render Intent:"), options->color_profile.render_intent, &c_options->color_profile.render_intent);
3076 gtk_table_attach(GTK_TABLE(table), tabcomp, 1, 2,
3078 GTK_FILL | GTK_EXPAND, 0, 0, 0);
3080 gtk_widget_show(tabcomp);
3083 /* advanced entry tab */
3084 static void config_tab_behavior(GtkWidget *notebook)
3091 GtkWidget *ct_button;
3095 GtkWidget *with_rename;
3096 GtkWidget *collections_on_top;
3098 vbox = scrolled_notebook_page(notebook, _("Behavior"));
3100 group = pref_group_new(vbox, FALSE, _("Delete"), GTK_ORIENTATION_VERTICAL);
3102 pref_checkbox_new_int(group, _("Confirm file delete"),
3103 options->file_ops.confirm_delete, &c_options->file_ops.confirm_delete);
3104 pref_checkbox_new_int(group, _("Enable Delete key"),
3105 options->file_ops.enable_delete_key, &c_options->file_ops.enable_delete_key);
3107 ct_button = pref_checkbox_new_int(group, _("Safe delete"),
3108 options->file_ops.safe_delete_enable, &c_options->file_ops.safe_delete_enable);
3110 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
3111 pref_checkbox_link_sensitivity(ct_button, hbox);
3113 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_SPACE);
3114 pref_label_new(hbox, _("Folder:"));
3116 tabcomp = tab_completion_new(&safe_delete_path_entry, options->file_ops.safe_delete_path, NULL, NULL, NULL, NULL);
3117 tab_completion_add_select_button(safe_delete_path_entry, NULL, TRUE);
3118 gtk_box_pack_start(GTK_BOX(hbox), tabcomp, TRUE, TRUE, 0);
3119 gtk_widget_show(tabcomp);
3121 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
3122 pref_checkbox_link_sensitivity(ct_button, hbox);
3124 pref_spacer(hbox, PREF_PAD_INDENT - PREF_PAD_GAP);
3125 spin = pref_spin_new_int(hbox, _("Maximum size:"), _("MB"),
3126 0, 2048, 1, options->file_ops.safe_delete_folder_maxsize, &c_options->file_ops.safe_delete_folder_maxsize);
3127 gtk_widget_set_tooltip_markup(spin, _("Set to 0 for unlimited size"));
3128 button = pref_button_new(NULL, NULL, _("View"), FALSE,
3129 G_CALLBACK(safe_delete_view_cb), NULL);
3130 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
3131 gtk_widget_show(button);
3133 button = pref_button_new(NULL, GTK_STOCK_CLEAR, NULL, FALSE,
3134 G_CALLBACK(safe_delete_clear_cb), NULL);
3135 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
3136 gtk_widget_show(button);
3139 group = pref_group_new(vbox, FALSE, _("Behavior"), GTK_ORIENTATION_VERTICAL);
3141 pref_checkbox_new_int(group, _("Descend folders in tree view"),
3142 options->tree_descend_subdirs, &c_options->tree_descend_subdirs);
3144 pref_checkbox_new_int(group, _("In place renaming"),
3145 options->file_ops.enable_in_place_rename, &c_options->file_ops.enable_in_place_rename);
3147 pref_checkbox_new_int(group, _("List directory view uses single click to enter"),
3148 options->view_dir_list_single_click_enter, &c_options->view_dir_list_single_click_enter);
3150 marks = pref_checkbox_new_int(group, _("Save marks on exit"),
3151 options->marks_save, &c_options->marks_save);
3152 gtk_widget_set_tooltip_text(marks,"Note that marks linked to a keyword will be saved irrespective of this setting");
3154 with_rename = pref_checkbox_new_int(group, _("Use \"With Rename\" as default for Copy/Move dialogs"),
3155 options->with_rename, &c_options->with_rename);
3156 gtk_widget_set_tooltip_text(with_rename,"Change the default button for Copy/Move dialogs");
3158 collections_on_top = pref_checkbox_new_int(group, _("Open collections on top"),
3159 options->collections_on_top, &c_options->collections_on_top);
3160 gtk_widget_set_tooltip_text(collections_on_top,"Open collections window on top");
3162 pref_spin_new_int(group, _("Recent folder list maximum size"), NULL,
3163 1, 50, 1, options->open_recent_list_maxsize, &c_options->open_recent_list_maxsize);
3165 pref_spin_new_int(group, _("Drag'n drop icon size"), NULL,
3166 16, 256, 16, options->dnd_icon_size, &c_options->dnd_icon_size);
3168 table = pref_table_new(group, 2, 1, FALSE, FALSE);
3169 add_clipboard_selection_menu(table, 0, 0, _("Copy path clipboard selection:"), options->clipboard_selection, &c_options->clipboard_selection);
3171 group = pref_group_new(vbox, FALSE, _("Navigation"), GTK_ORIENTATION_VERTICAL);
3173 pref_checkbox_new_int(group, _("Progressive keyboard scrolling"),
3174 options->progressive_key_scrolling, &c_options->progressive_key_scrolling);
3175 pref_spin_new_int(group, _("Keyboard scrolling step multiplier:"), NULL,
3176 1, 32, 1, options->keyboard_scroll_step, (int *)&c_options->keyboard_scroll_step);
3177 pref_checkbox_new_int(group, _("Mouse wheel scrolls image"),
3178 options->mousewheel_scrolls, &c_options->mousewheel_scrolls);
3179 pref_checkbox_new_int(group, _("Navigation by left or middle click on image"),
3180 options->image_lm_click_nav, &c_options->image_lm_click_nav);
3181 pref_checkbox_new_int(group, _("Play video by left click on image"),
3182 options->image_l_click_video, &c_options->image_l_click_video);
3183 table = pref_table_new(group, 2, 1, FALSE, FALSE);
3184 add_video_menu(table, 0, 0, _("Play with:"), options->image_l_click_video_editor, &c_options->image_l_click_video_editor);
3188 group = pref_group_new(vbox, FALSE, _("Debugging"), GTK_ORIENTATION_VERTICAL);
3190 pref_spin_new_int(group, _("Debug level:"), NULL,
3191 DEBUG_LEVEL_MIN, DEBUG_LEVEL_MAX, 1, get_debug_level(), &debug_c);
3193 pref_checkbox_new_int(group, _("Timer data"),
3194 options->log_window.timer_data, &c_options->log_window.timer_data);
3196 pref_spin_new_int(group, _("Log Window max. lines:"), NULL,
3197 1, 99999, 1, options->log_window_lines, &options->log_window_lines);
3201 /* accelerators tab */
3202 static void config_tab_accelerators(GtkWidget *notebook)
3208 GtkWidget *scrolled;
3209 GtkWidget *accel_view;
3210 GtkCellRenderer *renderer;
3211 GtkTreeSelection *selection;
3212 GtkTreeViewColumn *column;
3214 vbox = scrolled_notebook_page(notebook, _("Keyboard"));
3216 group = pref_group_new(vbox, TRUE, _("Accelerators"), GTK_ORIENTATION_VERTICAL);
3218 scrolled = gtk_scrolled_window_new(NULL, NULL);
3219 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
3220 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
3221 gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
3222 gtk_widget_show(scrolled);
3224 accel_store = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
3226 accel_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(accel_store));
3227 g_object_unref(accel_store);
3228 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(accel_view));
3229 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_MULTIPLE);
3231 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(accel_view), FALSE);
3233 renderer = gtk_cell_renderer_text_new();
3235 column = gtk_tree_view_column_new_with_attributes(_("Action"),
3240 gtk_tree_view_column_set_sort_column_id(column, AE_ACTION);
3241 gtk_tree_view_column_set_resizable(column, TRUE);
3242 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
3245 renderer = gtk_cell_renderer_accel_new();
3246 g_signal_connect(G_OBJECT(renderer), "accel-cleared",
3247 G_CALLBACK(accel_store_cleared_cb), accel_store);
3248 g_signal_connect(G_OBJECT(renderer), "accel-edited",
3249 G_CALLBACK(accel_store_edited_cb), accel_store);
3252 g_object_set (renderer,
3254 "accel-mode", GTK_CELL_RENDERER_ACCEL_MODE_OTHER,
3257 column = gtk_tree_view_column_new_with_attributes(_("KEY"),
3262 gtk_tree_view_column_set_sort_column_id(column, AE_KEY);
3263 gtk_tree_view_column_set_resizable(column, TRUE);
3264 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
3266 renderer = gtk_cell_renderer_text_new();
3268 column = gtk_tree_view_column_new_with_attributes(_("Tooltip"),
3273 gtk_tree_view_column_set_sort_column_id(column, AE_TOOLTIP);
3274 gtk_tree_view_column_set_resizable(column, TRUE);
3275 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
3277 renderer = gtk_cell_renderer_text_new();
3279 column = gtk_tree_view_column_new_with_attributes("Accel",
3284 gtk_tree_view_column_set_sort_column_id(column, AE_ACCEL);
3285 gtk_tree_view_column_set_resizable(column, TRUE);
3286 gtk_tree_view_append_column(GTK_TREE_VIEW(accel_view), column);
3288 accel_store_populate();
3289 gtk_container_add(GTK_CONTAINER(scrolled), accel_view);
3290 gtk_widget_show(accel_view);
3292 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
3294 button = pref_button_new(NULL, NULL, _("Defaults"), FALSE,
3295 G_CALLBACK(accel_default_cb), accel_view);
3296 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
3297 gtk_widget_show(button);
3299 button = pref_button_new(NULL, NULL, _("Reset selected"), FALSE,
3300 G_CALLBACK(accel_reset_cb), accel_view);
3301 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
3302 gtk_widget_show(button);
3306 static void config_tab_toolbar(GtkWidget *notebook)
3309 GtkWidget *toolbardata;
3312 lw = layout_window_list->data;
3314 vbox = scrolled_notebook_page(notebook, _("Toolbar"));
3316 toolbardata = toolbar_select_new(lw);
3317 gtk_box_pack_start(GTK_BOX(vbox), toolbardata, TRUE, TRUE, 0);
3318 gtk_widget_show(vbox);
3322 static void config_tab_stereo(GtkWidget *notebook)
3330 GtkWidget *fs_button;
3331 vbox = scrolled_notebook_page(notebook, _("Stereo"));
3333 group = pref_group_new(vbox, FALSE, _("Windowed stereo mode"), GTK_ORIENTATION_VERTICAL);
3335 table = pref_table_new(group, 2, 1, FALSE, FALSE);
3336 add_stereo_mode_menu(table, 0, 0, _("Windowed stereo mode"), options->stereo.mode, &c_options->stereo.mode, FALSE);
3338 table = pref_table_new(group, 2, 2, TRUE, FALSE);
3339 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
3340 pref_checkbox_new_int(box, _("Mirror left image"),
3341 options->stereo.mode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.mirror_left);
3342 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
3343 pref_checkbox_new_int(box, _("Flip left image"),
3344 options->stereo.mode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.flip_left);
3345 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
3346 pref_checkbox_new_int(box, _("Mirror right image"),
3347 options->stereo.mode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.mirror_right);
3348 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
3349 pref_checkbox_new_int(box, _("Flip right image"),
3350 options->stereo.mode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.flip_right);
3351 pref_checkbox_new_int(group, _("Swap left and right images"),
3352 options->stereo.mode & PR_STEREO_SWAP, &c_options->stereo.tmp.swap);
3353 pref_checkbox_new_int(group, _("Disable stereo mode on single image source"),
3354 options->stereo.mode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.temp_disable);
3356 group = pref_group_new(vbox, FALSE, _("Fullscreen stereo mode"), GTK_ORIENTATION_VERTICAL);
3357 fs_button = pref_checkbox_new_int(group, _("Use different settings for fullscreen"),
3358 options->stereo.enable_fsmode, &c_options->stereo.enable_fsmode);
3359 box2 = pref_box_new(group, FALSE, GTK_ORIENTATION_VERTICAL, PREF_PAD_SPACE);
3360 pref_checkbox_link_sensitivity(fs_button, box2);
3361 table = pref_table_new(box2, 2, 1, FALSE, FALSE);
3362 add_stereo_mode_menu(table, 0, 0, _("Fullscreen stereo mode"), options->stereo.fsmode, &c_options->stereo.fsmode, TRUE);
3363 table = pref_table_new(box2, 2, 2, TRUE, FALSE);
3364 box = pref_table_box(table, 0, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
3365 pref_checkbox_new_int(box, _("Mirror left image"),
3366 options->stereo.fsmode & PR_STEREO_MIRROR_LEFT, &c_options->stereo.tmp.fs_mirror_left);
3367 box = pref_table_box(table, 1, 0, GTK_ORIENTATION_HORIZONTAL, NULL);
3368 pref_checkbox_new_int(box, _("Flip left image"),
3369 options->stereo.fsmode & PR_STEREO_FLIP_LEFT, &c_options->stereo.tmp.fs_flip_left);
3370 box = pref_table_box(table, 0, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
3371 pref_checkbox_new_int(box, _("Mirror right image"),
3372 options->stereo.fsmode & PR_STEREO_MIRROR_RIGHT, &c_options->stereo.tmp.fs_mirror_right);
3373 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL);
3374 pref_checkbox_new_int(box, _("Flip right image"),
3375 options->stereo.fsmode & PR_STEREO_FLIP_RIGHT, &c_options->stereo.tmp.fs_flip_right);
3376 pref_checkbox_new_int(box2, _("Swap left and right images"),
3377 options->stereo.fsmode & PR_STEREO_SWAP, &c_options->stereo.tmp.fs_swap);
3378 pref_checkbox_new_int(box2, _("Disable stereo mode on single image source"),
3379 options->stereo.fsmode & PR_STEREO_TEMP_DISABLE, &c_options->stereo.tmp.fs_temp_disable);
3381 group2 = pref_group_new(box2, FALSE, _("Fixed position"), GTK_ORIENTATION_VERTICAL);
3382 table = pref_table_new(group2, 5, 3, FALSE, FALSE);
3383 pref_table_spin_new_int(table, 0, 0, _("Width"), NULL,
3384 1, 5000, 1, options->stereo.fixed_w, &c_options->stereo.fixed_w);
3385 pref_table_spin_new_int(table, 3, 0, _("Height"), NULL,
3386 1, 5000, 1, options->stereo.fixed_h, &c_options->stereo.fixed_h);
3387 pref_table_spin_new_int(table, 0, 1, _("Left X"), NULL,
3388 0, 5000, 1, options->stereo.fixed_x1, &c_options->stereo.fixed_x1);
3389 pref_table_spin_new_int(table, 3, 1, _("Left Y"), NULL,
3390 0, 5000, 1, options->stereo.fixed_y1, &c_options->stereo.fixed_y1);
3391 pref_table_spin_new_int(table, 0, 2, _("Right X"), NULL,
3392 0, 5000, 1, options->stereo.fixed_x2, &c_options->stereo.fixed_x2);
3393 pref_table_spin_new_int(table, 3, 2, _("Right Y"), NULL,
3394 0, 5000, 1, options->stereo.fixed_y2, &c_options->stereo.fixed_y2);
3398 /* Main preferences window */
3399 static void config_window_create(void)
3401 GtkWidget *win_vbox;
3403 GtkWidget *notebook;
3405 GtkWidget *ct_button;
3407 if (!c_options) c_options = init_options(NULL);
3409 configwindow = window_new(GTK_WINDOW_TOPLEVEL, "preferences", PIXBUF_INLINE_ICON_CONFIG, NULL, _("Preferences"));
3410 gtk_window_set_type_hint(GTK_WINDOW(configwindow), GDK_WINDOW_TYPE_HINT_DIALOG);
3411 g_signal_connect(G_OBJECT(configwindow), "delete_event",
3412 G_CALLBACK(config_window_delete), NULL);
3413 gtk_window_set_default_size(GTK_WINDOW(configwindow), CONFIG_WINDOW_DEF_WIDTH, CONFIG_WINDOW_DEF_HEIGHT);
3414 gtk_window_set_resizable(GTK_WINDOW(configwindow), TRUE);
3415 gtk_container_set_border_width(GTK_CONTAINER(configwindow), PREF_PAD_BORDER);
3417 win_vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE);
3418 gtk_container_add(GTK_CONTAINER(configwindow), win_vbox);
3419 gtk_widget_show(win_vbox);
3421 notebook = gtk_notebook_new();
3422 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
3423 gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), TRUE);
3424 gtk_box_pack_start(GTK_BOX(win_vbox), notebook, TRUE, TRUE, 0);
3426 config_tab_general(notebook);
3427 config_tab_image(notebook);
3428 config_tab_osd(notebook);
3429 config_tab_windows(notebook);
3430 config_tab_accelerators(notebook);
3431 config_tab_files(notebook);
3432 config_tab_metadata(notebook);
3433 config_tab_keywords(notebook);
3434 config_tab_color(notebook);
3435 config_tab_stereo(notebook);
3436 config_tab_behavior(notebook);
3437 config_tab_toolbar(notebook);
3439 hbox = gtk_hbutton_box_new();
3440 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
3441 gtk_box_set_spacing(GTK_BOX(hbox), PREF_PAD_BUTTON_GAP);
3442 gtk_box_pack_end(GTK_BOX(win_vbox), hbox, FALSE, FALSE, 0);
3443 gtk_widget_show(hbox);
3445 button = pref_button_new(NULL, GTK_STOCK_HELP, NULL, FALSE,
3446 G_CALLBACK(config_window_help_cb), notebook);
3447 gtk_container_add(GTK_CONTAINER(hbox), button);
3448 gtk_widget_set_can_default(button, TRUE);
3449 gtk_widget_show(button);
3451 button = pref_button_new(NULL, GTK_STOCK_OK, NULL, FALSE,
3452 G_CALLBACK(config_window_ok_cb), NULL);
3453 gtk_container_add(GTK_CONTAINER(hbox), button);
3454 gtk_widget_set_can_default(button, TRUE);
3455 gtk_widget_grab_default(button);
3456 gtk_widget_show(button);
3460 button = pref_button_new(NULL, GTK_STOCK_SAVE, NULL, FALSE,
3461 G_CALLBACK(config_window_save_cb), NULL);
3462 gtk_container_add(GTK_CONTAINER(hbox), button);
3463 gtk_widget_set_can_default(button, TRUE);
3464 gtk_widget_show(button);
3466 button = pref_button_new(NULL, GTK_STOCK_APPLY, NULL, FALSE,
3467 G_CALLBACK(config_window_apply_cb), NULL);
3468 gtk_container_add(GTK_CONTAINER(hbox), button);
3469 gtk_widget_set_can_default(button, TRUE);
3470 gtk_widget_show(button);
3472 button = pref_button_new(NULL, GTK_STOCK_CANCEL, NULL, FALSE,
3473 G_CALLBACK(config_window_close_cb), NULL);
3474 gtk_container_add(GTK_CONTAINER(hbox), button);
3475 gtk_widget_set_can_default(button, TRUE);
3476 gtk_widget_show(button);
3478 if (!generic_dialog_get_alternative_button_order(configwindow))
3480 gtk_box_reorder_child(GTK_BOX(hbox), ct_button, -1);
3483 gtk_widget_show(notebook);
3485 gtk_widget_show(configwindow);
3489 *-----------------------------------------------------------------------------
3490 * config window show (public)
3491 *-----------------------------------------------------------------------------
3494 void show_config_window(void)
3498 gtk_window_present(GTK_WINDOW(configwindow));
3502 config_window_create();
3511 void show_about_window(LayoutWindow *lw)
3513 GdkPixbuf *pixbuf_logo;
3514 GdkPixbuf *pixbuf_icon;
3515 gchar *authors[1000];
3523 #define LINE_LENGTH 1000
3524 gchar line[LINE_LENGTH];
3526 copyright = g_string_new(NULL);
3527 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");
3529 zd_path = g_build_filename(GQ_BIN_DIR, TIMEZONE_DATABASE, NULL);
3530 cd = ZDOpenDatabase(zd_path);
3533 copyright = g_string_append(copyright, ZDGetNotice(cd));
3535 ZDCloseDatabase(cd);
3539 path = g_build_filename(GQ_HELPDIR, "AUTHORS", NULL);
3540 fp = fopen(path, "r");
3543 while(fgets(line, LINE_LENGTH, fp))
3545 /* get rid of ending \n from fgets */
3546 line[strlen(line) - 1] = '\0';
3547 authors[i_authors] = g_strdup(line);
3550 authors[i_authors] = NULL;
3555 comment = g_strconcat("Development and bug reports:\n", GQ_EMAIL_ADDRESS,
3556 "\nhttps://github.com/BestImageViewer/geeqie/issues",NULL);
3558 pixbuf_logo = pixbuf_inline(PIXBUF_INLINE_LOGO);
3559 pixbuf_icon = pixbuf_inline(PIXBUF_INLINE_ICON);
3560 gtk_show_about_dialog(GTK_WINDOW(lw->window),
3561 "title", _("About Geeqie"),
3563 "program-name", GQ_APPNAME,
3565 "logo", pixbuf_logo,
3566 "icon", pixbuf_icon,
3567 "website", GQ_WEBSITE,
3568 "website-label", "Website",
3569 "comments", comment,
3571 "translator-credits", _("translator-credits"),
3572 "wrap-license", TRUE,
3573 "license", copyright->str,
3576 g_string_free(copyright, TRUE);
3579 while(n < i_authors)
3589 static void image_overlay_set_text_colours()
3591 c_options->image_overlay.text_red = options->image_overlay.text_red;
3592 c_options->image_overlay.text_green = options->image_overlay.text_green;
3593 c_options->image_overlay.text_blue = options->image_overlay.text_blue;
3594 c_options->image_overlay.text_alpha = options->image_overlay.text_alpha;
3595 c_options->image_overlay.background_red = options->image_overlay.background_red;
3596 c_options->image_overlay.background_green = options->image_overlay.background_green;
3597 c_options->image_overlay.background_blue = options->image_overlay.background_blue;
3598 c_options->image_overlay.background_alpha = options->image_overlay.background_alpha;
3600 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */