aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sdgui.c96
-rw-r--r--src/utils.c8
2 files changed, 75 insertions, 29 deletions
diff --git a/src/sdgui.c b/src/sdgui.c
index 81d17db..993d1f5 100644
--- a/src/sdgui.c
+++ b/src/sdgui.c
@@ -42,6 +42,8 @@ static struct
gint last; ///< The last dictionary index
GPtrArray *dictionaries; ///< All open dictionaries
+ gboolean loading; ///< Dictionaries are being loaded
+
gboolean watch_selection; ///< Following X11 PRIMARY?
}
g;
@@ -49,19 +51,19 @@ g;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static void
-init (gchar **filenames)
+load_from_filenames (GPtrArray *out, gchar **filenames)
{
for (gsize i = 0; filenames[i]; i++)
{
Dictionary *dict = g_malloc0 (sizeof *dict);
dict->filename = g_strdup (filenames[i]);
- g_ptr_array_add (g.dictionaries, dict);
+ g_ptr_array_add (out, dict);
}
}
// TODO: try to deduplicate, similar to app_load_config_values()
static gboolean
-init_from_key_file (GKeyFile *kf, GError **error)
+load_from_key_file (GPtrArray *out, GKeyFile *kf, GError **error)
{
const gchar *dictionaries = "Dictionaries";
gchar **names = g_key_file_get_keys (kf, dictionaries, NULL, NULL);
@@ -72,13 +74,13 @@ init_from_key_file (GKeyFile *kf, GError **error)
{
Dictionary *dict = g_malloc0 (sizeof *dict);
dict->name = names[i];
- g_ptr_array_add (g.dictionaries, dict);
+ g_ptr_array_add (out, dict);
}
g_free (names);
- for (gsize i = 0; i < g.dictionaries->len; i++)
+ for (gsize i = 0; i < out->len; i++)
{
- Dictionary *dict = g_ptr_array_index (g.dictionaries, i);
+ Dictionary *dict = g_ptr_array_index (out, i);
gchar *path =
g_key_file_get_string (kf, dictionaries, dict->name, error);
if (!path)
@@ -95,13 +97,13 @@ init_from_key_file (GKeyFile *kf, GError **error)
}
static gboolean
-init_from_config (GError **error)
+load_from_config (GPtrArray *out, GError **error)
{
GKeyFile *key_file = load_project_config_file (error);
if (!key_file)
return FALSE;
- gboolean result = init_from_key_file (key_file, error);
+ gboolean result = load_from_key_file (out, key_file, error);
g_key_file_free (key_file);
return result;
}
@@ -111,6 +113,8 @@ search (Dictionary *dict)
{
GtkEntryBuffer *buf = gtk_entry_get_buffer (GTK_ENTRY (g.entry));
const gchar *input_utf8 = gtk_entry_buffer_get_text (buf);
+ if (!dict->dict)
+ return;
StardictIterator *iterator =
stardict_dict_search (dict->dict, input_utf8, NULL);
@@ -295,20 +299,68 @@ show_error_dialog (GError *error)
g_error_free (error);
}
-static gboolean
-reload_dictionaries (GPtrArray *new_dictionaries, GError **error)
+static void
+on_new_dictionaries_loaded (G_GNUC_UNUSED GObject* source_object,
+ GAsyncResult* res, G_GNUC_UNUSED gpointer user_data)
{
- if (!load_dictionaries (new_dictionaries, error))
- return FALSE;
+ g.loading = FALSE;
+
+ GError *error = NULL;
+ GPtrArray *new_dictionaries =
+ g_task_propagate_pointer (G_TASK (res), &error);
+ if (!new_dictionaries)
+ {
+ show_error_dialog (error);
+ return;
+ }
while (gtk_notebook_get_n_pages (GTK_NOTEBOOK (g.notebook)))
gtk_notebook_remove_page (GTK_NOTEBOOK (g.notebook), -1);
g.dictionary = -1;
+ if (g.dictionaries)
+ g_ptr_array_free (g.dictionaries, TRUE);
+
stardict_view_set_position (STARDICT_VIEW (g.view), NULL, 0);
- g_ptr_array_free (g.dictionaries, TRUE);
g.dictionaries = new_dictionaries;
init_tabs ();
+}
+
+static void
+on_reload_dictionaries_task (GTask *task, G_GNUC_UNUSED gpointer source_object,
+ gpointer task_data, G_GNUC_UNUSED GCancellable *cancellable)
+{
+ GError *error = NULL;
+ if (load_dictionaries (task_data, &error))
+ {
+ g_task_return_pointer (task,
+ g_ptr_array_ref (task_data), (GDestroyNotify) g_ptr_array_unref);
+ }
+ else
+ g_task_return_error (task, error);
+}
+
+static gboolean
+reload_dictionaries (GPtrArray *new_dictionaries, GError **error)
+{
+ // TODO: We could cancel that task.
+ if (g.loading)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "already loading dictionaries");
+ return FALSE;
+ }
+
+ // TODO: Some other kind of indication.
+ // Note that "action widgets" aren't visible without GtkNotebook tabs.
+ g.loading = TRUE;
+
+ GTask *task = g_task_new (NULL, NULL, on_new_dictionaries_loaded, NULL);
+ g_task_set_name (task, __func__);
+ g_task_set_task_data (task,
+ new_dictionaries, (GDestroyNotify) g_ptr_array_unref);
+ g_task_run_in_thread (task, on_reload_dictionaries_task);
+ g_object_unref (task);
return TRUE;
}
@@ -429,19 +481,19 @@ main (int argc, char *argv[])
gtk_window_set_default_icon_name (PROJECT_NAME);
- g.dictionaries =
+ GPtrArray *new_dictionaries =
g_ptr_array_new_with_free_func ((GDestroyNotify) dictionary_destroy);
if (filenames)
- init (filenames);
- else if (!init_from_config (&error) && error)
+ {
+ load_from_filenames (new_dictionaries, filenames);
+ g_strfreev (filenames);
+ }
+ else if (!load_from_config (new_dictionaries, &error) && error)
die_with_dialog (error->message);
- g_strfreev (filenames);
- if (!g.dictionaries->len)
+ if (!new_dictionaries->len)
die_with_dialog (_("No dictionaries found either in "
"the configuration or on the command line"));
- if (!load_dictionaries (g.dictionaries, &error))
- die_with_dialog (error->message);
// Some Adwaita stupidity, plus defaults for our own widget.
// All the named colours have been there since GNOME 3.4
@@ -530,7 +582,6 @@ main (int argc, char *argv[])
g.view = stardict_view_new ();
gtk_box_pack_end (GTK_BOX (superbox), g.view, TRUE, TRUE, 0);
- init_tabs ();
GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
g_signal_connect (clipboard, "owner-change",
@@ -544,6 +595,9 @@ main (int argc, char *argv[])
g_signal_connect (g.view, "send",
G_CALLBACK (on_send), NULL);
+ if (!reload_dictionaries (new_dictionaries, &error))
+ die_with_dialog (error->message);
+
gtk_widget_show_all (g.window);
gtk_main ();
return 0;
diff --git a/src/utils.c b/src/utils.c
index 6a32bda..5542202 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -269,7 +269,6 @@ load_dictionaries_sequentially (GPtrArray *dictionaries, GError **e)
}
// Parallelize dictionary loading if possible, because of collation reindexing
-#if GLIB_CHECK_VERSION (2, 36, 0)
static void
load_worker (gpointer data, gpointer user_data)
{
@@ -304,10 +303,3 @@ load_dictionaries (GPtrArray *dictionaries, GError **e)
g_async_queue_unref (error_queue);
return result;
}
-#else // GLib < 2.36
-gboolean
-load_dictionaries (GPtrArray *dictionaries, GError **e)
-{
- return load_dictionaries_sequentially (dictionaries, e);
-}
-#endif // GLib < 2.36