diff --git a/ChangeLog b/ChangeLog index d55d435a..d2fc721c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,39 @@ +2004-10-26 Tristan Van Berkom + + * src/Makefile.am: CFLAGS was `-O2 -g', for now just `-g'. (Mixing + these two compiler options can cause really bad indigestion, i.e. + untracable bugs). + + * src/glade-gtk.c: + - empty(): now serves as a standard noop for fill-empty functions + (as ignore() noop serves for get/set property). + - glade_gtk_fixed_post_create(): Removed useless + gtk_widget_add_events() line. + - glade_gtk_message_dialog_post_create: Fixed 155849, Message + dialog children + are now selectable usable through the UI. + - glade_gtk_fixed_fill_empty(): Obsoleted by `empty()' + + * src/glade-project.c: glade_project_selection_add()/ + glade_project_selection_set(): + Functions no longer prematurly returns if the editor has no widget + loaded. (This is bug 155892) + + * src/glade-property.c: glade_property_set() Function now takes care of + removing widgets from and adding widgets to the project if that + widget belongs to a project in the case of construct_only, also, if + that widget is in the selection list, the selection list is handled + here too. + + * src/glade-widget.c: + - glade_widget_rebuild() Removed logic that handles + project/selection lists in favor of code in glade-property.c + - Added roboustness around glade_widget_set_widget() and + glade_widget_transport_children(). + + * widgets/gtkfixed.xml: Replaced fill-empty reference in favor of + `empty()'. + 2004-10-26 David Hoover * src/Makefile.am,src/glade-editor.c,src/glade-marshallers.list, diff --git a/src/Makefile.am b/src/Makefile.am index 04bb00a6..cac1745f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,7 +25,7 @@ INCLUDES = \ -DMODULES_DIR=\""@modulesdir@"\" \ -DG_LOG_DOMAIN=\"Glade\" -CFLAGS = -g -O2 -Wall +CFLAGS = -g -Wall glade_3_LDADD = \ $(GLADE_LIBS) diff --git a/src/glade-gtk.c b/src/glade-gtk.c index 78439fa9..d06c5677 100644 --- a/src/glade-gtk.c +++ b/src/glade-gtk.c @@ -531,7 +531,7 @@ glade_gtk_notebook_set_n_pages (GObject *object, GValue *value) * * TODO: write me */ -void GLADEGTK_API +static void glade_gtk_table_set_n_common (GObject *object, GValue *value, gboolean for_rows) { GladeWidget *widget; @@ -755,9 +755,10 @@ glade_gtk_statusbar_set_has_resize_grip (GObject *object, GValue *value) * @value: a #GValue * * This function does absolutely nothing + * (and is for use in overriding fill_empty functions). */ void GLADEGTK_API -empty (GObject *object, GValue *value) +empty (GObject *container) { } @@ -959,12 +960,6 @@ glade_gtk_fixed_post_create (GObject *object) * mouse events */ GTK_WIDGET_UNSET_FLAGS(object, GTK_NO_WINDOW); - gtk_widget_add_events(GTK_WIDGET(object), - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_ENTER_NOTIFY_MASK | - GDK_LEAVE_NOTIFY_MASK); - /* For backing pixmap */ g_signal_connect_after(object, "realize", @@ -1108,6 +1103,7 @@ glade_gtk_dialog_post_create (GObject *object) gtk_window_set_default_size (GTK_WINDOW (dialog), 320, 260); } + /** * glade_gtk_message_dialog_post_create: * @object: @@ -1117,13 +1113,44 @@ glade_gtk_dialog_post_create (GObject *object) void GLADEGTK_API glade_gtk_message_dialog_post_create (GObject *object) { - GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG (object); - + GtkDialog *dialog = GTK_DIALOG (object); + GladeWidget *widget; + GladeWidget *vbox_widget; + GladeWidget *actionarea_widget; + GladeWidgetClass *child_class; + g_return_if_fail (GTK_IS_MESSAGE_DIALOG (dialog)); + widget = glade_widget_get_from_gtk_widget (GTK_WIDGET (dialog)); + if (!widget) + return; + + + /* create the GladeWidgets for internal children */ + child_class = glade_widget_class_get_by_name ("GtkVBox"); + if (!child_class) + return; + + vbox_widget = glade_widget_new_for_internal_child (child_class, widget, + dialog->vbox, "vbox"); + if (!vbox_widget) + return; + + child_class = glade_widget_class_get_by_name ("GtkHButtonBox"); + if (!child_class) + return; + + actionarea_widget = + glade_widget_new_for_internal_child + (child_class, vbox_widget, dialog->action_area, "action_area"); + if (!actionarea_widget) + return; + + gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 115); } + #if 0 void GLADEGTK_API glade_gtk_table_post_create (GObject *object) @@ -1193,27 +1220,6 @@ glade_gtk_container_replace_child (GtkWidget *current, g_free (param_spec); g_free (value); - -#if 0 - /* If there is still no reason to keep this around come release - * time, kill it. - */ - - gtk_widget_unparent (child_info->widget); - child_info->widget = new; - gtk_widget_set_parent (child_info->widget, GTK_WIDGET (container)); - - /* */ - child = new; - if (GTK_WIDGET_REALIZED (container)) - gtk_widget_realize (child); - if (GTK_WIDGET_VISIBLE (container) && GTK_WIDGET_VISIBLE (child)) { - if (GTK_WIDGET_MAPPED (container)) - gtk_widget_map (child); - gtk_widget_queue_resize (child); - } - /* */ -#endif } /** @@ -1279,14 +1285,6 @@ glade_gtk_container_fill_empty (GObject *container) gtk_container_add (GTK_CONTAINER (container), glade_placeholder_new ()); } -void GLADEGTK_API -glade_gtk_fixed_fill_empty (GObject *fixed) -{ - /* This is here purly to override `glade_gtk_container_fill_empty()' - * there is to be no placeholder by default. - */ -} - /** * glade_gtk_dialog_fill_empty: * @dialog: diff --git a/src/glade-project.c b/src/glade-project.c index 8d0a2417..661f5a80 100644 --- a/src/glade-project.c +++ b/src/glade-project.c @@ -34,6 +34,8 @@ #include "glade-xml-utils.h" #include "glade-widget.h" #include "glade-placeholder.h" +#include "glade-project-window.h" +#include "glade-editor.h" #include "glade-utils.h" #include "glade-id-allocator.h" @@ -616,13 +618,19 @@ glade_project_selection_add (GladeProject *project, GtkWidget *widget, gboolean emit_signal) { + GladeProjectWindow *gpw; + gboolean has_nodes; g_return_if_fail (GLADE_IS_PROJECT (project)); g_return_if_fail (GTK_IS_WIDGET (widget)); - if (glade_util_has_nodes (widget)) + gpw = glade_project_window_get (); + has_nodes = glade_util_has_nodes (widget); + + if (has_nodes && gpw->editor->loaded_widget != NULL) return; - glade_util_add_nodes (widget); + if (has_nodes == FALSE) + glade_util_add_nodes (widget); if (project) { @@ -647,10 +655,14 @@ glade_project_selection_set (GladeProject *project, GtkWidget *widget, gboolean emit_signal) { + GladeProjectWindow *gpw; g_return_if_fail (GLADE_IS_PROJECT (project)); g_return_if_fail (GTK_IS_WIDGET (widget)); - if (glade_util_has_nodes (widget)) + gpw = glade_project_window_get (); + + if (glade_util_has_nodes (widget) && + gpw->editor->loaded_widget != NULL) return; glade_project_selection_clear (project, FALSE); diff --git a/src/glade-property.c b/src/glade-property.c index 0e923831..131b0a3a 100644 --- a/src/glade-property.c +++ b/src/glade-property.c @@ -30,6 +30,7 @@ #include "glade-property.h" #include "glade-property-class.h" #include "glade-parameter.h" +#include "glade-project.h" #include "glade-widget-class.h" #include "glade-debug.h" @@ -184,12 +185,44 @@ glade_property_set (GladeProperty *property, const GValue *value) g_value_reset (property->value); g_value_copy (value, property->value); - if (property->class->construct_only) - /* if we cant set it, rebuild it */ - glade_widget_rebuild (property->widget); - else if (property->class->set_function) + if (property->class->set_function) /* if there is a custom set_property, use it */ (*property->class->set_function) (G_OBJECT (property->widget->widget), value); + else if (property->class->construct_only) + { + /* In the case of construct_only, the widget must be rebuilt, here we + * take care of updating the project if the widget is in a project and + * updating the selection if the widget was selected. + */ + GList *selection; + gboolean reselect = FALSE; + if (property->widget->project) + { + if ((selection = + glade_project_selection_get (property->widget->project)) != NULL && + g_list_find(selection, property->widget->widget) != NULL) + { + reselect = TRUE; + glade_project_selection_remove(property->widget->project, + property->widget->widget, + FALSE); + } + glade_project_remove_widget (property->widget->project, + property->widget->widget); + } + + glade_widget_rebuild (property->widget); + + if (property->widget->project) + { + glade_project_add_widget (property->widget->project, + property->widget->widget); + if (reselect) + glade_project_selection_add(property->widget->project, + property->widget->widget, + TRUE); + } + } else glade_property_set_property (property, value); diff --git a/src/glade-widget.c b/src/glade-widget.c index be8f6b46..a631fb73 100644 --- a/src/glade-widget.c +++ b/src/glade-widget.c @@ -413,25 +413,19 @@ glade_widget_rebuild (GladeWidget *glade_widget) GtkWidget *new_widget, *old_widget; GladeWidgetClass *klass = glade_widget->widget_class; - /* Clear the project selection before destroying this widget */ - glade_project_selection_clear(glade_widget->project, TRUE); - /* Hold a reference to the old widget while we transport properties * and children from it */ new_widget = GTK_WIDGET(glade_widget_build_object(klass, glade_widget)); old_widget = g_object_ref(G_OBJECT(glade_widget_get_widget(glade_widget))); - glade_project_remove_widget(glade_widget->project, old_widget); - glade_widget_set_widget(glade_widget, new_widget); - g_object_unref(G_OBJECT(old_widget)); + /* Must use gtk_widget_destroy here for cases like dialogs and toplevels + * (otherwise I'd prefer g_object_unref() ) + */ + gtk_widget_destroy(old_widget); gtk_widget_show_all(new_widget); - - /* Set the new widget as the current selection */ - glade_project_add_widget(glade_widget->project, new_widget); - glade_project_selection_set(glade_widget->project, new_widget, TRUE); } @@ -1007,7 +1001,6 @@ glade_widget_connect_signal_handlers (GtkWidget *widget_gtk, gpointer data) } } - /** * glade_widget_transport_children: * @gwidget: A #GladeWidget @@ -1016,44 +1009,37 @@ glade_widget_connect_signal_handlers (GtkWidget *widget_gtk, gpointer data) * * Transports all children from @from_container to @to_container * - * Returns: whether any children were transported */ -static gboolean +static void glade_widget_transport_children (GladeWidget *gwidget, GtkContainer *from_container, GtkContainer *to_container) { - GList *children, *l; - if (from_container != NULL && - (l = children = - gtk_container_get_children(from_container)) != NULL) + GList *l, *children = + from_container ? gtk_container_get_children(from_container) : NULL; + + for (l = children; l && l->data; l = l->next) { - while (l && l->data) - { - GtkWidget *child = (GtkWidget *)l->data; + GtkWidget *child = (GtkWidget *)l->data; - /* If this widget is a container, all children get a temporary - * reference and are moved from the old container, to the new - * container and thier child properties are applied. - */ - g_object_ref(child); - gtk_container_remove(GTK_CONTAINER(from_container), child); - gtk_container_add(GTK_CONTAINER(to_container), child); - glade_widget_set_packing_properties - (glade_widget_get_from_gtk_widget (child), gwidget); - g_object_unref(child); + /* If this widget is a container, all children get a temporary + * reference and are moved from the old container, to the new + * container and thier child properties are applied. + */ + g_object_ref(child); + gtk_container_remove(GTK_CONTAINER(from_container), child); + gtk_container_add(GTK_CONTAINER(to_container), child); + glade_widget_set_packing_properties + (glade_widget_get_from_gtk_widget (child), gwidget); + g_object_unref(child); - l = l->next; - } - g_list_free(children); - return TRUE; } - return FALSE; + g_list_free(children); } /** * glade_widget_update_parent: - * @gwidget: A #GladeWidget + * @widget: A #GladeWidget * @old_widget: A #GtkWidget * @new_widget: A #GtkWidget * @@ -1075,8 +1061,7 @@ glade_widget_update_parent(GladeWidget *gwidget, GtkWidget *old_widget, GtkWidge { if (old_widget) parent->widget_class->replace_child - (GTK_WIDGET(old_widget), - GTK_WIDGET(new_widget), + (old_widget, new_widget, glade_widget_get_widget (parent)); glade_widget_set_packing_properties (gwidget, parent); @@ -1111,51 +1096,57 @@ glade_widget_set_widget (GladeWidget *gwidget, GtkWidget *new_widget) klass = gwidget->widget_class; old_widget = gwidget->widget; - /* Call custom notification of widget creation in plugin */ - if (klass->post_create_function) - klass->post_create_function (G_OBJECT(new_widget)); - /* Add internal reference to new widget */ gwidget->widget = g_object_ref (G_OBJECT(new_widget)); g_object_set_data (G_OBJECT (new_widget), "GladeWidgetDataTag", gwidget); - /* Take care of events and toolkit signals */ - gtk_widget_add_events (new_widget, GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_KEY_PRESS_MASK); + if (gwidget->internal == NULL) + { + /* Call custom notification of widget creation in plugin */ + if (klass->post_create_function) + klass->post_create_function (G_OBJECT(new_widget)); - if (GTK_WIDGET_TOPLEVEL (new_widget)) - g_signal_connect (G_OBJECT (new_widget), "delete_event", - G_CALLBACK (gtk_widget_hide_on_delete), NULL); + /* Take care of events and toolkit signals. + */ + gtk_widget_add_events (new_widget, GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_KEY_PRESS_MASK); - g_signal_connect (G_OBJECT (new_widget), "popup_menu", - G_CALLBACK (glade_widget_popup_menu), NULL); - g_signal_connect (G_OBJECT (new_widget), "key_press_event", - G_CALLBACK (glade_widget_key_press), NULL); + if (GTK_WIDGET_TOPLEVEL (new_widget)) + g_signal_connect (G_OBJECT (new_widget), "delete_event", + G_CALLBACK (gtk_widget_hide_on_delete), NULL); - glade_widget_connect_signal_handlers (new_widget, NULL); + g_signal_connect (G_OBJECT (new_widget), "popup_menu", + G_CALLBACK (glade_widget_popup_menu), NULL); + g_signal_connect (G_OBJECT (new_widget), "key_press_event", + G_CALLBACK (glade_widget_key_press), NULL); + + glade_widget_connect_signal_handlers (new_widget, NULL); - /* Take care of children - */ - if (GTK_IS_CONTAINER (new_widget) && - glade_widget_transport_children (gwidget, - GTK_CONTAINER(old_widget), - GTK_CONTAINER(new_widget)) == FALSE) - { - /* There we're no children to transport, call fill empty */ - if (klass->fill_empty) - klass->fill_empty (new_widget); + /* Take care of reparenting and packing. + */ + if (glade_widget_update_parent(gwidget, old_widget, new_widget) == FALSE) + { + /* XXX We have to take care of GtkWindow positioning + * (in the case of parentless widgets) + */ + } } - /* Take care of reparenting and packing. + if (GTK_IS_CONTAINER (new_widget) && + (GTK_IS_BIN(new_widget) == FALSE || GTK_BIN(new_widget)->child == NULL)) + glade_widget_transport_children (gwidget, + GTK_CONTAINER(old_widget), + GTK_CONTAINER(new_widget)); + + + /* Call fill empty function regardless of whether there were children before + * it is the plugin's responsability to check if it is empty or not. */ - if (glade_widget_update_parent(gwidget, old_widget, new_widget) == FALSE) - { - /* TODO: We have to take care of GtkWindow positioning - * (in the case of parentless widgets) - */ - } + if (klass->fill_empty) + klass->fill_empty (new_widget); + /* Remove internal reference to old widget */ if (old_widget) { @@ -1415,7 +1406,7 @@ glade_widget_replace (GtkWidget *old_widget, GtkWidget *new_widget) if (gold_widget) real_old_widget = glade_widget_get_widget (gold_widget); - glade_widget_update_parent(gnew_widget, old_widget, new_widget); + glade_widget_update_parent(gnew_widget, real_old_widget, real_new_widget); } /* XML Serialization */ diff --git a/widgets/gtkfixed.xml b/widgets/gtkfixed.xml index c0772bca..6996769b 100644 --- a/widgets/gtkfixed.xml +++ b/widgets/gtkfixed.xml @@ -1,5 +1,5 @@ glade_gtk_fixed_post_create - glade_gtk_fixed_fill_empty + empty