diff options
author | Tristan Van Berkom <tvb@src.gnome.org> | 2004-12-30 08:39:40 +0000 |
---|---|---|
committer | Tristan Van Berkom <tvb@src.gnome.org> | 2004-12-30 08:39:40 +0000 |
commit | 5a6fe7e3af1e0b53339ea123e034ad4f1841a658 (patch) | |
tree | 9afd5be7af60a1c1cc9ffbeeb9a1fa038a1c1735 | |
parent | 5f89e75bd38229ddbf8ae176560b13591822d876 (diff) | |
download | glade-5a6fe7e3af1e0b53339ea123e034ad4f1841a658.tar.gz |
Multiple widgets in Cut/Copy/Paste/Delete commands
* src/glade-command.[ch]: Multiple widgets in Cut/Copy/Paste/Delete commands
* src/glade-placeholder.c: Changed callers.
* src/glade-popup.c, src/glade-project-window.c: Use glade-utils for
Cut/Copy/Paste/Delete
* src/glade-project-view.[ch]: Implemented multiple selection.
* src/glade-project.[ch]: Implemented glade_project_is_selected.
* src/glade-utils.[ch]: Implemented: glade_util_paste_clipboard (),
glade_util_cut_selection (), glade_util_copy_selection () and
glade_util_delete_selection ().
* src/glade-widget.c: Implemented multiple selection.
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | src/glade-command.c | 595 | ||||
-rw-r--r-- | src/glade-command.h | 43 | ||||
-rw-r--r-- | src/glade-placeholder.c | 5 | ||||
-rw-r--r-- | src/glade-popup.c | 92 | ||||
-rw-r--r-- | src/glade-project-view.c | 101 | ||||
-rw-r--r-- | src/glade-project-view.h | 3 | ||||
-rw-r--r-- | src/glade-project-window.c | 90 | ||||
-rw-r--r-- | src/glade-project.c | 23 | ||||
-rw-r--r-- | src/glade-project.h | 3 | ||||
-rw-r--r-- | src/glade-signal-editor.c | 1 | ||||
-rw-r--r-- | src/glade-utils.c | 190 | ||||
-rw-r--r-- | src/glade-utils.h | 9 | ||||
-rw-r--r-- | src/glade-widget.c | 69 |
14 files changed, 704 insertions, 539 deletions
@@ -1,5 +1,24 @@ 2004-12-29 Tristan Van Berkom <tvb@cvs.gnome.org> + * src/glade-command.[ch]: Multiple widgets in Cut/Copy/Paste/Delete commands + + * src/glade-placeholder.c: Changed callers. + + * src/glade-popup.c, src/glade-project-window.c: Use glade-utils for + Cut/Copy/Paste/Delete + + * src/glade-project-view.[ch]: Implemented multiple selection. + + * src/glade-project.[ch]: Implemented glade_project_is_selected. + + * src/glade-utils.[ch]: Implemented: glade_util_paste_clipboard (), + glade_util_cut_selection (), glade_util_copy_selection () and + glade_util_delete_selection (). + + * src/glade-widget.c: Implemented multiple selection. + +2004-12-29 Tristan Van Berkom <tvb@cvs.gnome.org> + * src/glade-project-view.c: Selection on treeview now follows project->selection. diff --git a/src/glade-command.c b/src/glade-command.c index cdb5fc3c..08220421 100644 --- a/src/glade-command.c +++ b/src/glade-command.c @@ -40,6 +40,12 @@ #include "glade.h" +typedef struct { + GladeWidget *widget; + GladeWidget *parent; + GladePlaceholder *placeholder; +} CommandData; + static GObjectClass* parent_class = NULL; #define MAKE_TYPE(func, type, parent) \ @@ -75,7 +81,8 @@ glade_command_finalize (GObject *obj) GladeCommand *cmd = (GladeCommand *) obj; g_return_if_fail (cmd != NULL); - g_free (cmd->description); + if (cmd->description) + g_free (cmd->description); /* Call the base class dtor */ (* G_OBJECT_CLASS (parent_class)->finalize) (obj); @@ -325,8 +332,6 @@ glade_command_set_property_finalize (GObject *obj) { GladeCommandSetProperty *me; - g_return_if_fail (GLADE_IS_COMMAND_SET_PROPERTY (obj)); - me = GLADE_COMMAND_SET_PROPERTY (obj); if (G_VALUE_TYPE (me->arg_value) != 0) @@ -549,12 +554,9 @@ glade_command_set_name (GladeWidget *widget, const gchar* name) **************************************************/ typedef struct { - GladeCommand parent; - - GladeWidget *parent_widget; - GladeWidget *widget; - GladePlaceholder *placeholder; + GladeCommand parent; + GList *widgets; gboolean create; } GladeCommandCreateDelete; @@ -574,29 +576,39 @@ glade_command_create_delete_undo (GladeCommand *cmd) static gboolean glade_command_create_execute (GladeCommandCreateDelete *me) { - GladeWidget *widget = me->widget; - GladeWidget *parent = me->parent_widget; - GladePlaceholder *placeholder = me->placeholder; + CommandData *cdata; + GList *list; - if (parent) + for (list = me->widgets; list && list->data; list = list->next) { - if (placeholder) - glade_widget_replace - (parent, G_OBJECT (placeholder), widget->object); - else - { - glade_widget_class_container_add (parent->widget_class, - parent->object, - widget->object); - glade_widget_set_parent (widget, parent); - } + cdata = list->data; + + if (cdata->parent) + { + if (cdata->placeholder) + { + glade_widget_replace + (cdata->parent, + G_OBJECT (cdata->placeholder), + cdata->widget->object); + } + else + { + glade_widget_class_container_add + (cdata->parent->widget_class, + cdata->parent->object, + cdata->widget->object); + glade_widget_set_parent (cdata->widget, cdata->parent); + } } - glade_project_add_object (widget->project, widget->object); - glade_project_selection_set (widget->project, widget->object, TRUE); + glade_project_add_object (cdata->widget->project, cdata->widget->object); + glade_project_selection_set (cdata->widget->project, cdata->widget->object, TRUE); + + if (GTK_IS_WIDGET (cdata->widget->object)) + gtk_widget_show_all (GTK_WIDGET (cdata->widget->object)); - if (GTK_IS_WIDGET (widget->object)) - gtk_widget_show_all (GTK_WIDGET (widget->object)); + } return TRUE; } @@ -604,28 +616,33 @@ glade_command_create_execute (GladeCommandCreateDelete *me) static gboolean glade_command_delete_execute (GladeCommandCreateDelete *me) { - GladeWidget *widget = me->widget; - GladeWidget *parent = me->parent_widget; + CommandData *cdata; + GList *list; - g_return_val_if_fail (widget != NULL, TRUE); - - parent = glade_widget_get_parent (widget); - if (parent) + for (list = me->widgets; list && list->data; list = list->next) { - if (me->placeholder) - glade_widget_replace - (parent, widget->object, G_OBJECT (me->placeholder)); - else - glade_widget_class_container_remove (parent->widget_class, - parent->object, - widget->object); - } + cdata = list->data; - if (GTK_IS_WIDGET (widget->object)) - gtk_widget_hide (GTK_WIDGET (widget->object)); + if (cdata->parent) + { + if (cdata->placeholder) + { + glade_widget_replace + (cdata->parent, cdata->widget->object, + G_OBJECT (cdata->placeholder)); + } + else + glade_widget_class_container_remove (cdata->parent->widget_class, + cdata->parent->object, + cdata->widget->object); + } - glade_project_remove_object (widget->project, widget->object); + glade_project_remove_object (cdata->widget->project, cdata->widget->object); + if (GTK_IS_WIDGET (cdata->widget->object)) + gtk_widget_hide (GTK_WIDGET (cdata->widget->object)); + + } return TRUE; } @@ -653,15 +670,24 @@ static void glade_command_create_delete_finalize (GObject *obj) { GladeCommandCreateDelete *cmd; + CommandData *cdata; + GList *list; g_return_if_fail (GLADE_IS_COMMAND_CREATE_DELETE (obj)); cmd = GLADE_COMMAND_CREATE_DELETE (obj); - if (cmd->placeholder) - g_object_unref (cmd->placeholder); + for (list = cmd->widgets; list && list->data; list = list->next) + { + cdata = list->data; + + if (cdata->placeholder) + g_object_unref (G_OBJECT (cdata->placeholder)); - g_object_unref (cmd->widget); + if (cdata->widget) + g_object_unref (G_OBJECT (cdata->widget)); + } + g_list_free (cmd->widgets); glade_command_finalize (obj); } @@ -679,57 +705,66 @@ glade_command_create_delete_collapse (GladeCommand *this, GladeCommand *other) } /** - * Placeholder arg may be NULL for toplevel widgets - */ -static void -glade_command_create_delete_common (GladeWidget *widget, - GladeWidget *parent, - GladePlaceholder *placeholder, - gboolean create) -{ - GladeCommandCreateDelete *me; - GladeCommand *cmd; - - me = g_object_new (GLADE_COMMAND_CREATE_DELETE_TYPE, NULL); - cmd = GLADE_COMMAND (me); - - me->widget = g_object_ref(widget); - me->create = create; - me->placeholder = placeholder; - me->parent_widget = parent; - cmd->description = - g_strdup_printf (_("%s %s"), create ? - "Create" : "Delete", widget->name); - - if (placeholder) - g_object_ref (G_OBJECT (placeholder)); - - if (glade_command_create_delete_execute (GLADE_COMMAND (me))) - glade_command_push_undo (widget->project, GLADE_COMMAND (me)); - else - g_object_unref (G_OBJECT (me)); -} - -/** * glade_command_delete: * @widget: a #GladeWidget * * TODO: write me */ void -glade_command_delete (GladeWidget *widget) +glade_command_delete (GList *widgets) { - g_return_if_fail (GLADE_IS_WIDGET (widget)); + GladeCommandCreateDelete *me; + GladeWidget *widget; + CommandData *cdata; + GList *list; + + me = g_object_new (GLADE_COMMAND_CREATE_DELETE_TYPE, NULL); + me->create = FALSE; /* internal children cannot be deleted. Notify the user. */ - if (widget->internal) + for (list = widgets; list && list->data; list = list->next) { - glade_util_ui_warn (glade_project_window_get()->window, _("You cannot delete a widget internal to a composite widget.")); - return; + widget = list->data; + if (widget->internal) + { + glade_util_ui_warn (glade_project_window_get()->window, + _("You cannot delete a widget internal to a composite widget.")); + return; + } } - glade_command_create_delete_common (widget, glade_widget_get_parent (widget), - NULL, FALSE); + for (list = widgets; list && list->data; list = list->next) + { + widget = list->data; + + cdata = g_new0 (CommandData, 1); + cdata->widget = g_object_ref (G_OBJECT (widget)); + cdata->parent = glade_widget_get_parent (widget); + + if (cdata->parent != NULL && + glade_util_gtkcontainer_relation + (cdata->parent, cdata->widget)) + { + cdata->placeholder = + GLADE_PLACEHOLDER (glade_placeholder_new ()); + g_object_ref (G_OBJECT (cdata->placeholder)); + gtk_object_sink (GTK_OBJECT (cdata->placeholder)); + } + me->widgets = g_list_append (me->widgets, cdata); + } + + if (g_list_length (widgets) == 1) + GLADE_COMMAND (me)->description = + g_strdup_printf (_("Delete %s"), + GLADE_WIDGET (widgets->data)->name); + else + GLADE_COMMAND (me)->description = + g_strdup_printf (_("Delete multiple")); + + if (glade_command_create_delete_execute (GLADE_COMMAND (me))) + glade_command_push_undo (widget->project, GLADE_COMMAND (me)); + else + g_object_unref (G_OBJECT (me)); } /** @@ -747,37 +782,40 @@ glade_command_create (GladeWidgetClass *class, GladePlaceholder *placeholder, GladeProject *project) { - GladeProjectWindow *gpw = glade_project_window_get (); - GladeWidget *widget; - - g_return_if_fail (GLADE_IS_WIDGET_CLASS (class)); + GladeCommandCreateDelete *me; + CommandData *cdata; + + g_return_if_fail (class != NULL); + g_return_if_fail (GLADE_IS_PROJECT (project)); + if (g_type_is_a (class->type, GTK_TYPE_WINDOW) == FALSE) + g_return_if_fail (GLADE_IS_WIDGET (parent)); - /* Need either a parent or a placeholder or a project - */ - g_return_if_fail (parent != NULL || - placeholder != NULL || - GLADE_IS_PROJECT (project)); - g_assert (gpw != NULL); - g_return_if_fail (GLADE_IS_PALETTE (gpw->palette)); + me = g_object_new (GLADE_COMMAND_CREATE_DELETE_TYPE, NULL); + me->create = TRUE; - if (g_type_is_a (class->type, GTK_TYPE_WINDOW) == FALSE && !parent) - { - g_return_if_fail (placeholder != NULL); - g_return_if_fail ((parent = glade_placeholder_get_parent (placeholder))); - if (!project) project = parent->project; - } - else if (parent) project = parent->project; + cdata = g_new0 (CommandData, 1); + cdata->parent = parent; + if ((cdata->placeholder = placeholder) != NULL) + g_object_ref (G_OBJECT (placeholder)); - g_return_if_fail (project != NULL); + me->widgets = g_list_append (me->widgets, cdata); - widget = glade_widget_new (parent, class, project); /* widget may be null, e.g. the user clicked cancel on a query */ - if (widget == NULL) + if ((cdata->widget = glade_widget_new (parent, class, project)) == NULL) + { + g_object_unref (G_OBJECT (me)); return; + } - glade_command_create_delete_common (widget, parent, placeholder, TRUE); + GLADE_COMMAND (me)->description = + g_strdup_printf (_("Create %s"), + cdata->widget->name); + if (glade_command_create_delete_execute (GLADE_COMMAND (me))) + glade_command_push_undo (project, GLADE_COMMAND (me)); + else + g_object_unref (G_OBJECT (me)); } typedef enum { @@ -793,12 +831,9 @@ typedef enum { * Clipboard functions. **/ typedef struct { - GladeCommand parent; - - GladeWidget *parent_widget; - GladeWidget *widget; - GladePlaceholder *placeholder; - GladeCutCopyPasteType type; + GladeCommand parent; + GList *widgets; + GladeCutCopyPasteType type; } GladeCommandCutCopyPaste; @@ -813,33 +848,50 @@ static gboolean glade_command_paste_execute (GladeCommandCutCopyPaste *me) { GladeProjectWindow *gpw = glade_project_window_get (); + CommandData *cdata; + GList *list; + gboolean cleared = FALSE; - g_return_val_if_fail (g_list_find (gpw->clipboard->widgets, me->widget), TRUE); - - if (me->parent_widget != NULL) + for (list = me->widgets; list && list->data; list = list->next) { - if (me->placeholder) - glade_widget_replace - (me->parent_widget, - G_OBJECT (me->placeholder), - me->widget->object); - else + cdata = list->data; + + if (!cleared) { - glade_widget_class_container_add - (me->parent_widget->widget_class, - me->parent_widget->object, - me->widget->object); - glade_widget_set_parent (me->widget, me->parent_widget); + glade_project_selection_clear (cdata->widget->project, FALSE); + cleared = TRUE; } - } - glade_project_add_object (me->widget->project, me->widget->object); - glade_project_selection_set (me->widget->project, me->widget->object, TRUE); + if (cdata->parent != NULL) + { + /* glade_command_paste ganauntees that if there we are + * pasting to a placeholder, there is only one widget. + */ + if (cdata->placeholder) + glade_widget_replace + (cdata->parent, + G_OBJECT (cdata->placeholder), + cdata->widget->object); + else + { + glade_widget_class_container_add + (cdata->parent->widget_class, + cdata->parent->object, + cdata->widget->object); + glade_widget_set_parent (cdata->widget, cdata->parent); + } + } + + glade_project_add_object (cdata->widget->project, cdata->widget->object); + glade_project_selection_add (cdata->widget->project, cdata->widget->object, FALSE); - if (GTK_IS_WIDGET (me->widget->object)) - gtk_widget_show_all (GTK_WIDGET (me->widget->object)); + if (GTK_IS_WIDGET (cdata->widget->object)) + gtk_widget_show_all (GTK_WIDGET (cdata->widget->object)); + + glade_clipboard_remove (gpw->clipboard, cdata->widget); + } - glade_clipboard_remove (gpw->clipboard, me->widget); + if (cdata) glade_project_selection_changed (cdata->widget->project); return TRUE; } @@ -848,32 +900,35 @@ static gboolean glade_command_cut_execute (GladeCommandCutCopyPaste *me) { GladeProjectWindow *gpw = glade_project_window_get (); + CommandData *cdata; + GList *list; - g_return_val_if_fail (me->widget != NULL, TRUE); - - glade_clipboard_add (gpw->clipboard, me->widget); - - if (me->parent_widget) + for (list = me->widgets; list && list->data; list = list->next) { - if (me->placeholder) - glade_widget_replace - (me->parent_widget, - me->widget->object, - G_OBJECT (me->placeholder)); - else - glade_widget_class_container_remove - (me->parent_widget->widget_class, - me->parent_widget->object, - me->widget->object); - } - - if (GTK_IS_WIDGET (me->widget->object)) - gtk_widget_hide (GTK_WIDGET (me->widget->object)); + cdata = list->data; - /* This doesn't NULLify the widget->project pointer. - */ - glade_project_remove_object (me->widget->project, me->widget->object); + glade_clipboard_add (gpw->clipboard, cdata->widget); + if (cdata->parent) + { + if (cdata->placeholder) + glade_widget_replace + (cdata->parent, + cdata->widget->object, + G_OBJECT (cdata->placeholder)); + else + glade_widget_class_container_remove + (cdata->parent->widget_class, + cdata->parent->object, + cdata->widget->object); + } + + if (GTK_IS_WIDGET (cdata->widget->object)) + gtk_widget_hide (GTK_WIDGET (cdata->widget->object)); + + glade_project_remove_object (cdata->widget->project, cdata->widget->object); + + } return TRUE; } @@ -881,7 +936,14 @@ static gboolean glade_command_copy_execute (GladeCommandCutCopyPaste *me) { GladeProjectWindow *gpw = glade_project_window_get (); - glade_clipboard_add (gpw->clipboard, me->widget); + CommandData *cdata; + GList *list; + + for (list = me->widgets; list && list->data; list = list->next) + { + cdata = list->data; + glade_clipboard_add (gpw->clipboard, cdata->widget); + } return TRUE; } @@ -889,7 +951,14 @@ static gboolean glade_command_copy_undo (GladeCommandCutCopyPaste *me) { GladeProjectWindow *gpw = glade_project_window_get (); - glade_clipboard_remove (gpw->clipboard, me->widget); + CommandData *cdata; + GList *list; + + for (list = me->widgets; list && list->data; list = list->next) + { + cdata = list->data; + glade_clipboard_remove (gpw->clipboard, cdata->widget); + } return TRUE; } @@ -943,16 +1012,21 @@ glade_command_cut_copy_paste_undo (GladeCommand *cmd) static void glade_command_cut_copy_paste_finalize (GObject *obj) { - GladeCommandCutCopyPaste *cmd; + GladeCommandCutCopyPaste *me = GLADE_COMMAND_CUT_COPY_PASTE (obj); + CommandData *cdata; + GList *list; - g_return_if_fail (GLADE_IS_COMMAND_CUT_COPY_PASTE (obj)); - - cmd = GLADE_COMMAND_CUT_COPY_PASTE (obj); - - g_object_unref (cmd->widget); - if (cmd->placeholder) - g_object_unref (cmd->placeholder); + for (list = me->widgets; list && list->data; list = list->next) + { + cdata = list->data; + if (cdata->widget) + g_object_unref (cdata->widget); + if (cdata->placeholder) + g_object_unref (cdata->placeholder); + g_free (cdata); + } + g_list_free (me->widgets); glade_command_finalize (obj); } @@ -969,143 +1043,158 @@ glade_command_cut_copy_paste_collapse (GladeCommand *this, GladeCommand *other) } static void -glade_command_cut_copy_paste_common (GladeWidget *widget, +glade_command_cut_copy_paste_common (GList *widgets, GladeWidget *parent, GladePlaceholder *placeholder, - GladeProject *project, - GladeCutCopyPasteType type, - gboolean needs_placeholder) + GladeCutCopyPasteType type) { + GladeProjectWindow *gpw = glade_project_window_get (); GladeCommandCutCopyPaste *me; - GladeCommand *cmd; + CommandData *cdata; + GladeWidget *widget; + GladeProject *project; + GList *list; + gchar *fmt; - me = (GladeCommandCutCopyPaste *) g_object_new (GLADE_COMMAND_CUT_COPY_PASTE_TYPE, NULL); - cmd = (GladeCommand *) me; - - me->type = type; - me->widget = - (type == GLADE_COPY) ? - glade_widget_dup (widget) : - g_object_ref (widget); - me->parent_widget = parent; - me->placeholder = g_object_ref (placeholder); - if (!me->placeholder && needs_placeholder) - me->placeholder = GLADE_PLACEHOLDER (glade_placeholder_new ()); + g_return_if_fail (widgets != NULL); + /* Some prelimenary error checking here */ switch (type) { case GLADE_CUT: - cmd->description = g_strdup_printf (_("Cut %s"), widget->name); - break; case GLADE_COPY: - cmd->description = g_strdup_printf (_("Copy %s"), widget->name); + for (list = widgets; list && list->data; list = list->next) + { + widget = list->data; + if (widget->internal) + { + glade_util_ui_warn + (gpw->window, + _("You cannot copy/cut a widget internal to a composite widget.")); + return; + } + } + fmt = (type == GLADE_CUT) ? _("Cut %s") : _("Copy %s"); break; case GLADE_PASTE: - cmd->description = g_strdup_printf (_("Paste %s"), widget->name); + for (list = widgets; list && list->data; list = list->next) + { + widget = list->data; + if (GTK_IS_WINDOW (widget->object)) + { + glade_util_ui_warn + (gpw->window, + _("You cannot paste a top-level to a placeholder.")); + return; + } + } + g_return_if_fail (GLADE_IS_WIDGET (parent)); + fmt = _("Paste %s"); break; } + /* And now we feel safe enough to go on and create */ + widget = widgets->data; + project = widget->project; + me = (GladeCommandCutCopyPaste *) + g_object_new (GLADE_COMMAND_CUT_COPY_PASTE_TYPE, NULL); + me->type = type; + GLADE_COMMAND (me)->description = + g_strdup_printf + (fmt, g_list_length (widgets) == 1 ? + widget->name : _("multiple")); + + for (list = widgets; list && list->data; list = list->next) + { + widget = list->data; + + cdata = g_new0 (CommandData, 1); + + /* Widget */ + if (type == GLADE_COPY) + cdata->widget = glade_widget_dup (widget); + else + cdata->widget = g_object_ref (G_OBJECT (widget)); + + /* Parent */ + if (parent == NULL) + cdata->parent = glade_widget_get_parent (widget); + else + cdata->parent = parent; + + /* Placeholder */ + if (type == GLADE_CUT) + { + if (cdata->parent && + glade_util_gtkcontainer_relation + (cdata->parent, cdata->widget)) + { + cdata->placeholder = GLADE_PLACEHOLDER + (glade_placeholder_new ()); + g_object_ref (G_OBJECT (cdata->placeholder)); + gtk_object_sink (GTK_OBJECT (cdata->placeholder)); + } + else if (placeholder != NULL) + cdata->placeholder = g_object_ref (placeholder); + } + else if (placeholder != NULL) + cdata->placeholder = g_object_ref (placeholder); + + me->widgets = g_list_append (me->widgets, cdata); + } + /* * Push it onto the undo stack only on success */ - if (glade_command_cut_copy_paste_execute (cmd)) - glade_command_push_undo (project, cmd); + if (glade_command_cut_copy_paste_execute (GLADE_COMMAND (me))) + glade_command_push_undo (project, GLADE_COMMAND (me)); else g_object_unref (G_OBJECT (me)); } /** * glade_command_paste: - * @widget: a #GladeWidget + * @widgets: a #GList + * @parent: a #GladeWidget + * @placeholder: a #GladePlaceholder * * TODO: write me */ void -glade_command_paste (GladeWidget *parent, GladePlaceholder *placeholder) +glade_command_paste (GList *widgets, GladeWidget *parent, GladePlaceholder *placeholder) { - GladeProjectWindow *gpw; - GladeWidget *widget; - - gpw = glade_project_window_get (); - - if (!placeholder) + GladeProjectWindow *gpw = glade_project_window_get (); + if (placeholder != NULL && g_list_length (widgets) != 1) { - glade_util_ui_warn (gpw->window, _("Placeholder not selected!")); + glade_util_ui_warn + (gpw->window, + _("You cannot paste more than one widget to a placeholder.")); return; } - - g_return_if_fail (GLADE_IS_PLACEHOLDER (placeholder)); - - widget = gpw->clipboard->curr; - if (widget == NULL) - return; - - glade_command_cut_copy_paste_common (widget, parent, placeholder, - parent->project, GLADE_PASTE, FALSE); + glade_command_cut_copy_paste_common (widgets, parent, placeholder, GLADE_PASTE); } /** * glade_command_cut: - * @widget: a #GladeWidget + * @widgets: a #GList * * TODO: write me */ void -glade_command_cut (GladeWidget *widget, gboolean needs_placeholder) +glade_command_cut (GList *widgets) { - GladeProjectWindow *gpw; - - gpw = glade_project_window_get (); - - if (!widget) - { - glade_util_ui_warn (gpw->window, _("No widget selected!")); - return; - } - - g_return_if_fail (GLADE_IS_WIDGET (widget)); - - /* internal children cannot be cut. Notify the user. */ - if (widget->internal) - { - glade_util_ui_warn (gpw->window, _("You cannot cut a widget internal to a composite widget.")); - return; - } - - glade_command_cut_copy_paste_common (widget, glade_widget_get_parent (widget), - NULL, widget->project, GLADE_CUT, - needs_placeholder); + glade_command_cut_copy_paste_common (widgets, NULL, NULL, GLADE_CUT); } /** * glade_command_copy: - * @widget: a #GladeWidget + * @widgets: a #GList * * TODO: write me */ void -glade_command_copy (GladeWidget *widget) +glade_command_copy (GList *widgets) { - GladeProjectWindow *gpw; - - gpw = glade_project_window_get (); - - if (!widget) - { - glade_util_ui_warn (gpw->window, _("No widget selected!")); - return; - } - - g_return_if_fail (GLADE_IS_WIDGET (widget)); - - /* internal children cannot be copied. Notify the user */ - if (widget->internal) - { - glade_util_ui_warn (gpw->window, _("You cannot copy a widget internal to a composite widget.")); - return; - } - - glade_command_cut_copy_paste_common (widget, glade_widget_get_parent (widget), - NULL, widget->project, GLADE_COPY, FALSE); + glade_command_cut_copy_paste_common (widgets, NULL, NULL, GLADE_COPY); } /*********************************************************/ diff --git a/src/glade-command.h b/src/glade-command.h index e50975d0..f491c25e 100644 --- a/src/glade-command.h +++ b/src/glade-command.h @@ -41,26 +41,29 @@ struct _GladeCommandClass GType glade_command_get_type (void); -void glade_command_undo (GladeProject *project); -void glade_command_redo (GladeProject *project); - -void glade_command_set_property (GladeProperty *property, const GValue *value); -void glade_command_set_name (GladeWidget *glade_widget, const gchar *name); - -void glade_command_delete (GladeWidget *glade_widget); -void glade_command_create (GladeWidgetClass *widget_class, - GladeWidget *parent, - GladePlaceholder *placeholder, - GladeProject *project); - -void glade_command_cut (GladeWidget *widget, gboolean needs_placeholder); -void glade_command_copy (GladeWidget *glade_widget); -void glade_command_paste (GladeWidget *parent, GladePlaceholder *placeholder); - -void glade_command_add_signal (GladeWidget *glade_widget, const GladeSignal *signal); -void glade_command_remove_signal (GladeWidget *glade_widget, const GladeSignal *signal); -void glade_command_change_signal (GladeWidget *glade_widget, - const GladeSignal *old, const GladeSignal *new); +void glade_command_undo (GladeProject *project); +void glade_command_redo (GladeProject *project); + +void glade_command_set_property (GladeProperty *property, const GValue *value); +void glade_command_set_name (GladeWidget *glade_widget, const gchar *name); + +void glade_command_delete (GList *widgets); +void glade_command_create (GladeWidgetClass *widget_class, + GladeWidget *parent, + GladePlaceholder *placeholder, + GladeProject *project); + +void glade_command_cut (GList *widgets); +void glade_command_copy (GList *widgets); +void glade_command_paste (GList *widgets, + GladeWidget *parent, + GladePlaceholder *placeholder); + +void glade_command_add_signal (GladeWidget *glade_widget, const GladeSignal *signal); +void glade_command_remove_signal (GladeWidget *glade_widget, const GladeSignal *signal); +void glade_command_change_signal (GladeWidget *glade_widget, + const GladeSignal *old, + const GladeSignal *new); G_END_DECLS diff --git a/src/glade-placeholder.c b/src/glade-placeholder.c index 30a1b1fd..cf45052a 100644 --- a/src/glade-placeholder.c +++ b/src/glade-placeholder.c @@ -316,7 +316,8 @@ glade_placeholder_button_press (GtkWidget *widget, GdkEventButton *event) /* A widget type is selected in the palette. * Add a new widget of that type. */ - glade_command_create (gpw->add_class, NULL, + glade_command_create (gpw->add_class, + glade_placeholder_get_parent (placeholder), placeholder, project); /* reset the palette */ @@ -324,7 +325,7 @@ glade_placeholder_button_press (GtkWidget *widget, GdkEventButton *event) } else { - glade_project_selection_set (project, GTK_WIDGET (placeholder), TRUE); + glade_project_selection_set (project, G_OBJECT (placeholder), TRUE); } } else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) diff --git a/src/glade-popup.c b/src/glade-popup.c index c59475c8..c6aed5a1 100644 --- a/src/glade-popup.c +++ b/src/glade-popup.c @@ -41,69 +41,77 @@ glade_popup_select_cb (GtkMenuItem *item, GladeWidget *widget) static void glade_popup_cut_cb (GtkMenuItem *item, GladeWidget *widget) { - GladeWidget *parent; - gboolean need_placeholder = FALSE; + GladeProjectWindow *gpw = glade_project_window_get (); + GList *list; - if (!widget) - { - GladeProjectWindow *gpw = glade_project_window_get (); - glade_util_ui_warn (gpw->window, _("No widget selected!")); - return; - } + list = glade_project_selection_get (gpw->active_project); - /* If this widget is parented through the GtkContainer interface, - * a placeholder will be needed. - */ - if ((parent = glade_widget_get_parent (widget)) != NULL) - need_placeholder = - glade_util_gtkcontainer_relation (parent, widget); - glade_command_cut (widget, need_placeholder); + /* Assign selection first */ + if (g_list_find (list, glade_widget_get_object (widget)) == NULL) + glade_project_selection_set (gpw->active_project, + glade_widget_get_object (widget), FALSE); + + glade_util_cut_selection (); } static void glade_popup_copy_cb (GtkMenuItem *item, GladeWidget *widget) { - if (!widget) - { - GladeProjectWindow *gpw = glade_project_window_get (); - glade_util_ui_warn (gpw->window, _("No widget selected!")); - return; - } + GladeProjectWindow *gpw = glade_project_window_get (); + GList *list; - glade_command_copy (widget); + list = glade_project_selection_get (gpw->active_project); + + /* Assign selection first */ + if (g_list_find (list, glade_widget_get_object (widget)) == NULL) + glade_project_selection_set (gpw->active_project, + glade_widget_get_object (widget), FALSE); + + glade_util_copy_selection (); } static void glade_popup_paste_cb (GtkMenuItem *item, GladeWidget *widget) { - if (!widget) - { - GladeProjectWindow *gpw = glade_project_window_get (); - glade_util_ui_warn (gpw->window, _("No widget selected!")); - return; - } + GladeProjectWindow *gpw; - glade_command_paste (widget, NULL); + gpw = glade_project_window_get (); + glade_project_selection_set (gpw->active_project, + glade_widget_get_object (widget), FALSE); + glade_util_paste_clipboard (); } static void glade_popup_delete_cb (GtkMenuItem *item, GladeWidget *widget) { - glade_command_delete (widget); + GladeProjectWindow *gpw; + GList *list; + + gpw = glade_project_window_get (); + + list = glade_project_selection_get (gpw->active_project); + + /* Assign selection first */ + if (g_list_find (list, glade_widget_get_object (widget)) == NULL) + glade_project_selection_set (gpw->active_project, + glade_widget_get_object (widget), FALSE); + + glade_util_delete_selection (); } static void glade_popup_placeholder_paste_cb (GtkMenuItem *item, GladePlaceholder *placeholder) { - if (!placeholder) - { - GladeProjectWindow *gpw = glade_project_window_get (); - glade_util_ui_warn (gpw->window, _("No placeholder selected!")); - return; - } - glade_command_paste (glade_placeholder_get_parent (placeholder), - placeholder); + GladeProjectWindow *gpw; + GList *widgets = NULL, *list; + GladeWidget *w, *parent; + + gpw = glade_project_window_get (); + glade_project_selection_set (gpw->active_project, + G_OBJECT (placeholder), FALSE); + + glade_util_paste_clipboard (); } static void @@ -226,12 +234,8 @@ glade_popup_create_menu (GladeWidget *widget, gboolean add_childs) glade_popup_cut_cb, widget); glade_popup_append_item (popup_menu, GTK_STOCK_COPY, NULL, TRUE, glade_popup_copy_cb, widget); - - - if (glade_util_widget_pastable (widget)) - glade_popup_append_item (popup_menu, GTK_STOCK_PASTE, NULL, TRUE, - glade_popup_paste_cb, widget); - + glade_popup_append_item (popup_menu, GTK_STOCK_PASTE, NULL, TRUE, + glade_popup_paste_cb, widget); glade_popup_append_item (popup_menu, GTK_STOCK_DELETE, NULL, TRUE, glade_popup_delete_cb, widget); diff --git a/src/glade-project-view.c b/src/glade-project-view.c index 3a01c24a..c69a0671 100644 --- a/src/glade-project-view.c +++ b/src/glade-project-view.c @@ -360,23 +360,31 @@ glade_project_view_selection_update (GladeProjectView *view, g_return_if_fail (selection != NULL); + view->updating_treeview = TRUE; + gtk_tree_selection_unselect_all (selection); for (list = glade_project_selection_get (project); list && list->data; list = list->next) { - widget = glade_widget_get_from_gobject (G_OBJECT (list->data)); - class = glade_widget_get_class (widget); + if ((widget = glade_widget_get_from_gobject + (G_OBJECT (list->data))) != NULL) + { + class = glade_widget_get_class (widget); - if (view->is_list && !g_type_is_a (class->type, GTK_TYPE_WINDOW)) - continue; + if (view->is_list && + !g_type_is_a (class->type, GTK_TYPE_WINDOW)) + continue; - if ((iter = glade_project_view_find_iter_by_widget - (model, widget)) != NULL) - { - gtk_tree_selection_select_iter (selection, iter); + if ((iter = glade_project_view_find_iter_by_widget + (model, widget)) != NULL) + { + gtk_tree_selection_select_iter (selection, iter); + } } } + + view->updating_treeview = FALSE; } static void @@ -388,43 +396,44 @@ glade_project_view_class_init (GladeProjectViewClass *class) parent_class = g_type_class_peek_parent (class); - class->add_item = glade_project_view_add_item; - class->remove_item = glade_project_view_remove_item; - class->set_project = glade_project_view_set_project; - class->widget_name_changed = glade_project_view_widget_name_changed; - class->selection_update = glade_project_view_selection_update; + class->add_item = glade_project_view_add_item; + class->remove_item = glade_project_view_remove_item; + class->set_project = glade_project_view_set_project; + class->widget_name_changed = glade_project_view_widget_name_changed; + class->selection_update = glade_project_view_selection_update; +} + + +static void +gpw_foreach_add_selection (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + GladeWidget *widget; + gtk_tree_model_get (model, iter, WIDGET_COLUMN, &widget, -1); + glade_project_selection_add (widget->project, + glade_widget_get_object (widget), FALSE); } + static gboolean glade_project_view_selection_changed_cb (GtkTreeSelection *selection, GladeProjectView *view) { - GtkTreeModel *model; - GladeWidget *widget; - GtkTreeIter iter; - - if (!view->project) - return TRUE; - g_return_val_if_fail (GLADE_IS_PROJECT_VIEW (view), FALSE); - model = GTK_TREE_MODEL (view->model); - - /* There are no cells selected */ - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) - return TRUE; - - gtk_tree_model_get (model, &iter, WIDGET_COLUMN, &widget, -1); - - /* The cell exists, but not widget has been asociated with it */ - if (widget == NULL) - return TRUE; - - view->updating_selection = TRUE; - glade_project_selection_set (widget->project, - glade_widget_get_object (widget), TRUE); - view->updating_selection = FALSE; + if (view->project != NULL && + view->updating_treeview == FALSE) + { + view->updating_selection = TRUE; + glade_project_selection_clear (view->project, FALSE); + gtk_tree_selection_selected_foreach (selection, gpw_foreach_add_selection, view); + glade_project_selection_changed (view->project); + + view->updating_selection = FALSE; + } return TRUE; } @@ -464,11 +473,11 @@ glade_project_view_button_press_cb (GtkWidget *widget, GdkEventButton *event, GladeProjectView *view) { - GtkTreeView *tree_view = GTK_TREE_VIEW (widget); - GtkTreePath *path = NULL; + GtkTreeView *tree_view = GTK_TREE_VIEW (widget); + GtkTreePath *path = NULL; + gboolean handled = FALSE; - if (event->button == 3 && - event->window == gtk_tree_view_get_bin_window (tree_view)) + if (event->window == gtk_tree_view_get_bin_window (tree_view)) { if (gtk_tree_view_get_path_at_pos (tree_view, event->x, event->y, @@ -485,14 +494,18 @@ glade_project_view_button_press_cb (GtkWidget *widget, WIDGET_COLUMN, &widget, -1); if (widget != NULL) { - glade_popup_widget_pop (widget, event, FALSE); + + if (event->button == 3) + { + glade_popup_widget_pop (widget, event, FALSE); + handled = TRUE; + } } } gtk_tree_path_free (path); } - return TRUE; } - return FALSE; + return handled; } static void @@ -615,6 +628,7 @@ glade_project_view_init (GladeProjectView *view) g_signal_connect_data (G_OBJECT (selection), "changed", G_CALLBACK (glade_project_view_selection_changed_cb), view, NULL, 0); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); /* Popup menu */ g_signal_connect (G_OBJECT (view->tree_view), "button-press-event", @@ -627,6 +641,7 @@ glade_project_view_init (GladeProjectView *view) G_CALLBACK (glade_project_view_row_cb), view); view->updating_selection = FALSE; + view->updating_treeview = FALSE; } static void diff --git a/src/glade-project-view.h b/src/glade-project-view.h index f21ff620..816310a8 100644 --- a/src/glade-project-view.h +++ b/src/glade-project-view.h @@ -56,6 +56,9 @@ struct _GladeProjectView * for the project changed selection * signal */ + gboolean updating_treeview; /* Eliminate feedback from the tree-view + * (same as updating_selection) + */ }; struct _GladeProjectViewClass diff --git a/src/glade-project-window.c b/src/glade-project-window.c index 64e50646..2afa0001 100644 --- a/src/glade-project-window.c +++ b/src/glade-project-window.c @@ -421,106 +421,25 @@ gpw_quit_cb (void) static void gpw_copy_cb (void) { - GladeProjectWindow *gpw; - GList *list; - - gpw = glade_project_window_get (); - list = glade_project_selection_get (gpw->active_project); - /* TODO: support multiple selected items */ - if (list != NULL && list->next == NULL) - { - GladeWidget *widget = glade_widget_get_from_gobject (GTK_WIDGET (list->data)); - - if (widget) - glade_command_copy (widget); - } + glade_util_copy_selection (); } static void gpw_cut_cb (void) { - GladeProjectWindow *gpw; - GList *list; - - gpw = glade_project_window_get (); - list = glade_project_selection_get (gpw->active_project); - - /* TODO: support multiple selected items */ - if (list != NULL && list->next == NULL) - { - GladeWidget *widget = glade_widget_get_from_gobject (GTK_WIDGET (list->data)); - GladeWidget *parent; - - gboolean need_placeholder = FALSE; - - if (!widget) - { - GladeProjectWindow *gpw = glade_project_window_get (); - glade_util_ui_warn (gpw->window, _("No widget selected!")); - return; - } - - if ((parent = glade_widget_get_parent (widget)) != NULL) - need_placeholder = - glade_util_gtkcontainer_relation (parent, widget); - glade_command_cut (widget, need_placeholder); - } + glade_util_cut_selection (); } static void gpw_paste_cb (void) { - GladeProjectWindow *gpw; - GList *list; - - gpw = glade_project_window_get (); - list = glade_project_selection_get (gpw->active_project); - - /* TODO: support multiple selected items */ - if (list != NULL && list->next == NULL) - { - GladePlaceholder *placeholder = NULL; - GladeWidget *widget; - - - if (GLADE_IS_PLACEHOLDER (list->data)) - { - placeholder = list->data; - widget = glade_placeholder_get_parent (placeholder); - } - else - { - widget = glade_widget_get_from_gobject (G_OBJECT (list->data)); - } - - if (!widget) - { - GladeProjectWindow *gpw = glade_project_window_get (); - glade_util_ui_warn (gpw->window, - _("No widget or placeholder selected!")); - return; - } - - if (glade_util_widget_pastable (widget)) - glade_command_paste (widget, placeholder); - } + glade_util_paste_clipboard (); } static void gpw_delete_cb (void) { - GladeProjectWindow *gpw; - - gpw = glade_project_window_get (); - if (!gpw->active_project) - { - g_warning ("delete should not be sensitive: we don't have a project"); - return; - } - - /* glade_util_delete_selection performs a glade_command_delete - * on each of the selected widgets */ - glade_util_delete_selection (gpw->active_project); + glade_util_delete_selection (); } static void @@ -589,6 +508,7 @@ gpw_palette_button_clicked (GladePalette *palette, gpointer not_used) if (class && g_type_is_a (class->type, GTK_TYPE_WINDOW)) { glade_command_create (class, NULL, NULL, gpw->active_project); + glade_palette_unselect_widget (gpw->palette); gpw->add_class = NULL; } else diff --git a/src/glade-project.c b/src/glade-project.c index b1340881..c20e4c3a 100644 --- a/src/glade-project.c +++ b/src/glade-project.c @@ -527,6 +527,21 @@ glade_project_new_widget_name (GladeProject *project, const char *base_name) } /** + * glade_project_is_selected: + * @project: a #GladeProject + * @object: a #GObject + * + * Returns: whether @object is in @project selection + */ +gboolean +glade_project_is_selected (GladeProject *project, + GObject *object) +{ + g_return_val_if_fail (GLADE_IS_PROJECT (project), FALSE); + return (g_list_find (project->selection, object)) != NULL; +} + +/** * glade_project_selection_clear: * @project: a #GladeProject * @emit_signal: whether or not to emit a signal indication a selection change @@ -577,7 +592,7 @@ glade_project_selection_remove (GladeProject *project, g_return_if_fail (GLADE_IS_PROJECT (project)); g_return_if_fail (G_IS_OBJECT (object)); - if ((g_list_find (project->selection, object)) != NULL) + if (glade_project_is_selected (project, object)) { glade_util_remove_selection (object); project->selection = g_list_remove (project->selection, object); @@ -604,7 +619,7 @@ glade_project_selection_add (GladeProject *project, g_return_if_fail (GLADE_IS_PROJECT (project)); g_return_if_fail (G_IS_OBJECT (object)); - if ((g_list_find (project->selection, object)) == NULL) + if (glade_project_is_selected (project, object) == FALSE) { glade_util_add_selection (object); project->selection = g_list_prepend (project->selection, object); @@ -631,7 +646,8 @@ glade_project_selection_set (GladeProject *project, g_return_if_fail (GLADE_IS_PROJECT (project)); g_return_if_fail (G_IS_OBJECT (object)); - if ((g_list_find (project->selection, object)) == NULL) + if (glade_project_is_selected (project, object) == FALSE || + g_list_length (project->selection) != 1) { glade_project_selection_clear (project, FALSE); glade_project_selection_add (project, object, emit_signal); @@ -819,3 +835,4 @@ glade_project_get_tooltips (GladeProject *project) { return project->tooltips; } + diff --git a/src/glade-project.h b/src/glade-project.h index 6adac7a9..b2d33534 100644 --- a/src/glade-project.h +++ b/src/glade-project.h @@ -78,6 +78,8 @@ void glade_project_widget_name_changed (GladeProject *project, GladeWid GtkTooltips *glade_project_get_tooltips (GladeProject *project); /* Selection */ +gboolean glade_project_is_selected (GladeProject *project, + GObject *object); void glade_project_selection_set (GladeProject *project, GObject *object, gboolean emit_signal); @@ -92,6 +94,7 @@ void glade_project_selection_clear (GladeProject *project, void glade_project_selection_changed (GladeProject *project); GList *glade_project_selection_get (GladeProject *project); + G_END_DECLS #endif /* __GLADE_PROJECT_H__ */ diff --git a/src/glade-signal-editor.c b/src/glade-signal-editor.c index cc56ff65..87e29691 100644 --- a/src/glade-signal-editor.c +++ b/src/glade-signal-editor.c @@ -362,7 +362,6 @@ glade_signal_editor_handler_cell_edited (GtkCellRendererText *cell, /* we're changing a signal handler */ if (!slot && !is_void_signal_handler(new_handler)) { - /* XXX TODO: Action not yet undoable */ GladeSignal *old_signal = glade_signal_new (signal_name, diff --git a/src/glade-utils.c b/src/glade-utils.c index f7fba621..9a9c5cd9 100644 --- a/src/glade-utils.c +++ b/src/glade-utils.c @@ -830,42 +830,6 @@ glade_util_has_selection (GObject *object) (object, GLADE_UTIL_HAS_NODES)) != 0; } -/** - * glade_util_delete_selection: - * @project: a #GladeProject - * - * TODO: write me - */ -void -glade_util_delete_selection (GladeProject *project) -{ - GList *selection; - GList *free_me; - GList *list; - - g_return_if_fail (GLADE_IS_PROJECT (project)); - - selection = glade_project_selection_get (project); - if (!selection) - return; - - /* We have to be careful when deleting widgets from the selection - * because when we delete each widget, the selection pointer changes - * due to the g_list_remove performed by glade_command_delete. - * Copy the list and free it after we are done - */ - free_me = g_list_copy (selection); - for (list = free_me; list; list = list->next) { - GladeWidget *glade_widget; - - glade_widget = glade_widget_get_from_gobject (list->data); - if (glade_widget) - glade_command_delete (glade_widget); - } - - g_list_free (free_me); -} - /* * taken from gtk... maybe someday we can convince them to * expose gtk_container_get_all_children @@ -982,6 +946,8 @@ gboolean glade_util_gtkcontainer_relation (GladeWidget *parent, GladeWidget *widget) { GladeSupportedChild *support; + g_return_val_if_fail (GLADE_IS_WIDGET (parent), FALSE); + g_return_val_if_fail (GLADE_IS_WIDGET (widget), FALSE); return (GTK_IS_CONTAINER (parent->object) && (support = glade_widget_class_get_child_support (parent->widget_class, widget->widget_class->type)) && @@ -990,25 +956,149 @@ glade_util_gtkcontainer_relation (GladeWidget *parent, GladeWidget *widget) /** * glade_util_gtkcontainer_relation: + * @child: a GladeWidget * @widget: a GladeWidget * - * Returns whether this widget has an implementation to parent - * the primary selection on the clipboard. + * Returns whether this parent widget has an implementation to parent child. */ gboolean -glade_util_widget_pastable (GladeWidget *parent) +glade_util_widget_pastable (GladeWidget *child, + GladeWidget *parent) +{ + g_return_val_if_fail (GLADE_IS_WIDGET (child), FALSE); + g_return_val_if_fail (GLADE_IS_WIDGET (parent), FALSE); + return (glade_widget_class_get_child_support + (parent->widget_class, + child->widget_class->type) != NULL) ? TRUE : FALSE; +} + + +void +glade_util_paste_clipboard (void) { GladeProjectWindow *gpw; - GladeClipboard *clipboard; - GladeWidget *clip_widget; + GList *widgets = NULL, *list; + GladeWidget *widget, *parent; + GladePlaceholder *placeholder = NULL; + + gpw = glade_project_window_get (); + + if ((list = glade_project_selection_get (gpw->active_project)) == NULL) + { + glade_util_ui_warn (gpw->window, _("No widget selected!")); + return; + } + else if (g_list_length (list) > 1) + { + glade_util_ui_warn + (gpw->window, _("Unable to paste to multiple widgets")); + return; + } + + if (GLADE_IS_PLACEHOLDER (list->data)) + { + placeholder = list->data; + parent = glade_placeholder_get_parent (placeholder); + } + else + parent = glade_widget_get_from_gobject (GTK_WIDGET (list->data)); + + /* TODO Multiple selection on clipboard */ + if ((widget = gpw->clipboard->curr) != NULL) + { + if (parent && + glade_util_widget_pastable (widget, parent) == FALSE) + { + gchar *message = g_strdup_printf + (_("Unable to paste widget %s to parent %s"), + widget->name, parent->name); + glade_util_ui_warn (gpw->window, message); + g_free (message); + return; + } + widgets = g_list_append (widgets, widget); + glade_command_paste (widgets, parent, placeholder); + g_list_free (widgets); + } +} + +void +glade_util_cut_selection (void) +{ + GladeProjectWindow *gpw; + GList *widgets = NULL, *list; + GladeWidget *widget; + + gpw = glade_project_window_get (); - gpw = glade_project_window_get (); - clipboard = gpw->clipboard; - clip_widget = clipboard->curr; - - if (clip_widget) - return (glade_widget_class_get_child_support - (parent->widget_class, - clip_widget->widget_class->type) != NULL) ? TRUE : FALSE; - return FALSE; + for (list = glade_project_selection_get (gpw->active_project); + list && list->data; list = list->next) + { + widget = glade_widget_get_from_gobject (GTK_WIDGET (list->data)); + widgets = g_list_prepend (widgets, widget); + } + + if (widgets) + { + glade_command_cut (widgets); + g_list_free (widgets); + } + else + { + glade_util_ui_warn (gpw->window, _("No widget selected!")); + } +} + +void +glade_util_copy_selection (void) +{ + GladeProjectWindow *gpw; + GList *widgets = NULL, *list; + GladeWidget *widget; + + gpw = glade_project_window_get (); + + for (list = glade_project_selection_get (gpw->active_project); + list && list->data; list = list->next) + { + widget = glade_widget_get_from_gobject (GTK_WIDGET (list->data)); + widgets = g_list_prepend (widgets, widget); + } + + if (widgets) + { + glade_command_copy (widgets); + g_list_free (widgets); + } + else + { + glade_util_ui_warn (gpw->window, _("No widget selected!")); + } +} + +void +glade_util_delete_selection (void) +{ + GladeProjectWindow *gpw; + GList *widgets = NULL, *list; + GladeWidget *widget; + + gpw = glade_project_window_get (); + + for (list = glade_project_selection_get (gpw->active_project); + list && list->data; list = list->next) + { + widget = glade_widget_get_from_gobject (GTK_WIDGET (list->data)); + widgets = g_list_prepend (widgets, widget); + } + + if (widgets) + { + glade_command_delete (widgets); + g_list_free (widgets); + } + else + { + glade_util_ui_warn (gpw->window, _("No widget selected!")); + } } diff --git a/src/glade-utils.h b/src/glade-utils.h index 532dbfdb..93c356c7 100644 --- a/src/glade-utils.h +++ b/src/glade-utils.h @@ -41,8 +41,6 @@ void glade_util_file_dialog_set_filename (GtkWidget *file_dialog, gch void glade_util_replace (char *str, char a, char b); gchar *glade_util_duplicate_underscores (const char *name); -void glade_util_delete_selection (GladeProject *project); - void glade_util_add_selection (GObject *object); void glade_util_remove_selection (GObject *object); gboolean glade_util_has_selection (GObject *object); @@ -54,7 +52,12 @@ GList *glade_util_container_get_all_children (GtkContainer *container); GList *glade_util_uri_list_parse (const gchar* uri_list); gboolean glade_util_gtkcontainer_relation (GladeWidget *parent, GladeWidget *widget); -gboolean glade_util_widget_pastable (GladeWidget *parent); +gboolean glade_util_widget_pastable (GladeWidget *child, GladeWidget *parent); + +void glade_util_paste_clipboard (void); +void glade_util_cut_selection (void); +void glade_util_copy_selection (void); +void glade_util_delete_selection (void); G_END_DECLS diff --git a/src/glade-widget.c b/src/glade-widget.c index f3a516d5..24999577 100644 --- a/src/glade-widget.c +++ b/src/glade-widget.c @@ -1191,9 +1191,10 @@ glade_widget_button_press (GtkWidget *widget, GdkEventButton *event, gpointer unused_data) { - double x = event->x; - double y = event->y; + double x = event->x; + double y = event->y; GladeWidget *glade_widget; + gboolean handled = FALSE; glade_widget = glade_widget_retrieve_from_position (widget, (int) (x + 0.5), (int) (y + 0.5)); @@ -1203,31 +1204,41 @@ glade_widget_button_press (GtkWidget *widget, if (GTK_WIDGET_CAN_FOCUS (widget) && !GTK_WIDGET_HAS_FOCUS (widget)) gtk_widget_grab_focus (widget); - /* Allow plugins to use shift/cntl possibilities */ - if ((event->type != GDK_BUTTON_PRESS) || - (event->state & GDK_SHIFT_MASK) != 0 || - (event->state & GDK_CONTROL_MASK) != 0) - return FALSE; - + /* if it's already selected don't stop default handlers, e.g. toggle button */ if (event->button == 1) { - /* if it's already selected don't stop default handlers, e.g. toggle button */ - if (glade_util_has_selection (G_OBJECT(widget))) + if (event->state & GDK_CONTROL_MASK) { - return FALSE; + if (glade_project_is_selected (glade_widget->project, + glade_widget->object)) + glade_project_selection_remove + (glade_widget->project, + glade_widget->object, TRUE); + else + glade_project_selection_add + (glade_widget->project, + glade_widget->object, TRUE); + handled = TRUE; + } + else + { + if (glade_project_is_selected + (glade_widget->project, glade_widget->object) == FALSE || + g_list_length (glade_widget->project->selection) != 1) + { + glade_project_selection_set (glade_widget->project, + glade_widget->object, TRUE); + handled = TRUE; + } } - - glade_project_selection_set (glade_widget->project, G_OBJECT(widget), TRUE); - - return TRUE; } else if (event->button == 3) { glade_popup_widget_pop (glade_widget, event, TRUE); - return TRUE; + handled = TRUE; } - return FALSE; + return handled; } static gboolean @@ -1244,7 +1255,7 @@ glade_widget_key_press (GtkWidget *event_widget, /* We will delete all the selected items */ if (event->keyval == GDK_Delete) { - glade_util_delete_selection (glade_widget_get_project (glade_widget)); + glade_util_delete_selection (); return TRUE; } @@ -1646,8 +1657,6 @@ glade_widget_replace (GladeWidget *parent, GObject *old_object, GObject *new_obj { GladeWidget *gnew_widget = NULL; GladeWidget *gold_widget = NULL; - GObject *real_new_object = new_object; - GObject *real_old_object = old_object; g_return_if_fail (G_IS_OBJECT (old_object)); g_return_if_fail (G_IS_OBJECT (new_object)); @@ -1655,22 +1664,12 @@ glade_widget_replace (GladeWidget *parent, GObject *old_object, GObject *new_obj gnew_widget = glade_widget_get_from_gobject (new_object); gold_widget = glade_widget_get_from_gobject (old_object); - if (gnew_widget) - { - real_new_object = glade_widget_get_object (gnew_widget); - gnew_widget->parent = parent; - } - - if (gold_widget) - { - real_old_object = glade_widget_get_object (gold_widget); - gold_widget->parent = NULL; - } + if (gnew_widget) gnew_widget->parent = parent; + if (gold_widget) gold_widget->parent = NULL; - glade_widget_class_container_replace_child (parent->widget_class, - parent->object, - real_old_object, - real_new_object); + glade_widget_class_container_replace_child + (parent->widget_class, parent->object, + old_object, new_object); if (gnew_widget) glade_widget_set_packing_properties (gnew_widget, parent); |