app, libgimp, pdb: new API to advertize when procedures are sensitive.

The new function gimp_procedure_set_sensitivity_mask() allows plug-ins
to tell when a procedure should be marked as sensitive or not.
gimp_procedure_get_sensitivity_mask() retrieves this information.

Currently plug-ins are automatically marked as sensitive when an image
is present and a single drawable is selected. Nowadays, we can have
multiple selected layers so we should allow plug-ins to tell us if they
support working on multiple drawables. Actually we could even imagine
new plug-ins which would be made to work only on multiple drawables.
Oppositely, there are a lot of plug-ins which don't care at all if any
drawable is selected at all (so we should allow no drawable selected).

Finally why not even imagine plug-ins which don't care if no image is
shown? E.g. plug-ins to create new images or whatnot. This new API
allows our core to know all this and show procedure sensitivity
accordingly. By default, when the function is not called, the 1 image
with 1 drawable selected case is the default, allowing existing plug-ins
easier update.

Note: this only handles the sensitivity part right now. A plug-in which
would advertize working on several layer would still not work, because
the core won't allow sending several layers. It's coming in further
commits.
This commit is contained in:
Jehan 2021-04-01 23:49:11 +02:00
parent b1fed22763
commit dc7853233b
15 changed files with 304 additions and 19 deletions

View file

@ -1033,7 +1033,7 @@ filters_actions_update (GimpActionGroup *group,
gint i; gint i;
if (proc && if (proc &&
gimp_procedure_get_sensitive (proc, GIMP_OBJECT (drawable), NULL)) gimp_procedure_get_sensitive (proc, GIMP_OBJECT (image), NULL))
{ {
gimp_action_group_set_action_sensitive (group, "filters-repeat", TRUE); gimp_action_group_set_action_sensitive (group, "filters-repeat", TRUE);
gimp_action_group_set_action_sensitive (group, "filters-reshow", TRUE); gimp_action_group_set_action_sensitive (group, "filters-reshow", TRUE);
@ -1051,7 +1051,7 @@ filters_actions_update (GimpActionGroup *group,
proc = gimp_filter_history_nth (group->gimp, i); proc = gimp_filter_history_nth (group->gimp, i);
sensitive = gimp_procedure_get_sensitive (proc, GIMP_OBJECT (drawable), sensitive = gimp_procedure_get_sensitive (proc, GIMP_OBJECT (image),
NULL); NULL);
gimp_action_group_set_action_sensitive (group, name, sensitive); gimp_action_group_set_action_sensitive (group, name, sensitive);

View file

@ -168,12 +168,17 @@ gimp_gegl_procedure_get_sensitive (GimpProcedure *procedure,
GimpObject *object, GimpObject *object,
const gchar **tooltip) const gchar **tooltip)
{ {
GimpDrawable *drawable = GIMP_DRAWABLE (object); GimpImage *image = GIMP_IMAGE (object);
gboolean sensitive = FALSE; GList *drawables = NULL;
gboolean sensitive = FALSE;
if (drawable) if (image)
drawables = gimp_image_get_selected_drawables (image);
if (g_list_length (drawables) == 1)
{ {
GimpItem *item; GimpDrawable *drawable = drawables->data;
GimpItem *item;
if (GIMP_IS_LAYER_MASK (drawable)) if (GIMP_IS_LAYER_MASK (drawable))
item = GIMP_ITEM (gimp_layer_mask_get_layer (GIMP_LAYER_MASK (drawable))); item = GIMP_ITEM (gimp_layer_mask_get_layer (GIMP_LAYER_MASK (drawable)));
@ -185,6 +190,7 @@ gimp_gegl_procedure_get_sensitive (GimpProcedure *procedure,
if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
sensitive = FALSE; sensitive = FALSE;
} }
g_list_free (drawables);
return sensitive; return sensitive;
} }

View file

@ -163,7 +163,7 @@ plug_in_actions_update (GimpActionGroup *group,
const gchar *tooltip; const gchar *tooltip;
sensitive = gimp_procedure_get_sensitive (procedure, sensitive = gimp_procedure_get_sensitive (procedure,
GIMP_OBJECT (drawable), GIMP_OBJECT (image),
&tooltip); &tooltip);
gimp_action_group_set_action_sensitive (group, gimp_action_group_set_action_sensitive (group,
@ -330,22 +330,18 @@ plug_in_actions_add_proc (GimpActionGroup *group,
{ {
GimpContext *context = gimp_get_user_context (group->gimp); GimpContext *context = gimp_get_user_context (group->gimp);
GimpImage *image = gimp_context_get_image (context); GimpImage *image = gimp_context_get_image (context);
GimpDrawable *drawable = NULL;
gboolean sensitive; gboolean sensitive;
const gchar *tooltip; const gchar *tooltip;
if (image)
drawable = gimp_image_get_active_drawable (image);
sensitive = gimp_procedure_get_sensitive (GIMP_PROCEDURE (proc), sensitive = gimp_procedure_get_sensitive (GIMP_PROCEDURE (proc),
GIMP_OBJECT (drawable), GIMP_OBJECT (image),
&tooltip); &tooltip);
gimp_action_group_set_action_sensitive (group, gimp_action_group_set_action_sensitive (group,
gimp_object_get_name (proc), gimp_object_get_name (proc),
sensitive); sensitive);
if (! sensitive && drawable && tooltip) if (! sensitive && tooltip)
gimp_action_group_set_action_tooltip (group, gimp_action_group_set_action_tooltip (group,
gimp_object_get_name (proc), gimp_object_get_name (proc),
tooltip); tooltip);

View file

@ -28,7 +28,7 @@
#include "internal-procs.h" #include "internal-procs.h"
/* 756 procedures registered total */ /* 757 procedures registered total */
void void
internal_procs_init (GimpPDB *pdb) internal_procs_init (GimpPDB *pdb)

View file

@ -425,6 +425,39 @@ pdb_get_proc_image_types_invoker (GimpProcedure *procedure,
return return_vals; return return_vals;
} }
static GimpValueArray *
pdb_set_proc_sensitivity_mask_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
gboolean success = TRUE;
const gchar *procedure_name;
gint mask;
procedure_name = g_value_get_string (gimp_value_array_index (args, 0));
mask = g_value_get_int (gimp_value_array_index (args, 1));
if (success)
{
GimpPlugIn *plug_in = gimp->plug_in_manager->current_plug_in;
if (plug_in &&
gimp_pdb_is_canonical_procedure (procedure_name, error))
{
success = gimp_plug_in_set_proc_sensitivity_mask (plug_in, procedure_name,
mask, error);
}
else
success = FALSE;
}
return gimp_procedure_get_return_values (procedure, success,
error ? *error : NULL);
}
static GimpValueArray * static GimpValueArray *
pdb_set_proc_menu_label_invoker (GimpProcedure *procedure, pdb_set_proc_menu_label_invoker (GimpProcedure *procedure,
Gimp *gimp, Gimp *gimp,
@ -1518,6 +1551,36 @@ register_pdb_procs (GimpPDB *pdb)
gimp_pdb_register_procedure (pdb, procedure); gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure); g_object_unref (procedure);
/*
* gimp-pdb-set-proc-sensitivity-mask
*/
procedure = gimp_procedure_new (pdb_set_proc_sensitivity_mask_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-pdb-set-proc-sensitivity-mask");
gimp_procedure_set_static_help (procedure,
"Set the sensitivity mask for a plug-in procedure.",
"This procedure sets the sensitivity mask for the given procedure.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Jehan",
"Jehan",
"2021");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("procedure-name",
"procedure name",
"The procedure",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_int ("mask",
"mask",
"The procedure's sensitivity mask",
G_MININT32, G_MAXINT32, 0,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/* /*
* gimp-pdb-set-proc-menu-label * gimp-pdb-set-proc-menu-label
*/ */

View file

@ -81,6 +81,39 @@ gimp_plug_in_set_proc_image_types (GimpPlugIn *plug_in,
return TRUE; return TRUE;
} }
gboolean
gimp_plug_in_set_proc_sensitivity_mask (GimpPlugIn *plug_in,
const gchar *proc_name,
gint sensitivity_mask,
GError **error)
{
GimpPlugInProcedure *proc;
g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
proc = gimp_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register the sensitivity mask \"%x\" "
"for procedure \"%s\".\n"
"It has however not installed that procedure. "
"This is not allowed.",
gimp_object_get_name (plug_in),
gimp_file_get_utf8_name (plug_in->file),
sensitivity_mask, proc_name);
return FALSE;
}
gimp_plug_in_procedure_set_sensitivity_mask (proc, sensitivity_mask);
return TRUE;
}
gboolean gboolean
gimp_plug_in_set_proc_menu_label (GimpPlugIn *plug_in, gimp_plug_in_set_proc_menu_label (GimpPlugIn *plug_in,
const gchar *proc_name, const gchar *proc_name,

View file

@ -25,6 +25,10 @@ gboolean gimp_plug_in_set_proc_image_types (GimpPlugIn *plug_in,
const gchar *proc_name, const gchar *proc_name,
const gchar *image_types, const gchar *image_types,
GError **error); GError **error);
gboolean gimp_plug_in_set_proc_sensitivity_mask (GimpPlugIn *plug_in,
const gchar *proc_name,
gint sensitivity_mask,
GError **error);
gboolean gimp_plug_in_set_proc_menu_label (GimpPlugIn *plug_in, gboolean gimp_plug_in_set_proc_menu_label (GimpPlugIn *plug_in,
const gchar *proc_name, const gchar *proc_name,
const gchar *menu_label, const gchar *menu_label,

View file

@ -33,6 +33,7 @@
#include "core/gimp.h" #include "core/gimp.h"
#include "core/gimp-memsize.h" #include "core/gimp-memsize.h"
#include "core/gimpdrawable.h" #include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimpmarshal.h" #include "core/gimpmarshal.h"
#include "core/gimpparamspecs.h" #include "core/gimpparamspecs.h"
@ -303,17 +304,20 @@ gimp_plug_in_procedure_get_sensitive (GimpProcedure *procedure,
const gchar **tooltip) const gchar **tooltip)
{ {
GimpPlugInProcedure *proc = GIMP_PLUG_IN_PROCEDURE (procedure); GimpPlugInProcedure *proc = GIMP_PLUG_IN_PROCEDURE (procedure);
GimpDrawable *drawable; GimpImage *image;
GList *drawables = NULL;
GimpImageType image_type = -1; GimpImageType image_type = -1;
gboolean sensitive = FALSE; gboolean sensitive = FALSE;
g_return_val_if_fail (object == NULL || GIMP_IS_DRAWABLE (object), FALSE); g_return_val_if_fail (object == NULL || GIMP_IS_IMAGE (object), FALSE);
drawable = GIMP_DRAWABLE (object); image = GIMP_IMAGE (object);
if (image)
drawables = gimp_image_get_selected_drawables (image);
if (drawable) if (drawables)
{ {
const Babl *format = gimp_drawable_get_format (drawable); const Babl *format = gimp_drawable_get_format (drawables->data);
image_type = gimp_babl_format_get_image_type (format); image_type = gimp_babl_format_get_image_type (format);
} }
@ -342,6 +346,21 @@ gimp_plug_in_procedure_get_sensitive (GimpProcedure *procedure,
break; break;
} }
if (! image &&
(proc->sensitivity_mask & GIMP_PROCEDURE_SENSITIVE_NO_IMAGE) != 0)
sensitive = TRUE;
else if (g_list_length (drawables) == 1 && proc->sensitivity_mask != 0 &&
(proc->sensitivity_mask & GIMP_PROCEDURE_SENSITIVE_DRAWABLE) == 0)
sensitive = FALSE;
else if (g_list_length (drawables) == 0 &&
(proc->sensitivity_mask & GIMP_PROCEDURE_SENSITIVE_NO_DRAWABLES) == 0)
sensitive = FALSE;
else if (g_list_length (drawables) > 1 &&
(proc->sensitivity_mask & GIMP_PROCEDURE_SENSITIVE_DRAWABLES) == 0)
sensitive = FALSE;
g_list_free (drawables);
if (! sensitive) if (! sensitive)
*tooltip = proc->image_types_tooltip; *tooltip = proc->image_types_tooltip;
@ -1086,6 +1105,15 @@ gimp_plug_in_procedure_set_image_types (GimpPlugInProcedure *proc,
} }
} }
void
gimp_plug_in_procedure_set_sensitivity_mask (GimpPlugInProcedure *proc,
gint sensitivity_mask)
{
g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
proc->sensitivity_mask = sensitivity_mask;
}
static GSList * static GSList *
extensions_parse (gchar *extensions) extensions_parse (gchar *extensions)
{ {

View file

@ -51,6 +51,7 @@ struct _GimpPlugInProcedure
gchar *image_types; gchar *image_types;
GimpPlugInImageType image_types_val; GimpPlugInImageType image_types_val;
gchar *image_types_tooltip; gchar *image_types_tooltip;
gint sensitivity_mask;
gint64 mtime; gint64 mtime;
gboolean installed_during_init; gboolean installed_during_init;
@ -123,6 +124,9 @@ gboolean gimp_plug_in_procedure_take_icon (GimpPlugInProcedure *pro
void gimp_plug_in_procedure_set_image_types (GimpPlugInProcedure *proc, void gimp_plug_in_procedure_set_image_types (GimpPlugInProcedure *proc,
const gchar *image_types); const gchar *image_types);
void gimp_plug_in_procedure_set_sensitivity_mask (GimpPlugInProcedure *proc,
gint sensitivity_mask);
void gimp_plug_in_procedure_set_file_proc (GimpPlugInProcedure *proc, void gimp_plug_in_procedure_set_file_proc (GimpPlugInProcedure *proc,
const gchar *extensions, const gchar *extensions,
const gchar *prefixes, const gchar *prefixes,

View file

@ -389,6 +389,7 @@ plug_in_procedure_deserialize (GScanner *scanner,
gint n_args; gint n_args;
gint n_return_vals; gint n_return_vals;
gint n_menu_paths; gint n_menu_paths;
gint sensitivity_mask;
gint i; gint i;
if (! gimp_scanner_parse_string (scanner, &str)) if (! gimp_scanner_parse_string (scanner, &str))
@ -458,6 +459,11 @@ plug_in_procedure_deserialize (GScanner *scanner,
gimp_plug_in_procedure_set_image_types (*proc, str); gimp_plug_in_procedure_set_image_types (*proc, str);
g_free (str); g_free (str);
if (! gimp_scanner_parse_int (scanner, &sensitivity_mask))
return G_TOKEN_INT;
gimp_plug_in_procedure_set_sensitivity_mask (*proc, sensitivity_mask);
if (! gimp_scanner_parse_int (scanner, (gint *) &n_args)) if (! gimp_scanner_parse_int (scanner, (gint *) &n_args))
return G_TOKEN_INT; return G_TOKEN_INT;
if (! gimp_scanner_parse_int (scanner, (gint *) &n_return_vals)) if (! gimp_scanner_parse_int (scanner, (gint *) &n_return_vals))
@ -1281,6 +1287,10 @@ plug_in_rc_write (GSList *plug_in_defs,
gimp_config_writer_string (writer, proc->image_types); gimp_config_writer_string (writer, proc->image_types);
gimp_config_writer_linefeed (writer); gimp_config_writer_linefeed (writer);
gimp_config_writer_printf (writer, "%d",
proc->sensitivity_mask);
gimp_config_writer_linefeed (writer);
gimp_config_writer_printf (writer, "%d %d", gimp_config_writer_printf (writer, "%d %d",
procedure->num_args, procedure->num_args,
procedure->num_values); procedure->num_values);

View file

@ -423,6 +423,44 @@ _gimp_pdb_get_proc_image_types (const gchar *procedure_name)
return image_types; return image_types;
} }
/**
* _gimp_pdb_set_proc_sensitivity_mask:
* @procedure_name: The procedure.
* @mask: The procedure's sensitivity mask.
*
* Set the sensitivity mask for a plug-in procedure.
*
* This procedure sets the sensitivity mask for the given procedure.
*
* Returns: TRUE on success.
*
* Since: 3.0
**/
gboolean
_gimp_pdb_set_proc_sensitivity_mask (const gchar *procedure_name,
gint mask)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, procedure_name,
G_TYPE_INT, mask,
G_TYPE_NONE);
return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
"gimp-pdb-set-proc-sensitivity-mask",
args);
gimp_value_array_unref (args);
success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;
gimp_value_array_unref (return_vals);
return success;
}
/** /**
* _gimp_pdb_set_proc_menu_label: * _gimp_pdb_set_proc_menu_label:
* @procedure_name: The procedure for which to install the menu path. * @procedure_name: The procedure for which to install the menu path.

View file

@ -55,6 +55,8 @@ G_GNUC_INTERNAL GParamSpec* _gimp_pdb_get_proc_return_value (const gcha
G_GNUC_INTERNAL gboolean _gimp_pdb_set_proc_image_types (const gchar *procedure_name, G_GNUC_INTERNAL gboolean _gimp_pdb_set_proc_image_types (const gchar *procedure_name,
const gchar *image_types); const gchar *image_types);
G_GNUC_INTERNAL gchar* _gimp_pdb_get_proc_image_types (const gchar *procedure_name); G_GNUC_INTERNAL gchar* _gimp_pdb_get_proc_image_types (const gchar *procedure_name);
G_GNUC_INTERNAL gboolean _gimp_pdb_set_proc_sensitivity_mask (const gchar *procedure_name,
gint mask);
G_GNUC_INTERNAL gboolean _gimp_pdb_set_proc_menu_label (const gchar *procedure_name, G_GNUC_INTERNAL gboolean _gimp_pdb_set_proc_menu_label (const gchar *procedure_name,
const gchar *menu_label); const gchar *menu_label);
G_GNUC_INTERNAL gchar* _gimp_pdb_get_proc_menu_label (const gchar *procedure_name); G_GNUC_INTERNAL gchar* _gimp_pdb_get_proc_menu_label (const gchar *procedure_name);

View file

@ -72,6 +72,8 @@ struct _GimpProcedurePrivate
gchar *copyright; gchar *copyright;
gchar *date; gchar *date;
gint sensitivity_mask;
gint32 n_args; gint32 n_args;
GParamSpec **args; GParamSpec **args;
@ -424,6 +426,9 @@ gimp_procedure_real_install (GimpProcedure *procedure)
procedure->priv->menu_label); procedure->priv->menu_label);
} }
_gimp_pdb_set_proc_sensitivity_mask (gimp_procedure_get_name (procedure),
procedure->priv->sensitivity_mask);
for (list = gimp_procedure_get_menu_paths (procedure); for (list = gimp_procedure_get_menu_paths (procedure);
list; list;
list = g_list_next (list)) list = g_list_next (list))
@ -700,6 +705,60 @@ gimp_procedure_get_image_types (GimpProcedure *procedure)
return procedure->priv->image_types; return procedure->priv->image_types;
} }
/**
* gimp_procedure_set_sensitivity_mask:
* @procedure: A #GimpProcedure.
* @sensitivity_mask: A binary mask of #GimpProcedureSensitivityMask.
*
* Sets the case when @procedure is supposed to be sensitive or not.
* Note that it will be used by the core to determine whether to show a
* procedure as sensitive (hence forbid running it otherwise), yet it
* will not forbid thid-party plug-ins for instance to run manually your
* registered procedure. Therefore you should still handle non-supported
* cases appropriately by returning with %GIMP_PDB_EXECUTION_ERROR and a
* suitable error message.
*
* Similarly third-party plug-ins should verify they are allowed to call
* a procedure with gimp_procedure_get_sensitivity_mask() when running
* with dynamic contents.
*
* Note that by default, a procedure works on an image with a single
* drawable selected. Hence not setting the mask, setting it with 0 or
* setting it with a mask of %GIMP_PROCEDURE_SENSITIVE_DRAWABLE only are
* equivalent.
*
* Since: 3.0
**/
void
gimp_procedure_set_sensitivity_mask (GimpProcedure *procedure,
gint sensitivity_mask)
{
g_return_if_fail (GIMP_IS_PROCEDURE (procedure));
procedure->priv->sensitivity_mask = sensitivity_mask;
if (procedure->priv->installed)
_gimp_pdb_set_proc_sensitivity_mask (gimp_procedure_get_name (procedure),
procedure->priv->sensitivity_mask);
}
/**
* gimp_procedure_get_sensitivity_mask:
* @procedure: A #GimpProcedure.
*
* Returns: The procedure's sensitivity mask given in
* gimp_procedure_set_sensitivity_mask().
*
* Since: 3.0
**/
gint
gimp_procedure_get_sensitivity_mask (GimpProcedure *procedure)
{
g_return_val_if_fail (GIMP_IS_PROCEDURE (procedure), 0);
return procedure->priv->sensitivity_mask;
}
/** /**
* gimp_procedure_set_menu_label: * gimp_procedure_set_menu_label:
* @procedure: A #GimpProcedure. * @procedure: A #GimpProcedure.

View file

@ -144,6 +144,11 @@ void gimp_procedure_set_image_types (GimpProcedure *proced
const gchar *image_types); const gchar *image_types);
const gchar * gimp_procedure_get_image_types (GimpProcedure *procedure); const gchar * gimp_procedure_get_image_types (GimpProcedure *procedure);
void gimp_procedure_set_sensitivity_mask (GimpProcedure *procedure,
gint sensitivity_mask);
gint gimp_procedure_get_sensitivity_mask (GimpProcedure *procedure);
void gimp_procedure_set_menu_label (GimpProcedure *procedure, void gimp_procedure_set_menu_label (GimpProcedure *procedure,
const gchar *menu_label); const gchar *menu_label);
const gchar * gimp_procedure_get_menu_label (GimpProcedure *procedure); const gchar * gimp_procedure_get_menu_label (GimpProcedure *procedure);

View file

@ -426,6 +426,42 @@ CODE
); );
} }
sub pdb_set_proc_sensitivity_mask {
$blurb = "Set the sensitivity mask for a plug-in procedure.";
$help = <<HELP;
This procedure sets the sensitivity mask for the given procedure.
HELP
&jehan_pdb_misc('2021', '3.0');
$lib_private = 1;
@inargs = (
{ name => 'procedure_name', type => 'string', non_empty => 1,
desc => 'The procedure' },
{ name => 'mask', type => 'int32',,
desc => "The procedure's sensitivity mask" }
);
%invoke = (
code => <<'CODE'
{
GimpPlugIn *plug_in = gimp->plug_in_manager->current_plug_in;
if (plug_in &&
gimp_pdb_is_canonical_procedure (procedure_name, error))
{
success = gimp_plug_in_set_proc_sensitivity_mask (plug_in, procedure_name,
mask, error);
}
else
success = FALSE;
}
CODE
);
}
sub pdb_set_proc_menu_label { sub pdb_set_proc_menu_label {
$blurb = "Set the menu label for a plug-in procedure."; $blurb = "Set the menu label for a plug-in procedure.";
@ -1309,6 +1345,7 @@ CODE
pdb_get_proc_return_value pdb_get_proc_return_value
pdb_set_proc_image_types pdb_set_proc_image_types
pdb_get_proc_image_types pdb_get_proc_image_types
pdb_set_proc_sensitivity_mask
pdb_set_proc_menu_label pdb_set_proc_menu_label
pdb_get_proc_menu_label pdb_get_proc_menu_label
pdb_add_proc_menu_path pdb_add_proc_menu_path