[gimp] app: add extension installation in GimpExtensionManager.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add extension installation in GimpExtensionManager.
- Date: Mon, 29 Apr 2019 11:57:04 +0000 (UTC)
commit 50aa7233b27ff711e6176e4f497bff53d07bcb33
Author: Jehan <jehan girinstud io>
Date: Mon Apr 29 15:47:14 2019 +0900
app: add extension installation in GimpExtensionManager.
This completes my earlier commit 406279e4ef.
Extension installation is not about just decompressing a file in the
right folder. We must also make the extension manager and the GUI aware
of this newly available extension.
app/core/gimp-utils.c | 65 +++++++++++++++++++++++++++
app/core/gimp-utils.h | 2 +
app/core/gimpextensionmanager.c | 97 ++++++++++++++++++-----------------------
app/core/gimpextensionmanager.h | 6 +++
app/file-data/file-data-gex.c | 51 +++++++++++++++++++---
5 files changed, 160 insertions(+), 61 deletions(-)
---
diff --git a/app/core/gimp-utils.c b/app/core/gimp-utils.c
index ec9d2982c2..24637033ca 100644
--- a/app/core/gimp-utils.c
+++ b/app/core/gimp-utils.c
@@ -905,3 +905,68 @@ gimp_create_image_from_buffer (Gimp *gimp,
return image;
}
+
+/**
+ * gimp_rec_rm:
+ * @file: #GFile to delete from file system.
+ * @error:
+ *
+ * Delete @file. If file is a directory, it will delete its children as
+ * well recursively. It will not follow symlinks so you won't end up in
+ * infinite loops, not will you be at risk of deleting your whole file
+ * system (unless you pass the root of course!).
+ * Such function unfortunately does not exist in glib, which only allows
+ * to delete single files or empty directories by default.
+ *
+ * Returns: #TRUE if @file was successfully deleted and all its
+ * children, #FALSE otherwise with @error filled.
+ */
+gboolean
+gimp_rec_rm (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_rec_rm (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/gimp-utils.h b/app/core/gimp-utils.h
index 956216e82b..866936c682 100644
--- a/app/core/gimp-utils.h
+++ b/app/core/gimp-utils.h
@@ -102,5 +102,7 @@ GimpImage * gimp_create_image_from_buffer (Gimp *gimp,
GeglBuffer *buffer,
const gchar *image_name);
+gboolean gimp_rec_rm (GFile *file,
+ GError **error);
#endif /* __APP_GIMP_UTILS_H__ */
diff --git a/app/core/gimpextensionmanager.c b/app/core/gimpextensionmanager.c
index 8ea1dec374..bdd8dede31 100644
--- a/app/core/gimpextensionmanager.c
+++ b/app/core/gimpextensionmanager.c
@@ -37,6 +37,7 @@
#include "gimpextension-error.h"
#include "gimpobject.h"
#include "gimpmarshal.h"
+#include "gimp-utils.h"
#include "gimpextensionmanager.h"
@@ -61,6 +62,7 @@ enum
enum
{
+ EXTENSION_INSTALLED,
EXTENSION_REMOVED,
LAST_SIGNAL
};
@@ -124,9 +126,6 @@ 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,
@@ -194,6 +193,16 @@ gimp_extension_manager_class_init (GimpExtensionManagerClass *klass)
NULL, NULL,
GIMP_PARAM_READWRITE));
+ signals[EXTENSION_INSTALLED] =
+ g_signal_new ("extension-installed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GimpExtensionManagerClass, extension_installed),
+ NULL, NULL,
+ gimp_marshal_VOID__OBJECT_BOOLEAN,
+ G_TYPE_NONE, 2,
+ GIMP_TYPE_EXTENSION,
+ G_TYPE_BOOLEAN);
signals[EXTENSION_REMOVED] =
g_signal_new ("extension-removed",
G_TYPE_FROM_CLASS (klass),
@@ -405,7 +414,7 @@ gimp_extension_manager_finalize (GObject *object)
GFile *file;
file = g_file_new_for_path (gimp_extension_get_path (iter->data));
- if (! gimp_extension_manager_rec_delete (file, &error))
+ if (! gimp_rec_rm (file, &error))
g_warning ("%s: %s\n", G_STRFUNC, error->message);
g_object_unref (file);
}
@@ -711,6 +720,36 @@ gimp_extension_manager_can_run (GimpExtensionManager *manager,
return TRUE;
}
+/**
+ * gimp_extension_manager_install:
+ * @manager:
+ * @extension:
+ * @error:
+ *
+ * Install @extension. This merely adds the extension in the known
+ * extension list to make the manager aware of it at runtime, and to
+ * emit a signal for GUI update.
+ */
+gboolean
+gimp_extension_manager_install (GimpExtensionManager *manager,
+ GimpExtension *extension,
+ GError **error)
+{
+ gboolean success = FALSE;
+
+ if ((success = gimp_extension_load (extension, error)))
+ {
+ manager->p->extensions = g_list_prepend (manager->p->extensions,
+ extension);
+ g_signal_connect (extension, "notify::running",
+ G_CALLBACK (gimp_extension_manager_extension_running),
+ manager);
+ g_signal_emit (manager, signals[EXTENSION_INSTALLED], 0, extension, FALSE);
+ }
+
+ return success;
+}
+
/**
* gimp_extension_manager_remove:
* @manager:
@@ -967,53 +1006,3 @@ 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 a4bc1edd3d..7aebedeaa0 100644
--- a/app/core/gimpextensionmanager.h
+++ b/app/core/gimpextensionmanager.h
@@ -47,6 +47,9 @@ struct _GimpExtensionManagerClass
{
GimpObjectClass parent_class;
+ void (* extension_installed) (GimpExtensionManager *manager,
+ GimpExtension *extension,
+ gboolean is_system_ext);
void (* extension_removed) (GimpExtensionManager *manager,
gchar *extension_id);
};
@@ -67,6 +70,9 @@ gboolean gimp_extension_manager_is_running (GimpExtensi
gboolean gimp_extension_manager_can_run (GimpExtensionManager *manager,
GimpExtension *extension);
+gboolean gimp_extension_manager_install (GimpExtensionManager *manager,
+ GimpExtension *extension,
+ GError **error);
gboolean gimp_extension_manager_remove (GimpExtensionManager *manager,
GimpExtension *extension,
GError **error);
diff --git a/app/file-data/file-data-gex.c b/app/file-data/file-data-gex.c
index c10850d34c..efccb5d496 100644
--- a/app/file-data/file-data-gex.c
+++ b/app/file-data/file-data-gex.c
@@ -37,11 +37,14 @@
#include "core/gimpbrush-load.h"
#include "core/gimpbrush-private.h"
#include "core/gimpdrawable.h"
+#include "core/gimpextension.h"
+#include "core/gimpextensionmanager.h"
#include "core/gimpextension-error.h"
#include "core/gimpimage.h"
#include "core/gimplayer-new.h"
#include "core/gimpparamspecs.h"
#include "core/gimptempbuf.h"
+#include "core/gimp-utils.h"
#include "pdb/gimpprocedure.h"
@@ -75,7 +78,7 @@ static gboolean file_gex_validate_path (const gchar *path,
static gboolean file_gex_validate (GFile *file,
AsApp **appstream,
GError **error);
-static gboolean file_gex_decompress (GFile *file,
+static gchar * file_gex_decompress (GFile *file,
gchar *plugin_id,
GError **error);
@@ -342,13 +345,14 @@ file_gex_validate (GFile *file,
return success;
}
-static gboolean
+static gchar *
file_gex_decompress (GFile *file,
gchar *plugin_id,
GError **error)
{
GInputStream *input;
GFile *ext_dir = gimp_directory_file ("extensions", NULL);
+ gchar *plugin_dir = NULL;
gboolean success = FALSE;
g_return_val_if_fail (error != NULL && *error == NULL, FALSE);
@@ -476,9 +480,12 @@ file_gex_decompress (GFile *file,
gimp_file_get_utf8_name (file));
}
+ if (success)
+ plugin_dir = g_build_filename (g_file_get_path (ext_dir), plugin_id, NULL);
+
g_object_unref (ext_dir);
- return success;
+ return plugin_dir;
}
/* public functions */
@@ -494,16 +501,46 @@ file_gex_load_invoker (GimpProcedure *procedure,
GimpValueArray *return_vals;
const gchar *uri;
GFile *file;
- gboolean success = FALSE;
- AsApp *appdata = NULL;
+ gchar *ext_dir = NULL;
+ AsApp *appdata = NULL;
+ gboolean success = FALSE;
gimp_set_busy (gimp);
uri = g_value_get_string (gimp_value_array_index (args, 1));
file = g_file_new_for_uri (uri);
- if (file_gex_validate (file, &appdata, error))
- success = file_gex_decompress (file, (gchar *) as_app_get_id (appdata), error);
+ success = file_gex_validate (file, &appdata, error);
+ if (success)
+ ext_dir = file_gex_decompress (file, (gchar *) as_app_get_id (appdata), error);
+ if (ext_dir)
+ {
+ GimpExtension *extension;
+ GError *rm_error = NULL;
+
+ extension = gimp_extension_new (ext_dir, TRUE);
+ success = gimp_extension_manager_install (gimp->extension_manager, extension, error);
+
+ if (! success)
+ {
+ GFile *file;
+
+ g_object_unref (extension);
+
+ file = g_file_new_for_path (ext_dir);
+ if (! gimp_rec_rm (file, &rm_error))
+ {
+ g_warning ("%s: %s\n", G_STRFUNC, rm_error->message);
+ g_error_free (rm_error);
+ }
+ g_object_unref (file);
+ }
+ g_free (ext_dir);
+ }
+ else
+ {
+ success = FALSE;
+ }
g_object_unref (file);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]