diff options
author | Tristan Van Berkom <tvb@src.gnome.org> | 2008-10-16 14:31:42 +0000 |
---|---|---|
committer | Tristan Van Berkom <tvb@src.gnome.org> | 2008-10-16 14:31:42 +0000 |
commit | 4f1e473e0809ddd33e7e58de401f56b8b27516b1 (patch) | |
tree | edf270fdac8f422c05042a5b2fcf243113210b53 /gladeui/glade-name-context.c | |
parent | 9c7ab5ccecad6a33be739241f8d77a6fcf820f97 (diff) | |
download | glade-4f1e473e0809ddd33e7e58de401f56b8b27516b1.tar.gz |
Encapsulated name tracking mechanism
* gladeui/Makefile.am, gladeui/glade-name-context.[ch]: Encapsulated name tracking mechanism
* gladeui/glade-project.c, gladeui/glade-command.c: Now added a naming policy to the project
with prefs and load/save support + a glade command to set it - also revamped the prefs dialog,
it also pops up automatically for new projects.
* gladeui/glade-editor.c, gladeui/glade-editor-property.c, gladeui/glade-property-class.c,
gladeui/glade-property.c, gladeui/glade-widget.c: All effected since now
glade_property_class_make_gvalue_from_string () needs a GladeWidget argument to do
hierachic context sensitive searches... that and naming is much cleaner now.
* src/glade-window.c: remember to pass ownership of the project to the app.
* plugins/gtk+/glade-gtk.c, plugins/gtk+/glade-column-types.c, plugins/gtk+/glade-model-data.c:
BEWARE: Dangerous and still a work in progress.
svn path=/trunk/; revision=1972
Diffstat (limited to 'gladeui/glade-name-context.c')
-rw-r--r-- | gladeui/glade-name-context.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/gladeui/glade-name-context.c b/gladeui/glade-name-context.c new file mode 100644 index 00000000..d4b52918 --- /dev/null +++ b/gladeui/glade-name-context.c @@ -0,0 +1,241 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * glade-name-context.c + * + * Copyright (C) 2008 Tristan Van Berkom. + * + * Authors: + * Tristan Van Berkom <tvb@gnome.org> + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string.h> +#include <stdlib.h> + +#include "glade-id-allocator.h" +#include "glade-name-context.h" + +struct _GladeNameContext { + GHashTable *name_allocators; + + GHashTable *names; +}; + + + +GladeNameContext * +glade_name_context_new (void) +{ + GladeNameContext *context = g_new0 (GladeNameContext, 1); + + context->name_allocators = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) glade_id_allocator_destroy); + + context->names = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + NULL); + + return context; +} + +void +glade_name_context_destroy (GladeNameContext *context) +{ + g_return_if_fail (context != NULL); + + g_hash_table_destroy (context->name_allocators); + g_hash_table_destroy (context->names); + g_free (context); +} + +gchar * +glade_name_context_new_name (GladeNameContext *context, + const gchar *base_name) +{ + GladeIDAllocator *id_allocator; + const gchar *number; + gchar *name = NULL, *freeme = NULL; + guint i = 1; + + g_return_val_if_fail (context != NULL, NULL); + g_return_val_if_fail (base_name && base_name[0], NULL); + + number = base_name + strlen (base_name); + while (number > base_name && g_ascii_isdigit (number[-1])) + --number; + + if (*number) + { + freeme = g_strndup (base_name, number - base_name); + base_name = freeme; + } + + id_allocator = g_hash_table_lookup (context->name_allocators, base_name); + + if (id_allocator == NULL) + { + id_allocator = glade_id_allocator_new (); + g_hash_table_insert (context->name_allocators, + g_strdup (base_name), id_allocator); + } + + do + { + g_free (name); + i = glade_id_allocator_allocate (id_allocator); + name = g_strdup_printf ("%s%u", base_name, i); + } + while (glade_name_context_has_name (context, name)); + + g_free (freeme); + return name; +} + +gchar * +glade_name_context_dual_new_name (GladeNameContext *context, + GladeNameContext *another_context, + const gchar *base_name) +{ + GladeIDAllocator *id_allocator; + const gchar *number; + gchar *name = NULL, *freeme = NULL; + guint i = 1; + + g_return_val_if_fail (context != NULL, NULL); + g_return_val_if_fail (another_context != NULL, NULL); + g_return_val_if_fail (base_name && base_name[0], NULL); + + number = base_name + strlen (base_name); + while (number > base_name && g_ascii_isdigit (number[-1])) + --number; + + if (*number) + { + freeme = g_strndup (base_name, number - base_name); + base_name = freeme; + } + + id_allocator = g_hash_table_lookup (context->name_allocators, base_name); + + if (id_allocator == NULL) + { + id_allocator = glade_id_allocator_new (); + g_hash_table_insert (context->name_allocators, + g_strdup (base_name), id_allocator); + } + + do + { + g_free (name); + i = glade_id_allocator_allocate (id_allocator); + name = g_strdup_printf ("%s%u", base_name, i); + } + while (glade_name_context_has_name (context, name) || + glade_name_context_has_name (another_context, name)); + + g_free (freeme); + return name; +} + +guint +glade_name_context_n_names (GladeNameContext *context) +{ + g_return_val_if_fail (context != NULL, FALSE); + + return g_hash_table_size (context->names); +} + +gboolean +glade_name_context_has_name (GladeNameContext *context, + const gchar *name) +{ + g_return_val_if_fail (context != NULL, FALSE); + g_return_val_if_fail (name && name[0], FALSE); + + return (g_hash_table_lookup (context->names, name) != NULL); +} + +gboolean +glade_name_context_add_name (GladeNameContext *context, + const gchar *name) +{ + gboolean ret = FALSE; + + g_return_val_if_fail (context != NULL, FALSE); + g_return_val_if_fail (name && name[0], FALSE); + + if (!glade_name_context_has_name (context, name)) + { + g_hash_table_insert (context->names, g_strdup (name), GINT_TO_POINTER (TRUE)); + ret = TRUE; + } + + return ret; +} + +void +glade_name_context_release_name (GladeNameContext *context, + const gchar *name) +{ + + const gchar *first_number = name; + gchar *end_number, *base_name; + GladeIDAllocator *id_allocator; + gunichar ch; + gint id; + + g_return_if_fail (context != NULL); + g_return_if_fail (name && name[0]); + + /* Remove from name hash first... */ + g_hash_table_remove (context->names, name); + + do + { + ch = g_utf8_get_char (first_number); + + if (ch == 0 || g_unichar_isdigit (ch)) + break; + + first_number = g_utf8_next_char (first_number); + } + while (TRUE); + + /* if there is a number - then we have to unallocate it... */ + if (ch == 0) return; + + + base_name = g_strdup (name); + *(base_name + (first_number - name)) = 0; + + if ((id_allocator = + g_hash_table_lookup (context->name_allocators, base_name)) != NULL) + { + + id = (int) strtol (first_number, &end_number, 10); + if (*end_number == 0) + glade_id_allocator_release (id_allocator, id); + } + + g_free (base_name); +} |