diff --git a/ChangeLog b/ChangeLog index d0f920e9..5f662231 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2004-01-22 Joaquin Cuenca Abela + + * 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 * src/glade-signal.c: make the "signal" column non editable in the diff --git a/src/glade-signal-editor.c b/src/glade-signal-editor.c index 865c1bbb..351476dd 100644 --- a/src/glade-signal-editor.c +++ b/src/glade-signal-editor.c @@ -18,6 +18,7 @@ * * Authors: * Shane Butler + * Joaquin Cuenca Abela */ @@ -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 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, _(""), - 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, _(""), + 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 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, _(""), @@ -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, diff --git a/src/glade-widget.c b/src/glade-widget.c index 93e4b496..01da331f 100644 --- a/src/glade-widget.c +++ b/src/glade-widget.c @@ -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; diff --git a/src/glade-widget.h b/src/glade-widget.h index 51eee0c3..a07d6ff6 100644 --- a/src/glade-widget.h +++ b/src/glade-widget.h @@ -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);