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.
This commit is contained in:
Jehan 2019-04-29 15:47:14 +09:00
parent f7e483dd64
commit 50aa7233b2
5 changed files with 160 additions and 61 deletions

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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);

View File

@ -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);