fix some bugs in the signal editor. Now it's more or less bug free (I

2004-01-22  Joaquin Cuenca Abela  <e98cuenc@yahoo.com>

	* src/glade-signal-editor.c: fix some bugs in the signal editor. Now it's
	more or less bug free (I hope), but the UI still needs a bit of love.
	* src/glade-widget.[ch]: change the signals from a hash that points
	to a GList, to a hash that points to an GArray. The change it
	also solves some bugs in the old implementation.
This commit is contained in:
Joaquin Cuenca Abela 2004-01-22 21:21:02 +00:00 committed by Joaquín Cuenca Abela
parent 81f7db6aac
commit 0027cb6b74
4 changed files with 120 additions and 71 deletions

View File

@ -1,3 +1,11 @@
2004-01-22 Joaquin Cuenca Abela <e98cuenc@yahoo.com>
* src/glade-signal-editor.c: fix some bugs in the signal editor. Now it's
more or less bug free (I hope), but the UI still needs a bit of love.
* src/glade-widget.[ch]: change the signals from a hash that points
to a GList, to a hash that points to an GArray. The change it
also solves some bugs in the old implementation.
2004-01-19 Joaquin Cuenca Abela <e98cuenc@yahoo.com>
* src/glade-signal.c: make the "signal" column non editable in the

View File

@ -18,6 +18,7 @@
*
* Authors:
* Shane Butler <shane_b@users.sourceforge.net>
* Joaquin Cuenca Abela <e98cuenc@yahoo.com>
*/
@ -54,7 +55,7 @@ after_toggled (GtkCellRendererToggle *cell,
char *handler;
char *signal_name;
GladeSignal *old_signal;
GList *lsignal;
GladeSignal *signal;
GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
gboolean after;
@ -71,10 +72,10 @@ after_toggled (GtkCellRendererToggle *cell,
}
old_signal = glade_signal_new (signal_name, handler, after);
lsignal = glade_widget_find_signal (editor->widget, old_signal);
signal = glade_widget_find_signal (editor->widget, old_signal);
after = !after;
((GladeSignal*) lsignal->data)->after = after;
signal->after = after;
/* set new value */
gtk_tree_store_set (GTK_TREE_STORE (model), &iter, COLUMN_AFTER, after, -1);
@ -117,11 +118,9 @@ cell_edited (GtkCellRendererText *cell,
GtkTreeIter *iter2;
GladeSignal *old_signal;
GladeSignal *signal;
GList *lsignal;
gchar *signal_name;
gboolean after;
char *old_handler;
gboolean child = TRUE;
gtk_tree_model_get_iter (model, &iter, path);
iter2 = gtk_tree_iter_copy (&iter);
@ -139,8 +138,9 @@ cell_edited (GtkCellRendererText *cell,
iter_parent = iter;
old_signal = glade_signal_new (signal_name, old_handler, after);
lsignal = glade_widget_find_signal (editor->widget, old_signal);
signal = lsignal ? lsignal->data : NULL;
g_free (old_handler);
g_free (signal_name);
signal = glade_widget_find_signal (editor->widget, old_signal);
/* check that the new_text is a valid identifier. TODO: I don't like that! We're throwing away the text of the user
* without even giving him an explanation. We should keep the text and say him that it's invalid, and why. The
@ -152,12 +152,11 @@ cell_edited (GtkCellRendererText *cell,
if (signal == NULL)
{
/* we're adding a new signal */
signal = glade_signal_copy (old_signal);
g_free (signal->handler);
signal->handler = g_strdup (new_text);
g_free (old_signal->handler);
old_signal->handler = g_strdup (new_text);
glade_widget_add_signal (editor->widget, signal);
gtk_tree_store_set (GTK_TREE_STORE (model), &iter, COLUMN_HANDLER, signal->handler, COLUMN_VISIBLE, TRUE, COLUMN_SLOT, FALSE, -1);
glade_widget_add_signal (editor->widget, old_signal);
gtk_tree_store_set (GTK_TREE_STORE (model), &iter, COLUMN_HANDLER, old_signal->handler, COLUMN_VISIBLE, TRUE, COLUMN_SLOT, FALSE, -1);
/* TODO: Add the <Type...> item */
gtk_tree_store_append (GTK_TREE_STORE (model), &iter_new_slot, &iter_parent);
@ -187,8 +186,31 @@ cell_edited (GtkCellRendererText *cell,
{
/* we're erasing a signal */
glade_widget_remove_signal (editor->widget, signal);
gtk_tree_store_set (GTK_TREE_STORE (model), &iter, COLUMN_HANDLER, _("<Type the signal's handler here>"),
COLUMN_AFTER, FALSE, COLUMN_VISIBLE, FALSE, COLUMN_SLOT, TRUE, -1);
if (memcmp(&iter_parent, &iter, sizeof(GtkTreeIter)) == 0)
{
/* ok, we're editing the very first signal, and thus we can't just remove the entire row,
* as it also contains the signal's name */
char *next_handler;
gboolean next_after;
gboolean next_visible;
gboolean next_slot;
GtkTreeIter next_iter;
gtk_tree_store_set (GTK_TREE_STORE (model), &iter, COLUMN_HANDLER, _("<Type the signal's handler here>"),
COLUMN_AFTER, FALSE, COLUMN_VISIBLE, FALSE, COLUMN_SLOT, TRUE, -1);
/* TODO: Copy the first children of iter to iter, and remove it */
/* we're at the top, and we're erasing something. There should be at least a <Type...> child! */
g_assert (gtk_tree_model_iter_has_child (model, &iter));
gtk_tree_model_iter_nth_child (model, &next_iter, &iter, 0);
gtk_tree_model_get (model, &next_iter, COLUMN_HANDLER, &next_handler, COLUMN_AFTER, &next_after, COLUMN_VISIBLE, &next_visible, COLUMN_SLOT, &next_slot, -1);
gtk_tree_store_set (GTK_TREE_STORE (model), &iter, COLUMN_HANDLER, next_handler, COLUMN_AFTER, next_after, COLUMN_VISIBLE, next_visible, COLUMN_SLOT, next_slot, -1);
gtk_tree_store_remove (GTK_TREE_STORE (model), &next_iter);
g_free (next_handler);
}
else
gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
}
}
@ -292,7 +314,7 @@ glade_signal_editor_load_widget (GladeSignalEditor *editor,
GtkTreeIter parent_class;
GtkTreeIter parent_signal;
GtkTreePath *path_first;
GList *signals;
GArray *signals;
g_return_if_fail (GLADE_IS_SIGNAL_EDITOR (editor));
g_return_if_fail (widget == NULL || GLADE_IS_WIDGET (widget));
@ -319,7 +341,7 @@ glade_signal_editor_load_widget (GladeSignalEditor *editor,
gtk_tree_store_append (editor->model, &parent_signal, &parent_class);
signals = glade_widget_find_signals_by_name (widget, signal->name);
if (!signals)
if (!signals || signals->len == 0)
gtk_tree_store_set (editor->model, &parent_signal,
COLUMN_SIGNAL, signal->name,
COLUMN_HANDLER, _("<Type the signal's handler here>"),
@ -328,7 +350,8 @@ glade_signal_editor_load_widget (GladeSignalEditor *editor,
COLUMN_SLOT, TRUE, -1);
else
{
GladeSignal *widget_signal = (GladeSignal*) signals->data;
size_t i;
GladeSignal *widget_signal = (GladeSignal*) g_array_index (signals, GladeSignal*, 0);
gtk_tree_store_set (editor->model, &parent_signal,
COLUMN_SIGNAL, signal->name,
@ -336,9 +359,9 @@ glade_signal_editor_load_widget (GladeSignalEditor *editor,
COLUMN_AFTER, widget_signal->after,
COLUMN_VISIBLE, TRUE,
COLUMN_SLOT, FALSE, -1);
for (signals = signals->next; signals; signals = signals->next)
for (i = 1; i < signals->len; i++)
{
widget_signal = (GladeSignal*) signals->data;
widget_signal = (GladeSignal*) g_array_index (signals, GladeSignal*, i);
gtk_tree_store_append (editor->model, &iter, &parent_signal);
gtk_tree_store_set (editor->model, &iter,
COLUMN_HANDLER, widget_signal->handler,

View File

@ -79,6 +79,18 @@ glade_widget_properties_from_list (GList *list, GladeWidget *widget)
return new_list;
}
static void
glade_widget_free_signals (gpointer value)
{
GList *signals = (GList*) value;
if (signals)
{
g_list_foreach (signals, (GFunc) glade_signal_free, NULL);
g_list_free (signals);
}
}
/**
* glade_widget_new:
* @class: The GladeWidgeClass of the GladeWidget
@ -104,7 +116,7 @@ glade_widget_new (GladeWidgetClass *class, GladeProject *project)
widget->properties = glade_widget_properties_from_list (class->properties, widget);
/* we don't have packing properties until we container add the widget */
widget->packing_properties = NULL;
widget->signals = g_hash_table_new (g_str_hash, g_str_equal);
widget->signals = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) glade_widget_free_signals);
return widget;
}
@ -435,20 +447,6 @@ glade_widget_connect_other_signals (GladeWidget *widget)
}
}
static gboolean
glade_widget_free_signals (gpointer key, gpointer value, gpointer user_data)
{
GList *signals = (GList*) value;
if (signals)
{
g_list_foreach (signals, (GFunc) glade_signal_free, NULL);
g_list_free (signals);
}
return TRUE;
}
/**
* Free the GladeWidget associated to a widget. Note that this is
* connected to the destroy event of the corresponding GtkWidget so
@ -472,6 +470,7 @@ glade_widget_free (GladeWidget *widget)
g_list_foreach(widget->packing_properties, (GFunc) glade_property_free, NULL);
g_list_free (widget->packing_properties);
g_hash_table_foreach_remove (widget->signals, (GHRFunc) glade_widget_free_signals, NULL);
g_hash_table_destroy (widget->signals);
g_free (widget);
}
@ -1033,14 +1032,13 @@ glade_widget_replace_with_placeholder (GladeWidget *widget,
parent = glade_widget_get_parent (widget);
if (parent->class->replace_child) {
if (parent->class->replace_child)
parent->class->replace_child (widget->widget,
GTK_WIDGET (placeholder),
parent->widget);
}
}
GList *
GArray *
glade_widget_find_signals_by_name (GladeWidget *widget, const char *name)
{
return g_hash_table_lookup (widget->signals, name);
@ -1054,19 +1052,27 @@ glade_widget_find_signals_by_name (GladeWidget *widget, const char *name)
* Find the element in the signal list of the widget with the same
* signal as @signal or NULL if not present.
*/
GList *
GladeSignal *
glade_widget_find_signal (GladeWidget *widget, GladeSignal *signal)
{
GList *list;
size_t i;
GArray *signals = glade_widget_find_signals_by_name (widget, signal->name);
for (list = glade_widget_find_signals_by_name (widget, signal->name);
list; list = list->next)
if (!signals)
return NULL;
for (i = 0; i < signals->len; i++)
{
if (glade_signal_compare (GLADE_SIGNAL (list->data), signal))
return list;
GladeSignal *ret_signal = (GladeSignal*) g_array_index (signals, GladeSignal*, i);
if (glade_signal_compare (ret_signal, signal))
{
g_debug (("glade_widget_find_signal (%s, %s, %s) found\n", signal->name, signal->handler, signal->after ? "TRUE" : "FALSE"));
return ret_signal;
}
}
/* not found... */
g_debug (("glade_widget_find_signal (%s, %s, %s) not found\n", signal->name, signal->handler, signal->after ? "TRUE" : "FALSE"));
return NULL;
}
@ -1080,28 +1086,22 @@ glade_widget_find_signal (GladeWidget *widget, GladeSignal *signal)
void
glade_widget_add_signal (GladeWidget *widget, GladeSignal *signal)
{
GList *found;
GList *old_signals;
GArray *signals;
GladeSignal *new_signal;
g_return_if_fail (GLADE_IS_WIDGET (widget));
g_return_if_fail (GLADE_IS_SIGNAL (signal));
found = glade_widget_find_signal (widget, signal);
if (found)
signals = glade_widget_find_signals_by_name (widget, signal->name);
if (!signals)
{
glade_signal_free (signal);
return;
signals = g_array_new (FALSE, FALSE, sizeof (GladeSignal*));
g_hash_table_insert (widget->signals, g_strdup (signal->name), signals);
}
old_signals = glade_widget_find_signals_by_name (widget, signal->name);
if (old_signals)
{
g_hash_table_insert (widget->signals, signal->name, g_list_append (old_signals, signal));
return;
}
g_hash_table_insert(widget->signals, signal->name, g_list_append (NULL, signal));
return;
new_signal = glade_signal_copy (signal);
g_array_append_val (signals, new_signal);
}
/**
@ -1114,20 +1114,37 @@ glade_widget_add_signal (GladeWidget *widget, GladeSignal *signal)
void
glade_widget_remove_signal (GladeWidget *widget, GladeSignal *signal)
{
GList *found;
char *signal_name;
GArray *signals;
GladeSignal *tmp_signal;
size_t i;
g_return_if_fail (GLADE_IS_WIDGET (widget));
g_return_if_fail (GLADE_IS_SIGNAL (signal));
signal_name = g_strdup (signal->name);
found = glade_widget_find_signal (widget, signal);
if (found)
signals = glade_widget_find_signals_by_name (widget, signal->name);
if (!signals)
{
glade_signal_free (GLADE_SIGNAL (found->data));
g_hash_table_insert (widget->signals, signal_name, g_list_delete_link (found, found));
/* trying to remove an inexistent signal? */
g_assert (FALSE);
return;
}
g_free (signal_name);
for (i = 0; i < signals->len; i++)
{
tmp_signal = g_array_index (signals, GladeSignal*, i);
if (glade_signal_compare (tmp_signal, signal))
break;
}
if (i == signals->len)
{
/* trying to remove an inexistent signal? */
g_assert (FALSE);
return;
}
glade_signal_free (tmp_signal);
g_array_remove_index (signals, i);
}
static GladeXmlNode *
@ -1144,11 +1161,12 @@ glade_widget_write_signals (gpointer key, gpointer value, gpointer user_data)
{
WriteSignalsContext *write_signals_context = (WriteSignalsContext *) user_data;
GladeXmlNode *child;
size_t i;
GList *list = (GList *) value;
for (; list; list = list->next)
GArray *signals = (GArray *) value;
for (i = 0; i < signals->len; i++)
{
GladeSignal *signal = list->data;
GladeSignal *signal = g_array_index (signals, GladeSignal*, i);
child = glade_signal_write (write_signals_context->context, signal);
if (!child)
continue;

View File

@ -100,8 +100,8 @@ GladeWidget *glade_widget_get_from_gtk_widget (GtkWidget *widget);
GladeWidget *glade_widget_get_parent (GladeWidget *widget);
/* Widget signal*/
GList *glade_widget_find_signal (GladeWidget *widget, GladeSignal *signal);
GList *glade_widget_find_signals_by_name (GladeWidget *widget, const char *name);
GladeSignal *glade_widget_find_signal (GladeWidget *widget, GladeSignal *signal);
GArray *glade_widget_find_signals_by_name (GladeWidget *widget, const char *name);
void glade_widget_add_signal (GladeWidget *widget, GladeSignal *signal);
void glade_widget_remove_signal (GladeWidget *widget, GladeSignal *signal);