aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--addressbook/gui/component/e-book-shell-sidebar.c1
-rw-r--r--addressbook/gui/component/e-book-shell-view-private.c6
-rw-r--r--addressbook/gui/component/e-book-shell-view-private.h1
-rw-r--r--addressbook/gui/component/eab-composer-util.c1
-rw-r--r--addressbook/gui/widgets/e-addressbook-selector.c310
-rw-r--r--addressbook/gui/widgets/e-addressbook-selector.h7
-rw-r--r--calendar/gui/Makefile.am4
-rw-r--r--calendar/gui/e-calendar-selector.c155
-rw-r--r--calendar/gui/e-memo-list-selector.c287
-rw-r--r--calendar/gui/e-memo-list-selector.h71
-rw-r--r--calendar/gui/e-memos.c120
-rw-r--r--calendar/gui/e-task-list-selector.c288
-rw-r--r--calendar/gui/e-task-list-selector.h71
-rw-r--r--calendar/modules/e-cal-shell-content.c1
-rw-r--r--calendar/modules/e-memo-shell-content.c70
-rw-r--r--calendar/modules/e-memo-shell-sidebar.c4
-rw-r--r--calendar/modules/e-task-shell-content.c68
-rw-r--r--calendar/modules/e-task-shell-sidebar.c4
18 files changed, 1029 insertions, 440 deletions
diff --git a/addressbook/gui/component/e-book-shell-sidebar.c b/addressbook/gui/component/e-book-shell-sidebar.c
index 9532745c98..fd9cdbe925 100644
--- a/addressbook/gui/component/e-book-shell-sidebar.c
+++ b/addressbook/gui/component/e-book-shell-sidebar.c
@@ -21,6 +21,7 @@
#include "e-book-shell-sidebar.h"
+#include <string.h>
#include <glib/gi18n.h>
#include <e-book-shell-view.h>
diff --git a/addressbook/gui/component/e-book-shell-view-private.c b/addressbook/gui/component/e-book-shell-view-private.c
index 90ebad94f8..521260bdeb 100644
--- a/addressbook/gui/component/e-book-shell-view-private.c
+++ b/addressbook/gui/component/e-book-shell-view-private.c
@@ -276,6 +276,12 @@ book_shell_view_activate_selected_source (EBookShellView *book_shell_view,
e_book_shell_content_set_current_view (
book_shell_content, E_ADDRESSBOOK_VIEW (widget));
+ /* XXX We have to keep the addressbook selector informed of the
+ * current view so it can move contacts via drag-and-drop. */
+ e_addressbook_selector_set_current_view (
+ E_ADDRESSBOOK_SELECTOR (selector),
+ E_ADDRESSBOOK_VIEW (widget));
+
view_instance = e_addressbook_view_get_view_instance (view);
view_id = gal_view_instance_get_current_view_id (view_instance);
e_shell_view_set_view_id (shell_view, view_id);
diff --git a/addressbook/gui/component/e-book-shell-view-private.h b/addressbook/gui/component/e-book-shell-view-private.h
index d53ced9440..9bb4f91a22 100644
--- a/addressbook/gui/component/e-book-shell-view-private.h
+++ b/addressbook/gui/component/e-book-shell-view-private.h
@@ -40,6 +40,7 @@
#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h"
#include "addressbook/gui/widgets/eab-gui-util.h"
#include "addressbook/gui/widgets/e-addressbook-view.h"
+#include "addressbook/gui/widgets/e-addressbook-selector.h"
#include <e-book-shell-content.h>
#include <e-book-shell-sidebar.h>
diff --git a/addressbook/gui/component/eab-composer-util.c b/addressbook/gui/component/eab-composer-util.c
index ce3a96cc13..aa994df216 100644
--- a/addressbook/gui/component/eab-composer-util.c
+++ b/addressbook/gui/component/eab-composer-util.c
@@ -18,6 +18,7 @@
#include "eab-composer-util.h"
+#include <string.h>
#include <glib/gi18n.h>
#include <libebook/e-contact.h>
#include <libebook/e-destination.h>
diff --git a/addressbook/gui/widgets/e-addressbook-selector.c b/addressbook/gui/widgets/e-addressbook-selector.c
index 8e498fa380..e7bec99ba2 100644
--- a/addressbook/gui/widgets/e-addressbook-selector.c
+++ b/addressbook/gui/widgets/e-addressbook-selector.c
@@ -33,7 +33,7 @@
typedef struct _MergeContext MergeContext;
struct _EAddressbookSelectorPrivate {
- gint dummy_value;
+ EAddressbookView *current_view;
};
struct _MergeContext {
@@ -49,6 +49,11 @@ struct _MergeContext {
};
enum {
+ PROP_0,
+ PROP_CURRENT_VIEW
+};
+
+enum {
DND_TARGET_TYPE_VCARD,
DND_TARGET_TYPE_SOURCE_VCARD
};
@@ -192,168 +197,124 @@ addressbook_selector_load_primary_source (ESourceSelector *selector)
}
static void
-addressbook_selector_drag_leave (GtkWidget *widget,
- GdkDragContext *context,
- guint time_)
+addressbook_selector_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- /* XXX This is exactly the same as in ECalendarSelector.
- * Consider merging this callback into ESourceSelector. */
-
- GtkTreeView *tree_view;
- GtkTreeViewDropPosition pos;
-
- tree_view = GTK_TREE_VIEW (widget);
- pos = GTK_TREE_VIEW_DROP_BEFORE;
+ switch (property_id) {
+ case PROP_CURRENT_VIEW:
+ e_addressbook_selector_set_current_view (
+ E_ADDRESSBOOK_SELECTOR (object),
+ g_value_get_object (value));
+ return;
+ }
- gtk_tree_view_set_drag_dest_row (tree_view, NULL, pos);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
-static gboolean
-addressbook_selector_drag_motion (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- guint time_)
+static void
+addressbook_selector_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- /* XXX This is exactly the same as in ECalendarSelector.
- * Consider merging this callback into ESourceSelector. */
-
- GtkTreeView *tree_view;
- GtkTreeModel *model;
- GtkTreePath *path = NULL;
- GtkTreeIter iter;
- GtkTreeViewDropPosition pos;
- GdkDragAction action = 0;
- gpointer object;
-
- tree_view = GTK_TREE_VIEW (widget);
- model = gtk_tree_view_get_model (tree_view);
-
- if (!gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &path, NULL))
- goto exit;
-
- if (!gtk_tree_model_get_iter (model, &iter, path))
- goto exit;
-
- gtk_tree_model_get (model, &iter, 0, &object, -1);
-
- if (!E_IS_SOURCE (object) || e_source_get_readonly (object))
- goto exit;
+ switch (property_id) {
+ case PROP_CURRENT_VIEW:
+ g_value_set_object (
+ value,
+ e_addressbook_selector_get_current_view (
+ E_ADDRESSBOOK_SELECTOR (object)));
+ return;
+ }
- gtk_tree_view_set_drag_dest_row (
- tree_view, path, GTK_TREE_VIEW_DROP_INTO_OR_BEFORE);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
- pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
- gtk_tree_view_set_drag_dest_row (tree_view, path, pos);
+static void
+addressbook_selector_dispose (GObject *object)
+{
+ EAddressbookSelectorPrivate *priv;
- if (context->actions & GDK_ACTION_MOVE)
- action = GDK_ACTION_MOVE;
- else
- action = context->suggested_action;
+ priv = E_ADDRESSBOOK_SELECTOR_GET_PRIVATE (object);
-exit:
- if (path != NULL)
- gtk_tree_path_free (path);
+ if (priv->current_view != NULL) {
+ g_object_unref (priv->current_view);
+ priv->current_view = NULL;
+ }
- if (object != NULL)
- g_object_unref (object);
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
- gdk_drag_status (context, action, time_);
+static void
+addressbook_selector_constructed (GObject *object)
+{
+ ESourceSelector *selector;
- return TRUE;
+ selector = E_SOURCE_SELECTOR (object);
+ addressbook_selector_load_primary_source (selector);
}
-static gboolean
-addressbook_selector_drag_drop (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- guint time_)
+static void
+addressbook_selector_primary_selection_changed (ESourceSelector *selector)
{
- /* XXX This is exactly the same as in ECalendarSelector.
- * Consider merging this callback into ESourceSelector. */
-
- GtkTreeView *tree_view;
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
- gboolean drop_zone;
- gboolean valid;
- gpointer object;
-
- tree_view = GTK_TREE_VIEW (widget);
- model = gtk_tree_view_get_model (tree_view);
-
- if (!gtk_tree_view_get_path_at_pos (
- tree_view, x, y, &path, NULL, NULL, NULL))
- return FALSE;
+ ESource *source;
+ GConfClient *client;
+ const gchar *key;
+ const gchar *string;
- valid = gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_path_free (path);
- g_return_val_if_fail (valid, FALSE);
+ /* XXX If ESourceSelector had a "primary-uid" property,
+ * we could just bind the GConf key to it. */
- gtk_tree_model_get (model, &iter, 0, &object, -1);
- drop_zone = E_IS_SOURCE (object);
- g_object_unref (object);
+ source = e_source_selector_peek_primary_selection (selector);
+ if (source == NULL)
+ return;
- return drop_zone;
+ client = gconf_client_get_default ();
+ key = PRIMARY_ADDRESSBOOK_KEY;
+ string = e_source_peek_uid (source);
+ gconf_client_set_string (client, key, string, NULL);
+ g_object_unref (client);
}
-static void
-addressbook_selector_drag_data_received (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *selection_data,
- guint info,
- guint time_)
+static gboolean
+addressbook_selector_data_dropped (ESourceSelector *selector,
+ GtkSelectionData *selection_data,
+ ESource *destination,
+ GdkDragAction action,
+ guint info)
{
- /* XXX This is NEARLY the same as in ECalendarSelector.
- * Consider merging this callback into ESourceSelector.
- * Use a callback to allow subclasses to handle the
- * received selection data. */
-
+ EAddressbookSelectorPrivate *priv;
MergeContext *merge_context;
- GtkTreeView *tree_view;
- GtkTreeModel *model;
- GtkTreePath *path = NULL;
- GtkTreeIter iter;
+ EAddressbookModel *model;
EBook *source_book;
EBook *target_book;
GList *list;
const gchar *string;
gboolean remove_from_source;
- gboolean success = FALSE;
- gpointer object;
- tree_view = GTK_TREE_VIEW (widget);
- model = gtk_tree_view_get_model (tree_view);
+ priv = E_ADDRESSBOOK_SELECTOR_GET_PRIVATE (selector);
+ g_return_val_if_fail (priv->current_view != NULL, FALSE);
string = (const gchar *) selection_data->data;
- remove_from_source = (context->action == GDK_ACTION_MOVE);
-
- if (!gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &path, NULL))
- goto exit;
-
- if (!gtk_tree_model_get_iter (model, &iter, path))
- goto exit;
-
- gtk_tree_model_get (model, &iter, 0, &object, -1);
-
- if (!E_IS_SOURCE (object) || e_source_get_readonly (object))
- goto exit;
+ remove_from_source = (action == GDK_ACTION_MOVE);
- target_book = e_book_new (object, NULL);
+ target_book = e_book_new (destination, NULL);
if (target_book == NULL)
- goto exit;
+ return FALSE;
e_book_open (target_book, FALSE, NULL);
+ /* XXX Function assumes both out arguments are provided. All we
+ * care about is the contact list; source_book will be NULL. */
eab_book_and_contact_list_from_string (string, &source_book, &list);
if (list == NULL)
- goto exit;
+ return FALSE;
- /* XXX Get the currently selected EBook. */
+ model = e_addressbook_view_get_model (priv->current_view);
+ source_book = e_addressbook_model_get_book (model);
+ g_return_val_if_fail (E_IS_BOOK (source_book), FALSE);
merge_context = merge_context_new (source_book, target_book, list);
merge_context->remove_from_source = remove_from_source;
@@ -363,71 +324,38 @@ addressbook_selector_drag_data_received (GtkWidget *widget,
(EBookIdCallback) addressbook_selector_merge_next_cb,
merge_context);
- success = TRUE;
-
-exit:
- if (path != NULL)
- gtk_tree_path_free (path);
-
- if (object != NULL)
- g_object_unref (object);
-
- gtk_drag_finish (context, success, remove_from_source, time_);
-}
-
-static void
-addressbook_selector_primary_selection_changed (ESourceSelector *selector)
-{
- ESource *source;
- GConfClient *client;
- const gchar *key;
- const gchar *string;
-
- /* XXX If ESourceSelector had a "primary-uid" property,
- * we could just bind the GConf key to it. */
-
- source = e_source_selector_peek_primary_selection (selector);
- if (source == NULL)
- return;
-
- client = gconf_client_get_default ();
- key = PRIMARY_ADDRESSBOOK_KEY;
- string = e_source_peek_uid (source);
- gconf_client_set_string (client, key, string, NULL);
- g_object_unref (client);
-}
-
-static void
-addressbook_selector_constructed (GObject *object)
-{
- ESourceSelector *selector;
-
- selector = E_SOURCE_SELECTOR (object);
- addressbook_selector_load_primary_source (selector);
+ return TRUE;
}
static void
addressbook_selector_class_init (EAddressbookSelectorClass *class)
{
GObjectClass *object_class;
- GtkWidgetClass *widget_class;
ESourceSelectorClass *selector_class;
parent_class = g_type_class_peek_parent (class);
g_type_class_add_private (class, sizeof (EAddressbookSelectorPrivate));
object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = addressbook_selector_set_property;
+ object_class->get_property = addressbook_selector_get_property;
+ object_class->dispose = addressbook_selector_dispose;
object_class->constructed = addressbook_selector_constructed;
- widget_class = GTK_WIDGET_CLASS (class);
- widget_class->drag_leave = addressbook_selector_drag_leave;
- widget_class->drag_motion = addressbook_selector_drag_motion;
- widget_class->drag_drop = addressbook_selector_drag_drop;
- widget_class->drag_data_received = addressbook_selector_drag_data_received;
-
selector_class = E_SOURCE_SELECTOR_CLASS (class);
selector_class->primary_selection_changed =
addressbook_selector_primary_selection_changed;
+ selector_class->data_dropped = addressbook_selector_data_dropped;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CURRENT_VIEW,
+ g_param_spec_object (
+ "current-view",
+ NULL,
+ NULL,
+ E_TYPE_ADDRESSBOOK_VIEW,
+ G_PARAM_READWRITE));
}
static void
@@ -477,3 +405,39 @@ e_addressbook_selector_new (ESourceList *source_list)
E_TYPE_ADDRESSBOOK_SELECTOR,
"source-list", source_list, NULL);
}
+
+EAddressbookView *
+e_addressbook_selector_get_current_view (EAddressbookSelector *selector)
+{
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_SELECTOR (selector), NULL);
+
+ return selector->priv->current_view;
+}
+
+void
+e_addressbook_selector_set_current_view (EAddressbookSelector *selector,
+ EAddressbookView *current_view)
+{
+ /* XXX This is only needed for moving contacts via drag-and-drop.
+ * The selection data doesn't include the source of the data
+ * (the model for the currently selected address book view),
+ * so we have to rely on it being provided to us. I would
+ * be happy to see this function go away. */
+
+ g_return_if_fail (E_IS_ADDRESSBOOK_SELECTOR (selector));
+
+ if (current_view != NULL)
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (current_view));
+
+ if (selector->priv->current_view != NULL) {
+ g_object_unref (selector->priv->current_view);
+ selector->priv->current_view = NULL;
+ }
+
+ if (current_view != NULL)
+ g_object_ref (current_view);
+
+ selector->priv->current_view = current_view;
+
+ g_object_notify (G_OBJECT (selector), "current-view");
+}
diff --git a/addressbook/gui/widgets/e-addressbook-selector.h b/addressbook/gui/widgets/e-addressbook-selector.h
index 67a2c8f6e5..c0102cb3b8 100644
--- a/addressbook/gui/widgets/e-addressbook-selector.h
+++ b/addressbook/gui/widgets/e-addressbook-selector.h
@@ -23,6 +23,7 @@
#include <libedataserver/e-source-list.h>
#include <libedataserverui/e-source-selector.h>
+#include "e-addressbook-view.h"
/* Standard GObject macros */
#define E_TYPE_ADDRESSBOOK_SELECTOR \
@@ -60,6 +61,12 @@ struct _EAddressbookSelectorClass {
GType e_addressbook_selector_get_type (void);
GtkWidget * e_addressbook_selector_new (ESourceList *source_list);
+EAddressbookView *
+ e_addressbook_selector_get_current_view
+ (EAddressbookSelector *selector);
+void e_addressbook_selector_set_current_view
+ (EAddressbookSelector *selector,
+ EAddressbookView *current_view);
G_END_DECLS
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index b371ec263b..cf514f251e 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -133,6 +133,8 @@ libcal_gui_la_SOURCES = \
e-meeting-types.h \
e-meeting-utils.c \
e-meeting-utils.h \
+ e-memo-list-selector.c \
+ e-memo-list-selector.h \
e-memo-table.c \
e-memo-table.h \
e-memo-table-config.c \
@@ -143,6 +145,8 @@ libcal_gui_la_SOURCES = \
e-select-names-editable.h \
e-select-names-renderer.c \
e-select-names-renderer.h \
+ e-task-list-selector.c \
+ e-task-list-selector.h \
e-week-view-config.c \
e-week-view-config.h \
e-week-view-event-item.c \
diff --git a/calendar/gui/e-calendar-selector.c b/calendar/gui/e-calendar-selector.c
index 2fecc2eeca..54858e56f9 100644
--- a/calendar/gui/e-calendar-selector.c
+++ b/calendar/gui/e-calendar-selector.c
@@ -103,129 +103,16 @@ calendar_selector_update_objects (ECal *client,
return TRUE;
}
-static void
-calendar_selector_drag_leave (GtkWidget *widget,
- GdkDragContext *context,
- guint time_)
-{
- /* XXX This is exactly the same as in EAddressbookSelector.
- * Consider merging this callback into ESourceSelector. */
-
- GtkTreeView *tree_view;
- GtkTreeViewDropPosition pos;
-
- tree_view = GTK_TREE_VIEW (widget);
- pos = GTK_TREE_VIEW_DROP_BEFORE;
-
- gtk_tree_view_set_drag_dest_row (tree_view, NULL, pos);
-}
-
static gboolean
-calendar_selector_drag_motion (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- guint time_)
+calendar_selector_data_dropped (ESourceSelector *selector,
+ GtkSelectionData *selection_data,
+ ESource *destination,
+ GdkDragAction action,
+ guint info)
{
- /* XXX This is exactly the same as in EAddressbookSelector.
- * Consider merging this callback into ESourceSelector. */
-
GtkTreeView *tree_view;
GtkTreeModel *model;
GtkTreePath *path = NULL;
- GtkTreeIter iter;
- GtkTreeViewDropPosition pos;
- GdkDragAction action = 0;
- gpointer object;
-
- tree_view = GTK_TREE_VIEW (widget);
- model = gtk_tree_view_get_model (tree_view);
-
- if (!gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &path, NULL))
- goto exit;
-
- if (!gtk_tree_model_get_iter (model, &iter, path))
- goto exit;
-
- gtk_tree_model_get (model, &iter, 0, &object, -1);
-
- if (E_IS_SOURCE_GROUP (object) || e_source_get_readonly (object))
- goto exit;
-
- pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
- gtk_tree_view_set_drag_dest_row (tree_view, path, pos);
-
- if (context->actions & GDK_ACTION_MOVE)
- action = GDK_ACTION_MOVE;
- else
- action = context->suggested_action;
-
-exit:
- if (path != NULL)
- gtk_tree_path_free (path);
-
- if (object != NULL)
- g_object_unref (object);
-
- gdk_drag_status (context, action, time_);
-
- return TRUE;
-}
-
-static gboolean
-calendar_selector_drag_drop (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- guint time_)
-{
- /* XXX This is exactly the same as in EAddressbookSelector.
- * Consider merging this callback into ESourceSelector. */
-
- GtkTreeView *tree_view;
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
- gboolean drop_zone;
- gboolean valid;
- gpointer object;
-
- tree_view = GTK_TREE_VIEW (widget);
- model = gtk_tree_view_get_model (tree_view);
-
- if (!gtk_tree_view_get_path_at_pos (
- tree_view, x, y, &path, NULL, NULL, NULL))
- return FALSE;
-
- valid = gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_path_free (path);
- g_return_val_if_fail (valid, FALSE);
-
- gtk_tree_model_get (model, &iter, 0, &object, -1);
- drop_zone = E_IS_SOURCE (object);
- g_object_unref (object);
-
- return drop_zone;
-}
-
-static void
-calendar_selector_drag_data_received (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *selection_data,
- guint info,
- guint time_)
-{
- /* XXX This is NEARLY the same as in EAddressbookSelector.
- * Consider merging this callback into ESourceSelector.
- * Use a callback to allow subclasses to handle the
- * received selection data. */
-
- GtkTreeView *tree_view;
- GtkTreeModel *model;
- GtkTreePath *path = NULL;
- GtkTreeIter iter;
ECal *client;
icalcomponent *icalcomp;
const gchar *string;
@@ -233,22 +120,11 @@ calendar_selector_drag_data_received (GtkWidget *widget,
gboolean success = FALSE;
gpointer object = NULL;
- tree_view = GTK_TREE_VIEW (widget);
+ tree_view = GTK_TREE_VIEW (selector);
model = gtk_tree_view_get_model (tree_view);
string = (const gchar *) selection_data->data;
- remove_from_source = (context->action == GDK_ACTION_MOVE);
-
- if (!gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &path, NULL))
- goto exit;
-
- if (!gtk_tree_model_get_iter (model, &iter, path))
- goto exit;
-
- gtk_tree_model_get (model, &iter, 0, &object, -1);
-
- if (!E_IS_SOURCE (object) || e_source_get_readonly (object))
- goto exit;
+ remove_from_source = (action == GDK_ACTION_MOVE);
icalcomp = icalparser_parse_string (string);
@@ -256,7 +132,7 @@ calendar_selector_drag_data_received (GtkWidget *widget,
goto exit;
/* FIXME Deal with GDK_ACTION_ASK. */
- if (context->action == GDK_ACTION_COPY) {
+ if (action == GDK_ACTION_COPY) {
gchar *uid;
uid = e_cal_component_gen_uid ();
@@ -264,7 +140,7 @@ calendar_selector_drag_data_received (GtkWidget *widget,
}
client = auth_new_cal_from_source (
- E_SOURCE (object), E_CAL_SOURCE_TYPE_EVENT);
+ destination, E_CAL_SOURCE_TYPE_EVENT);
if (client != NULL) {
if (e_cal_open (client, TRUE, NULL)) {
@@ -277,6 +153,8 @@ calendar_selector_drag_data_received (GtkWidget *widget,
icalcomponent_free (icalcomp);
+ success = TRUE;
+
exit:
if (path != NULL)
gtk_tree_path_free (path);
@@ -284,22 +162,19 @@ exit:
if (object != NULL)
g_object_unref (object);
- gtk_drag_finish (context, success, remove_from_source, time_);
+ return TRUE;
}
static void
calendar_selector_class_init (ECalendarSelectorClass *class)
{
- GtkWidgetClass *widget_class;
+ ESourceSelectorClass *source_selector_class;
parent_class = g_type_class_peek_parent (class);
g_type_class_add_private (class, sizeof (ECalendarSelectorPrivate));
- widget_class = GTK_WIDGET_CLASS (class);
- widget_class->drag_leave = calendar_selector_drag_leave;
- widget_class->drag_motion = calendar_selector_drag_motion;
- widget_class->drag_drop = calendar_selector_drag_drop;
- widget_class->drag_data_received = calendar_selector_drag_data_received;
+ source_selector_class = E_SOURCE_SELECTOR_CLASS (class);
+ source_selector_class->data_dropped = calendar_selector_data_dropped;
}
static void
diff --git a/calendar/gui/e-memo-list-selector.c b/calendar/gui/e-memo-list-selector.c
new file mode 100644
index 0000000000..9d3408944b
--- /dev/null
+++ b/calendar/gui/e-memo-list-selector.c
@@ -0,0 +1,287 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-memo-list-selector.c
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "e-memo-list-selector.h"
+
+#include <string.h>
+#include <libecal/e-cal.h>
+#include "calendar/common/authentication.h"
+#include "calendar/gui/comp-util.h"
+
+#define E_MEMO_LIST_SELECTOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelectorPrivate))
+
+struct _EMemoListSelectorPrivate {
+ gint dummy_value;
+};
+
+enum {
+ DND_TARGET_TYPE_CALENDAR_LIST
+};
+
+static GtkTargetEntry drag_types[] = {
+ { "text/calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST },
+ { "text/x-calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST }
+};
+
+static gpointer parent_class;
+
+static gboolean
+memo_list_selector_update_single_object (ECal *client,
+ icalcomponent *icalcomp)
+{
+ gchar *uid;
+ icalcomponent *tmp_icalcomp;
+
+ uid = (gchar *) 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
+memo_list_selector_update_objects (ECal *client,
+ icalcomponent *icalcomp)
+{
+ icalcomponent *subcomp;
+ icalcomponent_kind kind;
+
+ kind = icalcomponent_isa (icalcomp);
+ if (kind == ICAL_VJOURNAL_COMPONENT)
+ return memo_list_selector_update_single_object (
+ client, icalcomp);
+ else if (kind != ICAL_VCALENDAR_COMPONENT)
+ return FALSE;
+
+ subcomp = icalcomponent_get_first_component (
+ icalcomp, ICAL_ANY_COMPONENT);
+ while (subcomp != NULL) {
+ 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 FALSE;
+ } else if (kind == ICAL_VJOURNAL_COMPONENT) {
+ success = memo_list_selector_update_single_object (
+ client, subcomp);
+ if (!success)
+ return FALSE;
+ }
+
+ subcomp = icalcomponent_get_next_component (
+ icalcomp, ICAL_ANY_COMPONENT);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+memo_list_selector_process_data (ESourceSelector *selector,
+ ECal *client,
+ const gchar *source_uid,
+ icalcomponent *icalcomp,
+ GdkDragAction action)
+{
+ ESourceList *source_list;
+ ESource *source;
+ icalcomponent *tmp_icalcomp = NULL;
+ const gchar *uid;
+ gchar *old_uid = NULL;
+ gboolean success = FALSE;
+ gboolean read_only = TRUE;
+ GError *error = NULL;
+
+ /* FIXME Deal with GDK_ACTION_ASK. */
+ if (action == GDK_ACTION_COPY) {
+ old_uid = g_strdup (icalcomponent_get_uid (icalcomp));
+ uid = e_cal_component_gen_uid ();
+ icalcomponent_set_uid (icalcomp, uid);
+ }
+
+ uid = icalcomponent_get_uid (icalcomp);
+ if (old_uid == NULL)
+ old_uid = g_strdup (uid);
+
+ if (e_cal_get_object (client, uid, NULL, &tmp_icalcomp, &error)) {
+ icalcomponent_free (tmp_icalcomp);
+ success = TRUE;
+ goto exit;
+ }
+
+ if (error != NULL && error->code != E_CALENDAR_STATUS_OBJECT_NOT_FOUND) {
+ g_message (
+ "Failed to search the object in destination "
+ "task list: %s", error->message);
+ g_error_free (error);
+ goto exit;
+ }
+
+ success = memo_list_selector_update_objects (client, icalcomp);
+
+ if (!success || action != GDK_ACTION_MOVE)
+ goto exit;
+
+ source_list = e_source_selector_get_source_list (selector);
+ source = e_source_list_peek_source_by_uid (source_list, source_uid);
+
+ if (!E_IS_SOURCE (source) || e_source_get_readonly (source))
+ goto exit;
+
+ client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL);
+ if (client == NULL) {
+ g_message ("Cannot create source client to remove old memo");
+ goto exit;
+ }
+
+ e_cal_is_read_only (client, &read_only, NULL);
+ if (!read_only && e_cal_open (client, TRUE, NULL))
+ e_cal_remove_object (client, old_uid, NULL);
+ else if (!read_only)
+ g_message ("Cannot open source client to remove old memo");
+
+ g_object_unref (client);
+
+exit:
+ g_free (old_uid);
+
+ return success;
+}
+
+static gboolean
+memo_list_selector_data_dropped (ESourceSelector *selector,
+ GtkSelectionData *selection_data,
+ ESource *destination,
+ GdkDragAction action,
+ guint info)
+{
+ ECal *client;
+ GSList *list, *iter;
+ gboolean success = FALSE;
+
+ client = auth_new_cal_from_source (
+ destination, E_CAL_SOURCE_TYPE_JOURNAL);
+
+ if (client == NULL || !e_cal_open (client, TRUE, NULL))
+ goto exit;
+
+ list = cal_comp_selection_get_string_list (selection_data);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ gchar *source_uid = iter->data;
+ icalcomponent *icalcomp;
+ gchar *component_string;
+
+ /* Each string is "source_uid\ncomponent_string". */
+ component_string = strchr (source_uid, '\n');
+ if (component_string == NULL)
+ continue;
+
+ *component_string++ = '\0';
+ icalcomp = icalparser_parse_string (component_string);
+ if (icalcomp == NULL)
+ continue;
+
+ success = memo_list_selector_process_data (
+ selector, client, source_uid, icalcomp, action);
+
+ icalcomponent_free (icalcomp);
+ }
+
+ g_slist_foreach (list, (GFunc) g_free, NULL);
+ g_slist_free (list);
+
+exit:
+ if (client != NULL)
+ g_object_unref (client);
+
+ return success;
+}
+
+static void
+memo_list_selector_class_init (EMemoListSelectorClass *class)
+{
+ ESourceSelectorClass *source_selector_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMemoListSelectorPrivate));
+
+ source_selector_class = E_SOURCE_SELECTOR_CLASS (class);
+ source_selector_class->data_dropped = memo_list_selector_data_dropped;
+}
+
+static void
+memo_list_selector_init (EMemoListSelector *selector)
+{
+ selector->priv = E_MEMO_LIST_SELECTOR_GET_PRIVATE (selector);
+
+ gtk_drag_dest_set (
+ GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL,
+ drag_types, G_N_ELEMENTS (drag_types),
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+}
+
+GType
+e_memo_list_selector_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EMemoListSelectorClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) memo_list_selector_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMemoListSelector),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) memo_list_selector_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ E_TYPE_SOURCE_SELECTOR, "EMemoListSelector",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_memo_list_selector_new (ESourceList *source_list)
+{
+ g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), NULL);
+
+ return g_object_new (
+ E_TYPE_MEMO_LIST_SELECTOR,
+ "source-list", source_list, NULL);
+}
diff --git a/calendar/gui/e-memo-list-selector.h b/calendar/gui/e-memo-list-selector.h
new file mode 100644
index 0000000000..c10cff2a2e
--- /dev/null
+++ b/calendar/gui/e-memo-list-selector.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-memo-list-selector.h
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* XXX This widget is nearly identical to ETaskListSelector. If
+ * ECalendarSelector ever learns how to move selections from
+ * one source to another, perhaps these ESourceSelector sub-
+ * classes could someday be combined. */
+
+#ifndef E_MEMO_LIST_SELECTOR_H
+#define E_MEMO_LIST_SELECTOR_H
+
+#include <libedataserver/e-source-list.h>
+#include <libedataserverui/e-source-selector.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MEMO_LIST_SELECTOR \
+ (e_memo_list_selector_get_type ())
+#define E_MEMO_LIST_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelector))
+#define E_MEMO_LIST_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelectorClass))
+#define E_IS_MEMO_LIST_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MEMO_LIST_SELECTOR))
+#define E_IS_MEMO_LIST_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MEMO_LIST_SELECTOR))
+#define E_MEMO_LIST_SELECTOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelectorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMemoListSelector EMemoListSelector;
+typedef struct _EMemoListSelectorClass EMemoListSelectorClass;
+typedef struct _EMemoListSelectorPrivate EMemoListSelectorPrivate;
+
+struct _EMemoListSelector {
+ ESourceSelector parent;
+ EMemoListSelectorPrivate *priv;
+};
+
+struct _EMemoListSelectorClass {
+ ESourceSelectorClass parent_class;
+};
+
+GType e_memo_list_selector_get_type (void);
+GtkWidget * e_memo_list_selector_new (ESourceList *source_list);
+
+G_END_DECLS
+
+#endif /* E_MEMO_LIST_SELECTOR_H */
diff --git a/calendar/gui/e-memos.c b/calendar/gui/e-memos.c
index 99e9fb2e18..04efd14dd1 100644
--- a/calendar/gui/e-memos.c
+++ b/calendar/gui/e-memos.c
@@ -193,126 +193,6 @@ setup_config (EMemos *memos)
priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
}
-struct AffectedComponents {
- EMemoTable *memo_table;
- GSList *components; /* contains pointers to ECalModelComponent */
-};
-
-/**
- * get_selected_components_cb
- * Helper function to fill list of selected components in EMemoTable.
- * This function is called from e_table_selected_row_foreach.
- **/
-static void
-get_selected_components_cb (int model_row, gpointer data)
-{
- struct AffectedComponents *ac = (struct AffectedComponents *) data;
-
- if (!ac || !ac->memo_table)
- return;
-
- ac->components = g_slist_prepend (ac->components, e_cal_model_get_component_at (E_CAL_MODEL (e_memo_table_get_model (ac->memo_table)), model_row));
-}
-
-/**
- * do_for_selected_components
- * Calls function func for all selected components in memo_table.
- *
- * @param memo_table Table with selected components of our interest.
- * @param func Function to be called on each selected component from cal_table.
- * The first parameter of this function is a pointer to ECalModelComponent and
- * the second parameter of this function is pointer to cal_table
- * @param user_data User data, will be passed to func.
- **/
-static void
-do_for_selected_components (EMemoTable *memo_table, GFunc func, gpointer user_data)
-{
- ETable *etable;
- struct AffectedComponents ac;
-
- g_return_if_fail (memo_table != NULL);
-
- ac.memo_table = memo_table;
- ac.components = NULL;
-
- etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable));
- e_table_selected_row_foreach (etable, get_selected_components_cb, &ac);
-
- g_slist_foreach (ac.components, func, user_data);
- g_slist_free (ac.components);
-}
-
-/**
- * obtain_list_of_components
- * As a callback function to convert each ECalModelComponent to string
- * of format "source_uid\ncomponent_str" and add this newly allocated
- * string to the list of components. Strings should be freed with g_free.
- *
- * @param data ECalModelComponent object.
- * @param user_data Pointer to GSList list, where to put new strings.
- **/
-static void
-obtain_list_of_components (gpointer data, gpointer user_data)
-{
- GSList **list;
- ECalModelComponent *comp_data;
-
- list = (GSList **) user_data;
- comp_data = (ECalModelComponent *) data;
-
- if (list && comp_data) {
- 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) {
- ESource *source = e_cal_get_source (comp_data->client);
- const char *source_uid = e_source_peek_uid (source);
-
- *list = g_slist_prepend (*list, g_strdup_printf ("%s\n%s", source_uid, comp_str));
-
- /* do not free this pointer, it owns libical */
- /* g_free (comp_str); */
- }
-
- icalcomponent_free (vcal);
- g_free (comp_str);
- }
-}
-
-static void
-table_drag_data_get (ETable *table,
- int row,
- int col,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- EMemos *memos)
-{
- EMemosPrivate *priv;
-
- priv = memos->priv;
-
- if (info == TARGET_VCALENDAR) {
- /* we will pass an icalcalendar component for both types */
- GSList *components = NULL;
-
- do_for_selected_components (E_MEMO_TABLE (priv->memos_view), obtain_list_of_components, &components);
-
- if (components) {
- cal_comp_selection_set_string_list (selection_data, components);
-
- g_slist_foreach (components, (GFunc)g_free, NULL);
- g_slist_free (components);
- }
- }
-}
-
static void
setup_widgets (EMemos *memos)
{
diff --git a/calendar/gui/e-task-list-selector.c b/calendar/gui/e-task-list-selector.c
new file mode 100644
index 0000000000..910ab3f33f
--- /dev/null
+++ b/calendar/gui/e-task-list-selector.c
@@ -0,0 +1,288 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-task-list-selector.c
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "e-task-list-selector.h"
+
+#include <string.h>
+#include <libecal/e-cal.h>
+#include "calendar/common/authentication.h"
+#include "calendar/gui/comp-util.h"
+
+#define E_TASK_LIST_SELECTOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelectorPrivate))
+
+struct _ETaskListSelectorPrivate {
+ gint dummy_value;
+};
+
+enum {
+ DND_TARGET_TYPE_CALENDAR_LIST
+};
+
+static GtkTargetEntry drag_types[] = {
+ { "text/calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST },
+ { "text/x-calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST }
+};
+
+static gpointer parent_class;
+
+static gboolean
+task_list_selector_update_single_object (ECal *client,
+ icalcomponent *icalcomp)
+{
+ gchar *uid;
+ icalcomponent *tmp_icalcomp;
+
+ uid = (gchar *) 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
+task_list_selector_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 task_list_selector_update_single_object (
+ client, icalcomp);
+ else if (kind != ICAL_VCALENDAR_COMPONENT)
+ return FALSE;
+
+ subcomp = icalcomponent_get_first_component (
+ icalcomp, ICAL_ANY_COMPONENT);
+ while (subcomp != NULL) {
+ 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 FALSE;
+ } else if (kind == ICAL_VTODO_COMPONENT ||
+ kind == ICAL_VEVENT_COMPONENT) {
+ success = task_list_selector_update_single_object (
+ client, subcomp);
+ if (!success)
+ return FALSE;
+ }
+
+ subcomp = icalcomponent_get_next_component (
+ icalcomp, ICAL_ANY_COMPONENT);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+task_list_selector_process_data (ESourceSelector *selector,
+ ECal *client,
+ const gchar *source_uid,
+ icalcomponent *icalcomp,
+ GdkDragAction action)
+{
+ ESourceList *source_list;
+ ESource *source;
+ icalcomponent *tmp_icalcomp = NULL;
+ const gchar *uid;
+ gchar *old_uid = NULL;
+ gboolean success = FALSE;
+ gboolean read_only = TRUE;
+ GError *error = NULL;
+
+ /* FIXME Deal with GDK_ACTION_ASK. */
+ if (action == GDK_ACTION_COPY) {
+ old_uid = g_strdup (icalcomponent_get_uid (icalcomp));
+ uid = e_cal_component_gen_uid ();
+ icalcomponent_set_uid (icalcomp, uid);
+ }
+
+ uid = icalcomponent_get_uid (icalcomp);
+ if (old_uid == NULL)
+ old_uid = g_strdup (uid);
+
+ if (e_cal_get_object (client, uid, NULL, &tmp_icalcomp, &error)) {
+ icalcomponent_free (tmp_icalcomp);
+ success = TRUE;
+ goto exit;
+ }
+
+ if (error != NULL && error->code != E_CALENDAR_STATUS_OBJECT_NOT_FOUND) {
+ g_message (
+ "Failed to search the object in destination "
+ "task list: %s", error->message);
+ g_error_free (error);
+ goto exit;
+ }
+
+ success = task_list_selector_update_objects (client, icalcomp);
+
+ if (!success || action != GDK_ACTION_MOVE)
+ goto exit;
+
+ source_list = e_source_selector_get_source_list (selector);
+ source = e_source_list_peek_source_by_uid (source_list, source_uid);
+
+ if (!E_IS_SOURCE (source) || e_source_get_readonly (source))
+ goto exit;
+
+ client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO);
+ if (client == NULL) {
+ g_message ("Cannot create source client to remove old task");
+ goto exit;
+ }
+
+ e_cal_is_read_only (client, &read_only, NULL);
+ if (!read_only && e_cal_open (client, TRUE, NULL))
+ e_cal_remove_object (client, old_uid, NULL);
+ else if (!read_only)
+ g_message ("Cannot open source client to remove old task");
+
+ g_object_unref (client);
+
+exit:
+ g_free (old_uid);
+
+ return success;
+}
+
+static gboolean
+task_list_selector_data_dropped (ESourceSelector *selector,
+ GtkSelectionData *selection_data,
+ ESource *destination,
+ GdkDragAction action,
+ guint info)
+{
+ ECal *client;
+ GSList *list, *iter;
+ gboolean success = FALSE;
+
+ client = auth_new_cal_from_source (
+ destination, E_CAL_SOURCE_TYPE_TODO);
+
+ if (client == NULL || !e_cal_open (client, TRUE, NULL))
+ goto exit;
+
+ list = cal_comp_selection_get_string_list (selection_data);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ gchar *source_uid = iter->data;
+ icalcomponent *icalcomp;
+ gchar *component_string;
+
+ /* Each string is "source_uid\ncomponent_string". */
+ component_string = strchr (source_uid, '\n');
+ if (component_string == NULL)
+ continue;
+
+ *component_string++ = '\0';
+ icalcomp = icalparser_parse_string (component_string);
+ if (icalcomp == NULL)
+ continue;
+
+ success = task_list_selector_process_data (
+ selector, client, source_uid, icalcomp, action);
+
+ icalcomponent_free (icalcomp);
+ }
+
+ g_slist_foreach (list, (GFunc) g_free, NULL);
+ g_slist_free (list);
+
+exit:
+ if (client != NULL)
+ g_object_unref (client);
+
+ return success;
+}
+
+static void
+task_list_selector_class_init (ETaskListSelectorClass *class)
+{
+ ESourceSelectorClass *source_selector_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ETaskListSelectorPrivate));
+
+ source_selector_class = E_SOURCE_SELECTOR_CLASS (class);
+ source_selector_class->data_dropped = task_list_selector_data_dropped;
+}
+
+static void
+task_list_selector_init (ETaskListSelector *selector)
+{
+ selector->priv = E_TASK_LIST_SELECTOR_GET_PRIVATE (selector);
+
+ gtk_drag_dest_set (
+ GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL,
+ drag_types, G_N_ELEMENTS (drag_types),
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+}
+
+GType
+e_task_list_selector_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (ETaskListSelectorClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) task_list_selector_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ETaskListSelector),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) task_list_selector_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ E_TYPE_SOURCE_SELECTOR, "ETaskListSelector",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_task_list_selector_new (ESourceList *source_list)
+{
+ g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), NULL);
+
+ return g_object_new (
+ E_TYPE_TASK_LIST_SELECTOR,
+ "source-list", source_list, NULL);
+}
diff --git a/calendar/gui/e-task-list-selector.h b/calendar/gui/e-task-list-selector.h
new file mode 100644
index 0000000000..847a221ba4
--- /dev/null
+++ b/calendar/gui/e-task-list-selector.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-task-list-selector.h
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* XXX This widget is nearly identical to EMemoListSelector. If
+ * ECalendarSelector ever learns how to move selections from
+ * one source to another, perhaps these ESourceSelector sub-
+ * classes could someday be combined. */
+
+#ifndef E_TASK_LIST_SELECTOR_H
+#define E_TASK_LIST_SELECTOR_H
+
+#include <libedataserver/e-source-list.h>
+#include <libedataserverui/e-source-selector.h>
+
+/* Standard GObject macros */
+#define E_TYPE_TASK_LIST_SELECTOR \
+ (e_task_list_selector_get_type ())
+#define E_TASK_LIST_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelector))
+#define E_TASK_LIST_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelectorClass))
+#define E_IS_TASK_LIST_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_TASK_LIST_SELECTOR))
+#define E_IS_TASK_LIST_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_TASK_LIST_SELECTOR))
+#define E_TASK_LIST_SELECTOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelectorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ETaskListSelector ETaskListSelector;
+typedef struct _ETaskListSelectorClass ETaskListSelectorClass;
+typedef struct _ETaskListSelectorPrivate ETaskListSelectorPrivate;
+
+struct _ETaskListSelector {
+ ESourceSelector parent;
+ ETaskListSelectorPrivate *priv;
+};
+
+struct _ETaskListSelectorClass {
+ ESourceSelectorClass parent_class;
+};
+
+GType e_task_list_selector_get_type (void);
+GtkWidget * e_task_list_selector_new (ESourceList *source_list);
+
+G_END_DECLS
+
+#endif /* E_TASK_LIST_SELECTOR_H */
diff --git a/calendar/modules/e-cal-shell-content.c b/calendar/modules/e-cal-shell-content.c
index 80b989f64d..cc1f1ca879 100644
--- a/calendar/modules/e-cal-shell-content.c
+++ b/calendar/modules/e-cal-shell-content.c
@@ -21,6 +21,7 @@
#include "e-cal-shell-content.h"
+#include <string.h>
#include <glib/gi18n.h>
#include "e-util/gconf-bridge.h"
diff --git a/calendar/modules/e-memo-shell-content.c b/calendar/modules/e-memo-shell-content.c
index 82495f836b..006e988c41 100644
--- a/calendar/modules/e-memo-shell-content.c
+++ b/calendar/modules/e-memo-shell-content.c
@@ -26,6 +26,7 @@
#include "e-util/gconf-bridge.h"
#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/comp-util.h"
#include "calendar/gui/e-cal-model-memos.h"
#include "calendar/gui/e-memo-table.h"
#include "calendar/gui/e-memo-table-config.h"
@@ -91,6 +92,45 @@ memo_shell_content_display_view_cb (EMemoShellContent *memo_shell_content,
}
static void
+memo_shell_content_table_foreach_cb (gint model_row,
+ gpointer user_data)
+{
+ ECalModelComponent *comp_data;
+ icalcomponent *clone;
+ icalcomponent *vcal;
+ gchar *string;
+
+ struct {
+ ECalModel *model;
+ GSList *list;
+ } *foreach_data = user_data;
+
+ comp_data = e_cal_model_get_component_at (
+ foreach_data->model, model_row);
+
+ vcal = e_cal_util_new_top_level ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ e_cal_util_add_timezones_from_component (vcal, comp_data->icalcomp);
+ icalcomponent_add_component (vcal, clone);
+
+ /* String is owned by libical; do not free. */
+ string = icalcomponent_as_ical_string (vcal);
+ if (string != NULL) {
+ ESource *source;
+ const gchar *source_uid;
+
+ source = e_cal_get_source (comp_data->client);
+ source_uid = e_source_peek_uid (source);
+
+ foreach_data->list = g_slist_prepend (
+ foreach_data->list,
+ g_strdup_printf ("%s\n%s", source_uid, string));
+ }
+
+ icalcomponent_free (vcal);
+}
+
+static void
memo_shell_content_table_drag_data_get_cb (EMemoShellContent *memo_shell_content,
gint row,
gint col,
@@ -99,7 +139,33 @@ memo_shell_content_table_drag_data_get_cb (EMemoShellContent *memo_shell_content
guint info,
guint time)
{
- /* FIXME */
+ EMemoTable *memo_table;
+ ETable *table;
+
+ struct {
+ ECalModel *model;
+ GSList *list;
+ } foreach_data;
+
+ if (info != TARGET_VCALENDAR)
+ return;
+
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+ table = e_memo_table_get_table (memo_table);
+
+ foreach_data.model = e_memo_table_get_model (memo_table);
+ foreach_data.list = NULL;
+
+ e_table_selected_row_foreach (
+ table, memo_shell_content_table_foreach_cb,
+ &foreach_data);
+
+ if (foreach_data.list != NULL) {
+ cal_comp_selection_set_string_list (
+ selection_data, foreach_data.list);
+ g_slist_foreach (foreach_data.list, (GFunc) g_free, NULL);
+ g_slist_free (foreach_data.list);
+ }
}
static void
@@ -110,7 +176,7 @@ memo_shell_content_table_drag_data_delete_cb (EMemoShellContent *memo_shell_cont
{
/* Moved components are deleted from source immediately when moved,
* because some of them can be part of destination source, and we
- * don't want to delete not-moved tasks. There is no such information
+ * don't want to delete not-moved memos. There is no such information
* which event has been moved and which not, so skip this method. */
}
diff --git a/calendar/modules/e-memo-shell-sidebar.c b/calendar/modules/e-memo-shell-sidebar.c
index d66f4881b1..d676a9bf58 100644
--- a/calendar/modules/e-memo-shell-sidebar.c
+++ b/calendar/modules/e-memo-shell-sidebar.c
@@ -29,7 +29,7 @@
#include "e-util/e-util.h"
#include "calendar/common/authentication.h"
#include "calendar/gui/calendar-config.h"
-#include "calendar/gui/e-calendar-selector.h"
+#include "calendar/gui/e-memo-list-selector.h"
#include "calendar/gui/misc.h"
#include "e-memo-shell-view.h"
@@ -388,7 +388,7 @@ memo_shell_sidebar_constructed (GObject *object)
container = GTK_CONTAINER (widget);
- widget = e_calendar_selector_new (source_list);
+ widget = e_memo_list_selector_new (source_list);
e_source_selector_set_select_new (E_SOURCE_SELECTOR (widget), TRUE);
gtk_container_add (container, widget);
a11y = gtk_widget_get_accessible (widget);
diff --git a/calendar/modules/e-task-shell-content.c b/calendar/modules/e-task-shell-content.c
index febd0c9ef2..5e98bf2f49 100644
--- a/calendar/modules/e-task-shell-content.c
+++ b/calendar/modules/e-task-shell-content.c
@@ -26,6 +26,7 @@
#include "e-util/gconf-bridge.h"
#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/comp-util.h"
#include "calendar/gui/e-cal-model-tasks.h"
#include "calendar/gui/e-calendar-table.h"
#include "calendar/gui/e-calendar-table-config.h"
@@ -92,6 +93,45 @@ task_shell_content_display_view_cb (ETaskShellContent *task_shell_content,
}
static void
+task_shell_content_table_foreach_cb (gint model_row,
+ gpointer user_data)
+{
+ ECalModelComponent *comp_data;
+ icalcomponent *clone;
+ icalcomponent *vcal;
+ gchar *string;
+
+ struct {
+ ECalModel *model;
+ GSList *list;
+ } *foreach_data = user_data;
+
+ comp_data = e_cal_model_get_component_at (
+ foreach_data->model, model_row);
+
+ vcal = e_cal_util_new_top_level ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ e_cal_util_add_timezones_from_component (vcal, comp_data->icalcomp);
+ icalcomponent_add_component (vcal, clone);
+
+ /* String is owned by libical; do not free. */
+ string = icalcomponent_as_ical_string (vcal);
+ if (string != NULL) {
+ ESource *source;
+ const gchar *source_uid;
+
+ source = e_cal_get_source (comp_data->client);
+ source_uid = e_source_peek_uid (source);
+
+ foreach_data->list = g_slist_prepend (
+ foreach_data->list,
+ g_strdup_printf ("%s\n%s", source_uid, string));
+ }
+
+ icalcomponent_free (vcal);
+}
+
+static void
task_shell_content_table_drag_data_get_cb (ETaskShellContent *task_shell_content,
gint row,
gint col,
@@ -100,7 +140,33 @@ task_shell_content_table_drag_data_get_cb (ETaskShellContent *task_shell_content
guint info,
guint time)
{
- /* FIXME */
+ ECalendarTable *task_table;
+ ETable *table;
+
+ struct {
+ ECalModel *model;
+ GSList *list;
+ } foreach_data;
+
+ if (info != TARGET_VCALENDAR)
+ return;
+
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ table = e_calendar_table_get_table (task_table);
+
+ foreach_data.model = e_calendar_table_get_model (task_table);
+ foreach_data.list = NULL;
+
+ e_table_selected_row_foreach (
+ table, task_shell_content_table_foreach_cb,
+ &foreach_data);
+
+ if (foreach_data.list != NULL) {
+ cal_comp_selection_set_string_list (
+ selection_data, foreach_data.list);
+ g_slist_foreach (foreach_data.list, (GFunc) g_free, NULL);
+ g_slist_free (foreach_data.list);
+ }
}
static void
diff --git a/calendar/modules/e-task-shell-sidebar.c b/calendar/modules/e-task-shell-sidebar.c
index bce2684515..6f2f1bb409 100644
--- a/calendar/modules/e-task-shell-sidebar.c
+++ b/calendar/modules/e-task-shell-sidebar.c
@@ -29,7 +29,7 @@
#include "e-util/e-util.h"
#include "calendar/common/authentication.h"
#include "calendar/gui/calendar-config.h"
-#include "calendar/gui/e-calendar-selector.h"
+#include "calendar/gui/e-task-list-selector.h"
#include "calendar/gui/misc.h"
#include "e-task-shell-view.h"
@@ -361,7 +361,7 @@ task_shell_sidebar_constructed (GObject *object)
container = GTK_CONTAINER (widget);
- widget = e_calendar_selector_new (source_list);
+ widget = e_task_list_selector_new (source_list);
e_source_selector_set_select_new (E_SOURCE_SELECTOR (widget), TRUE);
gtk_container_add (container, widget);
a11y = gtk_widget_get_accessible (widget);