aboutsummaryrefslogtreecommitdiffstats
path: root/shell/e-storage-set-view.c
diff options
context:
space:
mode:
authorEttore Perazzoli <ettore@src.gnome.org>2001-03-22 18:41:44 +0800
committerEttore Perazzoli <ettore@src.gnome.org>2001-03-22 18:41:44 +0800
commit2df293b5c71033efdbda28a6236563816ef7e139 (patch)
treee2392fa3e8a81d1a45467789ed1a089c0df34e8c /shell/e-storage-set-view.c
parent7aee2da177ed7eb902537e9d5d88baaeefdc36b5 (diff)
downloadgsoc2013-evolution-2df293b5c71033efdbda28a6236563816ef7e139.tar.gz
gsoc2013-evolution-2df293b5c71033efdbda28a6236563816ef7e139.tar.zst
gsoc2013-evolution-2df293b5c71033efdbda28a6236563816ef7e139.zip
More DnD work. Now we handle copying and moving of folders, although
the hooks to actually make the physical operation happen are missing. Also, fix a stupid cut & paste error in Chris' commit (and re-indent the code a bit to make it match the surrounding style). svn path=/trunk/; revision=8890
Diffstat (limited to 'shell/e-storage-set-view.c')
-rw-r--r--shell/e-storage-set-view.c197
1 files changed, 141 insertions, 56 deletions
diff --git a/shell/e-storage-set-view.c b/shell/e-storage-set-view.c
index ea66eb7e99..ba5172a73a 100644
--- a/shell/e-storage-set-view.c
+++ b/shell/e-storage-set-view.c
@@ -60,6 +60,18 @@ static char *list [] = {
</ETableSpecification>"
+/* This is used on the source side to define the two basic types that we always
+ export. */
+enum _DndTargetTypeIdx {
+ EVOLUTION_PATH_TARGET_TYPE_IDX = 0,
+ E_SHORTCUT_TARGET_TYPE_IDX = 1
+};
+typedef enum _DndTargetTypeIdx DndTargetTypeIdx;
+
+#define EVOLUTION_PATH_TARGET_TYPE "_EVOLUTION_PRIVATE_PATH"
+#define E_SHORTCUT_TARGET_TYPE "E-SHORTCUT"
+
+
#define PARENT_TYPE E_TREE_TYPE
static ETreeClass *parent_class = NULL;
@@ -133,15 +145,25 @@ static const int num_destination_drag_types = sizeof (destination_drag_types) /
static GtkTargetList *target_list;
+/* Sorting callbacks. */
+
static int
-storage_sort_callback (ETreeMemory *etmm, ETreePath node1, ETreePath node2, gpointer closure)
+storage_sort_callback (ETreeMemory *etmm,
+ ETreePath node1,
+ ETreePath node2,
+ void *closure)
{
- char *folder_path1 = e_tree_memory_node_get_data(etmm, node1);
- char *folder_path2 = e_tree_memory_node_get_data(etmm, node1);
+ char *folder_path1;
+ char *folder_path2;
gboolean path1_local;
gboolean path2_local;
- path1_local = !strcmp(folder_path1, G_DIR_SEPARATOR_S E_LOCAL_STORAGE_NAME);
- path2_local = !strcmp(folder_path2, G_DIR_SEPARATOR_S E_LOCAL_STORAGE_NAME);
+
+ folder_path1 = e_tree_memory_node_get_data(etmm, node1);
+ folder_path2 = e_tree_memory_node_get_data(etmm, node2);
+
+ path1_local = ! strcmp (folder_path1, G_DIR_SEPARATOR_S E_LOCAL_STORAGE_NAME);
+ path2_local = ! strcmp (folder_path2, G_DIR_SEPARATOR_S E_LOCAL_STORAGE_NAME);
+
if (path1_local && path2_local)
return 0;
if (path1_local)
@@ -149,17 +171,20 @@ storage_sort_callback (ETreeMemory *etmm, ETreePath node1, ETreePath node2, gpoi
if (path2_local)
return 1;
- return strcmp(e_tree_model_value_at(E_TREE_MODEL(etmm), node1, 0), e_tree_model_value_at(E_TREE_MODEL(etmm), node2, 0));
+ return strcmp (e_tree_model_value_at (E_TREE_MODEL (etmm), node1, 0),
+ e_tree_model_value_at (E_TREE_MODEL (etmm), node2, 0));
}
static int
folder_sort_callback (ETreeMemory *etmm, ETreePath path1, ETreePath path2, gpointer closure)
{
- return strcmp(e_tree_model_value_at(E_TREE_MODEL(etmm), path1, 0), e_tree_model_value_at(E_TREE_MODEL(etmm), path2, 0));
+ return strcmp (e_tree_model_value_at (E_TREE_MODEL (etmm), path1, 0),
+ e_tree_model_value_at (E_TREE_MODEL (etmm), path2, 0));
}
-/* Helper functions. */
+
+/* Helper functions. */
static gboolean
add_node_to_hash (EStorageSetView *storage_set_view,
@@ -281,7 +306,6 @@ get_folder_at_node (EStorageSetView *storage_set_view,
{
EStorageSetViewPrivate *priv;
const char *folder_path;
- EFolder *folder;
priv = storage_set_view->priv;
@@ -291,10 +315,7 @@ get_folder_at_node (EStorageSetView *storage_set_view,
folder_path = e_tree_memory_node_get_data (E_TREE_MEMORY(priv->etree_model), path);
g_assert (folder_path != NULL);
- folder = e_storage_set_get_folder (priv->storage_set, folder_path);
- g_assert (folder != NULL);
-
- return folder;
+ return e_storage_set_get_folder (priv->storage_set, folder_path);
}
static EvolutionShellComponentClient *
@@ -359,6 +380,9 @@ convert_corba_drag_action_to_gdk (GNOME_Evolution_ShellComponentDnd_ActionSet ac
return retval;
}
+/* This will look for the targets in @drag_context, choose one that matches
+ with the allowed types at @path, and return its name. The EVOLUTION_PATH
+ type always matches. */
static const char *
find_matching_target_for_drag_context (EStorageSetView *storage_set_view,
ETreePath path,
@@ -389,6 +413,10 @@ find_matching_target_for_drag_context (EStorageSetView *storage_set_view,
char *possible_type;
possible_type = gdk_atom_name ((GdkAtom) p->data);
+ if (strcmp (possible_type, EVOLUTION_PATH_TARGET_TYPE) == 0) {
+ g_free (possible_type);
+ return EVOLUTION_PATH_TARGET_TYPE;
+ }
for (q = accepted_types; q != NULL; q = q->next) {
const char *accepted_type;
@@ -451,18 +479,27 @@ create_target_entries_from_dnd_type_list (GList *dnd_types,
else
num_entries = g_list_length (dnd_types);
- /* We always add an entry for an Evolution URI type. This will let us
- do drag & drop within Evolution at least. */
- num_entries ++;
+ /* We always add two entries, one for an Evolution URI type, and one
+ for e-shortcuts. This will let us do drag & drop within Evolution
+ at least. */
+ num_entries += 2;
entries = g_new (GtkTargetEntry, num_entries);
i = 0;
/* The Evolution URI will always come first. */
- entries[i].target = E_SHORTCUT_TYPE;
+ entries[i].target = EVOLUTION_PATH_TARGET_TYPE;
entries[i].flags = 0;
- entries[i].info = 0;
+ entries[i].info = i;
+ g_assert (i == EVOLUTION_PATH_TARGET_TYPE_IDX);
+ i ++;
+
+ /* ...Then the shortcut type. */
+ entries[i].target = E_SHORTCUT_TARGET_TYPE;
+ entries[i].flags = 0;
+ entries[i].info = i;
+ g_assert (i == E_SHORTCUT_TARGET_TYPE_IDX);
i ++;
for (p = dnd_types; p != NULL; p = p->next, i++) {
@@ -524,24 +561,6 @@ create_target_list_for_node (EStorageSetView *storage_set_view,
return target_list;
}
-#if 0
-static void
-set_uri_list_selection (EStorageSetView *storage_set_view,
- GtkSelectionData *selection_data)
-{
- EStorageSetViewPrivate *priv;
- char *uri_list;
-
- priv = storage_set_view->priv;
-
- /* FIXME: Get `evolution:' from somewhere instead of hardcoding it here. */
- uri_list = g_strconcat ("evolution:", priv->selected_row_path, "\n", NULL);
- gtk_selection_data_set (selection_data, selection_data->target,
- 8, (guchar *) uri_list, strlen (uri_list));
- g_free (uri_list);
-}
-#endif
-
static void
set_e_shortcut_selection (EStorageSetView *storage_set_view,
GtkSelectionData *selection_data)
@@ -553,6 +572,7 @@ set_e_shortcut_selection (EStorageSetView *storage_set_view,
const char *name;
g_assert (storage_set_view != NULL);
+ g_assert (selection_data != NULL);
priv = storage_set_view->priv;
@@ -588,6 +608,22 @@ set_e_shortcut_selection (EStorageSetView *storage_set_view,
g_free (shortcut);
}
+static void
+set_evolution_path_selection (EStorageSetView *storage_set_view,
+ GtkSelectionData *selection_data)
+{
+ EStorageSetViewPrivate *priv;
+ const char *evolution_path;
+
+ g_assert (storage_set_view != NULL);
+ g_assert (selection_data != NULL);
+
+ priv = storage_set_view->priv;
+
+ gtk_selection_data_set (selection_data, selection_data->target,
+ 8, (guchar *) priv->selected_row_path, strlen (priv->selected_row_path) + 1);
+}
+
/* Folder context menu. */
/* FIXME: This should be moved somewhere else, so that also the shortcut code
@@ -944,9 +980,13 @@ tree_drag_data_get (ETree *etree,
storage_set_view = E_STORAGE_SET_VIEW (etree);
priv = storage_set_view->priv;
- if (info == 0) {
+ switch (info) {
+ case E_SHORTCUT_TARGET_TYPE_IDX:
set_e_shortcut_selection (storage_set_view, selection_data);
return;
+ case EVOLUTION_PATH_TARGET_TYPE_IDX:
+ set_evolution_path_selection (storage_set_view, selection_data);
+ return;
}
g_assert (info > 0);
@@ -1008,6 +1048,27 @@ tree_drag_data_delete (ETree *tree,
/* -- Destination-side DnD. */
static gboolean
+handle_evolution_path_drag_motion (EStorageSetView *storage_set_view,
+ ETreePath path,
+ GdkDragContext *context,
+ unsigned int time)
+{
+ GdkModifierType modifiers;
+ GdkDragAction action;
+
+ gdk_window_get_pointer (NULL, NULL, NULL, &modifiers);
+
+ if ((modifiers & GDK_CONTROL_MASK) != 0)
+ action = GDK_ACTION_COPY;
+ else
+ action = GDK_ACTION_MOVE;
+
+ gdk_drag_status (context, action, time);
+
+ return TRUE;
+}
+
+static gboolean
tree_drag_motion (ETree *tree,
int row,
ETreePath path,
@@ -1034,14 +1095,19 @@ tree_drag_motion (ETree *tree,
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;
+ g_print ("drag_motion %s\n", dnd_type);
+
+ if (strcmp (dnd_type, EVOLUTION_PATH_TARGET_TYPE) == 0)
+ return handle_evolution_path_drag_motion (storage_set_view, path, context, time);
+
+ destination_folder_interface = evolution_shell_component_client_get_dnd_source_interface (component_client);
+ if (destination_folder_interface == NULL)
+ return FALSE;
+
CORBA_exception_init (&ev);
corba_context.dndType = (char *) dnd_type; /* (Safe cast, as we don't actually free the corba_context.) */
@@ -1099,11 +1165,43 @@ tree_drag_data_received (ETree *etree,
EStorageSetView *storage_set_view;
EStorageSetViewPrivate *priv;
const char *target_path;
+ char *target_type;
storage_set_view = E_STORAGE_SET_VIEW (etree);
priv = storage_set_view->priv;
+ target_type = gdk_atom_name (selection_data->target);
+
+ if (strcmp (target_type, EVOLUTION_PATH_TARGET_TYPE) == 0) {
+ const char *source_path;
+ const char *destination_path;
+
+ source_path = (const char *) selection_data->data;
+ /* (Basic sanity checks.) */
+ if (source_path == NULL || source_path[0] != G_DIR_SEPARATOR || source_path[1] == '\0')
+ return;
+
+ destination_path = e_tree_memory_node_get_data (E_TREE_MEMORY (priv->etree_model), path);
+ if (destination_path == NULL)
+ return;
+
+ switch (context->action) {
+ case GDK_ACTION_MOVE:
+ g_print ("EStorageSetView: Moving from `%s' to `%s'\n", source_path, destination_path);
+ e_storage_set_async_move_folder (priv->storage_set, source_path, destination_path, NULL, NULL);
+ break;
+ case GDK_ACTION_COPY:
+ g_print ("EStorageSetView: Copying from `%s' to `%s'\n", source_path, destination_path);
+ e_storage_set_async_copy_folder (priv->storage_set, source_path, destination_path, NULL, NULL);
+ break;
+ default:
+ g_warning ("EStorageSetView: Don't know action %d\n", context->action);
+ }
+ }
+
target_path = e_tree_memory_node_get_data (E_TREE_MEMORY(priv->etree_model), path);
+
+ g_free (target_type);
}
static gboolean
@@ -1484,11 +1582,6 @@ class_init (EStorageSetViewClass *klass)
GTK_TYPE_STRING);
gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
-
- /* Set up DND. */
-
- target_list = gtk_target_list_new (source_drag_types, num_source_drag_types);
- g_assert (target_list != NULL);
}
static void
@@ -1702,19 +1795,11 @@ e_storage_set_view_construct (EStorageSetView *storage_set_view,
gtk_object_unref (GTK_OBJECT (extras));
-#if 0
- e_tree_drag_source_set (E_TREE (storage_set_view), GDK_BUTTON1_MASK,
- source_drag_types, num_source_drag_types,
- GDK_ACTION_MOVE | GDK_ACTION_COPY);
-
- e_tree_drag_dest_set (E_TREE (storage_set_view), GTK_DEST_DEFAULT_ALL,
- source_drag_types, num_source_drag_types,
- GDK_ACTION_MOVE | GDK_ACTION_COPY);
-#endif
-
gtk_object_ref (GTK_OBJECT (storage_set));
priv->storage_set = storage_set;
+ e_tree_drag_dest_set (E_TREE (storage_set_view), 0, NULL, 0, GDK_ACTION_MOVE | GDK_ACTION_COPY);
+
gtk_signal_connect_while_alive (GTK_OBJECT (storage_set), "new_storage",
GTK_SIGNAL_FUNC (new_storage_cb), storage_set_view,
GTK_OBJECT (storage_set_view));