No issues found
1 /*
2 * Evolution calendar - Send calendar component dialog
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
16 *
17 *
18 * Authors:
19 * JP Rosevear <jpr@ximian.com>
20 *
21 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <glib/gi18n-lib.h>
30 #include "libevolution-utils/e-alert-dialog.h"
31 #include "send-comp.h"
32
33 static gboolean
34 component_has_new_attendees (ECalComponent *comp)
35 {
36 g_return_val_if_fail (comp != NULL, FALSE);
37
38 if (!e_cal_component_has_attendees (comp))
39 return FALSE;
40
41 return g_object_get_data (G_OBJECT (comp), "new-attendees") != NULL;
42 }
43
44 static gboolean
45 component_has_recipients (ECalComponent *comp)
46 {
47 GSList *attendees = NULL;
48 ECalComponentAttendee *attendee;
49 ECalComponentOrganizer organizer;
50 gboolean res = FALSE;
51
52 g_return_val_if_fail (comp != NULL, FALSE);
53
54 e_cal_component_get_organizer (comp, &organizer);
55 e_cal_component_get_attendee_list (comp, &attendees);
56
57 if (!attendees) {
58 if (organizer.value && e_cal_component_get_vtype (comp) == E_CAL_COMPONENT_JOURNAL) {
59 /* memos store recipients in an extra property */
60 icalcomponent *icalcomp;
61 icalproperty *icalprop;
62
63 icalcomp = e_cal_component_get_icalcomponent (comp);
64
65 for (icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
66 icalprop != NULL;
67 icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY)) {
68 const gchar *x_name;
69
70 x_name = icalproperty_get_x_name (icalprop);
71
72 if (g_str_equal (x_name, "X-EVOLUTION-RECIPIENTS")) {
73 const gchar *str_recipients = icalproperty_get_x (icalprop);
74
75 res = str_recipients && g_ascii_strcasecmp (organizer.value, str_recipients) != 0;
76 break;
77 }
78 }
79 }
80
81 return res;
82 }
83
84 if (g_slist_length (attendees) > 1 || !e_cal_component_has_organizer (comp)) {
85 e_cal_component_free_attendee_list (attendees);
86 return TRUE;
87 }
88
89 attendee = attendees->data;
90
91 res = organizer.value && attendee && attendee->value && g_ascii_strcasecmp (organizer.value, attendee->value) != 0;
92
93 e_cal_component_free_attendee_list (attendees);
94
95 return res;
96 }
97
98 static gboolean
99 have_nonprocedural_alarm (ECalComponent *comp)
100 {
101 GList *uids, *l;
102
103 g_return_val_if_fail (comp != NULL, FALSE);
104
105 uids = e_cal_component_get_alarm_uids (comp);
106
107 for (l = uids; l; l = l->next) {
108 ECalComponentAlarm *alarm;
109 ECalComponentAlarmAction action = E_CAL_COMPONENT_ALARM_UNKNOWN;
110
111 alarm = e_cal_component_get_alarm (comp, (const gchar *) l->data);
112 if (alarm) {
113 e_cal_component_alarm_get_action (alarm, &action);
114 e_cal_component_alarm_free (alarm);
115
116 if (action != E_CAL_COMPONENT_ALARM_NONE &&
117 action != E_CAL_COMPONENT_ALARM_PROCEDURE &&
118 action != E_CAL_COMPONENT_ALARM_UNKNOWN) {
119 cal_obj_uid_list_free (uids);
120 return TRUE;
121 }
122 }
123 }
124
125 cal_obj_uid_list_free (uids);
126
127 return FALSE;
128 }
129
130 static GtkWidget *
131 add_checkbox (GtkBox *where,
132 const gchar *caption)
133 {
134 GtkWidget *checkbox, *align;
135
136 g_return_val_if_fail (where != NULL, NULL);
137 g_return_val_if_fail (caption != NULL, NULL);
138
139 checkbox = gtk_check_button_new_with_mnemonic (caption);
140 align = gtk_alignment_new (0.0, 0.5, 0.0, 0.0);
141 gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, 12, 12);
142 gtk_container_add (GTK_CONTAINER (align), checkbox);
143 gtk_widget_show (checkbox);
144 gtk_box_pack_start (where, align, TRUE, TRUE, 2);
145 gtk_widget_show (align);
146
147 return checkbox;
148 }
149
150 /**
151 * send_component_dialog:
152 *
153 * Pops up a dialog box asking the user whether he wants to send a
154 * iTip/iMip message
155 *
156 * Return value: TRUE if the user clicked Yes, FALSE otherwise.
157 **/
158 gboolean
159 send_component_dialog (GtkWindow *parent,
160 ECalClient *client,
161 ECalComponent *comp,
162 gboolean new,
163 gboolean *strip_alarms,
164 gboolean *only_new_attendees)
165 {
166 ECalComponentVType vtype;
167 const gchar *id;
168 GtkWidget *dialog, *sa_checkbox = NULL, *ona_checkbox = NULL;
169 GtkWidget *content_area;
170 gboolean res;
171
172 if (strip_alarms)
173 *strip_alarms = TRUE;
174
175 if (e_cal_client_check_save_schedules (client) || !component_has_recipients (comp))
176 return FALSE;
177
178 vtype = e_cal_component_get_vtype (comp);
179
180 switch (vtype) {
181 case E_CAL_COMPONENT_EVENT:
182 if (new)
183 id = "calendar:prompt-meeting-invite";
184 else
185 id = "calendar:prompt-send-updated-meeting-info";
186 break;
187
188 case E_CAL_COMPONENT_TODO:
189 if (new)
190 id = "calendar:prompt-send-task";
191 else
192 id = "calendar:prompt-send-updated-task-info";
193 break;
194 case E_CAL_COMPONENT_JOURNAL:
195 return TRUE;
196 default:
197 g_message (
198 "send_component_dialog(): "
199 "Cannot handle object of type %d", vtype);
200 return FALSE;
201 }
202
203 if (only_new_attendees && !component_has_new_attendees (comp)) {
204 /* do not show the check if there is no new attendee and
205 * set as all attendees are required to be notified */
206 *only_new_attendees = FALSE;
207
208 /* pretend it as being passed NULL to simplify code below */
209 only_new_attendees = NULL;
210 }
211
212 if (strip_alarms && !have_nonprocedural_alarm (comp)) {
213 /* pretend it as being passed NULL to simplify code below */
214 strip_alarms = NULL;
215 }
216
217 dialog = e_alert_dialog_new_for_args (parent, id, NULL);
218 content_area = e_alert_dialog_get_content_area (E_ALERT_DIALOG (dialog));
219
220 if (strip_alarms)
221 sa_checkbox = add_checkbox (GTK_BOX (content_area), _("Send my reminders with this event"));
222 if (only_new_attendees)
223 ona_checkbox = add_checkbox (GTK_BOX (content_area), _("Notify new attendees _only"));
224
225 res = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES;
226
227 if (res && strip_alarms)
228 *strip_alarms = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sa_checkbox));
229 if (only_new_attendees)
230 *only_new_attendees = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ona_checkbox));
231
232 gtk_widget_destroy (GTK_WIDGET (dialog));
233
234 return res;
235 }
236
237 gboolean
238 send_component_prompt_subject (GtkWindow *parent,
239 ECalClient *client,
240 ECalComponent *comp)
241 {
242 ECalComponentVType vtype;
243 const gchar *id;
244
245 vtype = e_cal_component_get_vtype (comp);
246
247 switch (vtype) {
248 case E_CAL_COMPONENT_EVENT:
249 id = "calendar:prompt-save-no-subject-calendar";
250 break;
251
252 case E_CAL_COMPONENT_TODO:
253 id = "calendar:prompt-save-no-subject-task";
254 break;
255 case E_CAL_COMPONENT_JOURNAL:
256 id = "calendar:prompt-send-no-subject-memo";
257 break;
258
259 default:
260 g_message (
261 "send_component_prompt_subject(): "
262 "Cannot handle object of type %d", vtype);
263 return FALSE;
264 }
265
266 if (e_alert_run_dialog_for_args (parent, id, NULL) == GTK_RESPONSE_YES)
267 return TRUE;
268 else
269 return FALSE;
270 }