234 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* 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 <https://www.gnu.org/licenses/>.
 | |
|  */
 | |
| 
 | |
| #include "config.h"
 | |
| 
 | |
| #include <string.h>
 | |
| #include <glib.h>
 | |
| 
 | |
| #include <libpika/pika.h>
 | |
| 
 | |
| #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);
 | |
| }
 |