libgimpbase: new GimpChoice class meant to represent a list of allowed values.
This will be used for creating limited lists of strings as argument types for procedures. Ideally enums are the best type for this, but it can only be used for generic libgimp* enum types, not custom enums created only for a given plug-in. For this, we currently just demote the args to ints which lose any semantic. A limited list of string will give back some semantic and some better validation, even though it's a tiny bit more annoying to work with strings than int types (at least in C).
This commit is contained in:
parent
29ce8f234f
commit
7e6b01a4e5
4 changed files with 420 additions and 0 deletions
|
|
@ -17,6 +17,16 @@ EXPORTS
|
|||
gimp_check_size_get_type
|
||||
gimp_check_type_get_type
|
||||
gimp_checks_get_colors
|
||||
gimp_choice_add
|
||||
gimp_choice_get_documentation
|
||||
gimp_choice_get_help
|
||||
gimp_choice_get_id
|
||||
gimp_choice_get_label
|
||||
gimp_choice_get_type
|
||||
gimp_choice_is_valid
|
||||
gimp_choice_list_nicks
|
||||
gimp_choice_new
|
||||
gimp_choice_new_with_values
|
||||
gimp_clone_type_get_type
|
||||
gimp_color_tag_get_type
|
||||
gimp_component_type_get_type
|
||||
|
|
|
|||
340
libgimpbase/gimpchoice.c
Normal file
340
libgimpbase/gimpchoice.c
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
/* LIBGIMP - The GIMP Library
|
||||
* Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* gimpchoice.c
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "gimpbasetypes.h"
|
||||
|
||||
#include "gimpchoice.h"
|
||||
#include "gimpparamspecs.h"
|
||||
|
||||
|
||||
typedef struct _GimpChoiceDesc
|
||||
{
|
||||
gchar *label;
|
||||
gchar *help;
|
||||
gint id;
|
||||
} GimpChoiceDesc;
|
||||
|
||||
struct _GimpChoice
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GHashTable *choices;
|
||||
GList *keys;
|
||||
};
|
||||
|
||||
|
||||
static void gimp_choice_finalize (GObject *object);
|
||||
|
||||
static void gimp_choice_desc_free (GimpChoiceDesc *desc);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpChoice, gimp_choice, G_TYPE_OBJECT)
|
||||
|
||||
#define parent_class gimp_choice_parent_class
|
||||
|
||||
static void
|
||||
gimp_choice_class_init (GimpChoiceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gimp_choice_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_choice_init (GimpChoice *choice)
|
||||
{
|
||||
choice->choices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
|
||||
(GDestroyNotify) gimp_choice_desc_free);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_choice_finalize (GObject *object)
|
||||
{
|
||||
GimpChoice *choice = GIMP_CHOICE (object);
|
||||
|
||||
g_hash_table_unref (choice->choices);
|
||||
g_list_free_full (choice->keys, (GDestroyNotify) g_free);
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
/**
|
||||
* gimp_choice_new:
|
||||
*
|
||||
* Returns: (transfer full): a #GimpChoice.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
GimpChoice *
|
||||
gimp_choice_new (void)
|
||||
{
|
||||
GimpChoice *choice;
|
||||
|
||||
choice = g_object_new (GIMP_TYPE_CHOICE, NULL);
|
||||
|
||||
return choice;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_choice_new_with_values:
|
||||
* @nick: the first value.
|
||||
* @id: integer ID for @nick.
|
||||
* @label: the label of @nick.
|
||||
* @help: longer help text for @nick.
|
||||
* ...: more triplets of string to pre-fill the created %GimpChoice.
|
||||
*
|
||||
* Returns: (transfer full): a #GimpChoice.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
GimpChoice *
|
||||
gimp_choice_new_with_values (const gchar *nick,
|
||||
gint id,
|
||||
const gchar *label,
|
||||
const gchar *help,
|
||||
...)
|
||||
{
|
||||
GimpChoice *choice;
|
||||
va_list va_args;
|
||||
|
||||
g_return_val_if_fail (nick != NULL, NULL);
|
||||
g_return_val_if_fail (label != NULL, NULL);
|
||||
|
||||
choice = gimp_choice_new ();
|
||||
|
||||
va_start (va_args, help);
|
||||
|
||||
do
|
||||
{
|
||||
gimp_choice_add (choice, nick, id, label, help);
|
||||
nick = va_arg (va_args, const gchar *);
|
||||
if (nick == NULL)
|
||||
break;
|
||||
id = va_arg (va_args, gint);
|
||||
label = va_arg (va_args, const gchar *);
|
||||
if (label == NULL)
|
||||
{
|
||||
g_critical ("%s: nick '%s' cannot have a NULL label.", G_STRFUNC, nick);
|
||||
break;
|
||||
}
|
||||
help = va_arg (va_args, const gchar *);
|
||||
}
|
||||
while (TRUE);
|
||||
|
||||
va_end (va_args);
|
||||
|
||||
return choice;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_choice_add:
|
||||
* @choice: the %GimpChoice.
|
||||
* @nick: the nick of @choice.
|
||||
* @id: optional integer ID for @nick.
|
||||
* @label: the label of @choice.
|
||||
* @help: optional longer help text for @nick.
|
||||
*
|
||||
* This procedure adds a new possible value to @choice list of values.
|
||||
* The @id is an optional integer identifier. This can be useful for instance
|
||||
* when you want to work with different enum values mapped to each @nick.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
gimp_choice_add (GimpChoice *choice,
|
||||
const gchar *nick,
|
||||
gint id,
|
||||
const gchar *label,
|
||||
const gchar *help)
|
||||
{
|
||||
GimpChoiceDesc *desc;
|
||||
GList *duplicate;
|
||||
|
||||
g_return_if_fail (label != NULL);
|
||||
|
||||
desc = g_new0 (GimpChoiceDesc, 1);
|
||||
desc->id = id;
|
||||
desc->label = g_strdup (label);
|
||||
desc->help = help != NULL ? g_strdup (help) : NULL;
|
||||
g_hash_table_insert (choice->choices, g_strdup (nick), desc);
|
||||
|
||||
duplicate = g_list_find_custom (choice->keys, nick, (GCompareFunc) g_strcmp0);
|
||||
if (duplicate != NULL)
|
||||
{
|
||||
choice->keys = g_list_remove_link (choice->keys, duplicate);
|
||||
gimp_choice_desc_free (duplicate->data);
|
||||
g_list_free (duplicate);
|
||||
}
|
||||
choice->keys = g_list_append (choice->keys, g_strdup (nick));
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_choice_is_valid:
|
||||
* @choice: a %GimpChoice.
|
||||
* @nick: the nick to check.
|
||||
*
|
||||
* This procedure checks if the given @nick is valid and refers to
|
||||
* an existing choice.
|
||||
*
|
||||
* Returns: Whether the choice is valid.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
gboolean
|
||||
gimp_choice_is_valid (GimpChoice *choice,
|
||||
const gchar *nick)
|
||||
{
|
||||
return (g_hash_table_lookup (choice->choices, nick) != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_choice_list_nicks:
|
||||
* @choice: a %GimpChoice.
|
||||
* @nick: the nick to check.
|
||||
*
|
||||
* This procedure returns the list of nicks allowed for @choice.
|
||||
*
|
||||
* Returns: (element-type gchar*) (transfer none): The list of @choice's nicks.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
GList *
|
||||
gimp_choice_list_nicks (GimpChoice *choice)
|
||||
{
|
||||
/* I don't use g_hash_table_get_keys() on purpose, because I want to retain
|
||||
* the adding-time order.
|
||||
*/
|
||||
return choice->keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_choice_get_id:
|
||||
* @choice: a %GimpChoice.
|
||||
* @nick: the nick to lookup.
|
||||
*
|
||||
* Returns: the ID of @nick.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
gint
|
||||
gimp_choice_get_id (GimpChoice *choice,
|
||||
const gchar *nick)
|
||||
{
|
||||
GimpChoiceDesc *desc;
|
||||
|
||||
desc = g_hash_table_lookup (choice->choices, nick);
|
||||
if (desc)
|
||||
return desc->id;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_choice_get_label:
|
||||
* @choice: a %GimpChoice.
|
||||
* @nick: the nick to lookup.
|
||||
*
|
||||
* Returns: (transfer none): the label of @nick.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
const gchar *
|
||||
gimp_choice_get_label (GimpChoice *choice,
|
||||
const gchar *nick)
|
||||
{
|
||||
GimpChoiceDesc *desc;
|
||||
|
||||
desc = g_hash_table_lookup (choice->choices, nick);
|
||||
if (desc)
|
||||
return desc->label;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_choice_get_help:
|
||||
* @choice: a %GimpChoice.
|
||||
* @nick: the nick to lookup.
|
||||
*
|
||||
* Returns the longer documentation for @nick.
|
||||
*
|
||||
* Returns: (transfer none): the help text of @nick.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
const gchar *
|
||||
gimp_choice_get_help (GimpChoice *choice,
|
||||
const gchar *nick)
|
||||
{
|
||||
GimpChoiceDesc *desc;
|
||||
|
||||
desc = g_hash_table_lookup (choice->choices, nick);
|
||||
if (desc)
|
||||
return desc->help;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_choice_get_documentation:
|
||||
* @choice: the %GimpChoice.
|
||||
* @nick: the possible value's nick you need documentation for.
|
||||
* @label: (transfer none): the label of @nick.
|
||||
* @help: (transfer none): the help text of @nick.
|
||||
*
|
||||
* Returns the documentation strings for @nick.
|
||||
*
|
||||
* Returns: %TRUE if @nick is found, %FALSE otherwise.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
gboolean
|
||||
gimp_choice_get_documentation (GimpChoice *choice,
|
||||
const gchar *nick,
|
||||
const gchar **label,
|
||||
const gchar **help)
|
||||
{
|
||||
GimpChoiceDesc *desc;
|
||||
|
||||
desc = g_hash_table_lookup (choice->choices, nick);
|
||||
if (desc)
|
||||
{
|
||||
*label = desc->label;
|
||||
*help = desc->help;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Private functions */
|
||||
|
||||
static void
|
||||
gimp_choice_desc_free (GimpChoiceDesc *desc)
|
||||
{
|
||||
g_free (desc->label);
|
||||
g_free (desc->help);
|
||||
g_free (desc);
|
||||
}
|
||||
69
libgimpbase/gimpchoice.h
Normal file
69
libgimpbase/gimpchoice.h
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* LIBGIMP - The GIMP Library
|
||||
* Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* gimpchoice.h
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__GIMP_BASE_H_INSIDE__) && !defined (GIMP_BASE_COMPILATION)
|
||||
#error "Only <libgimpbase/gimpbase.h> can be included directly."
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __GIMP_CHOICE_H__
|
||||
#define __GIMP_CHOICE_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
/* For information look into the C source or the html documentation */
|
||||
|
||||
|
||||
#define GIMP_TYPE_CHOICE (gimp_choice_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GimpChoice, gimp_choice, GIMP, CHOICE, GObject)
|
||||
|
||||
|
||||
GimpChoice * gimp_choice_new (void);
|
||||
GimpChoice * gimp_choice_new_with_values (const gchar *nick,
|
||||
gint id,
|
||||
const gchar *label,
|
||||
const gchar *help,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
void gimp_choice_add (GimpChoice *choice,
|
||||
const gchar *nick,
|
||||
gint id,
|
||||
const gchar *label,
|
||||
const gchar *help);
|
||||
|
||||
gboolean gimp_choice_is_valid (GimpChoice *choice,
|
||||
const gchar *nick);
|
||||
GList * gimp_choice_list_nicks (GimpChoice *choice);
|
||||
gint gimp_choice_get_id (GimpChoice *choice,
|
||||
const gchar *nick);
|
||||
const gchar * gimp_choice_get_label (GimpChoice *choice,
|
||||
const gchar *nick);
|
||||
const gchar * gimp_choice_get_help (GimpChoice *choice,
|
||||
const gchar *nick);
|
||||
gboolean gimp_choice_get_documentation (GimpChoice *choice,
|
||||
const gchar *nick,
|
||||
const gchar **label,
|
||||
const gchar **help);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GIMP_CHOICE_H__ */
|
||||
|
|
@ -51,6 +51,7 @@ stamp_compat_enums = custom_target('stamp-gimpcompatenums.h',
|
|||
libgimpbase_sources_introspectable = files(
|
||||
'gimpbasetypes.c',
|
||||
'gimpchecks.c',
|
||||
'gimpchoice.c',
|
||||
'gimpcpuaccel.c',
|
||||
'gimpenv.c',
|
||||
'gimpmemsize.c',
|
||||
|
|
|
|||
Loading…
Reference in a new issue