summaryrefslogtreecommitdiff
path: root/gladeui/glade-name-context.c
diff options
context:
space:
mode:
authorTristan Van Berkom <tvb@src.gnome.org>2008-10-16 14:31:42 +0000
committerTristan Van Berkom <tvb@src.gnome.org>2008-10-16 14:31:42 +0000
commit4f1e473e0809ddd33e7e58de401f56b8b27516b1 (patch)
treeedf270fdac8f422c05042a5b2fcf243113210b53 /gladeui/glade-name-context.c
parent9c7ab5ccecad6a33be739241f8d77a6fcf820f97 (diff)
downloadglade-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.c241
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);
+}