aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui
diff options
context:
space:
mode:
authorLarry Ewing <lewing@ximian.com>2004-06-02 17:33:36 +0800
committerLarry Ewing <lewing@src.gnome.org>2004-06-02 17:33:36 +0800
commit5786eb64a18ed1302ac6e10dc8aea2cc2d346ba1 (patch)
treeb186572bef6c3a1d2f3116682e0d50449d5b5e10 /calendar/gui
parent55e7f9a951704df272a3c56468be510cf0482e48 (diff)
downloadgsoc2013-evolution-5786eb64a18ed1302ac6e10dc8aea2cc2d346ba1.tar
gsoc2013-evolution-5786eb64a18ed1302ac6e10dc8aea2cc2d346ba1.tar.gz
gsoc2013-evolution-5786eb64a18ed1302ac6e10dc8aea2cc2d346ba1.tar.bz2
gsoc2013-evolution-5786eb64a18ed1302ac6e10dc8aea2cc2d346ba1.tar.lz
gsoc2013-evolution-5786eb64a18ed1302ac6e10dc8aea2cc2d346ba1.tar.xz
gsoc2013-evolution-5786eb64a18ed1302ac6e10dc8aea2cc2d346ba1.tar.zst
gsoc2013-evolution-5786eb64a18ed1302ac6e10dc8aea2cc2d346ba1.zip
add a drag delete handler. (table_drag_data_get): support text/vcard
2004-06-02 Larry Ewing <lewing@ximian.com> * gui/e-tasks.c (table_drag_data_delete): add a drag delete handler. (table_drag_data_get): support text/vcard drags. (setup_widgets): setup the etable as a drag source. * gui/tasks-component.c: add source selector Drag & Drop handlers. svn path=/trunk/; revision=26151
Diffstat (limited to 'calendar/gui')
-rw-r--r--calendar/gui/e-tasks.c121
-rw-r--r--calendar/gui/tasks-component.c236
2 files changed, 357 insertions, 0 deletions
diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c
index 22b2b1ce29..947cf60a11 100644
--- a/calendar/gui/e-tasks.c
+++ b/calendar/gui/e-tasks.c
@@ -102,6 +102,16 @@ enum {
LAST_SIGNAL
};
+enum DndTargetType {
+ TARGET_VCALENDAR
+};
+
+static GtkTargetEntry list_drag_types[] = {
+ { "text/calendar", 0, TARGET_VCALENDAR },
+ { "text/x-calendar", 0, TARGET_VCALENDAR }
+};
+static const int num_list_drag_types = sizeof (list_drag_types) / sizeof (list_drag_types[0]);
+
static GtkTableClass *parent_class;
static guint e_tasks_signals[LAST_SIGNAL] = { 0 };
@@ -325,6 +335,96 @@ setup_config (ETasks *tasks)
priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
}
+static void
+table_drag_data_get (ETable *table,
+ int row,
+ int col,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ ETasks *tasks)
+{
+ ETasksPrivate *priv;
+ ECalModelComponent *comp_data;
+
+ priv = tasks->priv;
+
+ if (priv->current_uid) {
+ ETableModel *model;
+
+ model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
+
+ comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
+
+ if (info == TARGET_VCALENDAR) {
+ /* we will pass an icalcalendar component for both types */
+ char *comp_str;
+ icalcomponent *vcal;
+
+ vcal = e_cal_util_new_top_level ();
+ e_cal_util_add_timezones_from_component (vcal, comp_data->icalcomp);
+ icalcomponent_add_component (
+ vcal,
+ icalcomponent_new_clone (comp_data->icalcomp));
+
+ comp_str = icalcomponent_as_ical_string (vcal);
+ if (comp_str) {
+ gtk_selection_data_set (selection_data, selection_data->target,
+ 8, comp_str, strlen (comp_str));
+ }
+ icalcomponent_free (vcal);
+ }
+ }
+}
+
+/*
+static void
+table_drag_begin (ETable *table,
+ int row,
+ int col,
+ GdkDragContext *context,
+ ETasks *tasks)
+{
+
+}
+
+
+static void
+table_drag_end (ETable *table,
+ int row,
+ int col,
+ GdkDragContext *context,
+ ETasks *tasks)
+{
+
+}
+*/
+
+static void
+table_drag_data_delete (ETable *table,
+ int row,
+ int col,
+ GdkDragContext *context,
+ ETasks *tasks)
+{
+ ETasksPrivate *priv;
+ ECalModelComponent *comp_data;
+ ETableModel *model;
+ gboolean read_only = TRUE;
+
+ priv = tasks->priv;
+
+ model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
+ comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
+
+ e_cal_is_read_only (comp_data->client, &read_only, NULL);
+ if (read_only)
+ return;
+
+ e_cal_remove_object (comp_data->client, icalcomponent_get_uid (comp_data->icalcomp), NULL);
+}
+
#define E_TASKS_TABLE_DEFAULT_STATE \
"<?xml version=\"1.0\"?>" \
"<ETableState>" \
@@ -374,6 +474,27 @@ setup_widgets (ETasks *tasks)
gtk_paned_add1 (GTK_PANED (paned), priv->tasks_view);
gtk_widget_show (priv->tasks_view);
+
+ e_table_drag_source_set (etable, GDK_BUTTON1_MASK,
+ list_drag_types, num_list_drag_types,
+ GDK_ACTION_MOVE|GDK_ACTION_COPY|GDK_ACTION_ASK);
+
+ g_signal_connect (etable, "table_drag_data_get",
+ G_CALLBACK(table_drag_data_get), tasks);
+ g_signal_connect (etable, "table_drag_data_delete",
+ G_CALLBACK(table_drag_data_delete), tasks);
+ /*
+ e_table_drag_dest_set (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
+ 0, list_drag_types, num_list_drag_types, GDK_ACTION_LINK);
+
+ g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
+ "table_drag_motion", G_CALLBACK(table_drag_motion_cb), editor);
+ g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
+ "table_drag_drop", G_CALLBACK (table_drag_drop_cb), editor);
+ g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
+ "table_drag_data_received", G_CALLBACK(table_drag_data_received_cb), editor);
+ */
+
g_signal_connect (etable, "cursor_change", G_CALLBACK (table_cursor_change_cb), tasks);
g_signal_connect (etable, "selection_change", G_CALLBACK (table_selection_change_cb), tasks);
diff --git a/calendar/gui/tasks-component.c b/calendar/gui/tasks-component.c
index 054ed3fe62..2f76ce0110 100644
--- a/calendar/gui/tasks-component.c
+++ b/calendar/gui/tasks-component.c
@@ -52,6 +52,16 @@
#define CREATE_TASK_ID "task"
#define CREATE_TASK_LIST_ID "task-list"
+enum DndTargetType {
+ DND_TARGET_TYPE_CALENDAR_LIST,
+};
+#define CALENDAR_TYPE "text/calendar"
+#define XCALENDAR_TYPE "text/x-calendar"
+static GtkTargetEntry drag_types[] = {
+ { CALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST },
+ { XCALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST }
+};
+static gint num_drag_types = sizeof(drag_types) / sizeof(drag_types[0]);
#define PARENT_TYPE bonobo_object_get_type ()
@@ -453,6 +463,219 @@ impl_upgradeFromVersion (PortableServer_Servant servant,
g_error_free(err);
}
+static gboolean
+selector_tree_drag_drop (GtkWidget *widget,
+ GdkDragContext *context,
+ int x,
+ int y,
+ guint time,
+ CalendarComponent *component)
+{
+ GtkTreeViewColumn *column;
+ int cell_x;
+ int cell_y;
+ GtkTreePath *path;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gpointer data;
+
+ if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), x, y, &path,
+ &column, &cell_x, &cell_y))
+ return FALSE;
+
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+
+ if (!gtk_tree_model_get_iter (model, &iter, path)) {
+ gtk_tree_path_free (path);
+ return FALSE;
+ }
+
+ gtk_tree_model_get (model, &iter, 0, &data, -1);
+
+ if (E_IS_SOURCE_GROUP (data)) {
+ g_object_unref (data);
+ gtk_tree_path_free (path);
+ return FALSE;
+ }
+
+ gtk_tree_path_free (path);
+ return TRUE;
+}
+
+static gboolean
+selector_tree_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ int x,
+ int y,
+ guint time,
+ gpointer user_data)
+{
+ GtkTreePath *path = NULL;
+ gpointer data = NULL;
+ GtkTreeViewDropPosition pos;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GdkDragAction action = GDK_ACTION_DEFAULT;
+
+ if (!gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget),
+ x, y, &path, &pos))
+ goto finish;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+
+ if (!gtk_tree_model_get_iter (model, &iter, path))
+ goto finish;
+
+ gtk_tree_model_get (model, &iter, 0, &data, -1);
+
+ if (E_IS_SOURCE_GROUP (data) || e_source_get_readonly (data))
+ goto finish;
+
+ gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW (widget), path, GTK_TREE_VIEW_DROP_INTO_OR_BEFORE);
+ action = context->suggested_action;
+
+ finish:
+ if (path)
+ gtk_tree_path_free (path);
+ if (data)
+ g_object_unref (data);
+
+ gdk_drag_status (context, action, time);
+ return TRUE;
+}
+
+static gboolean
+update_single_object (ECal *client, icalcomponent *icalcomp)
+{
+ char *uid;
+ icalcomponent *tmp_icalcomp;
+
+ uid = (char *) icalcomponent_get_uid (icalcomp);
+
+ if (e_cal_get_object (client, uid, NULL, &tmp_icalcomp, NULL))
+ return e_cal_modify_object (client, icalcomp, CALOBJ_MOD_ALL, NULL);
+
+ return e_cal_create_object (client, icalcomp, &uid, NULL);
+}
+
+static gboolean
+update_objects (ECal *client, icalcomponent *icalcomp)
+{
+ icalcomponent *subcomp;
+ icalcomponent_kind kind;
+
+ kind = icalcomponent_isa (icalcomp);
+ if (kind == ICAL_VTODO_COMPONENT || kind == ICAL_VEVENT_COMPONENT)
+ return update_single_object (client, icalcomp);
+ else if (kind != ICAL_VCALENDAR_COMPONENT)
+ return FALSE;
+
+ subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT);
+ while (subcomp) {
+ gboolean success;
+
+ kind = icalcomponent_isa (subcomp);
+ if (kind == ICAL_VTIMEZONE_COMPONENT) {
+ icaltimezone *zone;
+
+ zone = icaltimezone_new ();
+ icaltimezone_set_component (zone, subcomp);
+
+ success = e_cal_add_timezone (client, zone, NULL);
+ icaltimezone_free (zone, 1);
+ if (!success)
+ return success;
+ } else if (kind == ICAL_VTODO_COMPONENT ||
+ kind == ICAL_VEVENT_COMPONENT) {
+ success = update_single_object (client, subcomp);
+ if (!success)
+ return success;
+ }
+
+ subcomp = icalcomponent_get_next_component (icalcomp, ICAL_ANY_COMPONENT);
+ }
+
+ return TRUE;
+}
+
+static void
+selector_tree_drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint info,
+ guint time,
+ gpointer user_data)
+{
+ GtkTreePath *path = NULL;
+ GtkTreeViewDropPosition pos;
+ gpointer source = NULL;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean success = FALSE;
+ icalcomponent *icalcomp = NULL;
+ ECal *client = NULL;
+
+ if (!gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget),
+ x, y, &path, &pos))
+ goto finish;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+
+ if (!gtk_tree_model_get_iter (model, &iter, path))
+ goto finish;
+
+
+ gtk_tree_model_get (model, &iter, 0, &source, -1);
+
+ if (E_IS_SOURCE_GROUP (source) || e_source_get_readonly (source))
+ goto finish;
+
+ icalcomp = icalparser_parse_string (data->data);
+
+ if (icalcomp) {
+ char * uid;
+
+ /* FIXME deal with GDK_ACTION_ASK */
+ if (context->action == GDK_ACTION_COPY) {
+ uid = e_cal_component_gen_uid ();
+ icalcomponent_set_uid (icalcomp, uid);
+ }
+
+ client = auth_new_cal_from_source (source,
+ E_CAL_SOURCE_TYPE_TODO);
+
+ if (client) {
+ if (e_cal_open (client, TRUE, NULL)) {
+ success = TRUE;
+ update_objects (client, icalcomp);
+ }
+
+ g_object_unref (client);
+ }
+
+ icalcomponent_free (icalcomp);
+ }
+
+ finish:
+ if (source)
+ g_object_unref (source);
+ if (path)
+ gtk_tree_path_free (path);
+
+ gtk_drag_finish (context, success, context->action == GDK_ACTION_MOVE, time);
+}
+
+static void
+selector_tree_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, gpointer data)
+{
+ gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW (widget),
+ NULL, GTK_TREE_VIEW_DROP_BEFORE);
+}
+
+
static void
control_activate_cb (BonoboControl *control, gboolean activate, gpointer data)
{
@@ -634,6 +857,19 @@ create_component_view (TasksComponent *tasks_component)
/* Create sidebar selector */
component_view->source_selector = e_source_selector_new (tasks_component->priv->source_list);
+
+ g_signal_connect (component_view->source_selector, "drag-motion", G_CALLBACK (selector_tree_drag_motion),
+ tasks_component);
+ g_signal_connect (component_view->source_selector, "drag-leave", G_CALLBACK (selector_tree_drag_leave),
+ tasks_component);
+ g_signal_connect (component_view->source_selector, "drag-drop", G_CALLBACK (selector_tree_drag_drop),
+ tasks_component);
+ g_signal_connect (component_view->source_selector, "drag-data-received",
+ G_CALLBACK (selector_tree_drag_data_received), tasks_component);
+
+ gtk_drag_dest_set(component_view->source_selector, GTK_DEST_DEFAULT_ALL, drag_types,
+ num_drag_types, GDK_ACTION_COPY | GDK_ACTION_MOVE);
+
gtk_widget_show (component_view->source_selector);
selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL);