diff --git a/app/core/gimp-batch.c b/app/core/gimp-batch.c index 059be443e8..bc20768259 100644 --- a/app/core/gimp-batch.c +++ b/app/core/gimp-batch.c @@ -34,12 +34,12 @@ #include "pdb/gimppdb.h" #include "pdb/gimpprocedure.h" +#include "plug-in/gimppluginmanager.h" +#include "plug-in/gimppluginprocedure.h" + #include "gimp-intl.h" -#define BATCH_DEFAULT_EVAL_PROC "plug-in-script-fu-eval" - - static void gimp_batch_exit_after_callback (Gimp *gimp) G_GNUC_NORETURN; static gint gimp_batch_run_cmd (Gimp *gimp, @@ -54,15 +54,22 @@ gimp_batch_run (Gimp *gimp, const gchar *batch_interpreter, const gchar **batch_commands) { + GSList *batch_procedures; + GSList *iter; gulong exit_id; gint retval = EXIT_SUCCESS; if (! batch_commands || ! batch_commands[0]) return retval; - exit_id = g_signal_connect_after (gimp, "exit", - G_CALLBACK (gimp_batch_exit_after_callback), - NULL); + batch_procedures = gimp_plug_in_manager_get_batch_procedures (gimp->plug_in_manager); + if (g_slist_length (batch_procedures) == 0) + { + g_message (_("No batch interpreters are available. " + "Batch mode disabled.")); + retval = 69; /* EX_UNAVAILABLE - service unavailable (sysexits.h) */ + return retval; + } if (! batch_interpreter) { @@ -70,13 +77,76 @@ gimp_batch_run (Gimp *gimp, if (! batch_interpreter) { - batch_interpreter = BATCH_DEFAULT_EVAL_PROC; + if (g_slist_length (batch_procedures) == 1) + { + batch_interpreter = gimp_object_get_name (batch_procedures->data);; - if (gimp->be_verbose) - g_printerr (_("No batch interpreter specified, using the default " - "'%s'.\n"), batch_interpreter); + if (gimp->be_verbose) + g_printerr (_("No batch interpreter specified, using " + "'%s'.\n"), batch_interpreter); + } + else + { + retval = 64; /* EX_USAGE - command line usage error */ + g_print ("%s\n%s\n", + _("No batch interpreter specified."), + _("Available interpreters are:")); + + for (iter = batch_procedures; iter; iter = iter->next) + { + GimpPlugInProcedure *proc = iter->data; + gchar *locale_name; + + locale_name = g_locale_from_utf8 (proc->batch_interpreter_name, + -1, NULL, NULL, NULL); + + g_print ("- %s (%s)\n", + gimp_object_get_name (iter->data), + locale_name ? locale_name : proc->batch_interpreter_name); + + g_free (locale_name); + } + + return retval; + } } } + for (iter = batch_procedures; iter; iter = iter->next) + { + if (g_strcmp0 (gimp_object_get_name (iter->data), + batch_interpreter) == 0) + break; + } + + if (iter == NULL) + { + retval = 69; /* EX_UNAVAILABLE - service unavailable (sysexits.h) */ + g_print (_("The procedure '%s' is not a valid batch interpreter."), + batch_interpreter); + g_print ("\n%s\n%s\n", + _("Batch mode disabled."), + _("Available interpreters are:")); + + for (iter = batch_procedures; iter; iter = iter->next) + { + GimpPlugInProcedure *proc = iter->data; + gchar *locale_name; + + locale_name = g_locale_from_utf8 (proc->batch_interpreter_name, + -1, NULL, NULL, NULL); + + g_print ("- %s (%s)\n", + gimp_object_get_name (iter->data), + locale_name ? locale_name : proc->batch_interpreter_name); + + g_free (locale_name); + } + return retval; + } + + exit_id = g_signal_connect_after (gimp, "exit", + G_CALLBACK (gimp_batch_exit_after_callback), + NULL); /* script-fu text console, hardcoded for backward compatibility */ diff --git a/app/pdb/pdb-cmds.c b/app/pdb/pdb-cmds.c index e94579a95c..f7cd0fa9d9 100644 --- a/app/pdb/pdb-cmds.c +++ b/app/pdb/pdb-cmds.c @@ -1091,8 +1091,10 @@ pdb_set_batch_interpreter_invoker (GimpProcedure *procedure, { gboolean success = TRUE; const gchar *procedure_name; + const gchar *interpreter_name; procedure_name = g_value_get_string (gimp_value_array_index (args, 0)); + interpreter_name = g_value_get_string (gimp_value_array_index (args, 1)); if (success) { @@ -1102,8 +1104,9 @@ pdb_set_batch_interpreter_invoker (GimpProcedure *procedure, gimp_pdb_is_canonical_procedure (procedure_name, error)) { success = gimp_plug_in_set_batch_interpreter (plug_in, - procedure_name, - error); + procedure_name, + interpreter_name, + error); } else success = FALSE; @@ -2192,6 +2195,13 @@ register_pdb_procs (GimpPDB *pdb) FALSE, FALSE, TRUE, NULL, GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_string ("interpreter-name", + "interpreter name", + "A public-facing name for the interpreter, such as \"Python 3\".", + FALSE, FALSE, FALSE, + NULL, + GIMP_PARAM_READWRITE)); gimp_pdb_register_procedure (pdb, procedure); g_object_unref (procedure); diff --git a/app/plug-in/gimpplugin-proc.c b/app/plug-in/gimpplugin-proc.c index 145b8154f7..0d7edf6398 100644 --- a/app/plug-in/gimpplugin-proc.c +++ b/app/plug-in/gimpplugin-proc.c @@ -601,9 +601,11 @@ gimp_plug_in_set_file_proc_thumb_loader (GimpPlugIn *plug_in, gboolean gimp_plug_in_set_batch_interpreter (GimpPlugIn *plug_in, const gchar *proc_name, + const gchar *interpreter_name, GError **error) { GimpPlugInProcedure *proc; + GimpProcedure *procedure; g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE); g_return_val_if_fail (proc_name != NULL, FALSE); @@ -625,7 +627,27 @@ gimp_plug_in_set_batch_interpreter (GimpPlugIn *plug_in, return FALSE; } - gimp_plug_in_procedure_set_batch_interpreter (proc); + procedure = GIMP_PROCEDURE (proc); + + if (procedure->num_args < 2 || + ! GIMP_IS_PARAM_SPEC_RUN_MODE (procedure->args[0]) || + ! G_IS_PARAM_SPEC_STRING (procedure->args[1])) + { + g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_FAILED, + "Plug-in \"%s\"\n(%s)\n" + "attempted to register procedure \"%s\" " + "as a batch interpreter which does not take the standard " + "batch interpreter procedure arguments: " + "(GimpRunMode, gchar *) -> ()", + gimp_object_get_name (plug_in), + gimp_file_get_utf8_name (plug_in->file), + proc_name); + + return FALSE; + } + + gimp_plug_in_procedure_set_batch_interpreter (proc, interpreter_name); + gimp_plug_in_manager_add_batch_procedure (plug_in->manager, proc); return TRUE; } diff --git a/app/plug-in/gimpplugin-proc.h b/app/plug-in/gimpplugin-proc.h index dd53a9d340..9c12b82706 100644 --- a/app/plug-in/gimpplugin-proc.h +++ b/app/plug-in/gimpplugin-proc.h @@ -87,6 +87,7 @@ gboolean gimp_plug_in_set_file_proc_thumb_loader (GimpPlugIn *plug_in, GError **error); gboolean gimp_plug_in_set_batch_interpreter (GimpPlugIn *plug_in, const gchar *proc_name, + const gchar *interpreter_name, GError **error); diff --git a/app/plug-in/gimppluginmanager-restore.c b/app/plug-in/gimppluginmanager-restore.c index e2102d1873..32f12f68d5 100644 --- a/app/plug-in/gimppluginmanager-restore.c +++ b/app/plug-in/gimppluginmanager-restore.c @@ -854,6 +854,10 @@ gimp_plug_in_manager_add_to_db (GimpPlugInManager *manager, gimp_plug_in_manager_add_load_procedure (manager, proc); } } + else if (proc->batch_interpreter) + { + gimp_plug_in_manager_add_batch_procedure (manager, proc); + } } static void diff --git a/app/plug-in/gimppluginmanager.c b/app/plug-in/gimppluginmanager.c index 83b73354c8..31b86e1cde 100644 --- a/app/plug-in/gimppluginmanager.c +++ b/app/plug-in/gimppluginmanager.c @@ -134,6 +134,7 @@ gimp_plug_in_manager_finalize (GObject *object) g_clear_pointer (&manager->save_procs, g_slist_free); g_clear_pointer (&manager->export_procs, g_slist_free); g_clear_pointer (&manager->raw_load_procs, g_slist_free); + g_clear_pointer (&manager->batch_procs, g_slist_free); g_clear_pointer (&manager->display_load_procs, g_slist_free); g_clear_pointer (&manager->display_save_procs, g_slist_free); @@ -184,6 +185,7 @@ gimp_plug_in_manager_get_memsize (GimpObject *object, memsize += gimp_g_slist_get_memsize (manager->save_procs, 0); memsize += gimp_g_slist_get_memsize (manager->export_procs, 0); memsize += gimp_g_slist_get_memsize (manager->raw_load_procs, 0); + memsize += gimp_g_slist_get_memsize (manager->batch_procs, 0); memsize += gimp_g_slist_get_memsize (manager->display_load_procs, 0); memsize += gimp_g_slist_get_memsize (manager->display_save_procs, 0); memsize += gimp_g_slist_get_memsize (manager->display_export_procs, 0); @@ -316,6 +318,7 @@ gimp_plug_in_manager_add_procedure (GimpPlugInManager *manager, manager->save_procs = g_slist_remove (manager->save_procs, tmp_proc); manager->export_procs = g_slist_remove (manager->export_procs, tmp_proc); manager->raw_load_procs = g_slist_remove (manager->raw_load_procs, tmp_proc); + manager->batch_procs = g_slist_remove (manager->batch_procs, tmp_proc); manager->display_load_procs = g_slist_remove (manager->display_load_procs, tmp_proc); manager->display_save_procs = g_slist_remove (manager->display_save_procs, tmp_proc); manager->display_export_procs = g_slist_remove (manager->display_export_procs, tmp_proc); @@ -334,6 +337,25 @@ gimp_plug_in_manager_add_procedure (GimpPlugInManager *manager, g_object_ref (procedure)); } +void +gimp_plug_in_manager_add_batch_procedure (GimpPlugInManager *manager, + GimpPlugInProcedure *proc) +{ + g_return_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager)); + g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc)); + + if (! g_slist_find (manager->batch_procs, proc)) + manager->batch_procs = g_slist_prepend (manager->batch_procs, proc); +} + +GSList * +gimp_plug_in_manager_get_batch_procedures (GimpPlugInManager *manager) +{ + g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), NULL); + + return manager->batch_procs; +} + void gimp_plug_in_manager_add_temp_proc (GimpPlugInManager *manager, GimpTemporaryProcedure *procedure) diff --git a/app/plug-in/gimppluginmanager.h b/app/plug-in/gimppluginmanager.h index 11f80b120f..18328e3750 100644 --- a/app/plug-in/gimppluginmanager.h +++ b/app/plug-in/gimppluginmanager.h @@ -48,6 +48,7 @@ struct _GimpPlugInManager GSList *save_procs; GSList *export_procs; GSList *raw_load_procs; + GSList *batch_procs; GSList *display_load_procs; GSList *display_save_procs; @@ -100,6 +101,10 @@ void gimp_plug_in_manager_exit (GimpPlugInManager *manager) void gimp_plug_in_manager_add_procedure (GimpPlugInManager *manager, GimpPlugInProcedure *procedure); +void gimp_plug_in_manager_add_batch_procedure (GimpPlugInManager *manager, + GimpPlugInProcedure *proc); +GSList * gimp_plug_in_manager_get_batch_procedures (GimpPlugInManager *manager); + void gimp_plug_in_manager_add_temp_proc (GimpPlugInManager *manager, GimpTemporaryProcedure *procedure); void gimp_plug_in_manager_remove_temp_proc (GimpPlugInManager *manager, diff --git a/app/plug-in/gimppluginprocedure.c b/app/plug-in/gimppluginprocedure.c index 9ba1469ab4..cb2594595c 100644 --- a/app/plug-in/gimppluginprocedure.c +++ b/app/plug-in/gimppluginprocedure.c @@ -171,6 +171,7 @@ gimp_plug_in_procedure_finalize (GObject *object) g_slist_free_full (proc->mime_types_list, (GDestroyNotify) g_free); g_free (proc->thumb_loader); + g_free (proc->batch_interpreter_name); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -207,6 +208,7 @@ gimp_plug_in_procedure_get_memsize (GimpObject *object, memsize += gimp_string_get_memsize (proc->magics); memsize += gimp_string_get_memsize (proc->mime_types); memsize += gimp_string_get_memsize (proc->thumb_loader); + memsize += gimp_string_get_memsize (proc->batch_interpreter_name); for (slist = proc->extensions_list; slist; slist = g_slist_next (slist)) memsize += sizeof (GSList) + gimp_string_get_memsize (slist->data); @@ -1275,11 +1277,17 @@ gimp_plug_in_procedure_set_thumb_loader (GimpPlugInProcedure *proc, } void -gimp_plug_in_procedure_set_batch_interpreter (GimpPlugInProcedure *proc) +gimp_plug_in_procedure_set_batch_interpreter (GimpPlugInProcedure *proc, + const gchar *name) { g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc)); + g_return_if_fail (name != NULL); - proc->batch_interpreter = TRUE; + if (proc->batch_interpreter_name) + g_free (proc->batch_interpreter_name); + + proc->batch_interpreter = TRUE; + proc->batch_interpreter_name = g_strdup (name); } void diff --git a/app/plug-in/gimppluginprocedure.h b/app/plug-in/gimppluginprocedure.h index efa91b1eba..83500be4c0 100644 --- a/app/plug-in/gimppluginprocedure.h +++ b/app/plug-in/gimppluginprocedure.h @@ -66,6 +66,7 @@ struct _GimpPlugInProcedure gboolean handles_remote; gboolean handles_raw; gboolean batch_interpreter; + gchar *batch_interpreter_name; GSList *extensions_list; GSList *prefixes_list; GSList *magics_list; @@ -142,7 +143,8 @@ void gimp_plug_in_procedure_set_handles_remote(GimpPlugInProcedure *pro void gimp_plug_in_procedure_set_handles_raw (GimpPlugInProcedure *proc); void gimp_plug_in_procedure_set_thumb_loader (GimpPlugInProcedure *proc, const gchar *thumbnailer); -void gimp_plug_in_procedure_set_batch_interpreter (GimpPlugInProcedure *proc); +void gimp_plug_in_procedure_set_batch_interpreter (GimpPlugInProcedure *proc, + const gchar *name); void gimp_plug_in_procedure_handle_return_values (GimpPlugInProcedure *proc, Gimp *gimp, diff --git a/app/plug-in/plug-in-rc.c b/app/plug-in/plug-in-rc.c index 1070fd10fc..500e6f1404 100644 --- a/app/plug-in/plug-in-rc.c +++ b/app/plug-in/plug-in-rc.c @@ -60,8 +60,8 @@ static GTokenType plug_in_menu_path_deserialize (GScanner *scanner, GimpPlugInProcedure *proc); static GTokenType plug_in_icon_deserialize (GScanner *scanner, GimpPlugInProcedure *proc); -static GTokenType plug_in_file_proc_deserialize (GScanner *scanner, - GimpPlugInProcedure *proc); +static GTokenType plug_in_file_or_batch_proc_deserialize (GScanner *scanner, + GimpPlugInProcedure *proc); static GTokenType plug_in_proc_arg_deserialize (GScanner *scanner, Gimp *gimp, GimpProcedure *procedure, @@ -95,7 +95,8 @@ enum MIME_TYPES, HANDLES_REMOTE, HANDLES_RAW, - THUMB_LOADER + THUMB_LOADER, + BATCH_INTERPRETER, }; @@ -149,6 +150,8 @@ plug_in_rc_parse (Gimp *gimp, "load-proc", GINT_TO_POINTER (LOAD_PROC)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "save-proc", GINT_TO_POINTER (SAVE_PROC)); + g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, + "batch-interpreter", GINT_TO_POINTER (BATCH_INTERPRETER)); g_scanner_scope_add_symbol (scanner, LOAD_PROC, "extensions", GINT_TO_POINTER (EXTENSIONS)); @@ -449,7 +452,7 @@ plug_in_procedure_deserialize (GScanner *scanner, if (token != G_TOKEN_LEFT_PAREN) return token; - token = plug_in_file_proc_deserialize (scanner, *proc); + token = plug_in_file_or_batch_proc_deserialize (scanner, *proc); if (token != G_TOKEN_LEFT_PAREN) return token; @@ -609,8 +612,8 @@ plug_in_icon_deserialize (GScanner *scanner, } static GTokenType -plug_in_file_proc_deserialize (GScanner *scanner, - GimpPlugInProcedure *proc) +plug_in_file_or_batch_proc_deserialize (GScanner *scanner, + GimpPlugInProcedure *proc) { GTokenType token; gint symbol; @@ -622,113 +625,126 @@ plug_in_file_proc_deserialize (GScanner *scanner, return G_TOKEN_SYMBOL; symbol = GPOINTER_TO_INT (scanner->value.v_symbol); - if (symbol != LOAD_PROC && symbol != SAVE_PROC) + if (symbol != LOAD_PROC && symbol != SAVE_PROC && symbol != BATCH_INTERPRETER) return G_TOKEN_SYMBOL; - proc->file_proc = TRUE; - - g_scanner_set_scope (scanner, symbol); - - while (g_scanner_peek_next_token (scanner) == G_TOKEN_LEFT_PAREN) + if (symbol == BATCH_INTERPRETER) { - token = g_scanner_get_next_token (scanner); + gchar *interpreter_name; - if (token != G_TOKEN_LEFT_PAREN) - return token; + if (! gimp_scanner_parse_string (scanner, &interpreter_name)) + return G_TOKEN_STRING; - if (! gimp_scanner_parse_token (scanner, G_TOKEN_SYMBOL)) - return G_TOKEN_SYMBOL; + gimp_plug_in_procedure_set_batch_interpreter (proc, interpreter_name); + g_free (interpreter_name); + } + else + { + proc->file_proc = TRUE; - symbol = GPOINTER_TO_INT (scanner->value.v_symbol); + g_scanner_set_scope (scanner, symbol); - switch (symbol) + while (g_scanner_peek_next_token (scanner) == G_TOKEN_LEFT_PAREN) { - case EXTENSIONS: - { - gchar *extensions; + token = g_scanner_get_next_token (scanner); - if (! gimp_scanner_parse_string (scanner, &extensions)) - return G_TOKEN_STRING; + if (token != G_TOKEN_LEFT_PAREN) + return token; - g_free (proc->extensions); - proc->extensions = extensions; - } - break; + if (! gimp_scanner_parse_token (scanner, G_TOKEN_SYMBOL)) + return G_TOKEN_SYMBOL; - case PREFIXES: - { - gchar *prefixes; + symbol = GPOINTER_TO_INT (scanner->value.v_symbol); - if (! gimp_scanner_parse_string (scanner, &prefixes)) - return G_TOKEN_STRING; + switch (symbol) + { + case EXTENSIONS: + { + gchar *extensions; - g_free (proc->prefixes); - proc->prefixes = prefixes; - } - break; + if (! gimp_scanner_parse_string (scanner, &extensions)) + return G_TOKEN_STRING; - case MAGICS: - { - gchar *magics; + g_free (proc->extensions); + proc->extensions = extensions; + } + break; - if (! gimp_scanner_parse_string_no_validate (scanner, &magics)) - return G_TOKEN_STRING; + case PREFIXES: + { + gchar *prefixes; - g_free (proc->magics); - proc->magics = magics; - } - break; + if (! gimp_scanner_parse_string (scanner, &prefixes)) + return G_TOKEN_STRING; - case PRIORITY: - { - gint priority; + g_free (proc->prefixes); + proc->prefixes = prefixes; + } + break; - if (! gimp_scanner_parse_int (scanner, &priority)) - return G_TOKEN_INT; + case MAGICS: + { + gchar *magics; - gimp_plug_in_procedure_set_priority (proc, priority); - } - break; + if (! gimp_scanner_parse_string_no_validate (scanner, &magics)) + return G_TOKEN_STRING; - case MIME_TYPES: - { - gchar *mime_types; + g_free (proc->magics); + proc->magics = magics; + } + break; - if (! gimp_scanner_parse_string (scanner, &mime_types)) - return G_TOKEN_STRING; + case PRIORITY: + { + gint priority; - gimp_plug_in_procedure_set_mime_types (proc, mime_types); + if (! gimp_scanner_parse_int (scanner, &priority)) + return G_TOKEN_INT; - g_free (mime_types); - } - break; + gimp_plug_in_procedure_set_priority (proc, priority); + } + break; - case HANDLES_REMOTE: - gimp_plug_in_procedure_set_handles_remote (proc); - break; + case MIME_TYPES: + { + gchar *mime_types; - case HANDLES_RAW: - gimp_plug_in_procedure_set_handles_raw (proc); - break; + if (! gimp_scanner_parse_string (scanner, &mime_types)) + return G_TOKEN_STRING; - case THUMB_LOADER: - { - gchar *thumb_loader; + gimp_plug_in_procedure_set_mime_types (proc, mime_types); - if (! gimp_scanner_parse_string (scanner, &thumb_loader)) - return G_TOKEN_STRING; + g_free (mime_types); + } + break; - gimp_plug_in_procedure_set_thumb_loader (proc, thumb_loader); + case HANDLES_REMOTE: + gimp_plug_in_procedure_set_handles_remote (proc); + break; - g_free (thumb_loader); - } - break; + case HANDLES_RAW: + gimp_plug_in_procedure_set_handles_raw (proc); + break; - default: - return G_TOKEN_SYMBOL; + case THUMB_LOADER: + { + gchar *thumb_loader; + + if (! gimp_scanner_parse_string (scanner, &thumb_loader)) + return G_TOKEN_STRING; + + gimp_plug_in_procedure_set_thumb_loader (proc, thumb_loader); + + g_free (thumb_loader); + } + break; + + default: + return G_TOKEN_SYMBOL; + } + if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN)) + return G_TOKEN_RIGHT_PAREN; } - if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN)) - return G_TOKEN_RIGHT_PAREN; } if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN)) @@ -1281,6 +1297,13 @@ plug_in_rc_write (GSList *plug_in_defs, gimp_config_writer_close (writer); } + else if (proc->batch_interpreter) + { + gimp_config_writer_open (writer, "batch-interpreter"); + gimp_config_writer_string (writer, proc->batch_interpreter_name); + gimp_config_writer_close (writer); + } + gimp_config_writer_linefeed (writer); diff --git a/libgimp/gimpbatchprocedure.c b/libgimp/gimpbatchprocedure.c index 73f21b3b96..c7f16487e5 100644 --- a/libgimp/gimpbatchprocedure.c +++ b/libgimp/gimpbatchprocedure.c @@ -108,9 +108,14 @@ gimp_batch_procedure_finalize (GObject *object) static void gimp_batch_procedure_install (GimpProcedure *procedure) { + GimpBatchProcedure *proc = GIMP_BATCH_PROCEDURE (procedure); + + g_return_if_fail (proc->priv->interpreter_name != NULL); + GIMP_PROCEDURE_CLASS (parent_class)->install (procedure); - _gimp_pdb_set_batch_interpreter (gimp_procedure_get_name (procedure)); + _gimp_pdb_set_batch_interpreter (gimp_procedure_get_name (procedure), + proc->priv->interpreter_name); } #define ARG_OFFSET 2 @@ -175,6 +180,7 @@ gimp_batch_procedure_create_config (GimpProcedure *procedure, * gimp_batch_procedure_new: * @plug_in: a #GimpPlugIn. * @name: the new procedure's name. + * @interpreter_name: the public-facing name, e.g. "Python 3". * @proc_type: the new procedure's #GimpPDBProcType. * @run_func: the run function for the new procedure. * @run_data: user data passed to @run_func. @@ -207,6 +213,7 @@ gimp_batch_procedure_create_config (GimpProcedure *procedure, GimpProcedure * gimp_batch_procedure_new (GimpPlugIn *plug_in, const gchar *name, + const gchar *interpreter_name, GimpPDBProcType proc_type, GimpBatchFunc run_func, gpointer run_data, @@ -216,6 +223,7 @@ gimp_batch_procedure_new (GimpPlugIn *plug_in, 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 (interpreter_name != NULL && g_utf8_validate (interpreter_name, -1, NULL), 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); @@ -230,6 +238,8 @@ gimp_batch_procedure_new (GimpPlugIn *plug_in, procedure->priv->run_data = run_data; procedure->priv->run_data_destroy = run_data_destroy; + gimp_batch_procedure_set_interpreter_name (procedure, interpreter_name); + return GIMP_PROCEDURE (procedure); } @@ -263,6 +273,7 @@ gimp_batch_procedure_set_interpreter_name (GimpBatchProcedure *procedure, const gchar *interpreter_name) { g_return_if_fail (GIMP_IS_BATCH_PROCEDURE (procedure)); + g_return_if_fail (interpreter_name != NULL && g_utf8_validate (interpreter_name, -1, NULL)); g_free (procedure->priv->interpreter_name); procedure->priv->interpreter_name = g_strdup (interpreter_name); diff --git a/libgimp/gimpbatchprocedure.h b/libgimp/gimpbatchprocedure.h index 080e3d9cb4..aab7c01a90 100644 --- a/libgimp/gimpbatchprocedure.h +++ b/libgimp/gimpbatchprocedure.h @@ -79,6 +79,7 @@ GType gimp_batch_procedure_get_type (void) G_GNUC_CONST; GimpProcedure * gimp_batch_procedure_new (GimpPlugIn *plug_in, const gchar *name, + const gchar *interpreter_name, GimpPDBProcType proc_type, GimpBatchFunc run_func, gpointer run_data, diff --git a/libgimp/gimppdb_pdb.c b/libgimp/gimppdb_pdb.c index 0278366741..fcff5f4ab1 100644 --- a/libgimp/gimppdb_pdb.c +++ b/libgimp/gimppdb_pdb.c @@ -1140,6 +1140,7 @@ _gimp_pdb_set_file_proc_thumbnail_loader (const gchar *load_proc, /** * _gimp_pdb_set_batch_interpreter: * @procedure_name: The name of the procedure to be used for running batch commands. + * @interpreter_name: A public-facing name for the interpreter, such as \"Python 3\". * * Registers a batch interpreter procedure. * @@ -1151,7 +1152,8 @@ _gimp_pdb_set_file_proc_thumbnail_loader (const gchar *load_proc, * Since: 3.0 **/ gboolean -_gimp_pdb_set_batch_interpreter (const gchar *procedure_name) +_gimp_pdb_set_batch_interpreter (const gchar *procedure_name, + const gchar *interpreter_name) { GimpValueArray *args; GimpValueArray *return_vals; @@ -1159,6 +1161,7 @@ _gimp_pdb_set_batch_interpreter (const gchar *procedure_name) args = gimp_value_array_new_from_types (NULL, G_TYPE_STRING, procedure_name, + G_TYPE_STRING, interpreter_name, G_TYPE_NONE); return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (), diff --git a/libgimp/gimppdb_pdb.h b/libgimp/gimppdb_pdb.h index f39465c0fb..3ffd4ae568 100644 --- a/libgimp/gimppdb_pdb.h +++ b/libgimp/gimppdb_pdb.h @@ -97,7 +97,8 @@ G_GNUC_INTERNAL gboolean _gimp_pdb_set_file_proc_handles_remote (const gcha G_GNUC_INTERNAL gboolean _gimp_pdb_set_file_proc_handles_raw (const gchar *procedure_name); G_GNUC_INTERNAL gboolean _gimp_pdb_set_file_proc_thumbnail_loader (const gchar *load_proc, const gchar *thumb_proc); -G_GNUC_INTERNAL gboolean _gimp_pdb_set_batch_interpreter (const gchar *procedure_name); +G_GNUC_INTERNAL gboolean _gimp_pdb_set_batch_interpreter (const gchar *procedure_name, + const gchar *interpreter_name); G_GNUC_INTERNAL gboolean _gimp_pdb_get_data (const gchar *identifier, gint *bytes, guint8 **data); diff --git a/pdb/groups/pdb.pdb b/pdb/groups/pdb.pdb index 5aafff8874..bcc0644dab 100644 --- a/pdb/groups/pdb.pdb +++ b/pdb/groups/pdb.pdb @@ -1171,6 +1171,8 @@ HELP @inargs = ( { name => 'procedure_name', type => 'string', non_empty => 1, desc => 'The name of the procedure to be used for running batch commands' }, + { name => 'interpreter_name', type => 'string', + desc => 'A public-facing name for the interpreter, such as "Python 3".' } ); %invoke = ( @@ -1182,8 +1184,9 @@ HELP gimp_pdb_is_canonical_procedure (procedure_name, error)) { success = gimp_plug_in_set_batch_interpreter (plug_in, - procedure_name, - error); + procedure_name, + interpreter_name, + error); } else success = FALSE; diff --git a/plug-ins/python/python-eval.py b/plug-ins/python/python-eval.py index c0b51a0338..f351de2a85 100644 --- a/plug-ins/python/python-eval.py +++ b/plug-ins/python/python-eval.py @@ -42,7 +42,7 @@ class PythonEval (Gimp.PlugIn): return ['python-fu-eval'] def do_create_procedure(self, name): - procedure = Gimp.BatchProcedure.new(self, name, + procedure = Gimp.BatchProcedure.new(self, name, "Python 3", Gimp.PDBProcType.PLUGIN, code_eval, None) procedure.set_documentation ("Evaluate Python code", diff --git a/plug-ins/script-fu/script-fu.c b/plug-ins/script-fu/script-fu.c index 5dd8e90aac..87b87b5fb7 100644 --- a/plug-ins/script-fu/script-fu.c +++ b/plug-ins/script-fu/script-fu.c @@ -243,7 +243,7 @@ script_fu_create_procedure (GimpPlugIn *plug_in, } else if (! strcmp (name, "plug-in-script-fu-eval")) { - procedure = gimp_batch_procedure_new (plug_in, name, + procedure = gimp_batch_procedure_new (plug_in, name, "Script-fu (scheme)", GIMP_PDB_PROC_TYPE_PLUGIN, script_fu_batch_run, NULL, NULL);