aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--shell/ChangeLog32
-rw-r--r--shell/Evolution-ShellComponentDnd.idl3
-rw-r--r--shell/e-storage-set-view.c148
3 files changed, 165 insertions, 18 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog
index d27f938e69..a0c2bbd4bf 100644
--- a/shell/ChangeLog
+++ b/shell/ChangeLog
@@ -1,3 +1,25 @@
+2001-03-21 Ettore Perazzoli <ettore@ximian.com>
+
+ * e-storage-set-view.c (tree_drag_data_get): Get the target type
+ from the atom, and pass it through the `SourceFolder::getData'
+ invocation. Also, signal an error by passing `-1' as the length
+ value to `gtk_selection_data_set()'.
+ (find_matching_target_for_drag_context): New helper function.
+ (tree_drag_motion): Use it to figure out a suitable type for the
+ drop action, and pass it to the `DestinationFolder::handleMotion'
+ method.
+
+ * e-storage-set-view.c (get_component_at_node): New helper
+ function.
+ (table_drag_begin): Use it.
+ (convert_corba_drag_action_to_gdk): New helper function.
+ (table_drag_motion): Use the `DestinationFolder::handleMotion'
+ method to handle the "drag_motion" signal.
+
+ * Evolution-ShellComponentDnd.idl: Change the signature for the
+ `handleMotion' method so that it only has @suggested_action
+ parameter.
+
2001-03-20 JP Rosevear <jpr@ximian.com>
* importer/Makefile.am: make sure intelligent.h gets disted
@@ -6,29 +28,27 @@
* Merged e-tree-rework-branch:
-2001-03-19 Christopher James Lahey <clahey@ximian.com>
+ 2001-03-19 Christopher James Lahey <clahey@ximian.com>
* e-storage-set-view.c (etree_get_save_id): Made "root" detection
deal properly with removed nodes.
-2001-03-18 Christopher James Lahey <clahey@ximian.com>
+ 2001-03-18 Christopher James Lahey <clahey@ximian.com>
* e-shell-view.c (e_shell_view_save_settings): Added some unused
code to implement saving of the expanded state.
* e-storage-set-view.c: Added has_save_id and get_save_id methods.
-2001-03-13 Christopher James Lahey <clahey@ximian.com>
+ 2001-03-13 Christopher James Lahey <clahey@ximian.com>
* e-storage-set-view.c (ETREE_SPEC): Set draw-grid here to false.
-2001-03-09 Christopher James Lahey <clahey@ximian.com>
+ 2001-03-09 Christopher James Lahey <clahey@ximian.com>
* e-storage-set-view.c, e-storage-set-view.h: Chaned this to use
ETree instead of ETable.
-End of branch
-
2001-03-19 Ettore Perazzoli <ettore@ximian.com>
* evolution-shell-component-client.c: New members
diff --git a/shell/Evolution-ShellComponentDnd.idl b/shell/Evolution-ShellComponentDnd.idl
index f5fa3d0c0e..7eaea434fc 100644
--- a/shell/Evolution-ShellComponentDnd.idl
+++ b/shell/Evolution-ShellComponentDnd.idl
@@ -79,8 +79,7 @@ module ShellComponentDnd {
@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);
+ out Action suggested_action);
/* Data is dropped. We are given the data for the dropped
object, and we are supposed to perform the operation
diff --git a/shell/e-storage-set-view.c b/shell/e-storage-set-view.c
index 038e75c73a..f99c27647b 100644
--- a/shell/e-storage-set-view.c
+++ b/shell/e-storage-set-view.c
@@ -241,7 +241,7 @@ get_pixbuf_for_folder (EStorageSetView *storage_set_view,
GDK_INTERP_HYPER);
}
- g_hash_table_insert (priv->type_name_to_pixbuf, g_strdup(type_name), scaled_pixbuf);
+ g_hash_table_insert (priv->type_name_to_pixbuf, g_strdup (type_name), scaled_pixbuf);
}
return scaled_pixbuf;
@@ -269,7 +269,31 @@ get_folder_at_node (EStorageSetView *storage_set_view,
return folder;
}
-static GNOME_Evolution_ShellComponentDnd_Action
+static EvolutionShellComponentClient *
+get_component_at_node (EStorageSetView *storage_set_view,
+ ETreePath path)
+{
+ EStorageSetViewPrivate *priv;
+ EvolutionShellComponentClient *component_client;
+ EFolderTypeRegistry *folder_type_registry;
+ EFolder *folder;
+
+ priv = storage_set_view->priv;
+
+ folder = get_folder_at_node (storage_set_view, path);
+ if (folder == NULL)
+ return NULL;
+
+ folder_type_registry = e_storage_set_get_folder_type_registry (priv->storage_set);
+ g_assert (folder_type_registry != NULL);
+
+ component_client = e_folder_type_registry_get_handler_for_type (folder_type_registry,
+ e_folder_get_type_string (folder));
+
+ return component_client;
+}
+
+static GNOME_Evolution_ShellComponentDnd_ActionSet
convert_gdk_drag_action_to_corba (GdkDragAction action)
{
GNOME_Evolution_ShellComponentDnd_Action retval;
@@ -288,6 +312,72 @@ convert_gdk_drag_action_to_corba (GdkDragAction action)
return retval;
}
+static GdkDragAction
+convert_corba_drag_action_to_gdk (GNOME_Evolution_ShellComponentDnd_ActionSet action)
+{
+ GdkDragAction retval;
+
+ retval = GDK_ACTION_DEFAULT;
+
+ if (action & GNOME_Evolution_ShellComponentDnd_ACTION_COPY)
+ retval |= GDK_ACTION_COPY;
+ if (action & GNOME_Evolution_ShellComponentDnd_ACTION_MOVE)
+ retval |= GDK_ACTION_MOVE;
+ if (action & GNOME_Evolution_ShellComponentDnd_ACTION_LINK)
+ retval |= GDK_ACTION_LINK;
+ if (action & GNOME_Evolution_ShellComponentDnd_ACTION_ASK)
+ retval |= GDK_ACTION_ASK;
+
+ return retval;
+}
+
+static const char *
+find_matching_target_for_drag_context (EStorageSetView *storage_set_view,
+ ETreePath path,
+ GdkDragContext *drag_context)
+{
+ EStorageSetViewPrivate *priv;
+ EFolderTypeRegistry *folder_type_registry;
+ EFolder *folder;
+ GList *accepted_types;
+ GList *p, *q;
+
+ priv = storage_set_view->priv;
+ folder_type_registry = e_storage_set_get_folder_type_registry (priv->storage_set);
+
+ folder = get_folder_at_node (storage_set_view, path);
+ if (folder == NULL)
+ return NULL;
+
+ accepted_types = e_folder_type_registry_get_accepted_dnd_types_for_type (folder_type_registry,
+ e_folder_get_type_string (folder));
+
+ /* FIXME? We might make this more efficient. Currently it takes `n *
+ m' string compares, where `n' is the number of targets in the
+ @drag_context, and `m' is the number of supported types in
+ @folder. */
+
+ for (p = drag_context->targets; p != NULL; p = p->next) {
+ char *possible_type;
+
+ possible_type = gdk_atom_name ((GdkAtom) p->data);
+
+ for (q = accepted_types; q != NULL; q = q->next) {
+ const char *accepted_type;
+
+ accepted_type = (const char *) q->data;
+ if (strcmp (possible_type, accepted_type) == 0) {
+ g_free (possible_type);
+ return accepted_type;
+ }
+ }
+
+ g_free (possible_type);
+ }
+
+ return NULL;
+}
+
/* Custom marshalling function. */
@@ -709,7 +799,6 @@ tree_drag_begin (ETree *etree,
EStorageSetView *storage_set_view;
EStorageSetViewPrivate *priv;
EFolder *folder;
- EFolderTypeRegistry *folder_type_registry;
EvolutionShellComponentClient *component_client;
GNOME_Evolution_ShellComponent corba_component;
GNOME_Evolution_ShellComponentDnd_ActionSet possible_actions;
@@ -724,9 +813,7 @@ tree_drag_begin (ETree *etree,
g_assert (priv->drag_corba_source_interface == CORBA_OBJECT_NIL);
folder = get_folder_at_node (storage_set_view, path);
- 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));
+ component_client = get_component_at_node (storage_set_view, path);
g_assert (component_client != NULL);
@@ -824,6 +911,7 @@ tree_drag_data_get (ETree *etree,
EStorageSetView *storage_set_view;
EStorageSetViewPrivate *priv;
CORBA_Environment ev;
+ char *target_type;
storage_set_view = E_STORAGE_SET_VIEW (etree);
priv = storage_set_view->priv;
@@ -838,17 +926,19 @@ tree_drag_data_get (ETree *etree,
if (priv->drag_corba_source_interface == CORBA_OBJECT_NIL)
return;
+ target_type = gdk_atom_name ((GdkAtom) context->targets->data);
+
CORBA_exception_init (&ev);
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! */
+ target_type,
& priv->drag_corba_data,
&ev);
if (ev._major != CORBA_NO_EXCEPTION)
- gtk_selection_data_set (selection_data, selection_data->target, 8, "", 1);
+ gtk_selection_data_set (selection_data, selection_data->target, 8, "", -1);
else
gtk_selection_data_set (selection_data,
priv->drag_corba_data->target,
@@ -856,6 +946,8 @@ tree_drag_data_get (ETree *etree,
priv->drag_corba_data->bytes._buffer,
priv->drag_corba_data->bytes._length);
+ g_free (target_type);
+
CORBA_exception_free (&ev);
}
@@ -899,11 +991,47 @@ tree_drag_motion (ETree *tree,
{
EStorageSetView *storage_set_view;
EStorageSetViewPrivate *priv;
+ EvolutionShellComponentClient *component_client;
+ GNOME_Evolution_ShellComponentDnd_DestinationFolder destination_folder_interface;
+ GNOME_Evolution_ShellComponentDnd_Action suggested_action;
+ GNOME_Evolution_ShellComponentDnd_DestinationFolder_Context corba_context;
+ CORBA_boolean can_handle;
+ CORBA_Environment ev;
+ const char *dnd_type;
storage_set_view = E_STORAGE_SET_VIEW (tree);
priv = storage_set_view->priv;
- gdk_drag_status (context, GDK_ACTION_MOVE, time);
+ component_client = get_component_at_node (storage_set_view, path);
+ if (component_client == NULL)
+ return FALSE;
+
+ destination_folder_interface = evolution_shell_component_client_get_dnd_source_interface (component_client);
+ if (destination_folder_interface == NULL)
+ return FALSE;
+
+ dnd_type = find_matching_target_for_drag_context (storage_set_view, path, context);
+ if (dnd_type == NULL)
+ return FALSE;
+
+ CORBA_exception_init (&ev);
+
+ corba_context.dnd_type = (char *) dnd_type; /* (Safe cast, as we don't actually free the corba_context.) */
+ corba_context.possible_actions = convert_gdk_drag_action_to_corba (context->actions);
+ corba_context.suggested_action = convert_gdk_drag_action_to_corba (context->suggested_action);
+
+ can_handle = GNOME_Evolution_ShellComponentDnd_DestinationFolder_handleMotion (destination_folder_interface,
+ &corba_context,
+ &suggested_action,
+ &ev);
+ if (ev._major != CORBA_NO_EXCEPTION || ! can_handle) {
+ CORBA_exception_free (&ev);
+ return FALSE;
+ }
+
+ CORBA_exception_free (&ev);
+
+ gdk_drag_status (context, convert_corba_drag_action_to_gdk (suggested_action), time);
return TRUE;
}
@@ -980,7 +1108,7 @@ cursor_activated (ETree *tree,
priv = storage_set_view->priv;
- priv->selected_row_path = e_tree_memory_node_get_data (E_TREE_MEMORY(priv->etree_model), path);
+ priv->selected_row_path = e_tree_memory_node_get_data (E_TREE_MEMORY (priv->etree_model), path);
if (e_tree_model_node_depth (priv->etree_model, path) >= 2) {
/* it was a folder */