evolution-3.6.4/calendar/gui/e-calendar-selector.c

No issues found

  1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
  2 /* e-calendar-selector.c
  3  *
  4  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  5  *
  6  * This program is free software; you can redistribute it and/or
  7  * modify it under the terms of version 2 of the GNU General Public
  8  * License as published by the Free Software Foundation.
  9  *
 10  * This program is distributed in the hope that it will be useful,
 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  * General Public License for more details.
 14  *
 15  * You should have received a copy of the GNU General Public
 16  * License along with this program; if not, write to the
 17  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 18  * Boston, MA 02110-1301, USA.
 19  */
 20 
 21 #include <config.h>
 22 
 23 #include "e-calendar-selector.h"
 24 
 25 #include <libecal/libecal.h>
 26 
 27 #include "e-util/e-selection.h"
 28 
 29 #define E_CALENDAR_SELECTOR_GET_PRIVATE(obj) \
 30 	(G_TYPE_INSTANCE_GET_PRIVATE \
 31 	((obj), E_TYPE_CALENDAR_SELECTOR, ECalendarSelectorPrivate))
 32 
 33 struct _ECalendarSelectorPrivate {
 34 	gint dummy_value;
 35 };
 36 
 37 G_DEFINE_TYPE (
 38 	ECalendarSelector,
 39 	e_calendar_selector,
 40 	E_TYPE_SOURCE_SELECTOR)
 41 
 42 static gboolean
 43 calendar_selector_update_single_object (ECalClient *client,
 44                                         icalcomponent *icalcomp)
 45 {
 46 	gchar *uid;
 47 	icalcomponent *tmp_icalcomp;
 48 
 49 	uid = (gchar *) icalcomponent_get_uid (icalcomp);
 50 
 51 	if (e_cal_client_get_object_sync (client, uid, NULL, &tmp_icalcomp, NULL, NULL)) {
 52 		icalcomponent_free (tmp_icalcomp);
 53 
 54 		return e_cal_client_modify_object_sync (
 55 			client, icalcomp, CALOBJ_MOD_ALL, NULL, NULL);
 56 	}
 57 
 58 	uid = NULL;
 59 	if (!e_cal_client_create_object_sync (client, icalcomp, &uid, NULL, NULL))
 60 		return FALSE;
 61 
 62 	if (uid)
 63 		icalcomponent_set_uid (icalcomp, uid);
 64 	g_free (uid);
 65 
 66 	return TRUE;
 67 }
 68 
 69 static gboolean
 70 calendar_selector_update_objects (ECalClient *client,
 71                                   icalcomponent *icalcomp)
 72 {
 73 	icalcomponent *subcomp;
 74 	icalcomponent_kind kind;
 75 
 76 	kind = icalcomponent_isa (icalcomp);
 77 	if (kind == ICAL_VTODO_COMPONENT || kind == ICAL_VEVENT_COMPONENT)
 78 		return calendar_selector_update_single_object (
 79 			client, icalcomp);
 80 	else if (kind != ICAL_VCALENDAR_COMPONENT)
 81 		return FALSE;
 82 
 83 	subcomp = icalcomponent_get_first_component (
 84 		icalcomp, ICAL_ANY_COMPONENT);
 85 	while (subcomp != NULL) {
 86 		gboolean success;
 87 
 88 		kind = icalcomponent_isa (subcomp);
 89 		if (kind == ICAL_VTIMEZONE_COMPONENT) {
 90 			icaltimezone *zone;
 91 			GError *error = NULL;
 92 
 93 			zone = icaltimezone_new ();
 94 			icaltimezone_set_component (zone, subcomp);
 95 
 96 			e_cal_client_add_timezone_sync (client, zone, NULL, &error);
 97 			icaltimezone_free (zone, 1);
 98 
 99 			if (error != NULL) {
100 				g_warning (
101 					"%s: Failed to add timezone: %s",
102 					G_STRFUNC, error->message);
103 				g_error_free (error);
104 				return FALSE;
105 			}
106 		} else if (kind == ICAL_VTODO_COMPONENT ||
107 			kind == ICAL_VEVENT_COMPONENT) {
108 			success = calendar_selector_update_single_object (
109 				client, subcomp);
110 			if (!success)
111 				return FALSE;
112 		}
113 
114 		subcomp = icalcomponent_get_next_component (
115 			icalcomp, ICAL_ANY_COMPONENT);
116 	}
117 
118 	return TRUE;
119 }
120 
121 static void
122 client_opened_cb (GObject *source_object,
123                   GAsyncResult *result,
124                   gpointer user_data)
125 {
126 	ESource *source = E_SOURCE (source_object);
127 	EClient *client = NULL;
128 	icalcomponent *icalcomp = user_data;
129 	GError *error = NULL;
130 
131 	g_return_if_fail (icalcomp != NULL);
132 
133 	e_client_utils_open_new_finish (source, result, &client, &error);
134 
135 	if (error != NULL) {
136 		g_warn_if_fail (client == NULL);
137 		g_warning (
138 			"%s: Failed to open client: %s",
139 			G_STRFUNC, error->message);
140 		g_error_free (error);
141 	}
142 
143 	g_return_if_fail (E_IS_CLIENT (client));
144 
145 	calendar_selector_update_objects (E_CAL_CLIENT (client), icalcomp);
146 	g_object_unref (client);
147 
148 	icalcomponent_free (icalcomp);
149 }
150 
151 static void
152 calendar_selector_constructed (GObject *object)
153 {
154 	ESourceSelector *selector;
155 	ESourceRegistry *registry;
156 	ESource *source;
157 
158 	selector = E_SOURCE_SELECTOR (object);
159 	registry = e_source_selector_get_registry (selector);
160 	source = e_source_registry_ref_default_calendar (registry);
161 	e_source_selector_set_primary_selection (selector, source);
162 	g_object_unref (source);
163 
164 	/* Chain up to parent's constructed() method. */
165 	G_OBJECT_CLASS (e_calendar_selector_parent_class)->
166 		constructed (object);
167 }
168 
169 static gboolean
170 calendar_selector_data_dropped (ESourceSelector *selector,
171                                 GtkSelectionData *selection_data,
172                                 ESource *destination,
173                                 GdkDragAction action,
174                                 guint info)
175 {
176 	GtkTreePath *path = NULL;
177 	icalcomponent *icalcomp;
178 	const guchar *data;
179 	gboolean success = FALSE;
180 	gpointer object = NULL;
181 
182 	data = gtk_selection_data_get_data (selection_data);
183 	icalcomp = icalparser_parse_string ((const gchar *) data);
184 
185 	if (icalcomp == NULL)
186 		goto exit;
187 
188 	/* FIXME Deal with GDK_ACTION_ASK. */
189 	if (action == GDK_ACTION_COPY) {
190 		gchar *uid;
191 
192 		uid = e_cal_component_gen_uid ();
193 		icalcomponent_set_uid (icalcomp, uid);
194 	}
195 
196 	e_client_utils_open_new (
197 		destination, E_CLIENT_SOURCE_TYPE_EVENTS, FALSE, NULL,
198 		client_opened_cb, icalcomp);
199 
200 	success = TRUE;
201 
202 exit:
203 	if (path != NULL)
204 		gtk_tree_path_free (path);
205 
206 	if (object != NULL)
207 		g_object_unref (object);
208 
209 	return success;
210 }
211 
212 static void
213 e_calendar_selector_class_init (ECalendarSelectorClass *class)
214 {
215 	GObjectClass *object_class;
216 	ESourceSelectorClass *source_selector_class;
217 
218 	g_type_class_add_private (class, sizeof (ECalendarSelectorPrivate));
219 
220 	object_class = G_OBJECT_CLASS (class);
221 	object_class->constructed = calendar_selector_constructed;
222 
223 	source_selector_class = E_SOURCE_SELECTOR_CLASS (class);
224 	source_selector_class->data_dropped = calendar_selector_data_dropped;
225 }
226 
227 static void
228 e_calendar_selector_init (ECalendarSelector *selector)
229 {
230 	selector->priv = E_CALENDAR_SELECTOR_GET_PRIVATE (selector);
231 
232 	gtk_drag_dest_set (
233 		GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL,
234 		NULL, 0, GDK_ACTION_COPY | GDK_ACTION_MOVE);
235 
236 	e_drag_dest_add_calendar_targets (GTK_WIDGET (selector));
237 }
238 
239 GtkWidget *
240 e_calendar_selector_new (ESourceRegistry *registry)
241 {
242 	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
243 
244 	return g_object_new (
245 		E_TYPE_CALENDAR_SELECTOR,
246 		"extension-name", E_SOURCE_EXTENSION_CALENDAR,
247 		"registry", registry, NULL);
248 }