[gnome-text-editor] prefs: use DnD to install style-schemes in preferences
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-text-editor] prefs: use DnD to install style-schemes in preferences
- Date: Wed, 2 Feb 2022 20:38:42 +0000 (UTC)
commit 039d86f9eb50ac90af33cff1f5d81ef6e1cfbc3a
Author: Christian Hergert <chergert redhat com>
Date: Wed Feb 2 12:38:01 2022 -0800
prefs: use DnD to install style-schemes in preferences
This allows installation of style-schemes by dragging them from a file
browser, such as Nautilus, onto the preferences window. They are installed
to $XDG_DATA_DIR/gtksourceview-5/styles/ where they can be used by any
GtkSourceView-5.x based application.
While this isn't the most intuitive to know that you can do it, I don't
think it is a very commonly used feature either and we can probably get
away with documenting it instead of complicated the preferences with
additional buttons.
Fixes #291
src/editor-preferences-dialog.c | 124 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 124 insertions(+)
---
diff --git a/src/editor-preferences-dialog.c b/src/editor-preferences-dialog.c
index cde5762..cda3d49 100644
--- a/src/editor-preferences-dialog.c
+++ b/src/editor-preferences-dialog.c
@@ -380,6 +380,121 @@ style_scheme_activated_cb (EditorPreferencesDialog *self,
}
}
+static gboolean
+can_install_scheme (GtkSourceStyleSchemeManager *manager,
+ const char * const *scheme_ids,
+ GFile *file)
+{
+ g_autofree char *uri = NULL;
+ const char *path;
+
+ g_assert (GTK_SOURCE_IS_STYLE_SCHEME_MANAGER (manager));
+ g_assert (G_IS_FILE (file));
+
+ uri = g_file_get_uri (file);
+
+ /* Don't allow resources, which would be weird anyway */
+ if (g_str_has_prefix (uri, "resource://"))
+ return FALSE;
+
+ /* Make sure it's in the form of name.xml as we will require
+ * that elsewhere anyway.
+ */
+ if (!g_str_has_suffix (uri, ".xml"))
+ return FALSE;
+
+ /* Not a native file, so likely not already installed */
+ if (!g_file_is_native (file))
+ return TRUE;
+
+ path = g_file_peek_path (file);
+ scheme_ids = gtk_source_style_scheme_manager_get_scheme_ids (manager);
+ for (guint i = 0; scheme_ids[i] != NULL; i++)
+ {
+ GtkSourceStyleScheme *scheme = gtk_source_style_scheme_manager_get_scheme (manager, scheme_ids[i]);
+ const char *filename = gtk_source_style_scheme_get_filename (scheme);
+
+ /* If we have already loaded this scheme, then ignore it */
+ if (g_strcmp0 (filename, path) == 0)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+editor_preferences_dialog_install_schemes_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EditorApplication *app = (EditorApplication *)object;
+ g_autoptr(EditorPreferencesDialog) self = user_data;
+ GtkSourceStyleSchemeManager *manager;
+ g_autoptr(GError) error = NULL;
+
+ g_assert (EDITOR_IS_APPLICATION (app));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (EDITOR_IS_PREFERENCES_DIALOG (self));
+
+ if (!editor_application_install_schemes_finish (app, result, &error))
+ g_critical ("Failed to install schemes: %s", error->message);
+
+ manager = gtk_source_style_scheme_manager_get_default ();
+ gtk_source_style_scheme_manager_force_rescan (manager);
+
+ if (!self->disposed)
+ update_style_schemes (self);
+}
+
+static gboolean
+editor_preferences_dialog_drop_scheme_cb (EditorPreferencesDialog *self,
+ const GValue *value,
+ double x,
+ double y,
+ GtkDropTarget *drop_target)
+{
+ g_assert (EDITOR_IS_PREFERENCES_DIALOG (self));
+ g_assert (GTK_IS_DROP_TARGET (drop_target));
+
+ if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
+ {
+ GSList *list = g_value_get_boxed (value);
+ g_autoptr(GPtrArray) to_install = NULL;
+ g_autoptr(GTask) task = NULL;
+ GtkSourceStyleSchemeManager *manager;
+ const char * const *scheme_ids;
+
+ if (list == NULL)
+ return FALSE;
+
+ manager = gtk_source_style_scheme_manager_get_default ();
+ scheme_ids = gtk_source_style_scheme_manager_get_scheme_ids (manager);
+ to_install = g_ptr_array_new_with_free_func (g_object_unref);
+
+ for (const GSList *iter = list; iter; iter = iter->next)
+ {
+ GFile *file = iter->data;
+
+ if (can_install_scheme (manager, scheme_ids, file))
+ g_ptr_array_add (to_install, g_object_ref (file));
+ }
+
+ if (to_install->len == 0)
+ return FALSE;
+
+ editor_application_install_schemes_async (EDITOR_APPLICATION_DEFAULT,
+ (GFile **)(gpointer)to_install->pdata,
+ to_install->len,
+ NULL,
+ editor_preferences_dialog_install_schemes_cb,
+ g_object_ref (self));
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static void
editor_preferences_dialog_constructed (GObject *object)
{
@@ -432,6 +547,7 @@ editor_preferences_dialog_init (EditorPreferencesDialog *self)
{
AdwStyleManager *style_manager;
GtkStyleContext *style_context;
+ GtkDropTarget *drop_target;
gtk_widget_init_template (GTK_WIDGET (self));
@@ -439,6 +555,14 @@ editor_preferences_dialog_init (EditorPreferencesDialog *self)
gtk_widget_add_css_class (GTK_WIDGET (self), "devel");
#endif
+ drop_target = gtk_drop_target_new (GDK_TYPE_FILE_LIST, GDK_ACTION_COPY);
+ g_signal_connect_object (drop_target,
+ "drop",
+ G_CALLBACK (editor_preferences_dialog_drop_scheme_cb),
+ self,
+ G_CONNECT_SWAPPED);
+ gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (drop_target));
+
style_context = gtk_widget_get_style_context (GTK_WIDGET (self->source_view));
self->css_provider = gtk_css_provider_new ();
gtk_style_context_add_provider (style_context,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]