1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
/* GIMP - The GNU Image Manipulation Program
* 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 <glib.h>
#include <libgimp/gimp.h>
#include "tinyscheme/scheme-private.h"
#include "script-fu-types.h"
#include "script-fu-scripts.h"
#include "script-fu-script.h"
#include "script-fu-proc-factory.h"
/* Local functions */
static void script_fu_add_menu_to_procedure (GimpProcedure *procedure,
SFScript *script);
/* Methods to register PDB procs. A factory makes objects, here PDB procedures.
*
* Used by the outer script-fu-interpreter
*
* This is in libscriptfu to hide the SFScript type from outer plugins.
* These methods use instances of type SFScript as specs for procedures.
*
* FUTURE: migrate code.
* There are two flavors of factory-like code: for PDBProcType TEMPORARY and PLUGIN.
* extension-script-fu outer plugin only makes TEMPORARY
* script-fu-interpreter outer plugin only makes PLUGIN type
* This source file supports only script-fu-interpreter.
* script_fu_find_scripts() in script-fu-scripts.c is also a factory-like method,
* and could be extracted to a separate source file.
* Maybe more code sharing between the two flavors.
*/
/* Create and return a single PDB procedure of type PLUGIN,
* for the given proc name, from script_tree already loaded.
* Also add a menu for the procedure.
*
* PDB proc of type PLUGIN has permanent lifetime, unlike type TEMPORARY.
*
* Loaded .scm file(s) may have defined many procedures.
* Create a PDB procedure only for the one passed name.
*/
GimpProcedure *
script_fu_proc_factory_make_PLUGIN (GimpPlugIn *plug_in,
const gchar *proc_name)
{
SFScript * script = NULL;
GimpProcedure * procedure = NULL;
/* Require SFScripts already defined, one or more. */
/* Get the pertinent script from the tree. */
script = script_fu_find_script (proc_name);
if (script)
{
procedure = script_fu_script_create_PDB_procedure (
plug_in,
script,
GIMP_PDB_PROC_TYPE_PLUGIN);
script_fu_add_menu_to_procedure (procedure, script);
}
else
{
g_warning ("Failed to find script: %s.", proc_name);
}
return procedure;
}
/* Traverse the list of scripts, for each defined name of a PDB proc,
* add it list whose handle is given.
*
* Order is not important. Could just as well prepend.
*
* This is a GTraverseFunction
*/
static gboolean
script_fu_append_script_names (gpointer *foo G_GNUC_UNUSED,
GList *scripts,
GList **name_list)
{
for (GList * list = scripts; list; list = g_list_next (list))
{
SFScript *script = list->data;
if ( !script_fu_is_defined (script->name))
{
g_warning ("Run function not defined, or does not match PDB procedure name: %s",
script->name);
continue;
}
/* Must assign result from g_list_append back to name_list */
*name_list = g_list_append ( (GList *) *name_list, g_strdup (script->name));
}
return FALSE; /* We traversed all. */
}
/* Load script texts (.scm files) in the given paths.
* Iterate over all loaded scripts to get the PDB proc names they define.
* Return a list of the names.
*/
GList *
script_fu_proc_factory_list_names (GimpPlugIn *plug_in,
GList *paths)
{
GList * result_list = NULL;
GTree * script_tree = NULL;
/* Load (eval) all .scm files in all dirs in paths. */
script_tree = script_fu_scripts_load_into_tree (plug_in, paths);
/* Iterate over the tree, adding each script name to result list */
g_tree_foreach (script_tree,
(GTraverseFunc) script_fu_append_script_names,
&result_list);
return result_list;
}
/* From scriptfu's internal data, add any menu to given procedure in the PDB.
* Requires that a script was just eval'ed so that scriptfu's list of menus
* declared in a script is valid.
* Requires the proc exists in PDB.
*
* Not ensure the PDB proc has a menu, when no menu was defined in the script.
*
* Derived from script_fu_install_menu, but that is specific to TEMPORARY procs.
* Also, unlike script_fu_install_menu, we don't nuke the menu list as we proceed.
*
* For each "create" of a procedure, the gimp-script-fu-interpreter is started anew,
* and a new script_menu_list is derived from the .scm file.
* We don't traverse the menu list more than once per session, which soon exits.
*/
static void
script_fu_add_menu_to_procedure (GimpProcedure *procedure,
SFScript *script)
{
GList *menu_list;
gboolean did_add_menu = FALSE;
menu_list = script_fu_get_menu_list ();
/* menu_list might be NULL: for loop will have no iterations. */
/* Each .scm file can declare many menu paths.
* Traverse the list to find the menu path defined for the procedure.
* Each SFMenu points to the procedure (SFScript) it belongs to.
*/
for (GList * traverser = menu_list; traverser; traverser = g_list_next (traverser))
{
SFMenu *menu = traverser->data;
if (menu->script == script)
{
g_debug ("Add menu: %s", menu->menu_path);
gimp_procedure_add_menu_path (procedure, menu->menu_path);
did_add_menu = TRUE;
break;
}
}
/* Some procedures don't have menu path.
* It is normal, but not common, to define procs of type PLUGIN that don't appear in the menus.
* No part of GIMP defaults a menu path for procedures.
* A menu label without a menu path is probably a mistake by the script author.
*/
if ( ! did_add_menu )
{
/* Unusual for a .scm file to have no menu paths, but not an error. */
g_debug ("No menu paths! Does the procedure name in script-fu-menu-register match?");
/* FUTURE if the script defines a menu *label*, declare an error. */
}
/* script_menu_list is a reference we do not need to free. */
}
|