diff --git a/libgimpbase/gimpbase.def b/libgimpbase/gimpbase.def index 7c01ca46c3..5f05604cf4 100644 --- a/libgimpbase/gimpbase.def +++ b/libgimpbase/gimpbase.def @@ -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 diff --git a/libgimpbase/gimpchoice.c b/libgimpbase/gimpchoice.c new file mode 100644 index 0000000000..92a59ee2f6 --- /dev/null +++ b/libgimpbase/gimpchoice.c @@ -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 + * . + */ + +#include "config.h" + +#include + +#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); +} diff --git a/libgimpbase/gimpchoice.h b/libgimpbase/gimpchoice.h new file mode 100644 index 0000000000..783efca9f1 --- /dev/null +++ b/libgimpbase/gimpchoice.h @@ -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 + * . + */ + +#if !defined (__GIMP_BASE_H_INSIDE__) && !defined (GIMP_BASE_COMPILATION) +#error "Only 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__ */ diff --git a/libgimpbase/meson.build b/libgimpbase/meson.build index 5f90556d72..2fbd6710b1 100644 --- a/libgimpbase/meson.build +++ b/libgimpbase/meson.build @@ -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',