|
Packit |
1e8aac |
/*
|
|
Packit |
1e8aac |
* glade-name-context.c
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Copyright (C) 2008 Tristan Van Berkom.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This library is free software; you can redistribute it and/or modify it
|
|
Packit |
1e8aac |
* under the terms of the GNU Lesser General Public License as
|
|
Packit |
1e8aac |
* published by the Free Software Foundation; either version 2.1 of
|
|
Packit |
1e8aac |
* the License, or (at your option) any later version.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This library is distributed in the hope that it will be useful, but
|
|
Packit |
1e8aac |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
1e8aac |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
1e8aac |
* Lesser General Public License for more details.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
1e8aac |
* License along with this program; if not, write to the Free Software
|
|
Packit |
1e8aac |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Authors:
|
|
Packit |
1e8aac |
* Tristan Van Berkom <tvb@gnome.org>
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
#ifdef HAVE_CONFIG_H
|
|
Packit |
1e8aac |
#include <config.h>
|
|
Packit |
1e8aac |
#endif
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include <string.h>
|
|
Packit |
1e8aac |
#include <stdlib.h>
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include "glade-id-allocator.h"
|
|
Packit |
1e8aac |
#include "glade-name-context.h"
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
struct _GladeNameContext
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GHashTable *name_allocators;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GHashTable *names;
|
|
Packit |
1e8aac |
};
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GladeNameContext *
|
|
Packit |
1e8aac |
glade_name_context_new (void)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeNameContext *context = g_slice_new0 (GladeNameContext);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
context->name_allocators = g_hash_table_new_full (g_str_hash,
|
|
Packit |
1e8aac |
g_str_equal,
|
|
Packit |
1e8aac |
g_free,
|
|
Packit |
1e8aac |
(GDestroyNotify)
|
|
Packit |
1e8aac |
glade_id_allocator_destroy);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
context->names = g_hash_table_new_full (g_str_hash,
|
|
Packit |
1e8aac |
g_str_equal, g_free, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return context;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_name_context_destroy (GladeNameContext *context)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_return_if_fail (context != NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_hash_table_destroy (context->name_allocators);
|
|
Packit |
1e8aac |
g_hash_table_destroy (context->names);
|
|
Packit |
1e8aac |
g_slice_free (GladeNameContext, context);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gchar *
|
|
Packit |
1e8aac |
glade_name_context_new_name (GladeNameContext *context,
|
|
Packit |
1e8aac |
const gchar *base_name)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeIDAllocator *id_allocator;
|
|
Packit |
1e8aac |
const gchar *number;
|
|
Packit |
1e8aac |
gchar *name = NULL, *freeme = NULL;
|
|
Packit |
1e8aac |
guint i = 1;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (context != NULL, NULL);
|
|
Packit |
1e8aac |
g_return_val_if_fail (base_name && base_name[0], NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
number = base_name + strlen (base_name);
|
|
Packit |
1e8aac |
while (number > base_name && g_ascii_isdigit (number[-1]))
|
|
Packit |
1e8aac |
--number;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (*number)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
freeme = g_strndup (base_name, number - base_name);
|
|
Packit |
1e8aac |
base_name = freeme;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
id_allocator = g_hash_table_lookup (context->name_allocators, base_name);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (id_allocator == NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
id_allocator = glade_id_allocator_new ();
|
|
Packit |
1e8aac |
g_hash_table_insert (context->name_allocators,
|
|
Packit |
1e8aac |
g_strdup (base_name), id_allocator);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
do
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_free (name);
|
|
Packit |
1e8aac |
i = glade_id_allocator_allocate (id_allocator);
|
|
Packit |
1e8aac |
name = g_strdup_printf ("%s%u", base_name, i);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
while (glade_name_context_has_name (context, name));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (freeme);
|
|
Packit |
1e8aac |
return name;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
guint
|
|
Packit |
1e8aac |
glade_name_context_n_names (GladeNameContext *context)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_return_val_if_fail (context != NULL, FALSE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return g_hash_table_size (context->names);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gboolean
|
|
Packit |
1e8aac |
glade_name_context_has_name (GladeNameContext *context, const gchar *name)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_return_val_if_fail (context != NULL, FALSE);
|
|
Packit |
1e8aac |
g_return_val_if_fail (name && name[0], FALSE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return (g_hash_table_lookup (context->names, name) != NULL);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gboolean
|
|
Packit |
1e8aac |
glade_name_context_add_name (GladeNameContext *context, const gchar *name)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gboolean ret = FALSE;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (context != NULL, FALSE);
|
|
Packit |
1e8aac |
g_return_val_if_fail (name && name[0], FALSE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!glade_name_context_has_name (context, name))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_hash_table_insert (context->names, g_strdup (name),
|
|
Packit |
1e8aac |
GINT_TO_POINTER (TRUE));
|
|
Packit |
1e8aac |
ret = TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return ret;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_name_context_release_name (GladeNameContext *context, const gchar *name)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
const gchar *first_number = name;
|
|
Packit |
1e8aac |
gchar *end_number, *base_name;
|
|
Packit |
1e8aac |
GladeIDAllocator *id_allocator;
|
|
Packit |
1e8aac |
gunichar ch;
|
|
Packit |
1e8aac |
gint id;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (context != NULL);
|
|
Packit |
1e8aac |
g_return_if_fail (name && name[0]);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Remove from name hash first... */
|
|
Packit |
1e8aac |
g_hash_table_remove (context->names, name);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
do
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
ch = g_utf8_get_char (first_number);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (ch == 0 || g_unichar_isdigit (ch))
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
first_number = g_utf8_next_char (first_number);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
while (TRUE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* if there is a number - then we have to unallocate it... */
|
|
Packit |
1e8aac |
if (ch == 0)
|
|
Packit |
1e8aac |
return;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
base_name = g_strdup (name);
|
|
Packit |
1e8aac |
*(base_name + (first_number - name)) = 0;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((id_allocator =
|
|
Packit |
1e8aac |
g_hash_table_lookup (context->name_allocators, base_name)) != NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
id = (int) strtol (first_number, &end_number, 10);
|
|
Packit |
1e8aac |
if (*end_number == 0)
|
|
Packit |
1e8aac |
glade_id_allocator_release (id_allocator, id);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (base_name);
|
|
Packit |
1e8aac |
}
|