diff --git a/libgimp/gimp.def b/libgimp/gimp.def index 976df353b8..cc2279c440 100644 --- a/libgimp/gimp.def +++ b/libgimp/gimp.def @@ -619,6 +619,7 @@ EXPORTS gimp_load_procedure_get_thumbnail_loader gimp_load_procedure_get_type gimp_load_procedure_new + gimp_load_procedure_new2 gimp_load_procedure_set_handles_raw gimp_load_procedure_set_thumbnail_loader gimp_main diff --git a/libgimp/gimpimagemetadata.c b/libgimp/gimpimagemetadata.c index 35d8e44793..805ccaf4d7 100644 --- a/libgimp/gimpimagemetadata.c +++ b/libgimp/gimpimagemetadata.c @@ -121,7 +121,6 @@ gimp_image_metadata_load_finish (GimpImage *image, GimpMetadataLoadFlags flags) { g_return_if_fail (GIMP_IS_IMAGE (image)); - g_return_if_fail (mime_type != NULL); g_return_if_fail (GEXIV2_IS_METADATA (metadata)); if (flags & GIMP_METADATA_LOAD_COMMENT) diff --git a/libgimp/gimploadprocedure.c b/libgimp/gimploadprocedure.c index 09476dfe74..7b49dda525 100644 --- a/libgimp/gimploadprocedure.c +++ b/libgimp/gimploadprocedure.c @@ -25,6 +25,8 @@ #include "gimploadprocedure.h" #include "gimppdb_pdb.h" +#include "libgimp-intl.h" + /** * GimpLoadProcedure: @@ -53,6 +55,7 @@ struct _GimpLoadProcedurePrivate { GimpRunLoadFunc run_func; + GimpRunLoadFunc2 run_func2; gpointer run_data; GDestroyNotify run_data_destroy; @@ -193,11 +196,102 @@ gimp_load_procedure_run (GimpProcedure *procedure, gimp_value_array_append (remaining, value); } - return_values = load_proc->priv->run_func (procedure, - run_mode, - file, - remaining, - load_proc->priv->run_data); + if (load_proc->priv->run_func2) + { + GimpProcedureConfig *config; + GimpImage *image = NULL; + GimpMetadata *metadata = NULL; + gchar *mimetype = NULL; + GimpMetadataLoadFlags flags = GIMP_METADATA_LOAD_ALL; + GimpPDBStatusType status = GIMP_PDB_EXECUTION_ERROR; + + config = gimp_procedure_create_config (procedure); + mimetype = (gchar *) gimp_file_procedure_get_mime_types (GIMP_FILE_PROCEDURE (procedure)); + + if (mimetype != NULL) + { + char *delim; + + mimetype = g_strdup (mimetype); + mimetype = g_strstrip (mimetype); + delim = strstr (mimetype, ","); + if (delim) + *delim = '\0'; + /* Though docs only writes about the list being comma-separated, our + * code apparently also split by spaces. + */ + delim = strstr (mimetype, " "); + if (delim) + *delim = '\0'; + delim = strstr (mimetype, "\t"); + if (delim) + *delim = '\0'; + + metadata = gimp_metadata_load_from_file (file, NULL); + g_free (mimetype); + } + else + { + flags = GIMP_METADATA_LOAD_NONE; + } + + if (metadata == NULL) + metadata = gimp_metadata_new (); + + return_values = load_proc->priv->run_func2 (procedure, + run_mode, + file, + metadata, &flags, + config, + load_proc->priv->run_data); + + if (return_values != NULL && + gimp_value_array_length (return_values) > 0 && + G_VALUE_HOLDS_ENUM (gimp_value_array_index (return_values, 0))) + status = GIMP_VALUES_GET_ENUM (return_values, 0); + + gimp_procedure_config_end_run (config, status); + + if (status == GIMP_PDB_SUCCESS) + { + if (gimp_value_array_length (return_values) < 2 || + ! GIMP_VALUE_HOLDS_IMAGE (gimp_value_array_index (return_values, 1))) + { + GError *error = NULL; + + status = GIMP_PDB_EXECUTION_ERROR; + g_set_error (&error, GIMP_PLUG_IN_ERROR, 0, + _("This file loading plug-in returned SUCCESS as a status without an image. " + "This is a bug in the plug-in code. Contact the plug-in developer.")); + gimp_value_array_unref (return_values); + return_values = gimp_procedure_new_return_values (procedure, status, error); + } + else + { + image = GIMP_VALUES_GET_IMAGE (return_values, 1); + } + } + + if (image != NULL && metadata != NULL && flags != GIMP_METADATA_LOAD_NONE) + gimp_image_metadata_load_finish (image, NULL, metadata, flags); + + /* This is debug printing to help plug-in developers figure out best + * practices. + */ + if (G_OBJECT (config)->ref_count > 1) + g_printerr ("%s: ERROR: the GimpSaveProcedureConfig object was refed " + "by plug-in, it MUST NOT do that!\n", G_STRFUNC); + + g_object_unref (config); + } + else + { + return_values = load_proc->priv->run_func (procedure, + run_mode, + file, + remaining, + load_proc->priv->run_data); + } gimp_value_array_unref (remaining); @@ -275,6 +369,53 @@ gimp_load_procedure_new (GimpPlugIn *plug_in, return GIMP_PROCEDURE (procedure); } +/** + * gimp_load_procedure_new2: + * @plug_in: a #GimpPlugIn. + * @name: the new procedure's name. + * @proc_type: the new procedure's #GimpPDBProcType. + * @run_func: the run function for the new procedure. + * @run_data: user data passed to @run_func. + * @run_data_destroy: (nullable): free function for @run_data, or %NULL. + * + * Creates a new load procedure named @name which will call @run_func + * when invoked. + * + * See gimp_procedure_new() for information about @proc_type. + * + * Returns: (transfer full): a new #GimpProcedure. + * + * Since: 3.0 + **/ +GimpProcedure * +gimp_load_procedure_new2 (GimpPlugIn *plug_in, + const gchar *name, + GimpPDBProcType proc_type, + GimpRunLoadFunc2 run_func, + gpointer run_data, + GDestroyNotify run_data_destroy) +{ + GimpLoadProcedure *procedure; + + g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), NULL); + g_return_val_if_fail (gimp_is_canonical_identifier (name), NULL); + g_return_val_if_fail (proc_type != GIMP_PDB_PROC_TYPE_INTERNAL, NULL); + g_return_val_if_fail (proc_type != GIMP_PDB_PROC_TYPE_EXTENSION, NULL); + g_return_val_if_fail (run_func != NULL, NULL); + + procedure = g_object_new (GIMP_TYPE_LOAD_PROCEDURE, + "plug-in", plug_in, + "name", name, + "procedure-type", proc_type, + NULL); + + procedure->priv->run_func2 = run_func; + procedure->priv->run_data = run_data; + procedure->priv->run_data_destroy = run_data_destroy; + + return GIMP_PROCEDURE (procedure); +} + /** * gimp_load_procedure_set_handles_raw: * @procedure: A load procedure object. diff --git a/libgimp/gimploadprocedure.h b/libgimp/gimploadprocedure.h index 51d8e77968..d3e70d75e3 100644 --- a/libgimp/gimploadprocedure.h +++ b/libgimp/gimploadprocedure.h @@ -50,6 +50,29 @@ typedef GimpValueArray * (* GimpRunLoadFunc) (GimpProcedure *procedure, const GimpValueArray *args, gpointer run_data); +/** + * GimpRunLoadFunc2: + * @procedure: the #GimpProcedure that runs. + * @run_mode: the #GimpRunMode. + * @file: the #GFile to load from. + * @config: the @procedure's remaining arguments. + * @run_data: (closure): the run_data given in gimp_load_procedure_new(). + * + * The load function is run during the lifetime of the GIMP session, + * each time a plug-in load procedure is called. + * + * Returns: (transfer full): the @procedure's return values. + * + * Since: 3.0 + **/ +typedef GimpValueArray * (* GimpRunLoadFunc2) (GimpProcedure *procedure, + GimpRunMode run_mode, + GFile *file, + GimpMetadata *metadata, + GimpMetadataLoadFlags *flags, + GimpProcedureConfig *config, + gpointer run_data); + #define GIMP_TYPE_LOAD_PROCEDURE (gimp_load_procedure_get_type ()) #define GIMP_LOAD_PROCEDURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_LOAD_PROCEDURE, GimpLoadProcedure)) @@ -84,6 +107,12 @@ GimpProcedure * gimp_load_procedure_new (GimpPlugIn *plu GimpRunLoadFunc run_func, gpointer run_data, GDestroyNotify run_data_destroy); +GimpProcedure * gimp_load_procedure_new2 (GimpPlugIn *plug_in, + const gchar *name, + GimpPDBProcType proc_type, + GimpRunLoadFunc2 run_func, + gpointer run_data, + GDestroyNotify run_data_destroy); void gimp_load_procedure_set_handles_raw (GimpLoadProcedure *procedure, gboolean handles_raw); diff --git a/libgimpbase/gimpmetadata.h b/libgimpbase/gimpmetadata.h index 7038af3906..bb69480646 100644 --- a/libgimpbase/gimpmetadata.h +++ b/libgimpbase/gimpmetadata.h @@ -34,6 +34,7 @@ G_BEGIN_DECLS /** * GimpMetadataLoadFlags: + * @GIMP_METADATA_LOAD_NONE: Do not load the metadata * @GIMP_METADATA_LOAD_COMMENT: Load the comment * @GIMP_METADATA_LOAD_RESOLUTION: Load the resolution * @GIMP_METADATA_LOAD_ORIENTATION: Load the orientation (rotation) @@ -44,6 +45,7 @@ G_BEGIN_DECLS **/ typedef enum { + GIMP_METADATA_LOAD_NONE = 0, GIMP_METADATA_LOAD_COMMENT = 1 << 0, GIMP_METADATA_LOAD_RESOLUTION = 1 << 1, GIMP_METADATA_LOAD_ORIENTATION = 1 << 2, diff --git a/po-libgimp/POTFILES.in b/po-libgimp/POTFILES.in index 454a69f693..59c1001d99 100644 --- a/po-libgimp/POTFILES.in +++ b/po-libgimp/POTFILES.in @@ -6,6 +6,7 @@ libgimp/gimpbrushselectbutton.c libgimp/gimpexport.c libgimp/gimpimagemetadata.c libgimp/gimpimagemetadata-save.c +libgimp/gimploadprocedure.c libgimp/gimpparamspecs-desc.c libgimp/gimppatternselectbutton.c libgimp/gimppdb.c