evolution-3.6.4/modules/calendar/e-cal-shell-view-taskpad.c

No issues found

  1 /*
  2  * e-cal-shell-view-taskpad.c
  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  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 19  *
 20  */
 21 
 22 #ifdef HAVE_CONFIG_H
 23 #include <config.h>
 24 #endif
 25 
 26 #include "e-cal-shell-view-private.h"
 27 
 28 /* Much of this file is based on e-task-shell-view-actions.c. */
 29 
 30 static void
 31 action_calendar_taskpad_assign_cb (GtkAction *action,
 32                                    ECalShellView *cal_shell_view)
 33 {
 34 	ECalShellContent *cal_shell_content;
 35 	ECalModelComponent *comp_data;
 36 	ETaskTable *task_table;
 37 	GSList *list;
 38 
 39 	cal_shell_content = cal_shell_view->priv->cal_shell_content;
 40 	task_table = e_cal_shell_content_get_task_table (cal_shell_content);
 41 
 42 	list = e_task_table_get_selected (task_table);
 43 	g_return_if_fail (list != NULL);
 44 	comp_data = list->data;
 45 	g_slist_free (list);
 46 
 47 	/* XXX We only open the first selected task. */
 48 	e_cal_shell_view_taskpad_open_task (cal_shell_view, comp_data);
 49 
 50 	/* FIXME Need to actually assign the task. */
 51 }
 52 
 53 static void
 54 action_calendar_taskpad_forward_cb (GtkAction *action,
 55                                     ECalShellView *cal_shell_view)
 56 {
 57 	ECalShellContent *cal_shell_content;
 58 	EShell *shell;
 59 	EShellView *shell_view;
 60 	EShellWindow *shell_window;
 61 	ESourceRegistry *registry;
 62 	ECalModelComponent *comp_data;
 63 	ETaskTable *task_table;
 64 	ECalComponent *comp;
 65 	icalcomponent *clone;
 66 	GSList *list;
 67 
 68 	shell_view = E_SHELL_VIEW (cal_shell_view);
 69 	shell_window = e_shell_view_get_shell_window (shell_view);
 70 	shell = e_shell_window_get_shell (shell_window);
 71 
 72 	registry = e_shell_get_registry (shell);
 73 
 74 	cal_shell_content = cal_shell_view->priv->cal_shell_content;
 75 	task_table = e_cal_shell_content_get_task_table (cal_shell_content);
 76 
 77 	list = e_task_table_get_selected (task_table);
 78 	g_return_if_fail (list != NULL);
 79 	comp_data = list->data;
 80 	g_slist_free (list);
 81 
 82 	/* XXX We only forward the first selected task. */
 83 	comp = e_cal_component_new ();
 84 	clone = icalcomponent_new_clone (comp_data->icalcomp);
 85 	e_cal_component_set_icalcomponent (comp, clone);
 86 
 87 	itip_send_comp (
 88 		registry, E_CAL_COMPONENT_METHOD_PUBLISH, comp,
 89 		comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
 90 
 91 	g_object_unref (comp);
 92 }
 93 
 94 static void
 95 action_calendar_taskpad_mark_complete_cb (GtkAction *action,
 96                                           ECalShellView *cal_shell_view)
 97 {
 98 	ECalShellContent *cal_shell_content;
 99 	ETaskTable *task_table;
100 	ECalModel *model;
101 	GSList *list, *iter;
102 
103 	cal_shell_content = cal_shell_view->priv->cal_shell_content;
104 	task_table = e_cal_shell_content_get_task_table (cal_shell_content);
105 	list = e_task_table_get_selected (task_table);
106 	model = e_task_table_get_model (task_table);
107 
108 	for (iter = list; iter != NULL; iter = iter->next) {
109 		ECalModelComponent *comp_data = iter->data;
110 		e_cal_model_tasks_mark_comp_complete (
111 			E_CAL_MODEL_TASKS (model), comp_data);
112 	}
113 
114 	g_slist_free (list);
115 }
116 
117 static void
118 action_calendar_taskpad_mark_incomplete_cb (GtkAction *action,
119                                             ECalShellView *cal_shell_view)
120 {
121 	ECalShellContent *cal_shell_content;
122 	ETaskTable *task_table;
123 	ECalModel *model;
124 	GSList *list, *iter;
125 
126 	cal_shell_content = cal_shell_view->priv->cal_shell_content;
127 	task_table = e_cal_shell_content_get_task_table (cal_shell_content);
128 	list = e_task_table_get_selected (task_table);
129 	model = e_task_table_get_model (task_table);
130 
131 	for (iter = list; iter != NULL; iter = iter->next) {
132 		ECalModelComponent *comp_data = iter->data;
133 		e_cal_model_tasks_mark_comp_incomplete (
134 			E_CAL_MODEL_TASKS (model), comp_data);
135 	}
136 
137 	g_slist_free (list);
138 }
139 
140 static void
141 action_calendar_taskpad_new_cb (GtkAction *action,
142                                 ECalShellView *cal_shell_view)
143 {
144 	EShell *shell;
145 	EShellView *shell_view;
146 	EShellWindow *shell_window;
147 	ECalShellContent *cal_shell_content;
148 	ECalModelComponent *comp_data;
149 	ETaskTable *task_table;
150 	ECalClient *client;
151 	ECalComponent *comp;
152 	CompEditor *editor;
153 	GSList *list;
154 
155 	shell_view = E_SHELL_VIEW (cal_shell_view);
156 	shell_window = e_shell_view_get_shell_window (shell_view);
157 	shell = e_shell_window_get_shell (shell_window);
158 
159 	cal_shell_content = cal_shell_view->priv->cal_shell_content;
160 	task_table = e_cal_shell_content_get_task_table (cal_shell_content);
161 
162 	list = e_task_table_get_selected (task_table);
163 	g_return_if_fail (list != NULL);
164 	comp_data = list->data;
165 	g_slist_free (list);
166 
167 	client = comp_data->client;
168 	editor = task_editor_new (client, shell, COMP_EDITOR_NEW_ITEM);
169 	comp = cal_comp_task_new_with_defaults (client);
170 	comp_editor_edit_comp (editor, comp);
171 
172 	gtk_window_present (GTK_WINDOW (editor));
173 
174 	g_object_unref (comp);
175 }
176 
177 static void
178 action_calendar_taskpad_open_cb (GtkAction *action,
179                                  ECalShellView *cal_shell_view)
180 {
181 	ECalShellContent *cal_shell_content;
182 	ECalModelComponent *comp_data;
183 	ETaskTable *task_table;
184 	GSList *list;
185 
186 	cal_shell_content = cal_shell_view->priv->cal_shell_content;
187 	task_table = e_cal_shell_content_get_task_table (cal_shell_content);
188 
189 	list = e_task_table_get_selected (task_table);
190 	g_return_if_fail (list != NULL);
191 	comp_data = list->data;
192 	g_slist_free (list);
193 
194 	/* XXX We only open the first selected task. */
195 	e_cal_shell_view_taskpad_open_task (cal_shell_view, comp_data);
196 }
197 
198 static void
199 action_calendar_taskpad_open_url_cb (GtkAction *action,
200                                      ECalShellView *cal_shell_view)
201 {
202 	EShellView *shell_view;
203 	EShellWindow *shell_window;
204 	ECalShellContent *cal_shell_content;
205 	ECalModelComponent *comp_data;
206 	ETaskTable *task_table;
207 	icalproperty *prop;
208 	const gchar *uri;
209 	GSList *list;
210 
211 	shell_view = E_SHELL_VIEW (cal_shell_view);
212 	shell_window = e_shell_view_get_shell_window (shell_view);
213 
214 	cal_shell_content = cal_shell_view->priv->cal_shell_content;
215 	task_table = e_cal_shell_content_get_task_table (cal_shell_content);
216 
217 	list = e_task_table_get_selected (task_table);
218 	g_return_if_fail (list != NULL);
219 	comp_data = list->data;
220 
221 	/* XXX We only open the URI of the first selected task. */
222 	prop = icalcomponent_get_first_property (
223 		comp_data->icalcomp, ICAL_URL_PROPERTY);
224 	g_return_if_fail (prop != NULL);
225 
226 	uri = icalproperty_get_url (prop);
227 	e_show_uri (GTK_WINDOW (shell_window), uri);
228 }
229 
230 static void
231 action_calendar_taskpad_print_cb (GtkAction *action,
232                                   ECalShellView *cal_shell_view)
233 {
234 	ECalShellContent *cal_shell_content;
235 	ECalModelComponent *comp_data;
236 	ETaskTable *task_table;
237 	ECalComponent *comp;
238 	ECalModel *model;
239 	icalcomponent *clone;
240 	GSList *list;
241 
242 	cal_shell_content = cal_shell_view->priv->cal_shell_content;
243 	task_table = e_cal_shell_content_get_task_table (cal_shell_content);
244 	model = e_task_table_get_model (task_table);
245 
246 	list = e_task_table_get_selected (task_table);
247 	g_return_if_fail (list != NULL);
248 	comp_data = list->data;
249 	g_slist_free (list);
250 
251 	/* XXX We only print the first selected task. */
252 	comp = e_cal_component_new ();
253 	clone = icalcomponent_new_clone (comp_data->icalcomp);
254 	e_cal_component_set_icalcomponent (comp, clone);
255 
256 	print_comp (
257 		comp, comp_data->client,
258 		e_cal_model_get_timezone (model),
259 		e_cal_model_get_use_24_hour_format (model),
260 		GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
261 
262 	g_object_unref (comp);
263 }
264 
265 static void
266 action_calendar_taskpad_save_as_cb (GtkAction *action,
267                                     ECalShellView *cal_shell_view)
268 {
269 	EShell *shell;
270 	EShellView *shell_view;
271 	EShellWindow *shell_window;
272 	EShellBackend *shell_backend;
273 	ECalShellContent *cal_shell_content;
274 	ECalModelComponent *comp_data;
275 	ETaskTable *task_table;
276 	EActivity *activity;
277 	GSList *list;
278 	GFile *file;
279 	gchar *string;
280 
281 	shell_view = E_SHELL_VIEW (cal_shell_view);
282 	shell_window = e_shell_view_get_shell_window (shell_view);
283 	shell_backend = e_shell_view_get_shell_backend (shell_view);
284 	shell = e_shell_window_get_shell (shell_window);
285 
286 	cal_shell_content = cal_shell_view->priv->cal_shell_content;
287 	task_table = e_cal_shell_content_get_task_table (cal_shell_content);
288 
289 	list = e_task_table_get_selected (task_table);
290 	g_return_if_fail (list != NULL);
291 	comp_data = list->data;
292 	g_slist_free (list);
293 
294 	/* Translators: Default filename part saving a task to a file when
295 	 * no summary is filed, the '.ics' extension is concatenated to it. */
296 	string = icalcomp_suggest_filename (comp_data->icalcomp, _("task"));
297 	file = e_shell_run_save_dialog (
298 		shell, _("Save as iCalendar"), string,
299 		"*.ics:text/calendar", NULL, NULL);
300 	g_free (string);
301 	if (file == NULL)
302 		return;
303 
304 	string = e_cal_client_get_component_as_string (
305 		comp_data->client, comp_data->icalcomp);
306 	if (string == NULL) {
307 		g_warning ("Could not convert task to a string");
308 		g_object_unref (file);
309 		return;
310 	}
311 
312 	/* XXX No callback means errors are discarded. */
313 	activity = e_file_replace_contents_async (
314 		file, string, strlen (string), NULL, FALSE,
315 		G_FILE_CREATE_NONE, (GAsyncReadyCallback) NULL, NULL);
316 	e_shell_backend_add_activity (shell_backend, activity);
317 
318 	/* Free the string when the activity is finalized. */
319 	g_object_set_data_full (
320 		G_OBJECT (activity),
321 		"file-content", string,
322 		(GDestroyNotify) g_free);
323 
324 	g_object_unref (file);
325 }
326 
327 static GtkActionEntry calendar_taskpad_entries[] = {
328 
329 	{ "calendar-taskpad-assign",
330 	  NULL,
331 	  N_("_Assign Task"),
332 	  NULL,
333 	  NULL,  /* XXX Add a tooltip! */
334 	  G_CALLBACK (action_calendar_taskpad_assign_cb) },
335 
336 	{ "calendar-taskpad-forward",
337 	  "mail-forward",
338 	  N_("_Forward as iCalendar..."),
339 	  NULL,
340 	  NULL,  /* XXX Add a tooltip! */
341 	  G_CALLBACK (action_calendar_taskpad_forward_cb) },
342 
343 	{ "calendar-taskpad-mark-complete",
344 	  NULL,
345 	  N_("_Mark as Complete"),
346 	  NULL,
347 	  N_("Mark selected tasks as complete"),
348 	  G_CALLBACK (action_calendar_taskpad_mark_complete_cb) },
349 
350 	{ "calendar-taskpad-mark-incomplete",
351 	  NULL,
352 	  N_("_Mark as Incomplete"),
353 	  NULL,
354 	  N_("Mark selected tasks as incomplete"),
355 	  G_CALLBACK (action_calendar_taskpad_mark_incomplete_cb) },
356 
357 	{ "calendar-taskpad-new",
358 	  "stock_task",
359 	  N_("New _Task"),
360 	  NULL,
361 	  N_("Create a new task"),
362 	  G_CALLBACK (action_calendar_taskpad_new_cb) },
363 
364 	{ "calendar-taskpad-open",
365 	  GTK_STOCK_OPEN,
366 	  N_("_Open Task"),
367 	  NULL,
368 	  N_("View the selected task"),
369 	  G_CALLBACK (action_calendar_taskpad_open_cb) },
370 
371 	{ "calendar-taskpad-open-url",
372 	  "applications-internet",
373 	  N_("Open _Web Page"),
374 	  NULL,
375 	  NULL,  /* XXX Add a tooltip! */
376 	  G_CALLBACK (action_calendar_taskpad_open_url_cb) },
377 };
378 
379 static GtkActionEntry lockdown_printing_entries[] = {
380 
381 	{ "calendar-taskpad-print",
382 	  GTK_STOCK_PRINT,
383 	  NULL,
384 	  NULL,
385 	  N_("Print the selected task"),
386 	  G_CALLBACK (action_calendar_taskpad_print_cb) }
387 };
388 
389 static GtkActionEntry lockdown_save_to_disk_entries[] = {
390 
391 	{ "calendar-taskpad-save-as",
392 	  GTK_STOCK_SAVE_AS,
393 	  N_("_Save as iCalendar..."),
394 	  NULL,
395 	  NULL,  /* XXX Add a tooltip! */
396 	  G_CALLBACK (action_calendar_taskpad_save_as_cb) }
397 };
398 
399 void
400 e_cal_shell_view_taskpad_actions_init (ECalShellView *cal_shell_view)
401 {
402 	EShellView *shell_view;
403 	EShellWindow *shell_window;
404 	GtkActionGroup *action_group;
405 
406 	shell_view = E_SHELL_VIEW (cal_shell_view);
407 	shell_window = e_shell_view_get_shell_window (shell_view);
408 
409 	/* Calendar Actions */
410 	action_group = ACTION_GROUP (CALENDAR);
411 	gtk_action_group_add_actions (
412 		action_group, calendar_taskpad_entries,
413 		G_N_ELEMENTS (calendar_taskpad_entries), cal_shell_view);
414 
415 	/* Lockdown Printing Actions */
416 	action_group = ACTION_GROUP (LOCKDOWN_PRINTING);
417 	gtk_action_group_add_actions (
418 		action_group, lockdown_printing_entries,
419 		G_N_ELEMENTS (lockdown_printing_entries), cal_shell_view);
420 
421 	/* Lockdown Save-to-Disk Actions */
422 	action_group = ACTION_GROUP (LOCKDOWN_SAVE_TO_DISK);
423 	gtk_action_group_add_actions (
424 		action_group, lockdown_save_to_disk_entries,
425 		G_N_ELEMENTS (lockdown_save_to_disk_entries), cal_shell_view);
426 }
427 
428 void
429 e_cal_shell_view_taskpad_actions_update (ECalShellView *cal_shell_view)
430 {
431 	ECalShellContent *cal_shell_content;
432 	EShellWindow *shell_window;
433 	EShellView *shell_view;
434 	ETaskTable *task_table;
435 	GtkAction *action;
436 	GSList *list, *iter;
437 	gboolean assignable = TRUE;
438 	gboolean editable = TRUE;
439 	gboolean has_url = FALSE;
440 	gboolean sensitive;
441 	gint n_selected;
442 	gint n_complete = 0;
443 	gint n_incomplete = 0;
444 
445 	shell_view = E_SHELL_VIEW (cal_shell_view);
446 	shell_window = e_shell_view_get_shell_window (shell_view);
447 
448 	cal_shell_content = cal_shell_view->priv->cal_shell_content;
449 	task_table = e_cal_shell_content_get_task_table (cal_shell_content);
450 
451 	n_selected = e_table_selected_count (E_TABLE (task_table));
452 
453 	list = e_task_table_get_selected (task_table);
454 	for (iter = list; iter != NULL; iter = iter->next) {
455 		ECalModelComponent *comp_data = iter->data;
456 		icalproperty *prop;
457 		const gchar *cap;
458 		gboolean read_only;
459 
460 		read_only = e_client_is_readonly (E_CLIENT (comp_data->client));
461 		editable &= !read_only;
462 
463 		cap = CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT;
464 		if (e_client_check_capability (E_CLIENT (comp_data->client), cap))
465 			assignable = FALSE;
466 
467 		cap = CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK;
468 		if (e_client_check_capability (E_CLIENT (comp_data->client), cap))
469 			assignable = FALSE;
470 
471 		prop = icalcomponent_get_first_property (
472 			comp_data->icalcomp, ICAL_URL_PROPERTY);
473 		has_url |= (prop != NULL);
474 
475 		prop = icalcomponent_get_first_property (
476 			comp_data->icalcomp, ICAL_COMPLETED_PROPERTY);
477 		if (prop != NULL)
478 			n_complete++;
479 		else
480 			n_incomplete++;
481 	}
482 	g_slist_free (list);
483 
484 	action = ACTION (CALENDAR_TASKPAD_ASSIGN);
485 	sensitive = (n_selected == 1) && editable && assignable;
486 	gtk_action_set_sensitive (action, sensitive);
487 
488 	action = ACTION (CALENDAR_TASKPAD_FORWARD);
489 	sensitive = (n_selected == 1);
490 	gtk_action_set_sensitive (action, sensitive);
491 
492 	action = ACTION (CALENDAR_TASKPAD_MARK_COMPLETE);
493 	sensitive = (n_selected > 0) && editable && (n_incomplete > 0);
494 	gtk_action_set_sensitive (action, sensitive);
495 
496 	action = ACTION (CALENDAR_TASKPAD_MARK_INCOMPLETE);
497 	sensitive = (n_selected > 0) && editable && (n_complete > 0);
498 	gtk_action_set_sensitive (action, sensitive);
499 
500 	action = ACTION (CALENDAR_TASKPAD_OPEN);
501 	sensitive = (n_selected == 1);
502 	gtk_action_set_sensitive (action, sensitive);
503 
504 	action = ACTION (CALENDAR_TASKPAD_OPEN_URL);
505 	sensitive = (n_selected == 1) && has_url;
506 	gtk_action_set_sensitive (action, sensitive);
507 
508 	action = ACTION (CALENDAR_TASKPAD_PRINT);
509 	sensitive = (n_selected == 1);
510 	gtk_action_set_sensitive (action, sensitive);
511 
512 	action = ACTION (CALENDAR_TASKPAD_SAVE_AS);
513 	sensitive = (n_selected == 1);
514 	gtk_action_set_sensitive (action, sensitive);
515 }
516 
517 void
518 e_cal_shell_view_taskpad_open_task (ECalShellView *cal_shell_view,
519                                     ECalModelComponent *comp_data)
520 {
521 	EShell *shell;
522 	EShellView *shell_view;
523 	EShellWindow *shell_window;
524 	ESourceRegistry *registry;
525 	CompEditor *editor;
526 	CompEditorFlags flags = 0;
527 	ECalComponent *comp;
528 	icalcomponent *clone;
529 	icalproperty *prop;
530 	const gchar *uid;
531 
532 	g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view));
533 	g_return_if_fail (E_IS_CAL_MODEL_COMPONENT (comp_data));
534 
535 	shell_view = E_SHELL_VIEW (cal_shell_view);
536 	shell_window = e_shell_view_get_shell_window (shell_view);
537 	shell = e_shell_window_get_shell (shell_window);
538 
539 	registry = e_shell_get_registry (shell);
540 
541 	uid = icalcomponent_get_uid (comp_data->icalcomp);
542 	editor = comp_editor_find_instance (uid);
543 
544 	if (editor != NULL)
545 		goto exit;
546 
547 	comp = e_cal_component_new ();
548 	clone = icalcomponent_new_clone (comp_data->icalcomp);
549 	e_cal_component_set_icalcomponent (comp, clone);
550 
551 	prop = icalcomponent_get_first_property (
552 		comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY);
553 	if (prop != NULL)
554 		flags |= COMP_EDITOR_IS_ASSIGNED;
555 
556 	if (itip_organizer_is_user (registry, comp, comp_data->client))
557 		flags |= COMP_EDITOR_USER_ORG;
558 
559 	if (!e_cal_component_has_attendees (comp))
560 		flags |= COMP_EDITOR_USER_ORG;
561 
562 	editor = task_editor_new (comp_data->client, shell, flags);
563 	comp_editor_edit_comp (editor, comp);
564 
565 	g_object_unref (comp);
566 
567 	if (flags & COMP_EDITOR_IS_ASSIGNED)
568 		task_editor_show_assignment (TASK_EDITOR (editor));
569 
570 exit:
571 	gtk_window_present (GTK_WINDOW (editor));
572 }
573 
574 void
575 e_cal_shell_view_taskpad_set_status_message (ECalShellView *cal_shell_view,
576                                              const gchar *status_message,
577                                              gdouble percent)
578 {
579 	EActivity *activity;
580 	EShellView *shell_view;
581 	EShellBackend *shell_backend;
582 
583 	g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view));
584 
585 	shell_view = E_SHELL_VIEW (cal_shell_view);
586 	shell_backend = e_shell_view_get_shell_backend (shell_view);
587 
588 	activity = cal_shell_view->priv->taskpad_activity;
589 
590 	if (status_message == NULL || *status_message == '\0') {
591 		if (activity != NULL) {
592 			e_activity_set_state (activity, E_ACTIVITY_COMPLETED);
593 			g_object_unref (activity);
594 			activity = NULL;
595 		}
596 
597 	} else if (activity == NULL) {
598 		activity = e_activity_new ();
599 		e_activity_set_percent (activity, percent);
600 		e_activity_set_text (activity, status_message);
601 		e_shell_backend_add_activity (shell_backend, activity);
602 
603 	} else {
604 		e_activity_set_percent (activity, percent);
605 		e_activity_set_text (activity, status_message);
606 	}
607 
608 	cal_shell_view->priv->taskpad_activity = activity;
609 }