aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--shell/ChangeLog29
-rw-r--r--shell/e-storage-set-view.c197
-rw-r--r--shell/e-storage-set.c47
-rw-r--r--shell/e-storage-set.h14
4 files changed, 228 insertions, 59 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog
index 84952a0674..aa64a3df09 100644
--- a/shell/ChangeLog
+++ b/shell/ChangeLog
@@ -1,3 +1,32 @@
+2001-03-22 Ettore Perazzoli <ettore@ximian.com>
+
+ * e-storage-set-view.c: Removed `source_drag_types',
+ `num_source_drag_types', `destination_drag_types',
+ `num_destination_drag_types', `target_list'.
+ (E_SHORTCUT_TARGET_TYPE): Renamed from "E_SHORTCUT_TYPE".
+ (EVOLUTION_PATH_TARGET_TYPE): Define to "_EVOLUTION_PRIVATE_PATH".
+ (find_matching_target_for_drag_context): If any of the targets
+ matches it, return it.
+ (handle_evolution_path_drag_motion): New.
+ (tree_drag_motion): Use it if we are matching an
+ `EVOLUTION_PATH_TARGET_TYPE' target.
+ (e_storage_set_view_construct): Call `e_tree_drag_dest_set()' on
+ the view so that we become a possible DnD target.
+ (get_folder_at_node): Don't die if you don't find a folder there.
+ (create_target_entries_from_dnd_type_list): Make the first entry
+ an `EVOLUTION_PATH_TARGET_TYPE', the second one an
+ `E_SHORTCUT_TYPE', and the following ones the ones defined by the
+ folder.
+ (set_evolution_path_selection): New function to set the private
+ Evolution path selection.
+ (set_e_shortcut_selection): Assert @selection_data to be not NULL.
+ (class_init): Don't set up the `target_list' anymore.
+ (storage_sort_callback): Actually compare the two nodes, not the
+ first node with itself.
+
+ * e-storage-set.c (e_storage_set_async_copy_folder): New.
+ (e_storage_set_async_move_folder): New.
+
2001-03-22 Christopher James Lahey <clahey@ximian.com>
* e-storage-set-view.c (etree_get_save_id): Changed get_save_id to
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));
diff --git a/shell/e-storage-set.c b/shell/e-storage-set.c
index 9921fe192c..333ec39c99 100644
--- a/shell/e-storage-set.c
+++ b/shell/e-storage-set.c
@@ -602,4 +602,51 @@ e_storage_set_get_path_for_physical_uri (EStorageSet *storage_set,
}
+/**
+ * e_storage_set_async_copy_folder:
+ * @storage_set:
+ * @source_path:
+ * @destination_path:
+ * @callback:
+ * @data:
+ *
+ * Copy a folder from @source_path to @destination_path.
+ **/
+void
+e_storage_set_async_copy_folder (EStorageSet *storage_set,
+ const char *source_path,
+ const char *destination_path,
+ EStorageResultCallback callback,
+ void *data)
+{
+ g_return_if_fail (storage_set != NULL);
+ g_return_if_fail (E_IS_STORAGE_SET (storage_set));
+ g_return_if_fail (source_path != NULL);
+ g_return_if_fail (destination_path != NULL);
+}
+
+/**
+ * e_storage_set_async_move_folder:
+ * @storage_set:
+ * @source_path:
+ * @destination_path:
+ * @callback:
+ * @data:
+ *
+ * Move a folder from @source_path to @destination_path.
+ **/
+void
+e_storage_set_async_move_folder (EStorageSet *storage_set,
+ const char *source_path,
+ const char *destination_path,
+ EStorageResultCallback callback,
+ void *data)
+{
+ g_return_if_fail (storage_set != NULL);
+ g_return_if_fail (E_IS_STORAGE_SET (storage_set));
+ g_return_if_fail (source_path != NULL);
+ g_return_if_fail (destination_path != NULL);
+}
+
+
E_MAKE_TYPE (e_storage_set, "EStorageSet", EStorageSet, class_init, init, PARENT_TYPE)
diff --git a/shell/e-storage-set.h b/shell/e-storage-set.h
index b39725ea1c..66e2ce8ab0 100644
--- a/shell/e-storage-set.h
+++ b/shell/e-storage-set.h
@@ -69,19 +69,16 @@ GtkType e_storage_set_get_type (void);
void e_storage_set_construct (EStorageSet *storage_set,
EFolderTypeRegistry *folder_type_registry);
EStorageSet *e_storage_set_new (EFolderTypeRegistry *folder_type_registry);
-
gboolean e_storage_set_add_storage (EStorageSet *storage_set,
EStorage *storage);
gboolean e_storage_set_remove_storage (EStorageSet *storage_set,
EStorage *storage);
void e_storage_set_remove_all_storages (EStorageSet *storage_set);
-
GList *e_storage_set_get_storage_list (EStorageSet *storage_set);
EStorage *e_storage_set_get_storage (EStorageSet *storage_set,
const char *storage_name);
EFolder *e_storage_set_get_folder (EStorageSet *storage_set,
const char *path);
-
GtkWidget *e_storage_set_new_view (EStorageSet *storage_set);
void e_storage_set_async_create_folder (EStorageSet *storage_set,
@@ -95,6 +92,17 @@ void e_storage_set_async_remove_folder (EStorageSet *storage
EStorageResultCallback callback,
void *data);
+void e_storage_set_async_copy_folder (EStorageSet *storage_set,
+ const char *source_path,
+ const char *destination_path,
+ EStorageResultCallback callback,
+ void *data);
+void e_storage_set_async_move_folder (EStorageSet *storage_set,
+ const char *source_path,
+ const char *destination_path,
+ EStorageResultCallback callback,
+ void *data);
+
EFolderTypeRegistry *e_storage_set_get_folder_type_registry (EStorageSet *storage_set);
/* Utility functions. */