app, libgimp, pdb: private _gimp_resource_get_by_identifiers() PDB function.

This finds the core resource knowing its type, name, collection and internal
state (in other words, the values returned by _gimp_resource_get_identifiers()).
This commit is contained in:
Jehan 2023-07-20 01:36:52 +02:00
parent fe58de7f81
commit 38c717b149
7 changed files with 368 additions and 69 deletions

View File

@ -54,61 +54,24 @@
#include "gimp-intl.h"
static GimpResource * gimp_pdb_get_data_factory_item (Gimp *gimp,
GType data_type,
const gchar *name);
const gchar * gimp_pdb_get_data_label (GType data_type);
static GimpResource *
gimp_pdb_get_data_factory_item (Gimp *gimp,
GType data_type,
const gchar *name)
typedef struct
{
GimpDataFactory *factory;
GimpObject *resource;
const gchar *name;
const gchar *collection;
gboolean is_internal;
} SearchData;
factory = gimp_pdb_get_data_factory (gimp, data_type);
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
resource = gimp_container_get_child_by_name (gimp_data_factory_get_container (factory), name);
static GimpResource * gimp_pdb_get_data_factory_item (Gimp *gimp,
GType data_type,
const gchar *name,
const gchar *collection,
gboolean is_internal);
const gchar * gimp_pdb_get_data_label (GType data_type);
if (! resource)
resource = gimp_container_get_child_by_name (gimp_data_factory_get_container_obsolete (factory),
name);
static gboolean gimp_pdb_search_in_data_container (GimpData *data,
SearchData *search_data);;
if (! resource && ! strcmp (name, "Standard"))
resource = (GimpObject *) gimp_data_factory_data_get_standard (factory,
gimp_get_user_context (gimp));
return (GimpResource *) resource;
}
const gchar *
gimp_pdb_get_data_label (GType data_type)
{
g_return_val_if_fail (g_type_is_a (data_type, GIMP_TYPE_DATA), NULL);
if (g_type_is_a (data_type, GIMP_TYPE_BRUSH_GENERATED))
return C_("PDB-error-data-label", "Generated brush");
else if (g_type_is_a (data_type, GIMP_TYPE_BRUSH))
return C_("PDB-error-data-label", "Brush");
else if (g_type_is_a (data_type, GIMP_TYPE_PATTERN))
return C_("PDB-error-data-label", "Pattern");
else if (g_type_is_a (data_type, GIMP_TYPE_GRADIENT))
return C_("PDB-error-data-label", "Gradient");
else if (g_type_is_a (data_type, GIMP_TYPE_PALETTE))
return C_("PDB-error-data-label", "Palette");
else if (g_type_is_a (data_type, GIMP_TYPE_FONT))
return C_("PDB-error-data-label", "Font");
else if (g_type_is_a (data_type, GIMP_TYPE_DYNAMICS))
return C_("PDB-error-data-label", "Paint dynamics");
else if (g_type_is_a (data_type, GIMP_TYPE_MYBRUSH))
return C_("PDB-error-data-label", "MyPaint brush");
/* If we reach this, it means we forgot a data type in our list! */
g_return_val_if_reached (NULL);
}
GimpDataFactory *
gimp_pdb_get_data_factory (Gimp *gimp,
@ -164,7 +127,72 @@ gimp_pdb_get_resource (Gimp *gimp,
return NULL;
}
resource = gimp_pdb_get_data_factory_item (gimp, data_type, name);
resource = gimp_pdb_get_data_factory_item (gimp, data_type, name, NULL, TRUE);
if (! resource)
{
g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
/* TRANSLATOR: the first %s is a data label from the
* PDB-error-data-label context. The second %s is a data
* name.
*/
C_("PDB-error-message", "%s '%s' not found"), label, name);
}
else if ((access & GIMP_PDB_DATA_ACCESS_WRITE) &&
! gimp_data_is_writable (GIMP_DATA (resource)))
{
g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
/* TRANSLATOR: the first %s is a data label from the
* PDB-error-data-label context. The second %s is a data
* name.
*/
C_("PDB-error-message", "%s '%s' is not editable"), label, name);
return NULL;
}
else if ((access & GIMP_PDB_DATA_ACCESS_RENAME) &&
! gimp_viewable_is_name_editable (GIMP_VIEWABLE (resource)))
{
g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
/* TRANSLATOR: the first %s is a data label from the
* PDB-error-data-label context. The second %s is a data
* name.
*/
C_("PDB-error-message", "%s '%s' is not renamable"), label, name);
return NULL;
}
return resource;
}
GimpResource *
gimp_pdb_get_resource_by_id (Gimp *gimp,
GType data_type,
const gchar *name,
const gchar *collection,
gboolean is_internal,
GimpPDBDataAccess access,
GError **error)
{
GimpResource *resource;
const gchar *label;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
label = gimp_pdb_get_data_label (data_type);
if (! name || ! strlen (name))
{
g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
/* TRANSLATOR: %s is a data label from the
* PDB-error-data-label context.
*/
C_("PDB-error-message", "%s name cannot be empty"),
g_type_name (data_type));
return NULL;
}
resource = gimp_pdb_get_data_factory_item (gimp, data_type, name, collection, is_internal);
if (! resource)
{
@ -719,3 +747,83 @@ gimp_pdb_is_canonical_procedure (const gchar *procedure_name,
return TRUE;
}
/* Private functions. */
static GimpResource *
gimp_pdb_get_data_factory_item (Gimp *gimp,
GType data_type,
const gchar *name,
const gchar *collection,
gboolean is_internal)
{
GimpDataFactory *factory;
GimpContainer *container;
GimpObject *resource;
factory = gimp_pdb_get_data_factory (gimp, data_type);
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
container = gimp_data_factory_get_container (factory);
if (collection == NULL)
{
resource = gimp_container_get_child_by_name (container, name);
}
else
{
SearchData *data = g_new (SearchData, 1);
data->name = name;
data->collection = collection;
data->is_internal = is_internal;
resource = gimp_container_search (container,
(GimpContainerSearchFunc) gimp_pdb_search_in_data_container,
data);
g_free (data);
}
if (! resource)
resource = gimp_container_get_child_by_name (gimp_data_factory_get_container_obsolete (factory),
name);
if (! resource && ! strcmp (name, "Standard"))
resource = (GimpObject *) gimp_data_factory_data_get_standard (factory,
gimp_get_user_context (gimp));
return (GimpResource *) resource;
}
const gchar *
gimp_pdb_get_data_label (GType data_type)
{
g_return_val_if_fail (g_type_is_a (data_type, GIMP_TYPE_DATA), NULL);
if (g_type_is_a (data_type, GIMP_TYPE_BRUSH_GENERATED))
return C_("PDB-error-data-label", "Generated brush");
else if (g_type_is_a (data_type, GIMP_TYPE_BRUSH))
return C_("PDB-error-data-label", "Brush");
else if (g_type_is_a (data_type, GIMP_TYPE_PATTERN))
return C_("PDB-error-data-label", "Pattern");
else if (g_type_is_a (data_type, GIMP_TYPE_GRADIENT))
return C_("PDB-error-data-label", "Gradient");
else if (g_type_is_a (data_type, GIMP_TYPE_PALETTE))
return C_("PDB-error-data-label", "Palette");
else if (g_type_is_a (data_type, GIMP_TYPE_FONT))
return C_("PDB-error-data-label", "Font");
else if (g_type_is_a (data_type, GIMP_TYPE_DYNAMICS))
return C_("PDB-error-data-label", "Paint dynamics");
else if (g_type_is_a (data_type, GIMP_TYPE_MYBRUSH))
return C_("PDB-error-data-label", "MyPaint brush");
/* If we reach this, it means we forgot a data type in our list! */
g_return_val_if_reached (NULL);
}
static gboolean
gimp_pdb_search_in_data_container (GimpData *data,
SearchData *search_data)
{
return gimp_data_identify (data, search_data->name, search_data->collection, search_data->is_internal);
}

View File

@ -27,6 +27,13 @@ GimpResource * gimp_pdb_get_resource (Gimp *gimp,
const gchar *name,
GimpPDBDataAccess access,
GError **error);
GimpResource * gimp_pdb_get_resource_by_id (Gimp *gimp,
GType data_type,
const gchar *name,
const gchar *collection,
gboolean is_internal,
GimpPDBDataAccess access,
GError **error);
GimpBrush * gimp_pdb_get_generated_brush (Gimp *gimp,
const gchar *name,
GimpPDBDataAccess access,

View File

@ -30,7 +30,7 @@
#include "internal-procs.h"
/* 774 procedures registered total */
/* 775 procedures registered total */
void
internal_procs_init (GimpPDB *pdb)

View File

@ -82,6 +82,46 @@ resource_get_by_name_invoker (GimpProcedure *procedure,
return return_vals;
}
static GimpValueArray *
resource_get_by_identifiers_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
gboolean success = TRUE;
GimpValueArray *return_vals;
const gchar *type_name;
const gchar *resource_name;
const gchar *collection;
gboolean is_internal;
GimpResource *resource = NULL;
type_name = g_value_get_string (gimp_value_array_index (args, 0));
resource_name = g_value_get_string (gimp_value_array_index (args, 1));
collection = g_value_get_string (gimp_value_array_index (args, 2));
is_internal = g_value_get_boolean (gimp_value_array_index (args, 3));
if (success)
{
resource = gimp_pdb_get_resource_by_id (gimp, g_type_from_name (type_name),
resource_name, collection, is_internal,
GIMP_PDB_DATA_ACCESS_READ, error);
if (! resource)
success = FALSE;
}
return_vals = gimp_procedure_get_return_values (procedure, success,
error ? *error : NULL);
if (success)
g_value_set_object (gimp_value_array_index (return_vals, 1), resource);
return return_vals;
}
static GimpValueArray *
resource_id_is_valid_invoker (GimpProcedure *procedure,
Gimp *gimp,
@ -504,6 +544,56 @@ register_resource_procs (GimpPDB *pdb)
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-resource-get-by-identifiers
*/
procedure = gimp_procedure_new (resource_get_by_identifiers_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-resource-get-by-identifiers");
gimp_procedure_set_static_help (procedure,
"Returns the resource contained in a given file with a given name.",
"Returns a resource specifically stored in a given file path, under a given name (a single path may be a collection containing several resources).",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Jehan",
"Jehan",
"2023");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("type-name",
"type name",
"The name of the resource type",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("resource-name",
"resource name",
"The name of the resource",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("collection",
"collection",
"The collection identifier",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_boolean ("is-internal",
"is internal",
"Whether this is the identifier for internal data",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
gimp_param_spec_resource ("resource",
"resource",
"The resource",
FALSE,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-resource-id-is-valid
*/

View File

@ -75,6 +75,53 @@ _gimp_resource_get_by_name (const gchar *type_name,
return resource;
}
/**
* _gimp_resource_get_by_identifiers:
* @type_name: The name of the resource type.
* @resource_name: The name of the resource.
* @collection: The collection identifier.
* @is_internal: Whether this is the identifier for internal data.
*
* Returns the resource contained in a given file with a given name.
*
* Returns a resource specifically stored in a given file path, under a
* given name (a single path may be a collection containing several
* resources).
*
* Returns: (transfer none): The resource.
*
* Since: 3.0
**/
GimpResource *
_gimp_resource_get_by_identifiers (const gchar *type_name,
const gchar *resource_name,
const gchar *collection,
gboolean is_internal)
{
GimpValueArray *args;
GimpValueArray *return_vals;
GimpResource *resource = NULL;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, type_name,
G_TYPE_STRING, resource_name,
G_TYPE_STRING, collection,
G_TYPE_BOOLEAN, is_internal,
G_TYPE_NONE);
return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
"gimp-resource-get-by-identifiers",
args);
gimp_value_array_unref (args);
if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
resource = GIMP_VALUES_GET_RESOURCE (return_vals, 1);
gimp_value_array_unref (return_vals);
return resource;
}
/**
* gimp_resource_id_is_valid:
* @resource_id: The resource ID to check.

View File

@ -32,23 +32,27 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
G_GNUC_INTERNAL GimpResource* _gimp_resource_get_by_name (const gchar *type_name,
const gchar *resource_name);
gboolean gimp_resource_id_is_valid (gint resource_id);
gboolean gimp_resource_id_is_brush (gint resource_id);
gboolean gimp_resource_id_is_pattern (gint resource_id);
gboolean gimp_resource_id_is_gradient (gint resource_id);
gboolean gimp_resource_id_is_palette (gint resource_id);
gboolean gimp_resource_id_is_font (gint resource_id);
gchar* gimp_resource_get_name (GimpResource *resource);
G_GNUC_INTERNAL gboolean _gimp_resource_get_identifiers (GimpResource *resource,
gchar **name,
gchar **collection_id);
gboolean gimp_resource_is_editable (GimpResource *resource);
GimpResource* gimp_resource_duplicate (GimpResource *resource);
gboolean gimp_resource_rename (GimpResource *resource,
const gchar *new_name);
gboolean gimp_resource_delete (GimpResource *resource);
G_GNUC_INTERNAL GimpResource* _gimp_resource_get_by_name (const gchar *type_name,
const gchar *resource_name);
G_GNUC_INTERNAL GimpResource* _gimp_resource_get_by_identifiers (const gchar *type_name,
const gchar *resource_name,
const gchar *collection,
gboolean is_internal);
gboolean gimp_resource_id_is_valid (gint resource_id);
gboolean gimp_resource_id_is_brush (gint resource_id);
gboolean gimp_resource_id_is_pattern (gint resource_id);
gboolean gimp_resource_id_is_gradient (gint resource_id);
gboolean gimp_resource_id_is_palette (gint resource_id);
gboolean gimp_resource_id_is_font (gint resource_id);
gchar* gimp_resource_get_name (GimpResource *resource);
G_GNUC_INTERNAL gboolean _gimp_resource_get_identifiers (GimpResource *resource,
gchar **name,
gchar **collection_id);
gboolean gimp_resource_is_editable (GimpResource *resource);
GimpResource* gimp_resource_duplicate (GimpResource *resource);
gboolean gimp_resource_rename (GimpResource *resource,
const gchar *new_name);
gboolean gimp_resource_delete (GimpResource *resource);
G_END_DECLS

View File

@ -50,6 +50,48 @@ CODE
);
}
sub resource_get_by_identifiers {
$blurb = "Returns the resource contained in a given file with a given name.";
$help = <<'HELP';
Returns a resource specifically stored in a given file path, under a given name
(a single path may be a collection containing several resources).
HELP
&jehan_pdb_misc('2023', '3.0');
$lib_private = 1;
@inargs = (
{ name => 'type_name', type => 'string', non_empty => 1,
desc => 'The name of the resource type' },
{ name => 'resource_name', type => 'string', non_empty => 1,
desc => 'The name of the resource' },
{ name => 'collection', type => 'string', non_empty => 1,
desc => 'The collection identifier' },
{ name => 'is_internal', type => 'boolean',
desc => 'Whether this is the identifier for internal data'}
);
@outargs = (
{ name => 'resource',
type => 'resource',
desc => "The resource" }
);
%invoke = (
code => <<'CODE'
{
resource = gimp_pdb_get_resource_by_id (gimp, g_type_from_name (type_name),
resource_name, collection, is_internal,
GIMP_PDB_DATA_ACCESS_READ, error);
if (! resource)
success = FALSE;
}
CODE
);
}
sub resource_id_is_valid {
$blurb = 'Returns TRUE if the resource ID is valid.';
@ -440,6 +482,7 @@ CODE
"gimp-intl.h");
@procs = qw(resource_get_by_name
resource_get_by_identifiers
resource_id_is_valid
resource_id_is_brush
resource_id_is_pattern