/* PIKA - Photo and Image Kooker Application * a rebranding of The GNU Image Manipulation Program (created with heckimp) * A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio * * Original copyright, applying to most contents (license remains unchanged): * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "config.h" #include #include #include #include "scheme-wrapper.h" /* type "pointer" */ #include "script-fu-types.h" #include "script-fu-interface.h" /* ScriptFu's GUI implementation. */ #include "script-fu-dialog.h" /* Pika's GUI implementation. */ #include "script-fu-script.h" #include "script-fu-scripts.h" /* script_fu_find_script */ #include "script-fu-command.h" #include "script-fu-run-func.h" /* Outer run_funcs * One each for PikaProcedure and PikaImageProcedure. * These are called from Gimp, with two different signatures. * These form and interpret "commands" which are calls to inner run_funcs * defined in Scheme by a script. * These return the result of interpretation, * in a PikaValueArray whose only element is a status. * !!! ScriptFu does not let authors define procedures that return values. */ /* run_func for a PikaImageProcedure * * Type is PikaRunImageFunc. * * Uses Pika's config and gui. * * Since 3.0 */ PikaValueArray * script_fu_run_image_procedure (PikaProcedure *procedure, /* PikaImageProcedure */ PikaRunMode run_mode, PikaImage *image, guint n_drawables, PikaDrawable **drawables, PikaProcedureConfig *config, gpointer data) { PikaValueArray *result = NULL; SFScript *script; g_debug ("script_fu_run_image_procedure"); script = script_fu_find_script (pika_procedure_get_name (procedure)); if (! script) return pika_procedure_new_return_values (procedure, PIKA_PDB_CALLING_ERROR, NULL); ts_set_run_mode (run_mode); switch (run_mode) { case PIKA_RUN_INTERACTIVE: { guint n_specs; g_free (g_object_class_list_properties (G_OBJECT_GET_CLASS (config), &n_specs)); if (n_specs > 1) { /* Let user choose "other" args in a dialog, then interpret. Maintain a config. */ result = script_fu_dialog_run (procedure, script, image, n_drawables, drawables, config); } else { /* No "other" args for user to choose. No config to maintain. */ result = script_fu_interpret_image_proc (procedure, script, image, n_drawables, drawables, config); } break; } case PIKA_RUN_NONINTERACTIVE: { /* A call from another PDB procedure. * Use the given config, without interacting with user. * Since no user interaction, no config to maintain. */ result = script_fu_interpret_image_proc (procedure, script, image, n_drawables, drawables, config); break; } case PIKA_RUN_WITH_LAST_VALS: { /* User invoked from a menu "Filter>Run with last values". * Do not show dialog. config are already last values. */ result = script_fu_interpret_image_proc (procedure, script, image, n_drawables, drawables, config); break; } default: { result = pika_procedure_new_return_values (procedure, PIKA_PDB_CALLING_ERROR, NULL); } } return result; } /* run_func for a PikaProcedure. * * Type is PikaRunFunc * * Uses ScriptFu's own GUI implementation, and retains settings locally. * * Since prior to 3.0 but formerly named script_fu_script_proc */ PikaValueArray * script_fu_run_procedure (PikaProcedure *procedure, PikaProcedureConfig *config, gpointer data) { PikaPDBStatusType status = PIKA_PDB_SUCCESS; SFScript *script; GParamSpec **pspecs; guint n_pspecs; gint n_aux_args; PikaRunMode run_mode; GError *error = NULL; script = script_fu_find_script (pika_procedure_get_name (procedure)); if (! script) return pika_procedure_new_return_values (procedure, PIKA_PDB_CALLING_ERROR, NULL); pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (config), &n_pspecs); pika_procedure_get_aux_arguments (procedure, &n_aux_args); g_object_get (config, "run-mode", &run_mode, NULL); ts_set_run_mode (run_mode); switch (run_mode) { case PIKA_RUN_INTERACTIVE: { gint min_args = 0; /* First, try to collect the standard script arguments... */ min_args = script_fu_script_collect_standard_args (script, pspecs, n_pspecs, config); /* ...then acquire the rest of arguments (if any) with a dialog */ if (script->n_args > min_args) { status = script_fu_interface (script, min_args); break; } /* otherwise (if the script takes no more arguments), skip * this part and run the script directly (fallthrough) */ } case PIKA_RUN_NONINTERACTIVE: /* Verify actual args count equals declared arg count. * Scripts declare args except run_mode (SF hides it.) * pspecs have run_mode and one extra internal pspec, thus +2. */ if (n_pspecs != script->n_args + n_aux_args + 2) status = PIKA_PDB_CALLING_ERROR; if (status == PIKA_PDB_SUCCESS) { gchar *command; command = script_fu_script_get_command_from_params (script, pspecs, n_pspecs, config); /* run the command through the interpreter */ if (! script_fu_run_command (command, &error)) { return pika_procedure_new_return_values (procedure, PIKA_PDB_EXECUTION_ERROR, error); } g_free (command); } break; case PIKA_RUN_WITH_LAST_VALS: { gchar *command; /* First, try to collect the standard script arguments */ script_fu_script_collect_standard_args (script, pspecs, n_pspecs, config); command = script_fu_script_get_command (script); /* run the command through the interpreter */ if (! script_fu_run_command (command, &error)) { return pika_procedure_new_return_values (procedure, PIKA_PDB_EXECUTION_ERROR, error); } g_free (command); } break; default: break; } return pika_procedure_new_return_values (procedure, status, NULL); }