[gimp] app: add ability to remove an extension.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add ability to remove an extension.
- Date: Mon, 29 Apr 2019 11:56:59 +0000 (UTC)
commit f7e483dd64023115a3ad3e428a569baf0b78ecb0
Author: Jehan <jehan girinstud io>
Date: Mon Apr 29 14:33:45 2019 +0900
app: add ability to remove an extension.
Removing an extension means just unloading it and temporarily move it to
an "uninstalled" list. The actual files will only be deleted when
cleanly exiting the program, hence finalizing the extension manager.
This will allow undoing an extension removal easily.
app/core/gimpextension.c | 8 +++
app/core/gimpextension.h | 1 +
app/core/gimpextensionmanager.c | 143 ++++++++++++++++++++++++++++++++++++++++
app/core/gimpextensionmanager.h | 13 +++-
4 files changed, 162 insertions(+), 3 deletions(-)
---
diff --git a/app/core/gimpextension.c b/app/core/gimpextension.c
index 4618f2e03b..5675ca97f7 100644
--- a/app/core/gimpextension.c
+++ b/app/core/gimpextension.c
@@ -255,6 +255,14 @@ gimp_extension_get_description (GimpExtension *extension)
as_app_get_description (extension->p->app, NULL);
}
+const gchar *
+gimp_extension_get_path (GimpExtension *extension)
+{
+ g_return_val_if_fail (GIMP_IS_EXTENSION (extension), NULL);
+
+ return extension->p->path;
+}
+
gchar *
gimp_extension_get_markup_description (GimpExtension *extension)
{
diff --git a/app/core/gimpextension.h b/app/core/gimpextension.h
index 41b6bf577f..bfb3531cee 100644
--- a/app/core/gimpextension.h
+++ b/app/core/gimpextension.h
@@ -55,6 +55,7 @@ GimpExtension * gimp_extension_new (const gchar *dir,
const gchar * gimp_extension_get_name (GimpExtension *extension);
const gchar * gimp_extension_get_comment (GimpExtension *extension);
const gchar * gimp_extension_get_description (GimpExtension *extension);
+const gchar * gimp_extension_get_path (GimpExtension *extension);
gchar * gimp_extension_get_markup_description (GimpExtension *extension);
diff --git a/app/core/gimpextensionmanager.c b/app/core/gimpextensionmanager.c
index 5b5de7c290..8ea1dec374 100644
--- a/app/core/gimpextensionmanager.c
+++ b/app/core/gimpextensionmanager.c
@@ -34,6 +34,7 @@
#include "gimp.h"
#include "gimpextension.h"
+#include "gimpextension-error.h"
#include "gimpobject.h"
#include "gimpmarshal.h"
@@ -58,6 +59,12 @@ enum
PROP_PLUG_IN_PATHS,
};
+enum
+{
+ EXTENSION_REMOVED,
+ LAST_SIGNAL
+};
+
struct _GimpExtensionManagerPrivate
{
Gimp *gimp;
@@ -66,6 +73,8 @@ struct _GimpExtensionManagerPrivate
GList *sys_extensions;
/* Self-installed (read-write) extensions. */
GList *extensions;
+ /* Uninstalled extensions (cached to allow undo). */
+ GList *uninstalled_extensions;
/* Running extensions */
GHashTable *running_extensions;
@@ -115,6 +124,10 @@ static void gimp_extension_manager_extension_running (GimpExtension
GParamSpec *pspec,
GimpExtensionManager *manager);
+/* Utils. */
+static gboolean gimp_extension_manager_rec_delete (GFile *file,
+ GError **error);
+
G_DEFINE_TYPE_WITH_CODE (GimpExtensionManager, gimp_extension_manager,
GIMP_TYPE_OBJECT,
G_ADD_PRIVATE (GimpExtensionManager)
@@ -123,6 +136,8 @@ G_DEFINE_TYPE_WITH_CODE (GimpExtensionManager, gimp_extension_manager,
#define parent_class gimp_extension_manager_parent_class
+static guint signals[LAST_SIGNAL] = { 0, };
+
static void
gimp_extension_manager_class_init (GimpExtensionManagerClass *klass)
{
@@ -178,6 +193,16 @@ gimp_extension_manager_class_init (GimpExtensionManagerClass *klass)
g_param_spec_pointer ("plug-in-paths",
NULL, NULL,
GIMP_PARAM_READWRITE));
+
+ signals[EXTENSION_REMOVED] =
+ g_signal_new ("extension-removed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GimpExtensionManagerClass, extension_removed),
+ NULL, NULL,
+ gimp_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
}
static void
@@ -365,12 +390,27 @@ gimp_extension_manager_deserialize (GimpConfig *config,
static void
gimp_extension_manager_finalize (GObject *object)
{
+ GList *iter;
+
GimpExtensionManager *manager = GIMP_EXTENSION_MANAGER (object);
g_list_free_full (manager->p->sys_extensions, g_object_unref);
g_list_free_full (manager->p->extensions, g_object_unref);
g_hash_table_unref (manager->p->running_extensions);
+ for (iter = manager->p->uninstalled_extensions; iter; iter = iter->next)
+ {
+ /* Recursively delete folders of uninstalled extensions. */
+ GError *error = NULL;
+ GFile *file;
+
+ file = g_file_new_for_path (gimp_extension_get_path (iter->data));
+ if (! gimp_extension_manager_rec_delete (file, &error))
+ g_warning ("%s: %s\n", G_STRFUNC, error->message);
+ g_object_unref (file);
+ }
+ g_list_free_full (manager->p->uninstalled_extensions, g_object_unref);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -671,6 +711,59 @@ gimp_extension_manager_can_run (GimpExtensionManager *manager,
return TRUE;
}
+/**
+ * gimp_extension_manager_remove:
+ * @manager:
+ * @extension:
+ * @error:
+ *
+ * Uninstall @extension. Technically this only move the object to a
+ * temporary list. The extension folder will be really deleted when GIMP
+ * will stop.
+ * This allows to undo a deletion for as long as the session runs.
+ */
+gboolean
+gimp_extension_manager_remove (GimpExtensionManager *manager,
+ GimpExtension *extension,
+ GError **error)
+{
+ GList *iter;
+
+ g_return_val_if_fail (GIMP_IS_EXTENSION_MANAGER (manager), FALSE);
+ g_return_val_if_fail (GIMP_IS_EXTENSION (extension), FALSE);
+
+ iter = (GList *) gimp_extension_manager_get_system_extensions (manager);
+ for (; iter; iter = iter->next)
+ if (iter->data == extension)
+ {
+ /* System extensions cannot be uninstalled. */
+ if (error)
+ *error = g_error_new (GIMP_EXTENSION_ERROR,
+ GIMP_EXTENSION_FAILED,
+ _("System extensions cannot be uninstalled."));
+ return FALSE;
+ }
+
+ iter = (GList *) gimp_extension_manager_get_user_extensions (manager);
+ for (; iter; iter = iter->next)
+ if (gimp_extension_cmp (iter->data, extension) == 0)
+ break;
+
+ /* The extension has to be in the extension list. */
+ g_return_val_if_fail (iter != NULL, FALSE);
+
+ gimp_extension_stop (extension);
+
+ manager->p->extensions = g_list_remove_link (manager->p->extensions,
+ iter);
+ manager->p->uninstalled_extensions = g_list_concat (manager->p->uninstalled_extensions,
+ iter);
+ g_signal_emit (manager, signals[EXTENSION_REMOVED], 0,
+ gimp_object_get_name (extension));
+
+ return TRUE;
+}
+
/* Private functions. */
static void
@@ -874,3 +967,53 @@ gimp_extension_manager_extension_running (GimpExtension *extension,
gimp_extension_manager_refresh (manager);
}
+
+static gboolean
+gimp_extension_manager_rec_delete (GFile *file,
+ GError **error)
+{
+ gboolean success = TRUE;
+
+ if (g_file_query_exists (file, NULL))
+ {
+ if (g_file_query_file_type (file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL) == G_FILE_TYPE_DIRECTORY)
+ {
+ GFileEnumerator *enumerator;
+
+ enumerator = g_file_enumerate_children (file,
+ G_FILE_ATTRIBUTE_STANDARD_NAME ","
+ G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN ","
+ G_FILE_ATTRIBUTE_TIME_MODIFIED,
+ G_FILE_QUERY_INFO_NONE,
+ NULL, NULL);
+ if (enumerator)
+ {
+ GFileInfo *info;
+
+ while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)))
+ {
+ GFile *child;
+
+ child = g_file_enumerator_get_child (enumerator, info);
+ g_object_unref (info);
+
+ if (! gimp_extension_manager_rec_delete (child, error))
+ success = FALSE;
+
+ g_object_unref (child);
+ if (! success)
+ break;
+ }
+
+ g_object_unref (enumerator);
+ }
+ }
+
+ if (success)
+ /* Non-directory or empty directory. */
+ success = g_file_delete (file, NULL, error);
+ }
+
+ return success;
+}
diff --git a/app/core/gimpextensionmanager.h b/app/core/gimpextensionmanager.h
index 91384496dc..a4bc1edd3d 100644
--- a/app/core/gimpextensionmanager.h
+++ b/app/core/gimpextensionmanager.h
@@ -45,13 +45,16 @@ struct _GimpExtensionManager
struct _GimpExtensionManagerClass
{
- GimpObjectClass parent_class;
+ GimpObjectClass parent_class;
+
+ void (* extension_removed) (GimpExtensionManager *manager,
+ gchar *extension_id);
};
-GType gimp_extension_manager_get_type (void) G_GNUC_CONST;
+GType gimp_extension_manager_get_type (void) G_GNUC_CONST;
-GimpExtensionManager * gimp_extension_manager_new (Gimp *gimp);
+GimpExtensionManager * gimp_extension_manager_new (Gimp *gimp);
void gimp_extension_manager_initialize (GimpExtensionManager *manager);
void gimp_extension_manager_exit (GimpExtensionManager *manager);
@@ -64,4 +67,8 @@ gboolean gimp_extension_manager_is_running (GimpExtensi
gboolean gimp_extension_manager_can_run (GimpExtensionManager *manager,
GimpExtension *extension);
+gboolean gimp_extension_manager_remove (GimpExtensionManager *manager,
+ GimpExtension *extension,
+ GError **error);
+
#endif /* __GIMP_EXTENSION_MANAGER_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]