mirror of https://github.com/GNOME/gimp.git
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.
This commit is contained in:
parent
15a62eea8e
commit
f7e483dd64
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Loading…
Reference in New Issue