Spelling checks for keywords auto-completion list
[geeqie.git] / src / preferences.c
index dc26b82..dce9e05 100644 (file)
 #endif
 #endif
 
+#ifdef HAVE_SPELL
+#include <gspell/gspell.h>
+#endif
+
 #define EDITOR_NAME_MAX_LENGTH 32
 #define EDITOR_COMMAND_MAX_LENGTH 1024
 
@@ -415,6 +419,7 @@ static void config_window_apply(void)
        options->metadata.confirm_on_dir_change = c_options->metadata.confirm_on_dir_change;
        options->metadata.keywords_case_sensitive = c_options->metadata.keywords_case_sensitive;
        options->metadata.write_orientation = c_options->metadata.write_orientation;
+       options->metadata.check_spelling = c_options->metadata.check_spelling;
        options->stereo.mode = (c_options->stereo.mode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED | PR_STEREO_ANAGLYPH | PR_STEREO_HALF)) |
                               (c_options->stereo.tmp.mirror_right ? PR_STEREO_MIRROR_RIGHT : 0) |
                               (c_options->stereo.tmp.flip_right   ? PR_STEREO_FLIP_RIGHT : 0) |
@@ -1992,9 +1997,10 @@ static void config_tab_general(GtkWidget *notebook)
        gchar *rating_symbol;
        gchar *path;
        gchar *basename;
+       gchar *download_locn;
        GNetworkMonitor *net_mon;
-       GSocketConnectable *geeqie_org;
-       gboolean internet_available;
+       GSocketConnectable *tz_org;
+       gboolean internet_available = FALSE;
        TZData *tz;
 
        vbox = scrolled_notebook_page(notebook, _("General"));
@@ -2184,9 +2190,12 @@ static void config_tab_general(GtkWidget *notebook)
        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);
-       g_object_unref(geeqie_org);
+       tz_org = g_network_address_parse_uri(TIMEZONE_DATABASE_WEB, 80, NULL);
+       if (tz_org)
+               {
+               internet_available = g_network_monitor_can_reach(net_mon, tz_org, NULL, NULL);
+               g_object_unref(tz_org);
+               }
 
        group = pref_group_new(vbox, FALSE, _("Timezone database"), GTK_ORIENTATION_VERTICAL);
        hbox = pref_box_new(group, TRUE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
@@ -2198,9 +2207,9 @@ static void config_tab_general(GtkWidget *notebook)
 
        tz = g_new0(TZData, 1);
 
-       path = path_from_utf8(TIMEZONE_DATABASE);
+       path = path_from_utf8(TIMEZONE_DATABASE_WEB);
        basename = g_path_get_basename(path);
-       tz->timezone_database_user = g_build_filename(get_rc_dir(), basename, NULL);
+       tz->timezone_database_user = g_build_filename(get_rc_dir(), TIMEZONE_DATABASE_FILE, NULL);
        g_free(path);
        g_free(basename);
 
@@ -2213,6 +2222,10 @@ static void config_tab_general(GtkWidget *notebook)
                button = pref_button_new(GTK_WIDGET(hbox), NULL, _("Install"), FALSE, G_CALLBACK(timezone_database_install_cb), tz);
                }
 
+       download_locn = g_strconcat(_("Download database from: "), TIMEZONE_DATABASE_WEB, NULL);
+       pref_label_new(GTK_WIDGET(hbox), download_locn);
+       g_free(download_locn);
+
        if (!internet_available)
                {
                gtk_widget_set_tooltip_text(button, _("No Internet connection!\nThe timezone database is used to display exif time and date\ncorrected for UTC offset and Daylight Saving Time"));
@@ -2955,6 +2968,14 @@ static void config_tab_metadata(GtkWidget *notebook)
        pref_checkbox_new_int(group, _("Write metadata on directory change"),
                              options->metadata.confirm_on_dir_change, &c_options->metadata.confirm_on_dir_change);
 
+#ifdef HAVE_SPELL
+#if GTK_CHECK_VERSION(3,20,0)
+       group = pref_group_new(vbox, FALSE, _("Spelling checks"), GTK_ORIENTATION_VERTICAL);
+
+       ct_button = pref_checkbox_new_int(group, _("Check spelling -Requires restart"), options->metadata.check_spelling, &c_options->metadata.check_spelling);
+#endif
+#endif
+
        group = pref_group_new(vbox, FALSE, _("Pre-load metadata"), GTK_ORIENTATION_VERTICAL);
 
        ct_button = pref_checkbox_new_int(group, _("Read metadata in background"),
@@ -3255,6 +3276,9 @@ static void config_tab_keywords(GtkWidget *notebook)
        GtkTextIter iter;
        GtkTextBuffer *buffer;
        gchar *tmp;
+#ifdef HAVE_SPELL
+       GspellTextView *gspell_view;
+#endif
 
        vbox = scrolled_notebook_page(notebook, _("Keywords"));
 
@@ -3273,6 +3297,16 @@ static void config_tab_keywords(GtkWidget *notebook)
        gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
        gtk_widget_show(scrolled);
 
+#ifdef HAVE_SPELL
+#if GTK_CHECK_VERSION(3,20,0)
+       if (options->metadata.check_spelling)
+               {
+               gspell_view = gspell_text_view_get_from_gtk_text_view(GTK_TEXT_VIEW(keyword_text));
+               gspell_text_view_basic_setup(gspell_view);
+               }
+#endif
+#endif
+
        gtk_container_add(GTK_CONTAINER(scrolled), keyword_text);
        gtk_widget_show(keyword_text);
 
@@ -3527,6 +3561,10 @@ static void config_tab_behavior(GtkWidget *notebook)
        button = pref_button_new(NULL, GTK_STOCK_CLEAR, NULL, FALSE,
                                 G_CALLBACK(safe_delete_clear_cb), NULL);
        gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+
+       c_options->file_ops.no_trash = options->file_ops.no_trash;
+       c_options->file_ops.use_system_trash = options->file_ops.use_system_trash;
+
        pref_radiobutton_new(group, ct_button, _("Use system Trash bin"),
                                        options->file_ops.use_system_trash && !options->file_ops.no_trash, G_CALLBACK(use_system_trash_cb), NULL);
 
@@ -4068,7 +4106,6 @@ void show_about_window(LayoutWindow *lw)
        gchar *path;
        GString *copyright;
        gchar *timezone_path;
-       gchar *basename;
        ZoneDetect *cd;
        FILE *fp = NULL;
 #define LINE_LENGTH 1000
@@ -4077,21 +4114,21 @@ void show_about_window(LayoutWindow *lw)
        copyright = g_string_new(NULL);
        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");
 
-       path = path_from_utf8(TIMEZONE_DATABASE);
-       basename = g_path_get_basename(path);
-       timezone_path = g_build_filename(get_rc_dir(), basename, NULL);
+       timezone_path = g_build_filename(get_rc_dir(), TIMEZONE_DATABASE_FILE, NULL);
        if (g_file_test(timezone_path, G_FILE_TEST_EXISTS))
                {
                cd = ZDOpenDatabase(timezone_path);
                if (cd)
                        {
                        copyright = g_string_append(copyright, ZDGetNotice(cd));
-                       ZDCloseDatabase(cd);
                        }
+               else
+                       {
+                       log_printf("Error: Init of timezone database %s failed\n", timezone_path);
+                       }
+               ZDCloseDatabase(cd);
                }
-       g_free(path);
        g_free(timezone_path);
-       g_free(basename);
 
        authors[0] = NULL;
        path = g_build_filename(gq_helpdir, "AUTHORS", NULL);
@@ -4167,6 +4204,9 @@ static void timezone_async_ready_cb(GObject *source_object, GAsyncResult *res, g
        GError *error = NULL;
        TZData *tz = data;
        gchar *tmp_filename;
+       gchar *timezone_bin;
+       gchar *tmp_dir = NULL;
+       FileData *fd;
 
        if (!g_cancellable_is_cancelled(tz->cancellable))
                {
@@ -4176,13 +4216,35 @@ static void timezone_async_ready_cb(GObject *source_object, GAsyncResult *res, g
 
        if (g_file_copy_finish(G_FILE(source_object), res, &error))
                {
-               tmp_filename = g_file_get_parse_name(tz->tmp_g_file);
-               move_file(tmp_filename, tz->timezone_database_user);
+               tmp_filename = g_file_get_path(tz->tmp_g_file);
+               fd = file_data_new_simple(tmp_filename);
+               tmp_dir = open_archive(fd);
+
+               if (tmp_dir)
+                       {
+                       timezone_bin = g_build_filename(tmp_dir, TIMEZONE_DATABASE_VERSION, TIMEZONE_DATABASE_FILE, NULL);
+                       if (isfile(timezone_bin))
+                               {
+                               move_file(timezone_bin, tz->timezone_database_user);
+                               }
+                       else
+                               {
+                               warning_dialog(_("Warning: Cannot open timezone database file"), _("See the Log Window"), GTK_STOCK_DIALOG_WARNING, NULL);
+                               }
+
+                       g_free(timezone_bin);
+                       g_free(tmp_dir); // The folder in /tmp is deleted in exit_program_final()
+                       }
+               else
+                       {
+                       warning_dialog(_("Warning: Cannot open timezone database file"), _("See the Log Window"), GTK_STOCK_DIALOG_WARNING, NULL);
+                       }
                g_free(tmp_filename);
+               file_data_unref(fd);
                }
        else
                {
-               file_util_warning_dialog(_("Timezone database download failed"), error->message, GTK_STOCK_DIALOG_ERROR, NULL);
+               file_util_warning_dialog(_("Error: Timezone database download failed"), error->message, GTK_STOCK_DIALOG_ERROR, NULL);
                }
 
        g_file_delete(tz->tmp_g_file, NULL, &error);
@@ -4231,7 +4293,7 @@ static void timezone_database_install_cb(GtkWidget *widget, gpointer data)
                }
        else
                {
-               tz->timezone_database_gq = g_file_new_for_uri(TIMEZONE_DATABASE);
+               tz->timezone_database_gq = g_file_new_for_uri(TIMEZONE_DATABASE_WEB);
 
                tz->gd = generic_dialog_new(_("Timezone database"), "download_timezone_database", NULL, TRUE, timezone_cancel_button_cb, tz);