diff options
-rw-r--r-- | shell/ChangeLog | 26 | ||||
-rw-r--r-- | shell/Evolution-ShellComponentDnd.idl | 12 | ||||
-rw-r--r-- | shell/e-storage-set-view.c | 248 |
3 files changed, 249 insertions, 37 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog index db55da8345..1f6dfbdad8 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,5 +1,31 @@ 2001-03-19 Ettore Perazzoli <ettore@ximian.com> + * e-storage-set-view.c New members `drag_data', + `drag_corba_source_interface' and `drag_corba_source_context in + `EStorageSetViewPrivate'. + (init): Init the new members. + (destroy): Clean up the new members. + (table_drag_begin): Query for the + `EvolutionShellComponentDnd::SourceFolder' interface on the + handler for the folder we are dragging from, and initialize all + the CORBA context information for the drag, after invoking + `::beginDrag()' on it. + (convert_gdk_drag_action_to_corba): New helper function. + (table_drag_data_get): Get the data using + `::SourceFolder::getData'. + (table_drag_end): New, override for the "ETable::table_drag_end" + signal. Invoke `::endDrag' on the SourceFolder interface, + unref/release the interface, and clean up the source context. + (table_drag_data_delete): New, override for the + "ETable::table_drag_data_delete" signal. + (class_init): Install `table_drag_end' and + `table_drag_data_delete'. + + * Evolution-ShellComponentDnd.idl: Derive `::DestinationFolder' + and `SourceFolder' from `Bonobo::Unknown'. + +2001-03-19 Ettore Perazzoli <ettore@ximian.com> + * e-storage-set-view.c (table_drag_data_get): Don't get the selection through `evolution_shell_component_client_get_dnd_selection()'. diff --git a/shell/Evolution-ShellComponentDnd.idl b/shell/Evolution-ShellComponentDnd.idl index 766bff2b33..f5fa3d0c0e 100644 --- a/shell/Evolution-ShellComponentDnd.idl +++ b/shell/Evolution-ShellComponentDnd.idl @@ -25,13 +25,13 @@ module ShellComponentDnd { struct Data { short format; - short info; + short target; sequence <octet> bytes; }; exception NoData {}; - interface SourceFolder { + interface SourceFolder : Bonobo::Unknown { struct Context { string physical_uri; string folder_type; @@ -61,11 +61,12 @@ module ShellComponentDnd { delete it. */ void deleteData (in Context source_context); - /* The drag is over. */ + /* The drag is over. This should also clean up the data if + there was a `getData()' but no `deleteData()' after it. */ void endDrag (in Context source_context); }; - interface DestinationFolder { + interface DestinationFolder : Bonobo::Unknown { struct Context { string dnd_type; ActionSet possible_actions; @@ -75,7 +76,8 @@ module ShellComponentDnd { /* The user is moving a dragged object over our folder. This will return %FALSE if the specified object cannot be dropped; otherwise, it will return %TRUE and then set the - @action we want to be performed when the drop happens. */ + @default_action and @non_default_action we want to be + performed when the drop happens. */ boolean handleMotion (in Context destination_context, out Action default_action, out Action non_default_action); diff --git a/shell/e-storage-set-view.c b/shell/e-storage-set-view.c index 8c1a81ca25..35716d84e5 100644 --- a/shell/e-storage-set-view.c +++ b/shell/e-storage-set-view.c @@ -76,6 +76,19 @@ struct _EStorageSetViewPrivate { gboolean show_folders; + /* The `Evolution::ShellComponentDnd::SourceFolder' interface for the + folder we are dragging from, or CORBA_OBJECT_NIL if no dragging is + happening. */ + GNOME_Evolution_ShellComponentDnd_SourceFolder drag_corba_source_interface; + + /* Source context information. NULL if no dragging is in progress. */ + GNOME_Evolution_ShellComponentDnd_SourceFolder_Context *drag_corba_source_context; + + /* The data. */ + GNOME_Evolution_ShellComponentDnd_Data *drag_corba_data; + + /* When dragging, the X/Y coordinates of the point we drag from, as + well as the corresponding row/column numbers in the table. */ int drag_x, drag_y; int drag_column, drag_row; }; @@ -257,6 +270,25 @@ get_folder_at_row (EStorageSetView *storage_set_view, return folder; } +static GNOME_Evolution_ShellComponentDnd_Action +convert_gdk_drag_action_to_corba (GdkDragAction action) +{ + GNOME_Evolution_ShellComponentDnd_Action retval; + + retval = GNOME_Evolution_ShellComponentDnd_ACTION_DEFAULT; + + if (action & GDK_ACTION_COPY) + retval |= GNOME_Evolution_ShellComponentDnd_ACTION_COPY; + if (action & GDK_ACTION_MOVE) + retval |= GNOME_Evolution_ShellComponentDnd_ACTION_MOVE; + if (action & GDK_ACTION_LINK) + retval |= GNOME_Evolution_ShellComponentDnd_ACTION_LINK; + if (action & GDK_ACTION_ASK) + retval |= GNOME_Evolution_ShellComponentDnd_ACTION_ASK; + + return retval; +} + /* Custom marshalling function. */ @@ -556,6 +588,29 @@ destroy (GtkObject *object) gtk_object_unref (GTK_OBJECT (priv->storage_set)); + if (priv->drag_corba_source_interface != CORBA_OBJECT_NIL) { + CORBA_Environment ev; + + CORBA_exception_init (&ev); + + g_assert (priv->drag_corba_source_context != NULL); + + GNOME_Evolution_ShellComponentDnd_SourceFolder_endDrag (priv->drag_corba_source_interface, + priv->drag_corba_source_context, + &ev); + + Bonobo_Unknown_unref (priv->drag_corba_source_interface, &ev); + CORBA_Object_release (priv->drag_corba_source_interface, &ev); + + CORBA_exception_free (&ev); + } + + if (priv->drag_corba_source_context != NULL) + CORBA_free (priv->drag_corba_source_context); + + if (priv->drag_corba_data != NULL) + CORBA_free (priv->drag_corba_data); + g_free (priv); (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -644,6 +699,8 @@ motion_notify_event (GtkWidget *widget, /* ETable methods. */ +/* -- Source-side DnD. */ + static void table_drag_begin (ETable *etable, int row, int col, @@ -652,6 +709,13 @@ table_drag_begin (ETable *etable, EStorageSetView *storage_set_view; EStorageSetViewPrivate *priv; ETreePath *node; + EFolder *folder; + EFolderTypeRegistry *folder_type_registry; + EvolutionShellComponentClient *component_client; + GNOME_Evolution_ShellComponent corba_component; + GNOME_Evolution_ShellComponentDnd_ActionSet possible_actions; + GNOME_Evolution_ShellComponentDnd_Action suggested_action; + CORBA_Environment ev; storage_set_view = E_STORAGE_SET_VIEW (etable); priv = storage_set_view->priv; @@ -659,6 +723,87 @@ table_drag_begin (ETable *etable, node = e_tree_model_node_at_row (priv->etree_model, row); priv->selected_row_path = e_tree_model_node_get_data (priv->etree_model, node); + + g_assert (priv->drag_corba_source_interface == CORBA_OBJECT_NIL); + + folder = get_folder_at_row (storage_set_view, row); + folder_type_registry = e_storage_set_get_folder_type_registry (priv->storage_set); + component_client = e_folder_type_registry_get_handler_for_type (folder_type_registry, + e_folder_get_type_string (folder)); + + g_assert (component_client != NULL); + + /* Query the `ShellComponentDnd::SourceFolder' interface on the + component. */ + + CORBA_exception_init (&ev); + + corba_component = bonobo_object_corba_objref (BONOBO_OBJECT (component_client)); + priv->drag_corba_source_interface = Bonobo_Unknown_queryInterface (corba_component, + "IDL:GNOME/Evolution/ShellComponentDnd/SourceFolder:1.0", + &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + priv->drag_corba_source_interface = CORBA_OBJECT_NIL; + + CORBA_exception_free (&ev); + return; + } + + GNOME_Evolution_ShellComponentDnd_SourceFolder_beginDrag (priv->drag_corba_source_interface, + e_folder_get_physical_uri (folder), + e_folder_get_type_string (folder), + &possible_actions, + &suggested_action, + &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + Bonobo_Unknown_unref (priv->drag_corba_source_interface, &ev); + CORBA_Object_release (priv->drag_corba_source_interface, &ev); + + priv->drag_corba_source_interface = CORBA_OBJECT_NIL; + + CORBA_exception_free (&ev); + return; + } + + CORBA_exception_free (&ev); + + if (priv->drag_corba_source_context != NULL) + CORBA_free (priv->drag_corba_source_context); + + priv->drag_corba_source_context = GNOME_Evolution_ShellComponentDnd_SourceFolder_Context__alloc (); + priv->drag_corba_source_context->physical_uri = CORBA_string_dup (e_folder_get_physical_uri (folder)); + priv->drag_corba_source_context->folder_type = CORBA_string_dup (e_folder_get_type_string (folder)); + priv->drag_corba_source_context->possible_actions = possible_actions; + priv->drag_corba_source_context->suggested_action = suggested_action; +} + +static void +table_drag_end (ETable *table, + int row, + int col, + GdkDragContext *context) +{ + EStorageSetView *storage_set_view; + EStorageSetViewPrivate *priv; + CORBA_Environment ev; + + storage_set_view = E_STORAGE_SET_VIEW (table); + priv = storage_set_view->priv; + + CORBA_exception_init (&ev); + + GNOME_Evolution_ShellComponentDnd_SourceFolder_endDrag (priv->drag_corba_source_interface, + priv->drag_corba_source_context, + &ev); + + CORBA_free (priv->drag_corba_source_context); + priv->drag_corba_source_context = NULL; + + Bonobo_Unknown_unref (priv->drag_corba_source_interface, &ev); + CORBA_Object_release (priv->drag_corba_source_interface, &ev); + + CORBA_exception_free (&ev); } static void @@ -672,12 +817,7 @@ table_drag_data_get (ETable *etable, { EStorageSetView *storage_set_view; EStorageSetViewPrivate *priv; - EFolder *folder; - EFolderTypeRegistry *folder_type_registry; - EvolutionShellComponentClient *component_client; - char *selection; - int selection_length; - int format; + CORBA_Environment ev; storage_set_view = E_STORAGE_SET_VIEW (etable); priv = storage_set_view->priv; @@ -689,31 +829,57 @@ table_drag_data_get (ETable *etable, g_assert (info > 0); - folder = get_folder_at_row (storage_set_view, drag_row); - g_assert (folder != NULL); + if (priv->drag_corba_source_interface == CORBA_OBJECT_NIL) + return; - folder_type_registry = e_storage_set_get_folder_type_registry (priv->storage_set); - g_assert (folder_type_registry != NULL); + CORBA_exception_init (&ev); - component_client = e_folder_type_registry_get_handler_for_type (folder_type_registry, - e_folder_get_type_string (folder)); - g_assert (component_client != NULL); + GNOME_Evolution_ShellComponentDnd_SourceFolder_getData (priv->drag_corba_source_interface, + priv->drag_corba_source_context, + convert_gdk_drag_action_to_corba (context->action), + "", /* FIXME type! */ + & priv->drag_corba_data, + &ev); -#if 0 - evolution_shell_component_client_get_dnd_selection (component_client, - e_folder_get_physical_uri (folder), - info, - &format, &selection, &selection_length); - if (selection == NULL) + if (ev._major != CORBA_NO_EXCEPTION) + gtk_selection_data_set (selection_data, selection_data->target, 8, "", 1); + else + gtk_selection_data_set (selection_data, + priv->drag_corba_data->target, + priv->drag_corba_data->format, + priv->drag_corba_data->bytes._buffer, + priv->drag_corba_data->bytes._length); + + CORBA_exception_free (&ev); +} + +static void +table_drag_data_delete (ETable *table, + int row, + int col, + GdkDragContext *context) +{ + EStorageSetView *storage_set_view; + EStorageSetViewPrivate *priv; + CORBA_Environment ev; + + storage_set_view = E_STORAGE_SET_VIEW (table); + priv = storage_set_view->priv; + + if (priv->drag_corba_source_interface == CORBA_OBJECT_NIL) return; -#endif - gtk_selection_data_set (selection_data, selection_data->target, - format, selection, selection_length); + CORBA_exception_init (&ev); - g_free (selection); + GNOME_Evolution_ShellComponentDnd_SourceFolder_deleteData (priv->drag_corba_source_interface, + priv->drag_corba_source_context, + &ev); + + CORBA_exception_free (&ev); } +/* -- Destination-side DnD. */ + static gboolean table_drag_motion (ETable *table, int row, @@ -723,6 +889,12 @@ table_drag_motion (ETable *table, int y, unsigned int time) { + EStorageSetView *storage_set_view; + EStorageSetViewPrivate *priv; + + storage_set_view = E_STORAGE_SET_VIEW (table); + priv = storage_set_view->priv; + gdk_drag_status (context, GDK_ACTION_MOVE, time); return TRUE; @@ -1117,7 +1289,9 @@ class_init (EStorageSetViewClass *klass) etable_class->right_click = right_click; etable_class->cursor_activated = cursor_activated; etable_class->table_drag_begin = table_drag_begin; + etable_class->table_drag_end = table_drag_end; etable_class->table_drag_data_get = table_drag_data_get; + etable_class->table_drag_data_delete = table_drag_data_delete; etable_class->table_drag_motion = table_drag_motion; etable_class->table_drag_drop = table_drag_drop; etable_class->table_drag_data_received = table_drag_data_received; @@ -1167,15 +1341,25 @@ init (EStorageSetView *storage_set_view) priv = g_new (EStorageSetViewPrivate, 1); - priv->storage_set = NULL; - priv->path_to_etree_node = g_hash_table_new (g_str_hash, g_str_equal); - priv->type_name_to_pixbuf = g_hash_table_new (g_str_hash, g_str_equal); - priv->selected_row_path = NULL; - priv->show_folders = TRUE; - priv->drag_x = 0; - priv->drag_y = 0; - priv->drag_column = 0; - priv->drag_row = 0; + priv->storage_set = NULL; + priv->path_to_etree_node = g_hash_table_new (g_str_hash, g_str_equal); + priv->type_name_to_pixbuf = g_hash_table_new (g_str_hash, g_str_equal); + priv->selected_row_path = NULL; + priv->show_folders = TRUE; + + priv->drag_corba_source_interface = CORBA_OBJECT_NIL; + + priv->drag_corba_source_context->physical_uri = NULL; + priv->drag_corba_source_context->folder_type = NULL; + priv->drag_corba_source_context->possible_actions = GNOME_Evolution_ShellComponentDnd_ACTION_DEFAULT; + priv->drag_corba_source_context->suggested_action = GNOME_Evolution_ShellComponentDnd_ACTION_DEFAULT; + + priv->drag_corba_data = NULL; + + priv->drag_x = 0; + priv->drag_y = 0; + priv->drag_column = 0; + priv->drag_row = 0; storage_set_view->priv = priv; } |