[Glade-devel] Cut/Paste + Undo/Redo bug



--=-fmv3iiV5JUiwk9XxnnSG
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hi Archit,

(I've cc'ed Joaquin since the attached patch is big and maybe the mail
will not reach the list)

Attached there is the current diff of my tree against cvs where I think
I've fixed this bug (along with some others and along with adding some
new ones ;) )

If you could verify/review the patch it would be great!

On Sun, 2003-06-01 at 03:07, Archit Baweja wrote:
Well I had been testing my undo/redo code for cut/paste a lot, as I wrote it. 
I haven't fixed it yet, but just thought I'd mention it to you guys. Try this 
out

Create window
Add a hbox
Add a button
Now cut and then paste 3 times the button
Now keep doing undo
When it is time to undo the first cut (thats the third time it is *supposed* to
show up again), it crashes. 


What I think is the problem is that every cut creates a new placeholder,
so when you undo the first cut what happens is that it tries to paste on
a placeholder which isn't there anymore.

The main fixes to this is in command.c where I ref the placeholders and
in glade_widget_replace_with_placeholder where I pass the placeholder
instead of always creating a new one. 

I'm sorry that I attached the whole diff containing other changes but
extracting only that one was a bit painful. The description of the other
changes follows below.
It also contains cleanups to project/placeholder/widget I already
submitted separately to the list.

glade-clipboard.[ch]:
* (cleanup) moved cut/copy logic to the corresponding functions in
command.c, as they were only called there and since makes code similar
to the create/delete commands. Renamed  clipboard_copy
clipboard_add_copy. Now the API for a clipboard are: add, add_copy and
remove.
* (bugfix) clipboard->curr was set to null when removing a widget, now
it is set to the first widget of the clipboard->widgets list

glade-command.c
* above explained changes to cut/paste
* cleanup/fix create/delete in ways similar to the cut/paste commands
* please check the finalize functions... is it ok to unref
unconditionally? (as create/delete already did)

glade-placeholder.c
* misc cleanups, in particular add g_return_of_fail to check the args of
the functions we expose as APIs

maybe there are also other minor changes which I don't remember ;)


Let me know what do you think!

ciao
        paolo

PS: to Joaquin: do these changes looks ok? Do you want me to split em up
for submission?


--=-fmv3iiV5JUiwk9XxnnSG
Content-Disposition: attachment; filename=big-command.patch
Content-Type: text/x-patch; name=big-command.patch; charset=UTF-8
Content-Transfer-Encoding: 7bit

diff -upr gnome2/glade3/src/glade-clipboard.c glade3/src/glade-clipboard.c
--- gnome2/glade3/src/glade-clipboard.c 2003-05-24 17:41:46.000000000 +0200
+++ glade3/src/glade-clipboard.c        2003-06-02 14:28:27.000000000 +0200
@@ -29,7 +29,6 @@
 #include "glade-widget-class.h"
 #include "glade-placeholder.h"
 #include "glade-project.h"
-#include "glade-packing.h"
 
 static void
 glade_clipboard_class_init (GladeClipboardClass *klass)
@@ -96,10 +95,9 @@ glade_clipboard_new ()
  * @clipboard: 
  * @widget: 
  * 
- * Add a GladeWidget to the Clipboard. Basically has stuff common to 
- * Cut/Copy commands.
+ * Move a GladeWidget onto the Clipboard.
  **/
-static void
+void
 glade_clipboard_add (GladeClipboard *clipboard, GladeWidget *widget)
 {
        /*
@@ -117,65 +115,14 @@ glade_clipboard_add (GladeClipboard *cli
 }
 
 /**
- * glade_clipboard_remove:
- * @clipboard: 
- * @widget: 
- * 
- * Remove a GladeWidget from the Clipboard
- **/
-static void
-glade_clipboard_remove (GladeClipboard *clipboard, GladeWidget *widget)
-{
-       clipboard->widgets = g_list_remove (clipboard->widgets, widget);
-       clipboard->curr = NULL;
-
-       /*
-        * If there is a view present, update it.
-        */
-       if (clipboard->view)
-               glade_clipboard_view_remove (GLADE_CLIPBOARD_VIEW (clipboard->view), widget);
-}
-
-/**
- * glade_clipboard_cut:
- * @clipboard: 
- * @widget: 
- * 
- * Cut a GladeWidget onto the Clipboard. 
- **/
-GladePlaceholder *
-glade_clipboard_cut (GladeClipboard *clipboard, GladeWidget *widget)
-{
-       GladePlaceholder *placeholder = NULL;
-
-       g_return_val_if_fail (GLADE_IS_CLIPBOARD (clipboard), NULL);
-       g_return_val_if_fail (GLADE_IS_WIDGET (widget), NULL);
-
-       glade_project_remove_widget (widget);
-
-       /*
-        * We ref so that the widget and its children are not destroyed.
-        */
-       gtk_widget_ref (GTK_WIDGET (widget->widget));
-       if (widget->parent)
-               placeholder = glade_widget_replace_with_placeholder (widget);
-       else
-               gtk_widget_hide (widget->widget);
-
-       glade_clipboard_add (clipboard, widget);
-
-       return placeholder;
-}
-
-/**
- * glade_clipboard_copy:
+ * glade_clipboard_add_copy:
  * @clipboard: 
  * @widget: 
  * 
- * Copy a GladeWidget onto the Clipboard. 
+ * Add a copy of a GladeWidget onto the Clipboard. 
  **/
 void
-glade_clipboard_copy (GladeClipboard *clipboard, GladeWidget *widget)
+glade_clipboard_add_copy (GladeClipboard *clipboard, GladeWidget *widget)
 {
        GladeWidget *copy;
 
@@ -183,69 +130,33 @@ glade_clipboard_copy (GladeClipboard *cl
        g_return_if_fail (GLADE_IS_WIDGET (widget));
 
        copy = glade_widget_clone (widget);
-
        glade_clipboard_add (clipboard, copy);
 }
 
 /**
- * glade_clipboard_paste:
+ * glade_clipboard_remove:
  * @clipboard: 
- * @placeholder: 
+ * @widget: 
  * 
- * Paste a GladeWidget from the Clipboard.
+ * Remove a GladeWidget from the Clipboard
  **/
 void
-glade_clipboard_paste (GladeClipboard *clipboard,
-                      GladePlaceholder *placeholder)
+glade_clipboard_remove (GladeClipboard *clipboard, GladeWidget *widget)
 {
-       GladeWidget *widget;
-       GladeWidget *parent;
-       GladeProject *project;
-
-       g_return_if_fail (GLADE_IS_CLIPBOARD (clipboard));
-
-       widget = clipboard->curr;
-
-       if (!widget)
-               return;
+       GList *list;
 
-       parent = glade_placeholder_get_parent (placeholder);
-
-       project = parent->project;
-
-       widget->name = glade_widget_new_name (project, widget->class);
-       widget->parent = parent;
-       glade_packing_add_properties (widget);
-       glade_project_add_widget (project, widget);
-
-       if (parent)
-               parent->children = g_list_prepend (parent->children, widget);
-
-       glade_widget_set_contents (widget);
-       glade_widget_connect_signals (widget);
-
-       /*
-        * Toplevel widgets are not packed into other containers :-)
-        */
-       if (!GLADE_WIDGET_IS_TOPLEVEL (widget)) {
-               /* Signal error, if placeholder not selected */
-               if (!placeholder) {
-                       glade_util_ui_warn (_("Placeholder not selected!"));
-                       return;
-               }
-
-               glade_placeholder_replace (placeholder, parent, widget);
-               glade_widget_set_default_packing_options (widget);
-       }
+       clipboard->widgets = g_list_remove (clipboard->widgets, widget);
 
-       glade_project_selection_set (widget, TRUE);
+       list = g_list_first (clipboard->widgets);
+       if (list != NULL)
+               clipboard->curr = GLADE_WIDGET (list->data);
+       else
+               clipboard->curr = NULL;
 
        /*
-        * This damned 'if' statement caused a 1 month delay.
+        * If there is a view present, update it.
         */
-       if (GTK_IS_WIDGET (widget->widget))
-               gtk_widget_show_all (GTK_WIDGET (widget->widget));
-
-       glade_clipboard_remove (clipboard, widget);
+       if (clipboard->view)
+               glade_clipboard_view_remove (GLADE_CLIPBOARD_VIEW (clipboard->view), widget);
 }
 
diff -upr gnome2/glade3/src/glade-clipboard.h glade3/src/glade-clipboard.h
--- gnome2/glade3/src/glade-clipboard.h 2003-05-24 17:41:46.000000000 +0200
+++ glade3/src/glade-clipboard.h        2003-06-02 14:11:21.000000000 +0200
@@ -2,17 +2,21 @@
 #define __GLADE_CLIPBOARD_H__
 
 G_BEGIN_DECLS
+
 #define GLADE_TYPE_CLIPBOARD    (glade_clipboard_get_type ())
 #define GLADE_CLIPBOARD(obj)    (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_CLIPBOARD, GladeClipboard))
 #define GLADE_IS_CLIPBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_CLIPBOARD))
+
 typedef struct _GladeClipboardClass GladeClipboardClass;
 
 struct _GladeClipboard {
        GObject __parent__;
 
        GList *widgets;         /* A list of GladeWidget's on the clipboard */
+
        GladeWidget *curr;      /* The currently selected GladeWidget in the
-                                  Clipboard */
+                                * Clipboard
+                                */
 
        GtkWidget *view;        /* see glade-clipboard-view.c */
 };
@@ -23,14 +27,16 @@ struct _GladeClipboardClass {
 
 
 GType glade_clipboard_get_type ();
+
 GladeClipboard *glade_clipboard_new ();
 
-GladePlaceholder * glade_clipboard_cut    (GladeClipboard * clipboard,
-                                          GladeWidget * widget);
-void               glade_clipboard_copy   (GladeClipboard * clipboard,
-                                          GladeWidget * widget);
-void               glade_clipboard_paste  (GladeClipboard * clipboard,
-                                          GladePlaceholder * placeholder);
+void glade_clipboard_add (GladeClipboard *clipboard, GladeWidget *widget);
+
+void glade_clipboard_add_copy (GladeClipboard *clipboard, GladeWidget *widget);
+
+void glade_clipboard_remove (GladeClipboard *clipboard, GladeWidget *widget);
+
 
 G_END_DECLS
+
 #endif                         /* __GLADE_CLIPBOARD_H__ */
diff -upr gnome2/glade3/src/glade-command.c glade3/src/glade-command.c
--- gnome2/glade3/src/glade-command.c   2003-06-01 11:15:03.000000000 +0200
+++ glade3/src/glade-command.c  2003-06-02 17:04:17.000000000 +0200
@@ -29,6 +29,7 @@
 #include "glade-widget.h"
 #include "glade-widget-class.h"
 #include "glade-command.h"
+#include "glade-packing.h"
 #include "glade-property.h"
 #include "glade-debug.h"
 #include "glade-placeholder.h"
@@ -608,27 +609,20 @@ glade_command_create_execute (GladeComma
        GladeWidget *widget = me->widget;
        GladePlaceholder *placeholder = me->placeholder;
 
-       if (placeholder) {
-               if (widget->parent->class->placeholder_replace)
-                       widget->parent->class->placeholder_replace (GTK_WIDGET (placeholder),
-                                                                   widget->widget,
-                                                                   widget->parent->widget);
-               glade_widget_set_default_packing_options (widget);
-               me->placeholder = NULL;
-       }
+       glade_project_add_widget (widget->project, widget, widget->parent);
+       glade_project_selection_set (widget, TRUE);
 
-       if (widget->parent)
-               widget->parent->children = g_list_prepend (widget->parent->children, widget);
+       if (!GLADE_WIDGET_IS_TOPLEVEL (widget)) {
+               gtk_widget_ref (GTK_WIDGET (placeholder));
 
-       glade_project_selection_clear (widget->project, FALSE);
-       glade_project_add_widget (widget->project, widget);
-
-       if (GTK_IS_WIDGET (widget->widget)) {
-               glade_project_selection_add (widget, TRUE);
-               gtk_widget_show (widget->widget);
+               glade_placeholder_replace_with_widget (placeholder, widget);
+               glade_widget_set_default_packing_options (widget);
        }
 
-       return FALSE;
+       if (GTK_IS_WIDGET (widget->widget))
+               gtk_widget_show_all (widget->widget);
+
+       return TRUE;
 }
 
 static gboolean
@@ -638,19 +632,18 @@ glade_command_delete_execute (GladeComma
 
        g_return_val_if_fail (widget != NULL, TRUE);
 
-       glade_project_selection_remove (widget, TRUE);
-       glade_project_remove_widget (widget);
-
        if (widget->parent != NULL) {
+               /* We ref so that the widget and its children are not destroyed. */
                gtk_widget_ref (widget->widget);
-               me->placeholder = glade_widget_replace_with_placeholder (widget);
-       } else {
-               me->placeholder = NULL;
+
+               me->placeholder = glade_widget_replace_with_placeholder (widget, me->placeholder);
        }
 
        gtk_widget_hide (widget->widget);
 
-       return FALSE;
+       glade_project_remove_widget (widget);
+
+       return TRUE;
 }
 
 /**
@@ -669,6 +662,7 @@ glade_command_create_delete_execute (Gla
                retval = glade_command_delete_execute (me);
 
        me->create = !me->create;
+
        return retval;
 }
 
@@ -676,7 +670,10 @@ static void
 glade_command_create_delete_finalize (GObject *obj)
 {
        GladeCommandCreateDelete *cmd = GLADE_COMMAND_CREATE_DELETE (obj);
+
+       g_object_unref (cmd->placeholder);
        g_object_unref (cmd->widget);
+
         glade_command_finalize (obj);
 }
 
@@ -713,8 +710,8 @@ glade_command_create_delete_common (Glad
 
        g_debug(("Pushing: %s\n", cmd->description));
 
-       glade_command_create_delete_execute (GLADE_COMMAND (me));
-       glade_command_push_undo(widget->project, GLADE_COMMAND (me));
+       if (glade_command_create_delete_execute (GLADE_COMMAND (me)));
+               glade_command_push_undo(widget->project, GLADE_COMMAND (me));
 }
 
 void
@@ -732,7 +729,9 @@ glade_command_delete (GladeWidget *widge
  * from the placeholder).
  */
 void
-glade_command_create (GladeWidgetClass *class, GladePlaceholder *placeholder, GladeProject *project)
+glade_command_create (GladeWidgetClass *class,
+                     GladePlaceholder *placeholder,
+                     GladeProject *project)
 {
        GladeWidget *widget;
        GladeWidget *parent = NULL;
@@ -740,8 +739,7 @@ glade_command_create (GladeWidgetClass *
        g_return_if_fail (GLADE_IS_WIDGET_CLASS (class));
        g_return_if_fail (placeholder != NULL || GLADE_IS_PROJECT (project));
 
-       if (placeholder)
-       {
+       if (placeholder) {
                parent = glade_placeholder_get_parent (placeholder);
                g_return_if_fail (parent != NULL);
        }
@@ -786,9 +784,36 @@ glade_command_cut_paste_undo (GladeComma
 static gboolean
 glade_command_paste_execute (GladeCommandCutPaste *me)
 {
-       glade_clipboard_paste (me->clipboard, me->placeholder);
+       GladeWidget *widget = me->widget;
+       GladePlaceholder *placeholder = me->placeholder;
+       GladeWidget *parent;
+       GladeProject *project;
+
+       g_return_val_if_fail (g_list_find (me->clipboard->widgets, widget), TRUE);
+
+       parent = glade_placeholder_get_parent (placeholder);
+       project = parent->project;
+
+       widget->name = glade_widget_new_name (project, widget->class);
+       glade_packing_add_properties (widget);
+
+       glade_widget_set_contents (widget);
+       glade_widget_connect_signals (widget);
 
-       me->placeholder = NULL;
+       if (!GLADE_WIDGET_IS_TOPLEVEL (widget)) {
+               gtk_widget_ref (GTK_WIDGET (placeholder));
+
+               glade_placeholder_replace_with_widget (placeholder, widget);
+               glade_widget_set_default_packing_options (widget);
+       }
+
+       glade_project_add_widget (project, widget, parent);
+       glade_project_selection_set (widget, TRUE);
+
+       if (GTK_IS_WIDGET (widget->widget))
+               gtk_widget_show_all (GTK_WIDGET (widget->widget));
+
+       glade_clipboard_remove (me->clipboard, widget);
 
        return TRUE;
 }
@@ -796,7 +821,22 @@ glade_command_paste_execute (GladeComman
 static gboolean
 glade_command_cut_execute (GladeCommandCutPaste *me)
 {
-       me->placeholder = glade_clipboard_cut (me->clipboard, me->widget);
+       GladeWidget *widget = me->widget;
+
+       g_return_val_if_fail (widget != NULL, TRUE);
+
+       glade_clipboard_add (me->clipboard, widget);
+
+       if (widget->parent != NULL){
+               /* We ref so that the widget and its children are not destroyed. */
+               gtk_widget_ref (GTK_WIDGET (widget->widget));
+
+               me->placeholder = glade_widget_replace_with_placeholder (widget, me->placeholder);
+       }
+
+       gtk_widget_hide (widget->widget);
+
+       glade_project_remove_widget (widget);
 
        return TRUE;
 }
@@ -810,13 +850,14 @@ glade_command_cut_paste_execute (GladeCo
 {
        GladeCommandCutPaste *me = (GladeCommandCutPaste *) cmd;
        gboolean retval;
-       
+
        if (me->cut)
                retval = glade_command_cut_execute (me);
        else
                retval = glade_command_paste_execute (me);
 
        me->cut = !me->cut;
+
        return retval;
 }
 
@@ -825,10 +866,8 @@ glade_command_cut_paste_finalize (GObjec
 {
        GladeCommandCutPaste *cmd = GLADE_COMMAND_CUT_PASTE (obj);
 
-       /* if a pasted item has been undoed, and now we have to forget about it,
-        * then we should free the pasted widget (as nobody is going to use it anymore) */
-       if (!cmd->cut)
-               g_object_unref (cmd->widget);
+       g_object_unref (cmd->widget);
+       g_object_unref (cmd->placeholder);
 
        glade_command_finalize (obj);
 }
@@ -848,26 +887,25 @@ glade_command_cut_paste_collapse (GladeC
 static void
 glade_command_cut_paste_common (GladeWidget *widget,
                                GladePlaceholder *placeholder,
+                               GladeProject *project,
                                gboolean cut)
 {
        GladeCommandCutPaste *me;
        GladeCommand *cmd;
-       GladeProject *project;
        GladeProjectWindow *gpw;
 
        me = (GladeCommandCutPaste *) g_object_new (GLADE_COMMAND_CUT_PASTE_TYPE, NULL);
        cmd = (GladeCommand *) me;
        
-       project = glade_project_window_get_project ();
        gpw = glade_project_window_get ();
 
        me->cut = cut;
        me->widget = widget;
        me->placeholder = placeholder;
        me->clipboard = gpw->clipboard;
-       
+
        cmd->description = g_strdup_printf (_("%s %s"), cut ? "Cut" : "Paste", widget->name);
-       
+
        g_debug(("Pushing: %s\n", cmd->description));
 
        /*
@@ -878,13 +916,39 @@ glade_command_cut_paste_common (GladeWid
 }
 
 void
-glade_command_paste (GladeWidget *widget, GladePlaceholder *placeholder)
+glade_command_paste (GladePlaceholder *placeholder)
 {
-       glade_command_cut_paste_common (widget, placeholder, FALSE);
+       GladeProjectWindow *gpw;
+       GladeWidget *widget;
+       GladeWidget *parent;
+
+       if (placeholder == NULL) {
+               glade_util_ui_warn (_("Placeholder not selected!"));
+               return;
+       }
+
+       g_return_if_fail (glade_placeholder_is (placeholder));
+       
+       gpw = glade_project_window_get ();
+       widget = gpw->clipboard->curr;
+
+       if (widget == NULL)
+               return;
+
+       parent = glade_placeholder_get_parent (placeholder);
+
+       glade_command_cut_paste_common (widget, placeholder, parent->project, FALSE);
 }
 
 void
 glade_command_cut (GladeWidget *widget)
 {
-       glade_command_cut_paste_common (widget, NULL, TRUE);
+       if (widget == NULL) {
+               glade_util_ui_warn (_("No widget selected!"));
+               return;
+       }
+
+       g_return_if_fail (GLADE_IS_WIDGET (widget));
+
+       glade_command_cut_paste_common (widget, NULL, widget->project, TRUE);
 }
diff -upr gnome2/glade3/src/glade-command.h glade3/src/glade-command.h
--- gnome2/glade3/src/glade-command.h   2003-06-01 11:15:03.000000000 +0200
+++ glade3/src/glade-command.h  2003-06-02 11:11:04.000000000 +0200
@@ -19,7 +19,7 @@ void glade_command_delete (GladeWidget *
 void glade_command_create (GladeWidgetClass *class, GladePlaceholder *placeholder, GladeProject *project);
 
 void glade_command_cut   (GladeWidget *widget);
-void glade_command_paste (GladeWidget *widget, GladePlaceholder *placeholder);
+void glade_command_paste (GladePlaceholder *placeholder);
 
 G_END_DECLS
 

diff -upr gnome2/glade3/src/glade-placeholder.c glade3/src/glade-placeholder.c
--- gnome2/glade3/src/glade-placeholder.c       2003-06-01 11:15:03.000000000 +0200
+++ glade3/src/glade-placeholder.c      2003-06-02 16:17:49.000000000 +0200
@@ -245,8 +245,7 @@ glade_placeholder_on_button_press_event 
                                         gpointer not_used)
 {
        GladeProjectWindow *gpw = glade_project_window_get ();
-       GladeProject *project = glade_project_window_get_project (gpw);
-       
+
        if (event->button == 1 && event->type == GDK_BUTTON_PRESS) {
 
                if (gpw->add_class != NULL) {
@@ -369,8 +368,7 @@ glade_placeholder_new ()
 
 #undef GLADE_PLACEHOLDER_SIZE
 
-void glade_placeholder_add (GladeWidgetClass *class,
-                           GladeWidget *widget)
+void glade_placeholder_add (GladeWidgetClass *class, GladeWidget *widget)
 {
 
        if (GLADE_WIDGET_CLASS_TOPLEVEL (class)) {
@@ -389,10 +387,11 @@ void glade_placeholder_add (GladeWidgetC
 
 }
 
-
 GladeWidget *
 glade_placeholder_get_parent (GladePlaceholder *placeholder)
 {
+       g_return_val_if_fail (glade_placeholder_is (placeholder), NULL);
+
        GladeWidget *parent = NULL;
        GtkWidget *widget = gtk_widget_get_parent (placeholder);
 
@@ -409,75 +408,26 @@ glade_placeholder_get_parent (GladePlace
 }
 
 void
-glade_placeholder_replace (GladePlaceholder *placeholder, GladeWidget *parent, GladeWidget *child)
+glade_placeholder_replace_with_widget (GladePlaceholder *placeholder,
+                                      GladeWidget *widget)
 {
-       g_return_if_fail (GTK_IS_WIDGET (placeholder));
-       
+       GladeWidget *parent;
+
+       g_return_if_fail (glade_placeholder_is (placeholder));
+       g_return_if_fail (GLADE_IS_WIDGET (widget));
+
+       parent = glade_placeholder_get_parent (placeholder);
+
        if (parent->class->placeholder_replace != NULL)
-               parent->class->placeholder_replace (GTK_WIDGET (placeholder), child->widget, parent->widget);
+               parent->class->placeholder_replace (GTK_WIDGET (placeholder),
+                                                   widget->widget,
+                                                   parent->widget);
        else
                g_warning ("Could not replace a placeholder because a replace "
                           " function has not been implemented for \"%s\"\n",
                           parent->class->name);
 }
 
-
-
-GladePlaceholder *
-glade_placeholder_get_from_properties (GladeWidget *parent,
-                                      GHashTable *properties)
-{
-       GladePlaceholder *placeholder = NULL;
-       GList *list;
-
-       if (glade_widget_class_is (parent->class, "GtkVBox") ||
-           glade_widget_class_is (parent->class, "GtkHBox")) {
-               GtkBoxChild *box_child;
-               const gchar *val;
-               
-               list = gtk_container_children (GTK_CONTAINER (parent->widget));
-               val = g_hash_table_lookup (properties, "position");
-               if (!val)
-                       return NULL;
-
-               box_child = (GtkBoxChild *) g_list_nth (list, atoi (val));
-               placeholder = box_child->widget;
-               g_assert (placeholder);
-       } else if (glade_widget_class_is (parent->class, "GtkTable")) {
-               GtkTableChild *child;
-               const char *val;
-               int col;
-               int row;
-
-               val = g_hash_table_lookup (properties, "cell_x");
-               if (!val)
-                       return NULL;
-
-               col = atoi (val);
-               val = g_hash_table_lookup (properties, "cell_y");
-               if (!val)
-                       return NULL;
-
-               row = atoi (val);
-
-               list = GTK_TABLE (parent->widget)->children;
-               for (; list; list = list->next) {
-                       child = list->data;
-                       if ((child->left_attach == col) &&
-                           (child->top_attach  == row)) {
-                               placeholder = child->widget;
-                               break;
-                       }
-               }
-       } else if (glade_widget_class_is (parent->class, "GtkWindow")) {
-               placeholder = GTK_BIN (parent->widget)->child;
-       } else {
-               glade_implement_me ();
-       }
-
-       return placeholder;
-}
-
 gboolean
 glade_placeholder_is (GtkWidget *widget)
 {
@@ -493,117 +443,3 @@ glade_placeholder_is (GtkWidget *widget)
        return is;
 }
 
-
-void
-glade_placeholder_remove_all (GtkWidget *widget)
-{
-       GladeWidget *gwidget, *child_widget;
-       
-       
-       gwidget = glade_widget_get_from_gtk_widget (widget);
-       g_return_if_fail (widget != NULL);
-       
-       if (glade_widget_class_is (gwidget->class, "GtkVBox") ||
-           glade_widget_class_is (gwidget->class, "GtkHBox")) {
-               GList *element;
-               GtkBox *box;
-               GtkBoxChild *box_child;
-
-               box = GTK_BOX (widget);
-               
-               element = g_list_first (box->children);
-               while (element != NULL) {
-                       box_child = element->data;
-                       if (glade_placeholder_is (box_child->widget)) {
-                               child_widget = glade_widget_get_from_gtk_widget (box_child->widget);
-                               if (child_widget)
-                                       glade_command_delete (child_widget);
-                               gtk_container_remove (GTK_CONTAINER (box),
-                                                     box_child->widget);
-                               element = g_list_first (box->children);
-                       } else {
-                               element = g_list_next (element);
-                       }               
-               }
-       } else if (glade_widget_class_is (gwidget->class, "GtkDialog")) {
-               GList *element;
-               GtkBox *box;
-               GtkBoxChild *box_child;
-               gint i;
-
-               box = GTK_BOX (GTK_DIALOG (widget)->vbox);
-               for (i = 0; i < 2; i++) {
-                       
-                       element = g_list_first (box->children);
-                       
-                       while (element != NULL) {
-                               box_child = element->data;
-                               if (glade_placeholder_is (box_child->widget)) {
-                                       child_widget = glade_widget_get_from_gtk_widget (box_child->widget);
-                                       if (child_widget)
-                                               glade_command_delete (child_widget);
-                                       gtk_container_remove (GTK_CONTAINER (box),
-                                       box_child->widget);
-                                       element = g_list_first (box->children);
-                               } else {
-                                       element = g_list_next (element);
-                               }
-                       }
-                       box = GTK_BOX (GTK_DIALOG (widget)->action_area);
-               }
-       } else if (glade_widget_class_is (gwidget->class, "GtkTable")) {
-               GList *element;
-               GtkTableChild *table_child;
-
-               element = g_list_first (GTK_TABLE (widget)->children);
-               while (element != NULL) {
-                       table_child = element->data;
-                       if (glade_placeholder_is (table_child->widget)) {
-                               child_widget = glade_widget_get_from_gtk_widget (table_child->widget);
-                               if (child_widget)
-                                       glade_command_delete (child_widget);
-                               gtk_container_remove (GTK_CONTAINER (widget),
-                                                     table_child->widget);
-                               element = g_list_first (GTK_TABLE (widget)->children);
-                       } else {
-                               element = g_list_next (element);
-                       }
-               }
-       } else {
-               glade_implement_me ();
-       }
-
-}
-
-void
-glade_placeholder_fill_empty (GtkWidget *widget)
-{
-       GList *children;
-       gboolean empty = TRUE;
-
-       if (!GTK_IS_CONTAINER (widget))
-               return;
-       
-       /* fill with placeholders the containers that are inside of this container */
-       children = gtk_container_get_children (GTK_CONTAINER (widget));
-
-       /* loop over the children of this container, and fill them with placeholders */
-       while (children != NULL) {
-               glade_placeholder_fill_empty (GTK_WIDGET (children->data));
-               children = children->next;
-               empty = FALSE;
-       }
-
-       if (empty) {
-               /* retrieve the desired number of placeholders that this widget should hold */
-               int nb_children = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), 
"glade_nb_placeholders"));
-               int i;
-
-               if (nb_children == 0 && GTK_IS_BIN (widget))
-                       nb_children = 1;
-
-               for (i = nb_children; i > 0; i--)
-                       gtk_container_add (GTK_CONTAINER (widget), glade_placeholder_new ());
-       }
-}
-
diff -upr gnome2/glade3/src/glade-placeholder.h glade3/src/glade-placeholder.h
--- gnome2/glade3/src/glade-placeholder.h       2003-05-24 17:41:46.000000000 +0200
+++ glade3/src/glade-placeholder.h      2003-06-02 16:10:38.000000000 +0200
@@ -17,9 +17,8 @@ GladeWidget * glade_placeholder_get_pare
 
 void glade_placeholder_add_methods_to_class (GladeWidgetClass *class);
 
-void glade_placeholder_replace (GladePlaceholder *placeholder,
-                               GladeWidget *parent,
-                               GladeWidget *child);
+void glade_placeholder_replace_with_widget (GladePlaceholder *placeholder,
+                                           GladeWidget *widget);
 
 GladePlaceholder * glade_placeholder_get_from_properties (GladeWidget *parent,
                                                          GHashTable *properties);
@@ -30,7 +29,6 @@ gboolean glade_placeholder_is (GtkWidget
 
 void glade_placeholder_remove_all (GtkWidget *widget);
 
-void glade_placeholder_fill_empty (GtkWidget *widget);
 
 G_END_DECLS
 
diff -upr gnome2/glade3/src/glade-popup.c glade3/src/glade-popup.c
--- gnome2/glade3/src/glade-popup.c     2003-05-24 17:41:46.000000000 +0200
+++ glade3/src/glade-popup.c    2003-06-02 15:41:41.000000000 +0200
@@ -47,7 +47,7 @@ glade_popup_copy_cb (GtkMenuItem *item, 
        GladeProjectWindow *gpw;
 
        gpw = glade_project_window_get ();
-       glade_clipboard_copy (gpw->clipboard, widget);
+       glade_clipboard_add_copy (gpw->clipboard, widget);
 }
 
 static void
@@ -70,10 +70,7 @@ static void
 glade_popup_placeholder_paste_cb (GtkMenuItem *item,
                                  GladePlaceholder *placeholder)
 {
-       GladeProjectWindow *gpw = glade_project_window_get ();
-
-       if (gpw->clipboard->curr)
-               glade_command_paste (gpw->clipboard->curr, placeholder);
+       glade_command_paste (placeholder);
 }
 
 static void
diff -upr gnome2/glade3/src/glade-project.c glade3/src/glade-project.c
--- gnome2/glade3/src/glade-project.c   2003-05-24 17:41:46.000000000 +0200
+++ glade3/src/glade-project.c  2003-06-02 16:24:36.000000000 +0200
@@ -154,35 +154,50 @@ static void
 glade_project_add_widget_real (GladeProject *project,
                               GladeWidget *widget)
 {
-       GladeWidget *child;
-       GList *list;
-
        widget->project = project;
 
-       /*
-        * Add all the children as well.
-        */
-       list = widget->children;
-       for (; list; list = list->next) {
-               child = list->data;
-               glade_project_add_widget_real (project, child);
-               child->project = project;
-       }
-       
        project->widgets = g_list_prepend (project->widgets, widget);
 
        gtk_signal_emit (GTK_OBJECT (project),
                         glade_project_signals [ADD_WIDGET], widget);
 }
 
+/**
+ * glade_project_add_widget:
+ * @project: the project the widget is added to
+ * @widget: the GladeWidget to add
+ * @parent: the GladeWidget @widget is reparented to
+ *
+ * Adds a widget to the project. Parent should be NULL for toplevels.
+ **/
 void
 glade_project_add_widget (GladeProject *project,
-                         GladeWidget  *widget)
+                         GladeWidget *widget,
+                         GladeWidget *parent)
 {
+       GladeWidget *child;
+       GList *list;
+
        g_return_if_fail (GLADE_IS_PROJECT (project));
-       g_return_if_fail (GTK_IS_OBJECT (project));
+       g_return_if_fail (GLADE_IS_WIDGET (widget));
 
        glade_project_add_widget_real (project, widget);
+       widget->parent = parent;
+
+       /* Add all the children as well */
+       for (list = widget->children; list; list = list->next) {
+               child = list->data;
+               glade_project_add_widget_real (project, child);
+       }
+
+       /* reparent */
+       if (parent) {
+               g_return_if_fail (GLADE_IS_WIDGET (parent));
+
+               widget->parent = parent;
+               parent->children = g_list_prepend (parent->children, widget);
+       }
+
        project->changed = TRUE;
 }
 
@@ -207,8 +222,9 @@ glade_project_remove_widget_real (GladeP
        }
        
        project->selection = g_list_remove (project->selection, widget);
-       project->widgets   = g_list_remove (project->widgets, widget);
+       glade_project_selection_changed (project);
 
+       project->widgets   = g_list_remove (project->widgets, widget);
        gtk_signal_emit (GTK_OBJECT (project),
                         glade_project_signals [REMOVE_WIDGET], widget);
 }
@@ -223,7 +239,7 @@ glade_project_remove_widget (GladeWidget
        project = widget->project;
 
        glade_project_remove_widget_real (project, widget);
-       glade_project_selection_changed (project);
+
        project->changed = TRUE;
 }
        
diff -upr gnome2/glade3/src/glade-project.h glade3/src/glade-project.h
--- gnome2/glade3/src/glade-project.h   2003-05-24 17:41:46.000000000 +0200
+++ glade3/src/glade-project.h  2003-06-01 21:25:47.000000000 +0200
@@ -67,7 +67,8 @@ gboolean glade_project_save (GladeProjec
 /* Widget related stuff */
 void glade_project_remove_widget (GladeWidget *widget);
 void glade_project_add_widget (GladeProject  *project,
-                              GladeWidget *glade_widget);
+                              GladeWidget *widget,
+                              GladeWidget *parent);
 
 GladeWidget *glade_project_get_widget_by_name (GladeProject *project, const char *name);
 char *glade_project_new_widget_name (GladeProject *project, const char *base_name);
diff -upr gnome2/glade3/src/glade-project-window.c glade3/src/glade-project-window.c
--- gnome2/glade3/src/glade-project-window.c    2003-06-01 11:15:03.000000000 +0200
+++ glade3/src/glade-project-window.c   2003-06-02 14:28:19.000000000 +0200
@@ -349,7 +349,7 @@ gpw_copy_cb (void)
        widget = gpw->active_widget;
 
        if (widget)
-               glade_clipboard_copy (gpw->clipboard, widget);
+               glade_clipboard_add_copy (gpw->clipboard, widget);
 }
 
 static void
@@ -371,7 +371,8 @@ gpw_paste_cb (void)
        GladeProjectWindow *gpw;
 
        gpw = glade_project_window_get ();
-       glade_command_paste (gpw->active_widget, gpw->active_placeholder);
+       
+       glade_command_paste (gpw->active_placeholder);
 }
 
 static void
diff -upr gnome2/glade3/src/glade-widget.c glade3/src/glade-widget.c
--- gnome2/glade3/src/glade-widget.c    2003-06-01 11:15:04.000000000 +0200
+++ glade3/src/glade-widget.c   2003-06-02 16:48:47.000000000 +0200
@@ -802,19 +802,45 @@ glade_widget_new_full (GladeWidgetClass 
 
        glade_packing_add_properties (widget);
        glade_widget_create_gtk_widget (widget);
-       /*
-       glade_project_add_widget (project, widget);
 
-       if (parent)
-               parent->children = g_list_prepend (parent->children, widget);
-       */
-       
        glade_widget_set_contents (widget);
        glade_widget_connect_signals (widget);
 
        return widget;
 }
 
+static void
+glade_widget_fill_empty (GtkWidget *widget)
+{
+       GList *children;
+       gboolean empty = TRUE;
+
+       if (!GTK_IS_CONTAINER (widget))
+               return;
+       
+       /* fill with placeholders the containers that are inside of this container */
+       children = gtk_container_get_children (GTK_CONTAINER (widget));
+
+       /* loop over the children of this container, and fill them with placeholders */
+       while (children != NULL) {
+               glade_widget_fill_empty (GTK_WIDGET (children->data));
+               children = children->next;
+               empty = FALSE;
+       }
+
+       if (empty) {
+               /* retrieve the desired number of placeholders that this widget should hold */
+               int nb_children = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), 
"glade_nb_placeholders"));
+               int i;
+
+               if (nb_children == 0 && GTK_IS_BIN (widget))
+                       nb_children = 1;
+
+               for (i = nb_children; i > 0; i--)
+                       gtk_container_add (GTK_CONTAINER (widget), glade_placeholder_new ());
+       }
+}
+
 static GtkWidget *
 glade_widget_append_query (GtkWidget *table,
                           GladePropertyClass *property_class,
@@ -1004,7 +1030,7 @@ glade_widget_new_from_class (GladeWidget
 
        /* If we are a container, add the placeholders */
        if (g_type_is_a (class->type,  GTK_TYPE_CONTAINER))
-               glade_placeholder_fill_empty (widget->widget);
+               glade_widget_fill_empty (widget->widget);
        
        if (result) 
                glade_property_query_result_destroy (result);
@@ -1197,19 +1223,30 @@ glade_widget_clone (GladeWidget *widget)
        return clone;
 }
 
+/**
+ * glade_widget_replace_with_placeholder:
+ * @widget:
+ * @placeholder:
+ *
+ * Replaces @widget with @placeholder. If @placeholder is NULL a new one is created.
+ **/
 GladePlaceholder *
-glade_widget_replace_with_placeholder (GladeWidget *widget)
+glade_widget_replace_with_placeholder (GladeWidget *widget, GladePlaceholder *placeholder)
 {
-       GladePlaceholder *placeholder;
-       GladeWidget *parent = widget->parent;
+       g_return_val_if_fail (GLADE_IS_WIDGET (widget), NULL);
+
+       if (placeholder == NULL)
+               placeholder = glade_placeholder_new (widget->parent);
+       else
+               g_return_val_if_fail (glade_placeholder_is (placeholder), NULL);
 
-       /* Replace the slot it was occuping with a placeholder */
-       placeholder = glade_placeholder_new (widget->parent);
        if (widget->parent->class->placeholder_replace)
-               widget->parent->class->placeholder_replace (widget->widget, GTK_WIDGET (placeholder), 
widget->parent->widget);
+               widget->parent->class->placeholder_replace (widget->widget,
+                                                           GTK_WIDGET (placeholder),
+                                                           widget->parent->widget);
 
        /* Remove it from the parent's child list */
-       parent->children = g_list_remove (parent->children, widget);
+       widget->parent->children = g_list_remove (widget->parent->children, widget);
 
        /* Return the placeholder, if some one needs it, he can use it. */
        return placeholder;
@@ -1444,7 +1481,9 @@ glade_widget_apply_properties_from_hash 
 }
 
 static gboolean
-glade_widget_new_child_from_node (GladeXmlNode *node, GladeProject *project, GladeWidget *parent)
+glade_widget_new_child_from_node (GladeXmlNode *node,
+                                 GladeProject *project,
+                                 GladeWidget *parent)
 {
        GladeXmlNode *child_node;
        GladeXmlNode *child_properties;
@@ -1529,7 +1568,7 @@ glade_widget_new_child_from_node (GladeX
                g_value_unset (&string_value);
        }
        
-       glade_placeholder_fill_empty (parent->widget);
+       glade_widget_fill_empty (parent->widget);
 
        return TRUE;
 }
diff -upr gnome2/glade3/src/glade-widget.h glade3/src/glade-widget.h
--- gnome2/glade3/src/glade-widget.h    2003-06-01 11:15:04.000000000 +0200
+++ glade3/src/glade-widget.h   2003-06-02 14:16:06.000000000 +0200
@@ -90,8 +90,9 @@ void glade_widget_flag_unselected (Glade
 void glade_widget_select (GladeWidget *widget);
 
 GladeWidget *glade_widget_clone (GladeWidget *widget);
-GladePlaceholder * glade_widget_replace_with_placeholder (GladeWidget *widget);
-GladeWidget * glade_widget_get_from_gtk_widget (GtkWidget *widget);
+GladePlaceholder *glade_widget_replace_with_placeholder (GladeWidget *widget,
+                                                        GladePlaceholder *placeholder);
+GladeWidget *glade_widget_get_from_gtk_widget (GtkWidget *widget);
 
 /* Xml saving & reading */
 GladeXmlNode * glade_widget_write (GladeXmlContext *context, GladeWidget *widget);

--=-fmv3iiV5JUiwk9XxnnSG--





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]