Addl fix #521: zoom increment is not multiplicative
[geeqie.git] / src / preferences.c
index ad86037..8c6804f 100644 (file)
 #include "layout_config.h"
 #include "layout_util.h"
 #include "metadata.h"
+#include "misc.h"
 #include "osd.h"
 #include "pixbuf_util.h"
+#include "rcfile.h"
 #include "slideshow.h"
 #include "toolbar.h"
 #include "trash.h"
@@ -117,7 +119,8 @@ gchar *format_class_list[] = {
        N_("Metadata"),
        N_("Video"),
        N_("Collection"),
-       N_("Document")
+       N_("Document"),
+       N_("Archive")
        };
 
 /* config memory values */
@@ -137,6 +140,8 @@ static GtkWidget *safe_delete_path_entry;
 static GtkWidget *color_profile_input_file_entry[COLOR_PROFILE_INPUTS];
 static GtkWidget *color_profile_input_name_entry[COLOR_PROFILE_INPUTS];
 static GtkWidget *color_profile_screen_file_entry;
+static GtkWidget *external_preview_select_entry;
+static GtkWidget *external_preview_extract_entry;
 
 static GtkWidget *sidecar_ext_entry;
 static GtkWidget *help_search_engine_entry;
@@ -282,6 +287,7 @@ static void config_window_apply(void)
        options->image.max_autofit_size = c_options->image.max_autofit_size;
        options->image.max_enlargement_size = c_options->image.max_enlargement_size;
        options->image.use_clutter_renderer = c_options->image.use_clutter_renderer;
+       options->image.tile_size = c_options->image.tile_size;
        options->progressive_key_scrolling = c_options->progressive_key_scrolling;
        options->keyboard_scroll_step = c_options->keyboard_scroll_step;
 
@@ -322,6 +328,7 @@ static void config_window_apply(void)
 
        options->mousewheel_scrolls = c_options->mousewheel_scrolls;
        options->image_lm_click_nav = c_options->image_lm_click_nav;
+       options->image_l_click_archive = c_options->image_l_click_archive;
        options->image_l_click_video = c_options->image_l_click_video;
        options->image_l_click_video_editor = c_options->image_l_click_video_editor;
 
@@ -334,6 +341,8 @@ static void config_window_apply(void)
 
        options->image.zoom_increment = c_options->image.zoom_increment;
 
+       options->image.zoom_style = c_options->image.zoom_style;
+
        options->image.enable_read_ahead = c_options->image.enable_read_ahead;
 
 
@@ -434,10 +443,17 @@ static void config_window_apply(void)
        options->hide_window_in_fullscreen = c_options->hide_window_in_fullscreen;
        config_entry_to_option(help_search_engine_entry, &options->help_search_engine, NULL);
 
+       options->external_preview.enable = c_options->external_preview.enable;
+       config_entry_to_option(external_preview_select_entry, &options->external_preview.select, NULL);
+       config_entry_to_option(external_preview_extract_entry, &options->external_preview.extract, NULL);
+
        options->read_metadata_in_idle = c_options->read_metadata_in_idle;
 
        options->star_rating.star = c_options->star_rating.star;
        options->star_rating.rejected = c_options->star_rating.rejected;
+
+       options->threads.duplicates = c_options->threads.duplicates > 0 ? c_options->threads.duplicates : -1;
+
 #ifdef DEBUG
        set_debug_level(debug_c);
 #endif
@@ -510,7 +526,8 @@ static void config_window_help_cb(GtkWidget *widget, gpointer data)
        "GuideOptionsStereo.html",
        "GuideOptionsBehavior.html",
        "GuideOptionsToolbar.html",
-       "GuideOptionsToolbar.html"
+       "GuideOptionsToolbar.html",
+       "GuideOptionsAdvanced.html"
        };
 
        i = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
@@ -700,6 +717,47 @@ static void add_clipboard_selection_menu(GtkWidget *table, gint column, gint row
        gtk_widget_show(combo);
 }
 
+static void zoom_style_selection_menu_cb(GtkWidget *combo, gpointer data)
+{
+       gint *option = data;
+
+       switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
+               {
+               case 0:
+                       *option = ZOOM_GEOMETRIC;
+                       break;
+               case 1:
+                       *option = ZOOM_ARITHMETIC;
+                       break;
+               default:
+                       *option = ZOOM_GEOMETRIC;
+               }
+}
+
+static void add_zoom_style_selection_menu(GtkWidget *table, gint column, gint row, const gchar *text, ZoomStyle option, ZoomStyle *option_c)
+{
+       GtkWidget *combo;
+       gint current = 0;
+
+       *option_c = option;
+
+       pref_table_label(table, column, row, text, 0.0);
+
+       combo = gtk_combo_box_text_new();
+
+       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Geometric"));
+       if (option == ZOOM_GEOMETRIC) current = 0;
+       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Arithmetic"));
+       if (option == ZOOM_ARITHMETIC) current = 1;
+
+       gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
+
+       g_signal_connect(G_OBJECT(combo), "changed", G_CALLBACK(zoom_style_selection_menu_cb), option_c);
+
+       gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1, GTK_SHRINK, 0, 0, 0);
+       gtk_widget_show(combo);
+}
+
 typedef struct _UseableMouseItems UseableMouseItems;
 struct _UseableMouseItems
 {
@@ -774,7 +832,6 @@ static const UseableMouseItems useable_mouse_items[] = {
        {"ExifWin",     N_("Exif window"), PIXBUF_INLINE_ICON_EXIF},
        {"Thumbnails",  N_("Show thumbnails"), PIXBUF_INLINE_ICON_THUMB},
        {"ShowMarks",   N_("Show marks"), PIXBUF_INLINE_ICON_MARKS},
-       {"ImageGuidelines",     N_("Show guidelines"), PIXBUF_INLINE_ICON_GUIDELINES},
        {"DrawRectangle",       N_("Draw Rectangle"), PIXBUF_INLINE_ICON_DRAW_RECTANGLE},
        {"FloatTools",  N_("Float file list"), PIXBUF_INLINE_ICON_FLOAT},
        {"SBar",        N_("Info sidebar"), PIXBUF_INLINE_ICON_INFO},
@@ -2118,31 +2175,6 @@ static void config_tab_general(GtkWidget *notebook)
 
        pref_spacer(group, PREF_PAD_GROUP);
 
-       group = pref_group_new(vbox, FALSE, _("Info sidebar heights"), GTK_ORIENTATION_VERTICAL);
-       pref_label_new(group, _("NOTE! Geeqie must be restarted for changes to take effect"));
-       hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
-       pref_spin_new_int(hbox, _("Keywords:"), NULL,
-                                1, 9999, 1,
-                                options->info_keywords.height, &c_options->info_keywords.height);
-       pref_spin_new_int(hbox, _("Title:"), NULL,
-                                1, 9999, 1,
-                                options->info_title.height, &c_options->info_title.height);
-       pref_spin_new_int(hbox, _("Comment:"), NULL,
-                                1, 9999, 1,
-                                options->info_comment.height, &c_options->info_comment.height);
-       pref_spin_new_int(hbox, _("Rating:"), NULL,
-                                1, 9999, 1,
-                                options->info_rating.height, &c_options->info_rating.height);
-
-       pref_spacer(group, PREF_PAD_GROUP);
-
-       group = pref_group_new(vbox, FALSE, _("Show predefined keyword tree"), GTK_ORIENTATION_VERTICAL);
-
-       pref_checkbox_new_int(group, _("Show predefined keyword tree (NOTE! Geeqie must be restarted for change to take effect)"),
-                               options->show_predefined_keyword_tree, &c_options->show_predefined_keyword_tree);
-
-       pref_spacer(group, PREF_PAD_GROUP);
-
        net_mon = g_network_monitor_get_default();
        geeqie_org = g_network_address_parse_uri(GQ_WEBSITE, 80, NULL);
        internet_available = g_network_monitor_can_reach(net_mon, geeqie_org, NULL, NULL);
@@ -2255,6 +2287,10 @@ static void config_tab_image(GtkWidget *notebook)
                             G_CALLBACK(zoom_increment_cb), NULL);
        gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
 
+       c_options->image.zoom_style = options->image.zoom_style;
+       table = pref_table_new(group, 2, 1, FALSE, FALSE);
+       add_zoom_style_selection_menu(table, 0, 0, _("Zoom style:"), options->image.zoom_style, &c_options->image.zoom_style);
+
        group = pref_group_new(vbox, FALSE, _("Fit image to window"), GTK_ORIENTATION_VERTICAL);
 
        hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
@@ -2275,6 +2311,15 @@ static void config_tab_image(GtkWidget *notebook)
        pref_checkbox_link_sensitivity(ct_button, spin);
        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."));
 
+       group = pref_group_new(vbox, FALSE, _("Tile size"), GTK_ORIENTATION_VERTICAL);
+       gtk_widget_set_sensitive(group, !options->image.use_clutter_renderer);
+
+       hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
+       spin = pref_spin_new_int(hbox, _("Pixels"), _("(Requires restart)"),
+                                128, 4096, 128,
+                                options->image.tile_size, &c_options->image.tile_size);
+       gtk_widget_set_tooltip_text(GTK_WIDGET(hbox), _("This value changes the size of the tiles large images are split into. Increasing the size of the tiles will reduce the tiling effect seen on image changes, but will also slightly increase the delay before the first part of a large image is seen."));
+
        group = pref_group_new(vbox, FALSE, _("Appearance"), GTK_ORIENTATION_VERTICAL);
 
        pref_checkbox_new_int(group, _("Use custom border color in window mode"),
@@ -2304,11 +2349,63 @@ static void config_tab_image(GtkWidget *notebook)
 }
 
 /* windows tab */
+
+static void save_default_window_layout_cb(GtkWidget *widget, gpointer data)
+{
+       LayoutWindow *lw = NULL;
+       gchar *default_path;
+       gchar *tmp_id;
+
+       /* Get current lw */
+       layout_valid(&lw);
+
+       tmp_id = lw->options.id;
+       lw->options.id = g_strdup("lw_default");
+
+       default_path = g_build_filename(get_rc_dir(), DEFAULT_WINDOW_LAYOUT, NULL);
+       save_default_layout_options_to_file(default_path, options, lw);
+       g_free(lw->options.id);
+       lw->options.id = tmp_id;
+       g_free(default_path);
+}
+
+#if GTK_CHECK_VERSION(3,22,0)
+static gboolean popover_cb(gpointer data)
+{
+       GtkPopover *popover = data;
+
+       gtk_popover_popdown(popover);
+
+       return FALSE;
+}
+
+static void default_layout_changed_cb(GtkWidget *button, GtkPopover *popover)
+{
+       gtk_popover_popup(popover);
+
+       g_timeout_add(2000, popover_cb, popover);
+}
+
+static GtkWidget *create_popover(GtkWidget *parent, GtkWidget *child, GtkPositionType pos)
+{
+       GtkWidget *popover;
+
+       popover = gtk_popover_new(parent);
+       gtk_popover_set_position(GTK_POPOVER (popover), pos);
+       gtk_container_add (GTK_CONTAINER(popover), child);
+       gtk_container_set_border_width(GTK_CONTAINER (popover), 6);
+       gtk_widget_show (child);
+
+       return popover;
+}
+#endif
+
 static void config_tab_windows(GtkWidget *notebook)
 {
        GtkWidget *hbox;
        GtkWidget *vbox;
        GtkWidget *group;
+       GtkWidget *subgroup;
        GtkWidget *button;
        GtkWidget *ct_button;
        GtkWidget *spin;
@@ -2317,7 +2414,7 @@ static void config_tab_windows(GtkWidget *notebook)
 
        group = pref_group_new(vbox, FALSE, _("State"), GTK_ORIENTATION_VERTICAL);
 
-       ct_button = pref_checkbox_new_int(group, _("Remember window positions"),
+       ct_button = pref_checkbox_new_int(group, _("Remember session"),
                                          options->save_window_positions, &c_options->save_window_positions);
 
        button = pref_checkbox_new_int(group, _("Use saved window positions also for new windows"),
@@ -2337,6 +2434,18 @@ static void config_tab_windows(GtkWidget *notebook)
        pref_checkbox_new_int(group, _("Show window IDs"),
                              options->show_window_ids, &c_options->show_window_ids);
 
+       subgroup = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
+       pref_label_new(subgroup, _("Use current layout for default: "));
+       button = pref_button_new(subgroup, NULL, _("Set"), FALSE, G_CALLBACK(save_default_window_layout_cb), NULL);
+
+#if GTK_CHECK_VERSION(3,22,0)
+       GtkWidget *popover;
+
+       popover = create_popover(button, gtk_label_new(_("Current window layout\nhas been set as default")), GTK_POS_TOP);
+       gtk_popover_set_modal(GTK_POPOVER (popover), FALSE);
+       g_signal_connect(button, "clicked", G_CALLBACK(default_layout_changed_cb), popover);
+#endif
+
        group = pref_group_new(vbox, FALSE, _("Size"), GTK_ORIENTATION_VERTICAL);
 
        pref_checkbox_new_int(group, _("Fit window to image when tools are hidden/floating"),
@@ -3416,6 +3525,8 @@ static void config_tab_behavior(GtkWidget *notebook)
                              options->mousewheel_scrolls, &c_options->mousewheel_scrolls);
        pref_checkbox_new_int(group, _("Navigation by left or middle click on image"),
                              options->image_lm_click_nav, &c_options->image_lm_click_nav);
+       pref_checkbox_new_int(group, _("Open archive by left click on image"),
+                             options->image_l_click_archive, &c_options->image_l_click_archive);
        pref_checkbox_new_int(group, _("Play video by left click on image"),
                              options->image_l_click_video, &c_options->image_l_click_video);
        table = pref_table_new(group, 2, 1, FALSE, FALSE);
@@ -3587,6 +3698,107 @@ static void config_tab_toolbar_status(GtkWidget *notebook)
        gtk_widget_show(vbox);
 }
 
+/* advanced tab */
+static gint extension_sort_cb(gconstpointer a, gconstpointer b)
+{
+       return g_strcmp0((gchar *)a, (gchar *)b);
+}
+
+static void config_tab_advanced(GtkWidget *notebook)
+{
+       GtkWidget *vbox;
+       GtkWidget *group;
+       GSList *formats_list;
+       GList *extensions_list = NULL;
+       gchar **extensions;
+       GtkWidget *tabcomp;
+       GdkPixbufFormat *fm;
+       gint i;
+       GString *types_string = g_string_new(NULL);
+       GtkWidget *types_string_label;
+       GtkWidget *threads_string_label;
+       GtkWidget *dupes_threads_spin;
+
+       vbox = scrolled_notebook_page(notebook, _("Advanced"));
+       group = pref_group_new(vbox, FALSE, _("External preview extraction"), GTK_ORIENTATION_VERTICAL);
+
+       pref_checkbox_new_int(group, _("Use external preview extraction -  Requires restart"), options->external_preview.enable, &c_options->external_preview.enable);
+
+       pref_spacer(group, PREF_PAD_GROUP);
+
+       formats_list = gdk_pixbuf_get_formats();
+
+       while (formats_list)
+               {
+               fm = formats_list->data;
+               extensions = gdk_pixbuf_format_get_extensions(fm);
+
+               i = 0;
+               while (extensions[i])
+                       {
+                       extensions_list = g_list_insert_sorted(extensions_list, g_strdup(extensions[i]), extension_sort_cb);
+                       i++;
+                       }
+
+               g_strfreev(extensions);
+               formats_list = formats_list->next;
+               }
+
+       while (extensions_list)
+               {
+               if (types_string->len == 0)
+                       {
+                       types_string = g_string_append(types_string, extensions_list->data);
+                       }
+               else
+                       {
+                       types_string = g_string_append(types_string, ", ");
+                       types_string = g_string_append(types_string, extensions_list->data);
+                       }
+
+               extensions_list = extensions_list->next;
+               }
+
+       types_string = g_string_prepend(types_string, _("Usable file types:\n"));
+       types_string_label = pref_label_new(group, types_string->str);
+       gtk_label_set_line_wrap(GTK_LABEL(types_string_label), TRUE);
+
+       pref_spacer(group, PREF_PAD_GROUP);
+
+       group = pref_group_new(vbox, FALSE, _("File identification tool"), GTK_ORIENTATION_VERTICAL);
+       external_preview_select_entry = gtk_entry_new();
+       tabcomp = tab_completion_new(&external_preview_select_entry, options->external_preview.select, NULL, NULL, NULL, NULL);
+       tab_completion_add_select_button(external_preview_select_entry, _("Select file identification tool"), FALSE);
+       gtk_box_pack_start(GTK_BOX(group), tabcomp, TRUE, TRUE, 0);
+       gtk_widget_show(tabcomp);
+
+       group = pref_group_new(vbox, FALSE, _("Preview extraction tool"), GTK_ORIENTATION_VERTICAL);
+       external_preview_extract_entry = gtk_entry_new();
+       tabcomp = tab_completion_new(&external_preview_extract_entry, options->external_preview.extract, NULL, NULL, NULL, NULL);
+       tab_completion_add_select_button(external_preview_extract_entry, _("Select preview extraction tool"), FALSE);
+       gtk_box_pack_start(GTK_BOX(group), tabcomp, TRUE, TRUE, 0);
+       gtk_widget_show(tabcomp);
+
+       gtk_widget_show(vbox);
+
+       g_slist_free(formats_list);
+       string_list_free(extensions_list);
+       g_string_free(types_string, TRUE);
+
+       pref_spacer(group, PREF_PAD_GROUP);
+
+       pref_line(vbox, PREF_PAD_SPACE);
+       group = pref_group_new(vbox, FALSE, _("Thread pool limits"), GTK_ORIENTATION_VERTICAL);
+
+       threads_string_label = pref_label_new(group, "This option limits the number of threads (or cpu cores)\nthat Geeqie will use when running duplicate checks. The default value is 0, which means all available cores will be used.");
+       gtk_label_set_line_wrap(GTK_LABEL(threads_string_label), TRUE);
+
+       pref_spacer(vbox, PREF_PAD_GROUP);
+
+       dupes_threads_spin = pref_spin_new_int(vbox, _("Duplicate check:"), _("max. threads"), 0, get_cpu_cores(), 1, options->threads.duplicates, &c_options->threads.duplicates);
+       gtk_widget_set_tooltip_markup(dupes_threads_spin, _("Set to 0 for unlimited"));
+}
+
 /* stereo tab */
 static void config_tab_stereo(GtkWidget *notebook)
 {
@@ -3714,6 +3926,7 @@ static void config_window_create(LayoutWindow *lw)
        config_tab_behavior(notebook);
        config_tab_toolbar_main(notebook);
        config_tab_toolbar_status(notebook);
+       config_tab_advanced(notebook);
 
        gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), lw->options.preferences_window.page_number);
 
@@ -3813,7 +4026,7 @@ void show_about_window(LayoutWindow *lw)
        g_free(basename);
 
        authors[0] = NULL;
-       path = g_build_filename(GQ_HELPDIR, "AUTHORS", NULL);
+       path = g_build_filename(gq_helpdir, "AUTHORS", NULL);
        fp = fopen(path, "r");
        if (fp)
                {