2 * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2007 Colin Leroy <colin@colino.net> and
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "claws-features.h"
28 #include <glib/gi18n.h>
38 #include "folder_item_prefs.h"
41 #include "vcalendar.h"
42 #include "vcal_manager.h"
43 #include "vcal_folder.h"
44 #include "vcal_meeting_gtk.h"
45 #include "vcal_interface.h"
46 #include "prefs_account.h"
47 #include "prefs_common.h"
53 #include "alertpanel.h"
54 #include "vcal_prefs.h"
55 #include "statusbar.h"
59 MimeViewerFactory vcal_viewer_factory;
61 static void create_meeting_from_message_cb_ui(GtkAction *action, gpointer data);
63 static GdkColor uri_color = {
72 MimeViewer mimeviewer;
79 GtkWidget *scrolledwin;
87 GtkWidget *description;
95 GtkWidget *unavail_box;
98 static GtkActionEntry vcalendar_main_menu[] = {{
99 "Message/CreateMeeting",
100 NULL, N_("Create meeting from message..."), NULL, NULL, G_CALLBACK(create_meeting_from_message_cb_ui)
103 static void create_meeting_from_message_cb_ui(GtkAction *action, gpointer data)
105 MainWindow *mainwin = mainwindow_get_mainwindow();
106 SummaryView *summaryview = mainwin->summaryview;
107 GSList *msglist = summary_get_selected_msg_list(summaryview);
108 FolderItem *item = NULL;
113 if (summary_is_locked(summaryview) || !msglist) {
115 g_slist_free(msglist);
118 total = g_slist_length(msglist);
120 msg = g_strdup_printf(_("You are about to create %d "
121 "meetings, one by one. Do you "
122 "want to continue?"),
125 && alertpanel(_("Warning"), msg, GTK_STOCK_CANCEL, "+" GTK_STOCK_YES, NULL)
126 != G_ALERTALTERNATE) {
132 main_window_cursor_wait(summaryview->mainwin);
133 gtk_cmclist_freeze(GTK_CMCLIST(summaryview->ctree));
134 folder_item_update_freeze();
137 item = summaryview->folder_item;
139 STATUSBAR_PUSH(mainwin, _("Creating meeting..."));
141 for (cur = msglist; cur; cur = cur->next) {
142 MsgInfo *msginfo = procmsg_msginfo_get_full_info((MsgInfo *)cur->data);
143 VCalEvent *event = NULL;
146 if (MSG_IS_ENCRYPTED(msginfo->flags)) {
147 fp = procmime_get_first_encrypted_text_content(msginfo);
149 fp = procmime_get_first_text_content(msginfo);
154 time_t t = time(NULL);
157 gchar *orgname = NULL;
158 gchar *summary = g_strdup(msginfo->subject ? msginfo->subject:_("no subject"));
159 gchar *description = file_read_stream_to_str(fp);
160 gchar *dtstart = g_strdup(icaltime_as_ical_string(icaltime_from_timet(t, FALSE)));
161 gchar *dtend = g_strdup(icaltime_as_ical_string(icaltime_from_timet(t2, FALSE)));
163 gchar *tzid = g_strdup("UTC");
165 gint method = ICAL_METHOD_REQUEST;
167 PrefsAccount *account = NULL;
171 if (item && item->prefs && item->prefs->enable_default_account)
172 account = account_find_from_id(item->prefs->default_account);
175 account = account_get_cur_account();
180 org = g_strdup(account->address);
182 if (account->set_domain && account->domain) {
183 g_snprintf(uid, sizeof(uid), "%s", account->domain);
184 } else if (!strncmp(get_domain_name(), "localhost", strlen("localhost"))) {
185 g_snprintf(uid, sizeof(uid), "%s",
186 strchr(account->address, '@') ?
187 strchr(account->address, '@')+1 :
190 g_snprintf(uid, sizeof(uid), "%s", "");
192 generate_msgid(uid, 255, account->address);
194 event = vcal_manager_new_event(uid,
195 org, NULL, NULL/*location*/, summary, description,
196 dtstart, dtend, recur, tzid, url, method, sequence,
197 ICAL_VTODO_COMPONENT);
199 /* hack to get default hours */
200 g_free(event->dtstart);
201 g_free(event->dtend);
202 event->dtstart = NULL;
205 vcal_meeting_create(event);
206 vcal_manager_free_event(event);
220 procmsg_msginfo_free(&msginfo);
223 statusbar_progress_all(0,0,0);
224 STATUSBAR_POP(mainwin);
226 folder_item_update_thaw();
227 gtk_cmclist_thaw(GTK_CMCLIST(summaryview->ctree));
228 main_window_cursor_normal(summaryview->mainwin);
229 g_slist_free(msglist);
232 static gchar *get_tmpfile(VCalViewer *vcalviewer)
234 gchar *tmpfile = NULL;
236 if (!vcalviewer->tmpfile) {
237 tmpfile = procmime_get_tmp_file_name(vcalviewer->mimeinfo);
238 debug_print("creating %s\n", tmpfile);
240 if (procmime_get_part(tmpfile, vcalviewer->mimeinfo) < 0) {
241 g_warning("Can't get mimepart file");
245 vcalviewer->tmpfile = tmpfile;
248 return vcalviewer->tmpfile;
251 static GtkWidget *vcal_viewer_get_widget(MimeViewer *_mimeviewer)
253 VCalViewer *vcalviewer = (VCalViewer *) _mimeviewer;
255 debug_print("vcal_viewer_get_widget\n");
256 gtk_widget_show_all(vcalviewer->scrolledwin);
257 return vcalviewer->scrolledwin;
260 static void vcal_viewer_clear_viewer(MimeViewer *_mimeviewer)
262 VCalViewer *vcalviewer = (VCalViewer *) _mimeviewer;
264 debug_print("vcal_viewer_clear_viewer\n");
266 g_free(vcalviewer->file);
267 vcalviewer->file = NULL;
268 if (vcalviewer->tmpfile) {
269 debug_print("unlinking %s\n", vcalviewer->tmpfile);
270 g_unlink(vcalviewer->tmpfile);
271 g_free(vcalviewer->tmpfile);
272 vcalviewer->tmpfile = NULL;
274 vcalviewer->mimeinfo = NULL;
277 static VCalEvent *vcalviewer_get_component(const gchar *file, const gchar *charset)
279 gchar *compstr = NULL;
280 VCalEvent *event = NULL;
286 g_return_val_if_fail(file != NULL, NULL);
288 if ((fp = g_fopen(file, "rb")) == NULL) {
289 FILE_OP_ERROR(file, "g_fopen");
293 array = g_byte_array_new();
295 while ((n_read = fread(buf, sizeof(gchar), sizeof(buf), fp)) > 0) {
296 if (n_read < sizeof(buf) && ferror(fp))
298 g_byte_array_append(array, (guchar *)buf, n_read);
302 FILE_OP_ERROR("file stream", "fread");
303 g_byte_array_free(array, TRUE);
309 g_byte_array_append(array, (guchar *)buf, 1);
310 compstr = (gchar *)array->data;
311 g_byte_array_free(array, FALSE);
316 event = vcal_get_event_from_ical(compstr, charset);
323 #define GTK_LABEL_SET_TEXT_TRIMMED(label, text) { \
324 gchar *tmplbl = strretchomp(g_strdup(text)); \
325 gtk_label_set_text(label, tmplbl); \
329 static void vcalviewer_answer_set_choices(VCalViewer *vcalviewer, VCalEvent *event, enum icalproperty_method method);
331 static void vcalviewer_reset(VCalViewer *vcalviewer)
333 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), "-");
334 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who), "-");
335 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->location), "-");
336 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->summary), "-");
337 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->description), "-");
338 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start), "-");
339 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->end), "-");
340 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->attendees), "-");
341 g_free(vcalviewer->url);
342 vcalviewer->url = NULL;
343 gtk_widget_hide(vcalviewer->uribtn);
344 vcalviewer_answer_set_choices(vcalviewer, NULL, ICAL_METHOD_CANCEL);
347 static void vcalviewer_show_error(VCalViewer *vcalviewer, const gchar *msg)
349 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), msg);
352 static void vcalviewer_hide_error(VCalViewer *vcalviewer)
354 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), "-");
357 static void vcalviewer_show_unavailable(VCalViewer *vcalviewer, gboolean visi)
360 gtk_widget_show_all(vcalviewer->unavail_box);
362 gtk_widget_hide(vcalviewer->unavail_box);
365 static void vcalviewer_answer_set_choices(VCalViewer *vcalviewer, VCalEvent *event, enum icalproperty_method method)
369 gtk_widget_hide(vcalviewer->reedit);
370 gtk_widget_hide(vcalviewer->cancel);
371 gtk_widget_hide(vcalviewer->answer);
372 gtk_widget_hide(vcalviewer->button);
374 for (i = 0; i < 3; i++)
375 gtk_combo_box_remove_text(GTK_COMBO_BOX(vcalviewer->answer), 0);
377 vcalviewer_show_unavailable(vcalviewer, FALSE);
379 if (method == ICAL_METHOD_REQUEST && event && !event->rec_occurence) {
380 PrefsAccount *account = vcal_manager_get_account_from_event(event);
383 account = vcal_manager_get_account_from_event(vcalviewer->event);
385 if (!account && event) {
386 account = account_get_default();
387 vcal_manager_update_answer(event, account->address,
389 ICAL_PARTSTAT_NEEDSACTION,
390 ICAL_CUTYPE_INDIVIDUAL);
393 gtk_combo_box_append_text(GTK_COMBO_BOX(vcalviewer->answer), _("Accept"));
394 gtk_combo_box_append_text(GTK_COMBO_BOX(vcalviewer->answer), _("Tentatively accept"));
395 gtk_combo_box_append_text(GTK_COMBO_BOX(vcalviewer->answer), _("Decline"));
396 gtk_widget_set_sensitive(vcalviewer->answer, TRUE);
397 gtk_widget_set_sensitive(vcalviewer->button, TRUE);
398 gtk_widget_show(vcalviewer->answer);
399 gtk_widget_show(vcalviewer->button);
401 gtk_combo_box_append_text(GTK_COMBO_BOX(vcalviewer->answer), "-");
402 gtk_widget_set_sensitive(vcalviewer->answer, FALSE);
403 gtk_widget_set_sensitive(vcalviewer->button, FALSE);
406 gtk_combo_box_append_text(GTK_COMBO_BOX(vcalviewer->answer), "-");
407 gtk_widget_set_sensitive(vcalviewer->answer, FALSE);
408 gtk_widget_set_sensitive(vcalviewer->button, FALSE);
410 gtk_combo_box_set_active(GTK_COMBO_BOX(vcalviewer->answer), 0);
412 if (event && event->method == ICAL_METHOD_REQUEST) {
413 PrefsAccount *account = vcal_manager_get_account_from_event(event);
414 gchar *internal_ifb = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
415 "vcalendar", G_DIR_SEPARATOR_S,
416 "internal.ifb", NULL);
417 gchar *myfb = file_read_to_str(internal_ifb);
418 g_free(internal_ifb);
420 enum icalparameter_partstat answer =
421 vcal_manager_get_reply_for_attendee(event, account->address);
423 if (answer == ICAL_PARTSTAT_ACCEPTED)
424 gtk_combo_box_set_active(GTK_COMBO_BOX(vcalviewer->answer), 0);
425 if (answer == ICAL_PARTSTAT_TENTATIVE)
426 gtk_combo_box_set_active(GTK_COMBO_BOX(vcalviewer->answer), 1);
427 if (answer == ICAL_PARTSTAT_DECLINED)
428 gtk_combo_box_set_active(GTK_COMBO_BOX(vcalviewer->answer), 2);
429 if (event->dtstart && event->dtend && myfb && *myfb
430 && answer != ICAL_PARTSTAT_ACCEPTED
431 && answer != ICAL_PARTSTAT_TENTATIVE) {
432 if (!attendee_available(NULL, event->dtstart, event->dtend, myfb))
433 vcalviewer_show_unavailable(vcalviewer, TRUE);
439 g_free(vcalviewer->url);
440 if (event && event->url && *(event->url)) {
441 vcalviewer->url = g_strdup(event->url);
442 gtk_widget_show(vcalviewer->uribtn);
444 vcalviewer->url = NULL;
445 gtk_widget_hide(vcalviewer->uribtn);
449 static FolderItem *vcalendar_get_current_item(void)
451 MainWindow *mainwin = mainwindow_get_mainwindow();
452 FolderItem *item = NULL;
453 Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
456 item = mainwin->summaryview->folder_item;
457 if (item->folder == folder)
460 return folder->inbox;
466 void vcalviewer_display_event (VCalViewer *vcalviewer, VCalEvent *event)
469 gchar *attendees = NULL;
470 gboolean mine = FALSE;
472 gboolean save_evt = FALSE;
473 FolderItem *item = vcalendar_get_current_item();
480 if (event->type == ICAL_VTODO_COMPONENT) {
482 label = g_strjoin(" ", _("You have a Todo item."),
483 _("Details follow:"), NULL);
484 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
486 } else if (event->method == ICAL_METHOD_REQUEST) {
488 if (account_find_from_address(event->organizer, FALSE)) {
489 label = g_strjoin(" ", _("You have created a meeting."),
490 _("Details follow:"), NULL);
491 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
494 label = g_strjoin(" ", _("You have been invited to a meeting."),
495 _("Details follow:"), NULL);
496 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
499 } else if (event->method == ICAL_METHOD_CANCEL) {
501 label = g_strjoin(" ",
502 _("A meeting to which you had been invited has been cancelled."),
503 _("Details follow:"), NULL);
504 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
506 vcalendar_refresh_folder_contents(item);
507 } else if (event->method == ICAL_METHOD_REPLY) {
508 /* don't change label */
511 label = g_strjoin(" ", _("You have been forwarded an appointment."),
512 _("Details follow:"), NULL);
513 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
519 if (event->orgname && *(event->orgname)
520 && event->organizer && *(event->organizer)) {
521 gchar *addr = g_strconcat(event->orgname, " <", event->organizer, ">", NULL);
522 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who), addr);
524 } else if (event->organizer && *(event->organizer)) {
525 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who), event->organizer);
527 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who), "-");
531 if (event->location && *(event->location)) {
532 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->location), event->location);
534 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->location), "-");
538 if (event->summary && *(event->summary)) {
539 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->summary), event->summary);
541 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->summary), "-");
545 if (event->description && *(event->description)) {
546 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->description), event->description);
548 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->description), "-");
552 g_free(vcalviewer->url);
553 if (event->url && *(event->url)) {
554 vcalviewer->url = g_strdup(event->url);
555 gtk_widget_show(vcalviewer->uribtn);
557 vcalviewer->url = NULL;
558 gtk_widget_hide(vcalviewer->uribtn);
562 if (event->start && *(event->start)) {
563 if (event->recur && *(event->recur)) {
564 gchar *tmp = g_strdup_printf(g_strconcat("%s <span weight=\"bold\">",
565 _("(this event recurs)"),"</span>", NULL),
567 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start), tmp);
568 gtk_label_set_use_markup(GTK_LABEL(vcalviewer->start), TRUE);
570 } else if (event->rec_occurence) {
571 gchar *tmp = g_strdup_printf(g_strconcat("%s <span weight=\"bold\">",
572 _("(this event is part of a recurring event)"),
575 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start), tmp);
576 gtk_label_set_use_markup(GTK_LABEL(vcalviewer->start), TRUE);
579 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start), event->start);
582 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start), "-");
586 if (event->end && *(event->end)) {
587 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->end), event->end);
589 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->end), "-");
593 attendees = g_strdup("");
594 for (list = vcal_manager_get_answers_emails(event);
595 list && list->data; list = list->next) {
596 gchar *attendee = (gchar *)list->data;
597 gchar *name = vcal_manager_get_attendee_name(event, attendee);
598 gchar *ename = g_markup_printf_escaped("%s", name?name:"");
599 gchar *eatt = g_markup_printf_escaped("%s", attendee);
600 enum icalparameter_partstat acode = vcal_manager_get_reply_for_attendee(event, attendee);
601 gchar *answer = vcal_manager_get_reply_text_for_attendee(event, attendee);
602 gchar *type = vcal_manager_get_cutype_text_for_attendee(event, attendee);
605 tmp = g_strdup_printf(
606 "%s%s<%s> (%s, <span%s>%s</span>)",
607 (ename && *(ename))?ename:"",
608 (ename && *(ename))?" ":"",
609 (eatt && *(eatt))?eatt:"",
610 (type && *(type))?type:"",
611 (acode != ICAL_PARTSTAT_ACCEPTED ? " foreground=\"red\"":""),
612 (answer && *(answer))?answer:"");
613 e_len = strlen(attendees);
616 attendees = g_realloc(attendees, e_len+n_len+2);
617 *(attendees+e_len) = '\n';
618 strcpy(attendees+e_len+1, tmp);
620 attendees = g_realloc(attendees, e_len+n_len+1);
621 strcpy(attendees, tmp);
631 if (attendees && *(attendees)) {
632 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->attendees), attendees);
634 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->attendees), "-");
637 gtk_label_set_use_markup(GTK_LABEL(vcalviewer->attendees), TRUE);
641 if (event->type != ICAL_VTODO_COMPONENT)
642 vcalviewer_answer_set_choices(vcalviewer, event, event->method);
644 vcalviewer_answer_set_choices(vcalviewer, event, ICAL_METHOD_PUBLISH);
646 vcalviewer_answer_set_choices(vcalviewer, event, ICAL_METHOD_REPLY);
647 gtk_widget_show(vcalviewer->reedit);
648 gtk_widget_show(vcalviewer->cancel);
651 /* save if cancelled */
653 vcal_manager_save_event(event, TRUE);
656 gchar *vcalviewer_get_uid_from_mimeinfo(MimeInfo *mimeinfo)
658 gchar *tmpfile = procmime_get_tmp_file_name(mimeinfo);
659 const gchar *charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
660 gchar *compstr = NULL;
662 VCalEvent *event = NULL;
665 charset = CS_WINDOWS_1252;
667 if (!strcasecmp(charset, CS_ISO_8859_1))
668 charset = CS_WINDOWS_1252;
670 if (procmime_get_part(tmpfile, mimeinfo) < 0) {
671 g_warning("Can't get mimepart file");
676 compstr = file_read_to_str(tmpfile);
678 event = vcal_get_event_from_ical(compstr, charset);
680 res = g_strdup(event->uid);
682 vcal_manager_free_event(event);
684 debug_print("got uid: %s\n", res);
689 static void vcalviewer_get_request_values(VCalViewer *vcalviewer, MimeInfo *mimeinfo, gboolean is_todo)
691 VCalEvent *saved_event = NULL;
692 const gchar *charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
693 const gchar *saveme = procmime_mimeinfo_get_parameter(mimeinfo, "vcalsave");
695 if (!vcalviewer->event)
699 charset = CS_WINDOWS_1252;
701 if (!strcasecmp(charset, CS_ISO_8859_1))
702 charset = CS_WINDOWS_1252;
704 /* see if we have it registered and more recent */
705 saved_event = vcal_manager_load_event(vcalviewer->event->uid);
706 if (saved_event && saved_event->sequence >= vcalviewer->event->sequence) {
707 charset = CS_INTERNAL;
708 saved_event->method = vcalviewer->event->method;
709 vcalviewer_display_event(vcalviewer, saved_event);
710 vcal_manager_free_event(saved_event);
712 } else if (saved_event) {
713 vcal_manager_free_event(saved_event);
716 /* load it and register it */
718 if (!saveme || strcmp(saveme,"no"))
719 vcal_manager_save_event(vcalviewer->event, FALSE);
721 vcalviewer_display_event(vcalviewer, vcalviewer->event);
724 static void vcalviewer_get_reply_values(VCalViewer *vcalviewer, MimeInfo *mimeinfo)
726 const gchar *charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
727 VCalEvent *saved_event = NULL;
728 gchar *attendee = NULL, *label = NULL;
729 Answer *answer = NULL;
731 if (!vcalviewer->event)
735 charset = CS_WINDOWS_1252;
737 if (!strcasecmp(charset, CS_ISO_8859_1))
738 charset = CS_WINDOWS_1252;
740 if (!vcalviewer->event->answers || g_slist_length(vcalviewer->event->answers) > 1) {
741 g_warning("strange, no answers or more than one");
744 if (vcalviewer->event->answers) {
745 answer = (Answer *)vcalviewer->event->answers->data;
746 attendee = g_strdup(answer->attendee);
751 label = g_strjoin(" ",
752 _("You have received an answer to an unknown meeting proposal."),
753 _("Details follow:"), NULL);
754 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
756 label = g_strdup_printf(_("You have received an answer to a meeting proposal.\n"
757 "%s has %s the invitation whose details follow:"),
758 attendee, vcal_manager_answer_get_text(answer->answer));
759 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
764 saved_event = vcal_manager_load_event(vcalviewer->event->uid);
765 if (saved_event && answer) {
766 vcal_manager_update_answer(saved_event,
767 answer->attendee, answer->name, answer->answer, answer->cutype);
768 vcal_manager_save_event(saved_event, TRUE);
769 saved_event->method = vcalviewer->event->method;
770 vcalviewer_display_event(vcalviewer, saved_event);
771 vcal_manager_free_event(saved_event);
775 if (vcalviewer->event->organizer) {
776 if (vcalviewer->event->orgname) {
777 gchar *addr = g_strconcat(vcalviewer->event->orgname, " <",
778 vcalviewer->event->organizer, ">", NULL);
779 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who), addr);
782 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who),
783 vcalviewer->event->organizer);
786 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who), "-");
789 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->location),
790 vcalviewer->event->location?vcalviewer->event->location:"-");
792 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->summary),
793 vcalviewer->event->summary?vcalviewer->event->summary:"-");
795 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->description),
796 vcalviewer->event->description?vcalviewer->event->description:"-");
798 g_free(vcalviewer->url);
799 if (vcalviewer->event->url) {
800 vcalviewer->url = g_strdup(vcalviewer->event->url);
801 gtk_widget_show(vcalviewer->uribtn);
803 vcalviewer->url = NULL;
804 gtk_widget_hide(vcalviewer->uribtn);
807 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start),
808 vcalviewer->event->start?vcalviewer->event->start:"-");
809 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->end),
810 vcalviewer->event->end?vcalviewer->event->end:"-");
812 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->attendees), "-");
814 vcalviewer_answer_set_choices(vcalviewer, NULL, ICAL_METHOD_REPLY);
817 static void vcalviewer_get_event(VCalViewer *vcalviewer, MimeInfo *mimeinfo)
819 gchar *tmpfile = get_tmpfile(vcalviewer);
820 const gchar *charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
823 charset = CS_WINDOWS_1252;
825 if (!strcasecmp(charset, CS_ISO_8859_1))
826 charset = CS_WINDOWS_1252;
828 if (vcalviewer->event) {
829 vcal_manager_free_event(vcalviewer->event);
830 vcalviewer->event = NULL;
834 vcalviewer_reset(vcalviewer);
835 vcalviewer_show_error(vcalviewer, _("Error - could not get the calendar MIME part."));
839 vcalviewer->event = vcalviewer_get_component(tmpfile, charset);
840 if (!vcalviewer->event) {
841 vcalviewer_reset(vcalviewer);
842 vcalviewer_show_error(vcalviewer, _("Error - no calendar part found."));
846 if (vcalviewer->event->type == ICAL_VTODO_COMPONENT) {
847 vcalviewer_get_request_values(vcalviewer, mimeinfo, TRUE);
848 } else if (vcalviewer->event->method == ICAL_METHOD_REQUEST ||
849 vcalviewer->event->method == ICAL_METHOD_PUBLISH ||
850 vcalviewer->event->method == ICAL_METHOD_CANCEL) {
851 vcalviewer_get_request_values(vcalviewer, mimeinfo, FALSE);
852 } else if (vcalviewer->event->method == ICAL_METHOD_REPLY) {
853 vcalviewer_get_reply_values(vcalviewer, mimeinfo);
855 vcalviewer_reset(vcalviewer);
856 vcalviewer_show_error(vcalviewer, _("Error - Unknown calendar component type."));
860 static VCalViewer *s_vcalviewer = NULL;
862 static void vcal_viewer_show_mimepart(MimeViewer *_mimeviewer, const gchar *file, MimeInfo *mimeinfo)
864 VCalViewer *vcalviewer = (VCalViewer *) _mimeviewer;
867 s_vcalviewer = vcalviewer;
869 if (mimeinfo == NULL) {
870 vcal_viewer_clear_viewer(_mimeviewer);
874 debug_print("vcal_viewer_show_mimepart : %s\n", file);
876 vcal_viewer_clear_viewer(_mimeviewer);
877 gtk_widget_show_all(vcalviewer->scrolledwin);
878 g_free(vcalviewer->file);
879 vcalviewer->file = g_strdup(file);
880 vcalviewer->mimeinfo = mimeinfo;
881 vcalviewer_hide_error(vcalviewer);
882 vcalviewer_get_event(vcalviewer, mimeinfo);
884 gtk_widget_set_size_request(vcalviewer->description,
885 vcalviewer->scrolledwin->allocation.width - 200, -1);
886 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->location), TRUE);
887 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->summary), TRUE);
888 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->description), TRUE);
889 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->attendees), FALSE);
891 if (prefs_common_get_prefs()->textfont) {
892 PangoFontDescription *font_desc;
894 font_desc = pango_font_description_from_string
895 (prefs_common_get_prefs()->textfont);
897 gtk_widget_modify_font(
898 vcalviewer->description, font_desc);
899 pango_font_description_free(font_desc);
905 void vcalviewer_reload(FolderItem *item)
908 MainWindow *mainwin = mainwindow_get_mainwindow();
909 Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
911 folder_item_scan(item);
912 if (mainwin && mainwin->summaryview->folder_item) {
913 FolderItem *cur = mainwin->summaryview->folder_item;
914 if (cur->folder == folder)
915 folder_item_scan(cur);
917 if (mainwin && mainwin->summaryview->folder_item == item) {
918 debug_print("reload: %p, %p\n", (MimeViewer *)s_vcalviewer, s_vcalviewer->mimeinfo);
919 summary_redisplay_msg(mainwin->summaryview);
924 static void vcal_viewer_destroy_viewer(MimeViewer *_mimeviewer)
926 VCalViewer *vcalviewer = (VCalViewer *) _mimeviewer;
928 debug_print("vcal_viewer_destroy_viewer\n");
930 if (s_vcalviewer == vcalviewer)
932 vcal_viewer_clear_viewer(_mimeviewer);
936 static gboolean vcalviewer_reedit_cb(GtkButton *widget, gpointer data)
938 VCalViewer *vcalviewer = (VCalViewer *)data;
939 gchar * uid = vcalviewer_get_uid_from_mimeinfo(vcalviewer->mimeinfo);
940 VCalEvent *event = NULL;
942 s_vcalviewer = vcalviewer;
943 /* see if we have it registered and more recent */
944 event = vcal_manager_load_event(uid);
945 vcal_meeting_create(event);
946 vcal_manager_free_event(event);
950 static gboolean vcalviewer_uribtn_cb(GtkButton *widget, gpointer data)
952 VCalViewer *vcalviewer = (VCalViewer *)data;
955 open_uri(vcalviewer->url, prefs_common_get_uri_cmd());
960 void vcalendar_refresh_folder_contents(FolderItem *item)
962 Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
963 if (folder && item->folder == folder) {
964 MainWindow *mainwin = mainwindow_get_mainwindow();
965 folder_item_scan(item);
966 if (mainwin->summaryview->folder_item == item) {
967 summary_show(mainwin->summaryview, item);
972 static void send_cancel_notify_toggled_cb(GtkToggleButton *button, gboolean *data)
974 *data = gtk_toggle_button_get_active(button);
977 void vcalendar_cancel_meeting(FolderItem *item, const gchar *uid)
979 VCalEvent *event = NULL;
980 VCalMeeting *meet = NULL;
983 Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
984 gboolean redisp = FALSE;
985 GtkWidget *send_notify_chkbtn = gtk_check_button_new_with_label(_("Send a notification to the attendees"));
986 gboolean send_notify = TRUE;
988 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(send_notify_chkbtn), TRUE);
989 gtk_widget_show(send_notify_chkbtn);
990 g_signal_connect(G_OBJECT(send_notify_chkbtn), "toggled",
991 G_CALLBACK(send_cancel_notify_toggled_cb),
994 val = alertpanel_full(_("Cancel meeting"),
995 _("Are you sure you want to cancel this meeting?"),
996 GTK_STOCK_NO, GTK_STOCK_YES, NULL, FALSE,
997 send_notify_chkbtn, ALERT_WARNING, G_ALERTDEFAULT);
999 if (val != G_ALERTALTERNATE)
1002 event = vcal_manager_load_event(uid);
1005 event->method = ICAL_METHOD_CANCEL;
1008 MainWindow *mainwin = mainwindow_get_mainwindow();
1009 if (mainwin->summaryview->folder_item == item) {
1011 summary_show(mainwin->summaryview, NULL);
1016 meet = vcal_meeting_create_hidden(event);
1017 if (!vcal_meeting_send(meet)) {
1018 event->method = ICAL_METHOD_REQUEST;
1019 vcal_manager_save_event(event, TRUE);
1020 vcal_manager_free_event(event);
1022 folder_item_scan(item);
1024 if (folder && redisp) {
1025 MainWindow *mainwin = mainwindow_get_mainwindow();
1026 summary_show(mainwin->summaryview, item);
1032 vcal_manager_save_event(event, TRUE);
1034 file = vcal_manager_get_event_file(event->uid);
1036 vcal_manager_free_event(event);
1039 folder_item_scan(item);
1040 if (folder && redisp) {
1041 MainWindow *mainwin = mainwindow_get_mainwindow();
1042 summary_show(mainwin->summaryview, item);
1048 static gboolean vcalviewer_cancel_cb(GtkButton *widget, gpointer data)
1050 VCalViewer *vcalviewer = (VCalViewer *)data;
1051 FolderItem *item = vcalendar_get_current_item();
1052 gchar * uid = vcalviewer_get_uid_from_mimeinfo(vcalviewer->mimeinfo);
1053 vcalendar_cancel_meeting(item, uid);
1057 static gboolean vcalviewer_action_cb(GtkButton *widget, gpointer data)
1059 VCalViewer *vcalviewer = (VCalViewer *)data;
1060 gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(vcalviewer->answer));
1061 enum icalparameter_partstat reply[3] = {ICAL_PARTSTAT_ACCEPTED, ICAL_PARTSTAT_TENTATIVE, ICAL_PARTSTAT_DECLINED};
1062 PrefsAccount *account = NULL;
1063 VCalEvent *saved_event = NULL, *event = NULL;
1064 debug_print("index chosen %d\n", index);
1066 if (index < 0 || index > 2) {
1070 s_vcalviewer = vcalviewer;
1072 if (!vcalviewer->event) {
1073 g_warning("can't get event");
1077 /* see if we have it registered and more recent */
1078 event = vcalviewer->event;
1079 saved_event = vcal_manager_load_event(vcalviewer->event->uid);
1080 if (saved_event && saved_event->sequence >= vcalviewer->event->sequence) {
1081 saved_event->method = vcalviewer->event->method;
1082 event = saved_event;
1083 } else if (saved_event) {
1084 vcal_manager_free_event(saved_event);
1087 account = vcal_manager_get_account_from_event(event);
1090 AlertValue val = alertpanel_full(_("No account found"),
1091 _("You have no account matching any attendee.\n"
1092 "Do you want to reply anyway?"),
1093 GTK_STOCK_CANCEL, g_strconcat("+", _("Reply anyway"), NULL),
1094 NULL, FALSE, NULL, ALERT_QUESTION, G_ALERTDEFAULT);
1095 if (val == G_ALERTALTERNATE) {
1096 account = account_get_default();
1097 vcal_manager_update_answer(event, account->address,
1099 ICAL_PARTSTAT_NEEDSACTION,
1100 ICAL_CUTYPE_INDIVIDUAL);
1103 vcal_manager_free_event(saved_event);
1108 vcal_manager_update_answer(event, account->address, account->name, reply[index], 0);
1110 if (event->organizer && *(event->organizer) &&
1111 !vcal_manager_reply(account, event)) {
1112 g_warning("couldn't send reply");
1114 debug_print("no organizer, not sending answer\n");
1117 vcal_manager_save_event(event, TRUE);
1119 vcalviewer_display_event(vcalviewer, event);
1121 vcal_manager_free_event(saved_event);
1125 #define TABLE_ADD_LINE(label_text, widget) { \
1126 gchar *tmpstr = g_strdup_printf("<span weight=\"bold\">%s</span>",\
1128 GtkWidget *label = gtk_label_new(tmpstr); \
1130 gtk_label_set_use_markup (GTK_LABEL (label), TRUE); \
1131 gtk_misc_set_alignment (GTK_MISC(label), 1, 0); \
1132 gtk_table_attach (GTK_TABLE (vcalviewer->table), \
1133 label, 0, 1, i, i+1, \
1134 GTK_FILL, GTK_FILL, 6, 6); \
1135 gtk_table_attach (GTK_TABLE (vcalviewer->table), \
1136 widget, 1, 2, i, i+1, \
1137 GTK_FILL, GTK_FILL, 6, 6); \
1138 if (GTK_IS_LABEL(widget)) { \
1139 gtk_label_set_use_markup(GTK_LABEL (widget), TRUE); \
1140 gtk_misc_set_alignment (GTK_MISC(widget),0, 0); \
1141 gtk_label_set_line_wrap(GTK_LABEL(widget), TRUE); \
1146 static gchar *vcal_viewer_get_selection(MimeViewer *_viewer)
1148 VCalViewer *viewer = (VCalViewer *)_viewer;
1149 if (viewer->summary == NULL)
1151 if (gtk_label_get_text(GTK_LABEL(viewer->description))
1152 && *(gtk_label_get_text(GTK_LABEL(viewer->description))) > 2) {
1154 if (gtk_label_get_selection_bounds(GTK_LABEL(viewer->description),
1156 gchar *tmp = g_strdup(gtk_label_get_text(
1157 GTK_LABEL(viewer->description))+start);
1158 tmp[end-start] = '\0';
1161 return g_strdup(gtk_label_get_text(GTK_LABEL(viewer->description)));
1164 else if (gtk_label_get_text(GTK_LABEL(viewer->summary))
1165 && *(gtk_label_get_text(GTK_LABEL(viewer->summary))) > 2)
1166 return g_strdup(gtk_label_get_text(GTK_LABEL(viewer->summary)));
1172 static gboolean vcal_viewer_scroll_page(MimeViewer *_viewer, gboolean up)
1174 VCalViewer *viewer = (VCalViewer *)_viewer;
1175 GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment(
1176 GTK_SCROLLED_WINDOW(viewer->scrolledwin));
1178 return gtkutils_scroll_page(viewer->table, vadj, up);
1181 static void vcal_viewer_scroll_one_line(MimeViewer *_viewer, gboolean up)
1183 VCalViewer *viewer = (VCalViewer *)_viewer;
1184 GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment(
1185 GTK_SCROLLED_WINDOW(viewer->scrolledwin));
1187 gtkutils_scroll_one_line(viewer->table, vadj, up);
1190 MimeViewer *vcal_viewer_create(void)
1192 VCalViewer *vcalviewer;
1194 GtkWidget *hbox = NULL, *vbox = NULL;
1195 GtkWidget *warning_img;
1196 GtkWidget *warning_label;
1198 debug_print("Creating vcal view...\n");
1199 vcalviewer = g_new0(VCalViewer, 1);
1200 vcalviewer->mimeviewer.factory = &vcal_viewer_factory;
1202 vcalviewer->mimeviewer.get_widget = vcal_viewer_get_widget;
1203 vcalviewer->mimeviewer.show_mimepart = vcal_viewer_show_mimepart;
1204 vcalviewer->mimeviewer.clear_viewer = vcal_viewer_clear_viewer;
1205 vcalviewer->mimeviewer.destroy_viewer = vcal_viewer_destroy_viewer;
1206 vcalviewer->mimeviewer.get_selection = vcal_viewer_get_selection;
1207 vcalviewer->mimeviewer.scroll_page = vcal_viewer_scroll_page;
1208 vcalviewer->mimeviewer.scroll_one_line = vcal_viewer_scroll_one_line;
1210 vcalviewer->table = gtk_table_new(8, 2, FALSE);
1211 vcalviewer->type = gtk_label_new("meeting");
1212 vcalviewer->who = gtk_label_new("who");
1213 vcalviewer->start = gtk_label_new("start");
1214 vcalviewer->end = gtk_label_new("end");
1215 vcalviewer->location = gtk_label_new("location");
1216 vcalviewer->summary = gtk_label_new("summary");
1217 vcalviewer->description = gtk_label_new("description");
1218 vcalviewer->attendees = gtk_label_new("attendees");
1220 vcalviewer->answer = gtk_combo_box_new_text();
1221 vcalviewer->url = NULL;
1222 vcalviewer->button = gtk_button_new_with_label(_("Answer"));
1223 vcalviewer->reedit = gtk_button_new_with_label(_("Edit meeting..."));
1224 vcalviewer->cancel = gtk_button_new_with_label(_("Cancel meeting..."));
1225 vcalviewer->uribtn = gtk_button_new_with_label(_("Launch website"));
1226 vcalviewer->unavail_box = gtk_hbox_new(FALSE, 6);
1227 warning_img = gtk_image_new_from_stock
1228 (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_SMALL_TOOLBAR);
1229 warning_label = gtk_label_new(_("You are already busy at this time."));
1231 gtk_box_pack_start(GTK_BOX(vcalviewer->unavail_box), warning_img, FALSE, FALSE, 0);
1232 gtk_box_pack_start(GTK_BOX(vcalviewer->unavail_box), warning_label, FALSE, FALSE, 0);
1234 hbox = gtk_hbox_new(FALSE, 6);
1235 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->answer, FALSE, FALSE, 0);
1236 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->button, FALSE, FALSE, 0);
1237 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->reedit, FALSE, FALSE, 0);
1238 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->cancel, FALSE, FALSE, 0);
1239 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->uribtn, FALSE, FALSE, 0);
1241 vbox = gtk_vbox_new(FALSE, 6);
1242 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1243 gtk_box_pack_start(GTK_BOX(vbox), vcalviewer->unavail_box, FALSE, FALSE, 0);
1245 vcalviewer_answer_set_choices(vcalviewer, NULL, ICAL_METHOD_REQUEST);
1247 gtk_label_set_selectable(GTK_LABEL(vcalviewer->type), TRUE);
1248 gtk_label_set_selectable(GTK_LABEL(vcalviewer->who), TRUE);
1249 gtk_label_set_selectable(GTK_LABEL(vcalviewer->start), TRUE);
1250 gtk_label_set_selectable(GTK_LABEL(vcalviewer->end), TRUE);
1251 gtk_label_set_selectable(GTK_LABEL(vcalviewer->location), TRUE);
1252 gtk_label_set_selectable(GTK_LABEL(vcalviewer->summary), TRUE);
1253 gtk_label_set_selectable(GTK_LABEL(vcalviewer->description), TRUE);
1254 gtk_label_set_selectable(GTK_LABEL(vcalviewer->attendees), TRUE);
1256 g_signal_connect(G_OBJECT(vcalviewer->button), "clicked",
1257 G_CALLBACK(vcalviewer_action_cb), vcalviewer);
1259 g_signal_connect(G_OBJECT(vcalviewer->reedit), "clicked",
1260 G_CALLBACK(vcalviewer_reedit_cb), vcalviewer);
1262 g_signal_connect(G_OBJECT(vcalviewer->cancel), "clicked",
1263 G_CALLBACK(vcalviewer_cancel_cb), vcalviewer);
1265 g_signal_connect(G_OBJECT(vcalviewer->uribtn), "clicked",
1266 G_CALLBACK(vcalviewer_uribtn_cb), vcalviewer);
1268 TABLE_ADD_LINE(_("Event:"), vcalviewer->type);
1269 TABLE_ADD_LINE(_("Organizer:"), vcalviewer->who);
1270 TABLE_ADD_LINE(_("Location:"), vcalviewer->location);
1271 TABLE_ADD_LINE(_("Summary:"), vcalviewer->summary);
1272 TABLE_ADD_LINE(_("Starting:"), vcalviewer->start);
1273 TABLE_ADD_LINE(_("Ending:"), vcalviewer->end);
1274 TABLE_ADD_LINE(_("Description:"), vcalviewer->description);
1275 TABLE_ADD_LINE(_("Attendees:"), vcalviewer->attendees);
1276 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->attendees), FALSE);
1277 TABLE_ADD_LINE(_("Action:"), vbox);
1279 vcalviewer->scrolledwin = gtk_scrolled_window_new(NULL, NULL);
1280 gtk_scrolled_window_add_with_viewport(
1281 GTK_SCROLLED_WINDOW(vcalviewer->scrolledwin),
1283 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(vcalviewer->scrolledwin),
1285 GTK_POLICY_AUTOMATIC);
1287 gtk_widget_show_all(vcalviewer->scrolledwin);
1288 return (MimeViewer *) vcalviewer;
1291 static gchar *content_types[] =
1292 {"text/calendar", NULL};
1294 MimeViewerFactory vcal_viewer_factory =
1301 static gint alert_timeout_tag = 0;
1302 static gint scan_timeout_tag = 0;
1304 static gboolean vcal_webcal_check(gpointer data)
1306 Folder *root = folder_find_from_name ("vCalendar", vcal_folder_get_class());
1308 if (prefs_common_get_prefs()->work_offline)
1311 manual_update = FALSE;
1312 folderview_check_new(root);
1313 manual_update = TRUE;
1317 static guint context_menu_id = 0;
1318 static guint main_menu_id = 0;
1320 void vcalendar_init(void)
1322 MainWindow *mainwin = mainwindow_get_mainwindow();
1323 Folder *folder = NULL;
1324 gchar *directory = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
1327 if (!is_dir_exist(directory) && make_dir (directory) != 0) {
1336 mimeview_register_viewer_factory(&vcal_viewer_factory);
1337 folder_register_class(vcal_folder_get_class());
1339 folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
1341 START_TIMING("creating folder");
1342 folder = folder_new(vcal_folder_get_class(), "vCalendar", NULL);
1343 folder->klass->create_tree(folder);
1345 folder_scan_tree(folder, TRUE);
1349 if (!folder->inbox) {
1350 folder->klass->create_tree(folder);
1351 folder_scan_tree(folder, TRUE);
1353 if (folder->klass->scan_required(folder, folder->inbox)) {
1354 START_TIMING("scanning folder");
1355 folder_item_scan(folder->inbox);
1359 vcal_folder_gtk_init();
1361 alert_timeout_tag = g_timeout_add(60*1000,
1362 (GSourceFunc)vcal_meeting_alert_check,
1364 scan_timeout_tag = g_timeout_add(3600*1000,
1365 (GSourceFunc)vcal_webcal_check,
1367 if (prefs_common_get_prefs()->enable_color) {
1368 gtkut_convert_int_to_gdk_color(prefs_common_get_prefs()->uri_col,
1372 gtk_action_group_add_actions(mainwin->action_group, vcalendar_main_menu,
1373 1, (gpointer)mainwin);
1374 MENUITEM_ADDUI_ID_MANAGER(mainwin->ui_manager, "/Menu/Message", "CreateMeeting",
1375 "Message/CreateMeeting", GTK_UI_MANAGER_MENUITEM,
1377 MENUITEM_ADDUI_ID_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "CreateMeeting",
1378 "Message/CreateMeeting", GTK_UI_MANAGER_MENUITEM,
1383 void vcalendar_done(void)
1385 MainWindow *mainwin = mainwindow_get_mainwindow();
1386 FolderView *folderview = NULL;
1387 FolderItem *fitem = NULL;
1389 icalmemory_free_ring();
1391 vcal_folder_free_data();
1393 if (mainwin == NULL)
1396 folderview = mainwin->folderview;
1397 fitem = folderview->summaryview->folder_item;
1400 fitem->folder->klass == vcal_folder_get_class()) {
1401 folderview_unselect(folderview);
1402 summary_clear_all(folderview->summaryview);
1403 if (fitem->folder->klass->item_closed)
1404 fitem->folder->klass->item_closed(fitem);
1407 mimeview_unregister_viewer_factory(&vcal_viewer_factory);
1408 folder_unregister_class(vcal_folder_get_class());
1409 vcal_folder_gtk_done();
1411 g_source_remove(alert_timeout_tag);
1412 alert_timeout_tag = 0;
1413 g_source_remove(scan_timeout_tag);
1414 scan_timeout_tag = 0;
1416 MENUITEM_REMUI_MANAGER(mainwin->ui_manager,mainwin->action_group, "Message/CreateMeeting", main_menu_id);
1418 MENUITEM_REMUI_MANAGER(mainwin->ui_manager,mainwin->action_group, "Message/CreateMeeting", context_menu_id);
1419 context_menu_id = 0;