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(_("%s <span weight=\"bold\">(this event recurs)</span>"),
566 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start), tmp);
567 gtk_label_set_use_markup(GTK_LABEL(vcalviewer->start), TRUE);
569 } else if (event->rec_occurence) {
570 gchar *tmp = g_strdup_printf(_("%s <span weight=\"bold\">(this event is part of a recurring event)</span>"),
572 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start), tmp);
573 gtk_label_set_use_markup(GTK_LABEL(vcalviewer->start), TRUE);
576 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start), event->start);
579 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start), "-");
583 if (event->end && *(event->end)) {
584 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->end), event->end);
586 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->end), "-");
590 attendees = g_strdup("");
591 for (list = vcal_manager_get_answers_emails(event);
592 list && list->data; list = list->next) {
593 gchar *attendee = (gchar *)list->data;
594 gchar *name = vcal_manager_get_attendee_name(event, attendee);
595 gchar *ename = g_markup_printf_escaped("%s", name?name:"");
596 gchar *eatt = g_markup_printf_escaped("%s", attendee);
597 enum icalparameter_partstat acode = vcal_manager_get_reply_for_attendee(event, attendee);
598 gchar *answer = vcal_manager_get_reply_text_for_attendee(event, attendee);
599 gchar *type = vcal_manager_get_cutype_text_for_attendee(event, attendee);
602 tmp = g_strdup_printf(
603 "%s%s<%s> (%s, <span%s>%s</span>)",
604 (ename && *(ename))?ename:"",
605 (ename && *(ename))?" ":"",
606 (eatt && *(eatt))?eatt:"",
607 (type && *(type))?type:"",
608 (acode != ICAL_PARTSTAT_ACCEPTED ? " foreground=\"red\"":""),
609 (answer && *(answer))?answer:"");
610 e_len = strlen(attendees);
613 attendees = g_realloc(attendees, e_len+n_len+2);
614 *(attendees+e_len) = '\n';
615 strcpy(attendees+e_len+1, tmp);
617 attendees = g_realloc(attendees, e_len+n_len+1);
618 strcpy(attendees, tmp);
628 if (attendees && *(attendees)) {
629 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->attendees), attendees);
631 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->attendees), "-");
634 gtk_label_set_use_markup(GTK_LABEL(vcalviewer->attendees), TRUE);
638 if (event->type != ICAL_VTODO_COMPONENT)
639 vcalviewer_answer_set_choices(vcalviewer, event, event->method);
641 vcalviewer_answer_set_choices(vcalviewer, event, ICAL_METHOD_PUBLISH);
643 vcalviewer_answer_set_choices(vcalviewer, event, ICAL_METHOD_REPLY);
644 gtk_widget_show(vcalviewer->reedit);
645 gtk_widget_show(vcalviewer->cancel);
648 /* save if cancelled */
650 vcal_manager_save_event(event, TRUE);
653 gchar *vcalviewer_get_uid_from_mimeinfo(MimeInfo *mimeinfo)
655 gchar *tmpfile = procmime_get_tmp_file_name(mimeinfo);
656 const gchar *charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
657 gchar *compstr = NULL;
659 VCalEvent *event = NULL;
662 charset = CS_WINDOWS_1252;
664 if (!strcasecmp(charset, CS_ISO_8859_1))
665 charset = CS_WINDOWS_1252;
667 if (procmime_get_part(tmpfile, mimeinfo) < 0) {
668 g_warning("Can't get mimepart file");
673 compstr = file_read_to_str(tmpfile);
675 event = vcal_get_event_from_ical(compstr, charset);
677 res = g_strdup(event->uid);
679 vcal_manager_free_event(event);
681 debug_print("got uid: %s\n", res);
686 static void vcalviewer_get_request_values(VCalViewer *vcalviewer, MimeInfo *mimeinfo, gboolean is_todo)
688 VCalEvent *saved_event = NULL;
689 const gchar *charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
690 const gchar *saveme = procmime_mimeinfo_get_parameter(mimeinfo, "vcalsave");
692 if (!vcalviewer->event)
696 charset = CS_WINDOWS_1252;
698 if (!strcasecmp(charset, CS_ISO_8859_1))
699 charset = CS_WINDOWS_1252;
701 /* see if we have it registered and more recent */
702 saved_event = vcal_manager_load_event(vcalviewer->event->uid);
703 if (saved_event && saved_event->sequence >= vcalviewer->event->sequence) {
704 charset = CS_INTERNAL;
705 saved_event->method = vcalviewer->event->method;
706 vcalviewer_display_event(vcalviewer, saved_event);
707 vcal_manager_free_event(saved_event);
709 } else if (saved_event) {
710 vcal_manager_free_event(saved_event);
713 /* load it and register it */
715 if (!saveme || strcmp(saveme,"no"))
716 vcal_manager_save_event(vcalviewer->event, FALSE);
718 vcalviewer_display_event(vcalviewer, vcalviewer->event);
721 static void vcalviewer_get_reply_values(VCalViewer *vcalviewer, MimeInfo *mimeinfo)
723 const gchar *charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
724 VCalEvent *saved_event = NULL;
725 gchar *attendee = NULL, *label = NULL;
726 Answer *answer = NULL;
728 if (!vcalviewer->event)
732 charset = CS_WINDOWS_1252;
734 if (!strcasecmp(charset, CS_ISO_8859_1))
735 charset = CS_WINDOWS_1252;
737 if (!vcalviewer->event->answers || g_slist_length(vcalviewer->event->answers) > 1) {
738 g_warning("strange, no answers or more than one");
741 if (vcalviewer->event->answers) {
742 answer = (Answer *)vcalviewer->event->answers->data;
743 attendee = g_strdup(answer->attendee);
748 label = g_strjoin(" ",
749 _("You have received an answer to an unknown meeting proposal."),
750 _("Details follow:"), NULL);
751 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
753 label = g_strdup_printf(_("You have received an answer to a meeting proposal.\n"
754 "%s has %s the invitation whose details follow:"),
755 attendee, vcal_manager_answer_get_text(answer->answer));
756 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
761 saved_event = vcal_manager_load_event(vcalviewer->event->uid);
762 if (saved_event && answer) {
763 vcal_manager_update_answer(saved_event,
764 answer->attendee, answer->name, answer->answer, answer->cutype);
765 vcal_manager_save_event(saved_event, TRUE);
766 saved_event->method = vcalviewer->event->method;
767 vcalviewer_display_event(vcalviewer, saved_event);
768 vcal_manager_free_event(saved_event);
772 if (vcalviewer->event->organizer) {
773 if (vcalviewer->event->orgname) {
774 gchar *addr = g_strconcat(vcalviewer->event->orgname, " <",
775 vcalviewer->event->organizer, ">", NULL);
776 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who), addr);
779 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who),
780 vcalviewer->event->organizer);
783 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who), "-");
786 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->location),
787 vcalviewer->event->location?vcalviewer->event->location:"-");
789 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->summary),
790 vcalviewer->event->summary?vcalviewer->event->summary:"-");
792 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->description),
793 vcalviewer->event->description?vcalviewer->event->description:"-");
795 g_free(vcalviewer->url);
796 if (vcalviewer->event->url) {
797 vcalviewer->url = g_strdup(vcalviewer->event->url);
798 gtk_widget_show(vcalviewer->uribtn);
800 vcalviewer->url = NULL;
801 gtk_widget_hide(vcalviewer->uribtn);
804 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start),
805 vcalviewer->event->start?vcalviewer->event->start:"-");
806 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->end),
807 vcalviewer->event->end?vcalviewer->event->end:"-");
809 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->attendees), "-");
811 vcalviewer_answer_set_choices(vcalviewer, NULL, ICAL_METHOD_REPLY);
814 static void vcalviewer_get_event(VCalViewer *vcalviewer, MimeInfo *mimeinfo)
816 gchar *tmpfile = get_tmpfile(vcalviewer);
817 const gchar *charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
820 charset = CS_WINDOWS_1252;
822 if (!strcasecmp(charset, CS_ISO_8859_1))
823 charset = CS_WINDOWS_1252;
825 if (vcalviewer->event) {
826 vcal_manager_free_event(vcalviewer->event);
827 vcalviewer->event = NULL;
831 vcalviewer_reset(vcalviewer);
832 vcalviewer_show_error(vcalviewer, _("Error - could not get the calendar MIME part."));
836 vcalviewer->event = vcalviewer_get_component(tmpfile, charset);
837 if (!vcalviewer->event) {
838 vcalviewer_reset(vcalviewer);
839 vcalviewer_show_error(vcalviewer, _("Error - no calendar part found."));
843 if (vcalviewer->event->type == ICAL_VTODO_COMPONENT) {
844 vcalviewer_get_request_values(vcalviewer, mimeinfo, TRUE);
845 } else if (vcalviewer->event->method == ICAL_METHOD_REQUEST ||
846 vcalviewer->event->method == ICAL_METHOD_PUBLISH ||
847 vcalviewer->event->method == ICAL_METHOD_CANCEL) {
848 vcalviewer_get_request_values(vcalviewer, mimeinfo, FALSE);
849 } else if (vcalviewer->event->method == ICAL_METHOD_REPLY) {
850 vcalviewer_get_reply_values(vcalviewer, mimeinfo);
852 vcalviewer_reset(vcalviewer);
853 vcalviewer_show_error(vcalviewer, _("Error - Unknown calendar component type."));
857 static VCalViewer *s_vcalviewer = NULL;
859 static void vcal_viewer_show_mimepart(MimeViewer *_mimeviewer, const gchar *file, MimeInfo *mimeinfo)
861 VCalViewer *vcalviewer = (VCalViewer *) _mimeviewer;
864 s_vcalviewer = vcalviewer;
866 if (mimeinfo == NULL) {
867 vcal_viewer_clear_viewer(_mimeviewer);
871 debug_print("vcal_viewer_show_mimepart : %s\n", file);
873 vcal_viewer_clear_viewer(_mimeviewer);
874 gtk_widget_show_all(vcalviewer->scrolledwin);
875 g_free(vcalviewer->file);
876 vcalviewer->file = g_strdup(file);
877 vcalviewer->mimeinfo = mimeinfo;
878 vcalviewer_hide_error(vcalviewer);
879 vcalviewer_get_event(vcalviewer, mimeinfo);
881 gtk_widget_set_size_request(vcalviewer->description,
882 vcalviewer->scrolledwin->allocation.width - 200, -1);
883 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->location), TRUE);
884 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->summary), TRUE);
885 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->description), TRUE);
886 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->attendees), FALSE);
888 if (prefs_common_get_prefs()->textfont) {
889 PangoFontDescription *font_desc;
891 font_desc = pango_font_description_from_string
892 (prefs_common_get_prefs()->textfont);
894 gtk_widget_modify_font(
895 vcalviewer->description, font_desc);
896 pango_font_description_free(font_desc);
902 void vcalviewer_reload(FolderItem *item)
905 MainWindow *mainwin = mainwindow_get_mainwindow();
906 Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
908 folder_item_scan(item);
909 if (mainwin && mainwin->summaryview->folder_item) {
910 FolderItem *cur = mainwin->summaryview->folder_item;
911 if (cur->folder == folder)
912 folder_item_scan(cur);
914 if (mainwin && mainwin->summaryview->folder_item == item) {
915 debug_print("reload: %p, %p\n", (MimeViewer *)s_vcalviewer, s_vcalviewer->mimeinfo);
916 summary_redisplay_msg(mainwin->summaryview);
921 static void vcal_viewer_destroy_viewer(MimeViewer *_mimeviewer)
923 VCalViewer *vcalviewer = (VCalViewer *) _mimeviewer;
925 debug_print("vcal_viewer_destroy_viewer\n");
927 if (s_vcalviewer == vcalviewer)
929 vcal_viewer_clear_viewer(_mimeviewer);
933 static gboolean vcalviewer_reedit_cb(GtkButton *widget, gpointer data)
935 VCalViewer *vcalviewer = (VCalViewer *)data;
936 gchar * uid = vcalviewer_get_uid_from_mimeinfo(vcalviewer->mimeinfo);
937 VCalEvent *event = NULL;
939 s_vcalviewer = vcalviewer;
940 /* see if we have it registered and more recent */
941 event = vcal_manager_load_event(uid);
942 vcal_meeting_create(event);
943 vcal_manager_free_event(event);
947 static gboolean vcalviewer_uribtn_cb(GtkButton *widget, gpointer data)
949 VCalViewer *vcalviewer = (VCalViewer *)data;
952 open_uri(vcalviewer->url, prefs_common_get_uri_cmd());
957 void vcalendar_refresh_folder_contents(FolderItem *item)
959 Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
960 if (folder && item->folder == folder) {
961 MainWindow *mainwin = mainwindow_get_mainwindow();
962 folder_item_scan(item);
963 if (mainwin->summaryview->folder_item == item) {
964 summary_show(mainwin->summaryview, item);
969 static void send_cancel_notify_toggled_cb(GtkToggleButton *button, gboolean *data)
971 *data = gtk_toggle_button_get_active(button);
974 void vcalendar_cancel_meeting(FolderItem *item, const gchar *uid)
976 VCalEvent *event = NULL;
977 VCalMeeting *meet = NULL;
980 Folder *folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
981 gboolean redisp = FALSE;
982 GtkWidget *send_notify_chkbtn = gtk_check_button_new_with_label(_("Send a notification to the attendees"));
983 gboolean send_notify = TRUE;
985 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(send_notify_chkbtn), TRUE);
986 gtk_widget_show(send_notify_chkbtn);
987 g_signal_connect(G_OBJECT(send_notify_chkbtn), "toggled",
988 G_CALLBACK(send_cancel_notify_toggled_cb),
991 val = alertpanel_full(_("Cancel meeting"),
992 _("Are you sure you want to cancel this meeting?"),
993 GTK_STOCK_NO, GTK_STOCK_YES, NULL, FALSE,
994 send_notify_chkbtn, ALERT_WARNING, G_ALERTDEFAULT);
996 if (val != G_ALERTALTERNATE)
999 event = vcal_manager_load_event(uid);
1002 event->method = ICAL_METHOD_CANCEL;
1005 MainWindow *mainwin = mainwindow_get_mainwindow();
1006 if (mainwin->summaryview->folder_item == item) {
1008 summary_show(mainwin->summaryview, NULL);
1013 meet = vcal_meeting_create_hidden(event);
1014 if (!vcal_meeting_send(meet)) {
1015 event->method = ICAL_METHOD_REQUEST;
1016 vcal_manager_save_event(event, TRUE);
1017 vcal_manager_free_event(event);
1019 folder_item_scan(item);
1021 if (folder && redisp) {
1022 MainWindow *mainwin = mainwindow_get_mainwindow();
1023 summary_show(mainwin->summaryview, item);
1029 vcal_manager_save_event(event, TRUE);
1031 file = vcal_manager_get_event_file(event->uid);
1033 vcal_manager_free_event(event);
1036 folder_item_scan(item);
1037 if (folder && redisp) {
1038 MainWindow *mainwin = mainwindow_get_mainwindow();
1039 summary_show(mainwin->summaryview, item);
1045 static gboolean vcalviewer_cancel_cb(GtkButton *widget, gpointer data)
1047 VCalViewer *vcalviewer = (VCalViewer *)data;
1048 FolderItem *item = vcalendar_get_current_item();
1049 gchar * uid = vcalviewer_get_uid_from_mimeinfo(vcalviewer->mimeinfo);
1050 vcalendar_cancel_meeting(item, uid);
1054 static gboolean vcalviewer_action_cb(GtkButton *widget, gpointer data)
1056 VCalViewer *vcalviewer = (VCalViewer *)data;
1057 gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(vcalviewer->answer));
1058 enum icalparameter_partstat reply[3] = {ICAL_PARTSTAT_ACCEPTED, ICAL_PARTSTAT_TENTATIVE, ICAL_PARTSTAT_DECLINED};
1059 PrefsAccount *account = NULL;
1060 VCalEvent *saved_event = NULL, *event = NULL;
1061 debug_print("index chosen %d\n", index);
1063 if (index < 0 || index > 2) {
1067 s_vcalviewer = vcalviewer;
1069 if (!vcalviewer->event) {
1070 g_warning("can't get event");
1074 /* see if we have it registered and more recent */
1075 event = vcalviewer->event;
1076 saved_event = vcal_manager_load_event(vcalviewer->event->uid);
1077 if (saved_event && saved_event->sequence >= vcalviewer->event->sequence) {
1078 saved_event->method = vcalviewer->event->method;
1079 event = saved_event;
1080 } else if (saved_event) {
1081 vcal_manager_free_event(saved_event);
1084 account = vcal_manager_get_account_from_event(event);
1087 AlertValue val = alertpanel_full(_("No account found"),
1088 _("You have no account matching any attendee.\n"
1089 "Do you want to reply anyway?"),
1090 GTK_STOCK_CANCEL, _("+Reply anyway"), NULL, FALSE,
1091 NULL, ALERT_QUESTION, G_ALERTDEFAULT);
1092 if (val == G_ALERTALTERNATE) {
1093 account = account_get_default();
1094 vcal_manager_update_answer(event, account->address,
1096 ICAL_PARTSTAT_NEEDSACTION,
1097 ICAL_CUTYPE_INDIVIDUAL);
1100 vcal_manager_free_event(saved_event);
1105 vcal_manager_update_answer(event, account->address, account->name, reply[index], 0);
1107 if (event->organizer && *(event->organizer) &&
1108 !vcal_manager_reply(account, event)) {
1109 g_warning("couldn't send reply");
1111 debug_print("no organizer, not sending answer\n");
1114 vcal_manager_save_event(event, TRUE);
1116 vcalviewer_display_event(vcalviewer, event);
1118 vcal_manager_free_event(saved_event);
1122 #define TABLE_ADD_LINE(label_text, widget) { \
1123 gchar *tmpstr = g_strdup_printf("<span weight=\"bold\">%s</span>",\
1125 GtkWidget *label = gtk_label_new(tmpstr); \
1127 gtk_label_set_use_markup (GTK_LABEL (label), TRUE); \
1128 gtk_misc_set_alignment (GTK_MISC(label), 1, 0); \
1129 gtk_table_attach (GTK_TABLE (vcalviewer->table), \
1130 label, 0, 1, i, i+1, \
1131 GTK_FILL, GTK_FILL, 6, 6); \
1132 gtk_table_attach (GTK_TABLE (vcalviewer->table), \
1133 widget, 1, 2, i, i+1, \
1134 GTK_FILL, GTK_FILL, 6, 6); \
1135 if (GTK_IS_LABEL(widget)) { \
1136 gtk_label_set_use_markup(GTK_LABEL (widget), TRUE); \
1137 gtk_misc_set_alignment (GTK_MISC(widget),0, 0); \
1138 gtk_label_set_line_wrap(GTK_LABEL(widget), TRUE); \
1143 static gchar *vcal_viewer_get_selection(MimeViewer *_viewer)
1145 VCalViewer *viewer = (VCalViewer *)_viewer;
1146 if (viewer->summary == NULL)
1148 if (gtk_label_get_text(GTK_LABEL(viewer->description))
1149 && *(gtk_label_get_text(GTK_LABEL(viewer->description))) > 2) {
1151 if (gtk_label_get_selection_bounds(GTK_LABEL(viewer->description),
1153 gchar *tmp = g_strdup(gtk_label_get_text(
1154 GTK_LABEL(viewer->description))+start);
1155 tmp[end-start] = '\0';
1158 return g_strdup(gtk_label_get_text(GTK_LABEL(viewer->description)));
1161 else if (gtk_label_get_text(GTK_LABEL(viewer->summary))
1162 && *(gtk_label_get_text(GTK_LABEL(viewer->summary))) > 2)
1163 return g_strdup(gtk_label_get_text(GTK_LABEL(viewer->summary)));
1169 static gboolean vcal_viewer_scroll_page(MimeViewer *_viewer, gboolean up)
1171 VCalViewer *viewer = (VCalViewer *)_viewer;
1172 GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment(
1173 GTK_SCROLLED_WINDOW(viewer->scrolledwin));
1175 return gtkutils_scroll_page(viewer->table, vadj, up);
1178 static void vcal_viewer_scroll_one_line(MimeViewer *_viewer, gboolean up)
1180 VCalViewer *viewer = (VCalViewer *)_viewer;
1181 GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment(
1182 GTK_SCROLLED_WINDOW(viewer->scrolledwin));
1184 gtkutils_scroll_one_line(viewer->table, vadj, up);
1187 MimeViewer *vcal_viewer_create(void)
1189 VCalViewer *vcalviewer;
1191 GtkWidget *hbox = NULL, *vbox = NULL;
1192 GtkWidget *warning_img;
1193 GtkWidget *warning_label;
1195 debug_print("Creating vcal view...\n");
1196 vcalviewer = g_new0(VCalViewer, 1);
1197 vcalviewer->mimeviewer.factory = &vcal_viewer_factory;
1199 vcalviewer->mimeviewer.get_widget = vcal_viewer_get_widget;
1200 vcalviewer->mimeviewer.show_mimepart = vcal_viewer_show_mimepart;
1201 vcalviewer->mimeviewer.clear_viewer = vcal_viewer_clear_viewer;
1202 vcalviewer->mimeviewer.destroy_viewer = vcal_viewer_destroy_viewer;
1203 vcalviewer->mimeviewer.get_selection = vcal_viewer_get_selection;
1204 vcalviewer->mimeviewer.scroll_page = vcal_viewer_scroll_page;
1205 vcalviewer->mimeviewer.scroll_one_line = vcal_viewer_scroll_one_line;
1207 vcalviewer->table = gtk_table_new(8, 2, FALSE);
1208 vcalviewer->type = gtk_label_new("meeting");
1209 vcalviewer->who = gtk_label_new("who");
1210 vcalviewer->start = gtk_label_new("start");
1211 vcalviewer->end = gtk_label_new("end");
1212 vcalviewer->location = gtk_label_new("location");
1213 vcalviewer->summary = gtk_label_new("summary");
1214 vcalviewer->description = gtk_label_new("description");
1215 vcalviewer->attendees = gtk_label_new("attendees");
1217 vcalviewer->answer = gtk_combo_box_new_text();
1218 vcalviewer->url = NULL;
1219 vcalviewer->button = gtk_button_new_with_label(_("Answer"));
1220 vcalviewer->reedit = gtk_button_new_with_label(_("Edit meeting..."));
1221 vcalviewer->cancel = gtk_button_new_with_label(_("Cancel meeting..."));
1222 vcalviewer->uribtn = gtk_button_new_with_label(_("Launch website"));
1223 vcalviewer->unavail_box = gtk_hbox_new(FALSE, 6);
1224 warning_img = gtk_image_new_from_stock
1225 (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_SMALL_TOOLBAR);
1226 warning_label = gtk_label_new(_("You are already busy at this time."));
1228 gtk_box_pack_start(GTK_BOX(vcalviewer->unavail_box), warning_img, FALSE, FALSE, 0);
1229 gtk_box_pack_start(GTK_BOX(vcalviewer->unavail_box), warning_label, FALSE, FALSE, 0);
1231 hbox = gtk_hbox_new(FALSE, 6);
1232 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->answer, FALSE, FALSE, 0);
1233 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->button, FALSE, FALSE, 0);
1234 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->reedit, FALSE, FALSE, 0);
1235 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->cancel, FALSE, FALSE, 0);
1236 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->uribtn, FALSE, FALSE, 0);
1238 vbox = gtk_vbox_new(FALSE, 6);
1239 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1240 gtk_box_pack_start(GTK_BOX(vbox), vcalviewer->unavail_box, FALSE, FALSE, 0);
1242 vcalviewer_answer_set_choices(vcalviewer, NULL, ICAL_METHOD_REQUEST);
1244 gtk_label_set_selectable(GTK_LABEL(vcalviewer->type), TRUE);
1245 gtk_label_set_selectable(GTK_LABEL(vcalviewer->who), TRUE);
1246 gtk_label_set_selectable(GTK_LABEL(vcalviewer->start), TRUE);
1247 gtk_label_set_selectable(GTK_LABEL(vcalviewer->end), TRUE);
1248 gtk_label_set_selectable(GTK_LABEL(vcalviewer->location), TRUE);
1249 gtk_label_set_selectable(GTK_LABEL(vcalviewer->summary), TRUE);
1250 gtk_label_set_selectable(GTK_LABEL(vcalviewer->description), TRUE);
1251 gtk_label_set_selectable(GTK_LABEL(vcalviewer->attendees), TRUE);
1253 g_signal_connect(G_OBJECT(vcalviewer->button), "clicked",
1254 G_CALLBACK(vcalviewer_action_cb), vcalviewer);
1256 g_signal_connect(G_OBJECT(vcalviewer->reedit), "clicked",
1257 G_CALLBACK(vcalviewer_reedit_cb), vcalviewer);
1259 g_signal_connect(G_OBJECT(vcalviewer->cancel), "clicked",
1260 G_CALLBACK(vcalviewer_cancel_cb), vcalviewer);
1262 g_signal_connect(G_OBJECT(vcalviewer->uribtn), "clicked",
1263 G_CALLBACK(vcalviewer_uribtn_cb), vcalviewer);
1265 TABLE_ADD_LINE(_("Event:"), vcalviewer->type);
1266 TABLE_ADD_LINE(_("Organizer:"), vcalviewer->who);
1267 TABLE_ADD_LINE(_("Location:"), vcalviewer->location);
1268 TABLE_ADD_LINE(_("Summary:"), vcalviewer->summary);
1269 TABLE_ADD_LINE(_("Starting:"), vcalviewer->start);
1270 TABLE_ADD_LINE(_("Ending:"), vcalviewer->end);
1271 TABLE_ADD_LINE(_("Description:"), vcalviewer->description);
1272 TABLE_ADD_LINE(_("Attendees:"), vcalviewer->attendees);
1273 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->attendees), FALSE);
1274 TABLE_ADD_LINE(_("Action:"), vbox);
1276 vcalviewer->scrolledwin = gtk_scrolled_window_new(NULL, NULL);
1277 gtk_scrolled_window_add_with_viewport(
1278 GTK_SCROLLED_WINDOW(vcalviewer->scrolledwin),
1280 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(vcalviewer->scrolledwin),
1282 GTK_POLICY_AUTOMATIC);
1284 gtk_widget_show_all(vcalviewer->scrolledwin);
1285 return (MimeViewer *) vcalviewer;
1288 static gchar *content_types[] =
1289 {"text/calendar", NULL};
1291 MimeViewerFactory vcal_viewer_factory =
1298 static gint alert_timeout_tag = 0;
1299 static gint scan_timeout_tag = 0;
1301 static gboolean vcal_webcal_check(gpointer data)
1303 Folder *root = folder_find_from_name ("vCalendar", vcal_folder_get_class());
1305 if (prefs_common_get_prefs()->work_offline)
1308 manual_update = FALSE;
1309 folderview_check_new(root);
1310 manual_update = TRUE;
1314 static guint context_menu_id = 0;
1315 static guint main_menu_id = 0;
1317 void vcalendar_init(void)
1319 MainWindow *mainwin = mainwindow_get_mainwindow();
1320 Folder *folder = NULL;
1321 gchar *directory = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
1324 if (!is_dir_exist(directory) && make_dir (directory) != 0) {
1333 mimeview_register_viewer_factory(&vcal_viewer_factory);
1334 folder_register_class(vcal_folder_get_class());
1336 folder = folder_find_from_name ("vCalendar", vcal_folder_get_class());
1338 START_TIMING("creating folder");
1339 folder = folder_new(vcal_folder_get_class(), "vCalendar", NULL);
1340 folder->klass->create_tree(folder);
1342 folder_scan_tree(folder, TRUE);
1346 if (!folder->inbox) {
1347 folder->klass->create_tree(folder);
1348 folder_scan_tree(folder, TRUE);
1350 if (folder->klass->scan_required(folder, folder->inbox)) {
1351 START_TIMING("scanning folder");
1352 folder_item_scan(folder->inbox);
1356 vcal_folder_gtk_init();
1358 alert_timeout_tag = g_timeout_add(60*1000,
1359 (GSourceFunc)vcal_meeting_alert_check,
1361 scan_timeout_tag = g_timeout_add(3600*1000,
1362 (GSourceFunc)vcal_webcal_check,
1364 if (prefs_common_get_prefs()->enable_color) {
1365 gtkut_convert_int_to_gdk_color(prefs_common_get_prefs()->uri_col,
1369 gtk_action_group_add_actions(mainwin->action_group, vcalendar_main_menu,
1370 1, (gpointer)mainwin);
1371 MENUITEM_ADDUI_ID_MANAGER(mainwin->ui_manager, "/Menu/Message", "CreateMeeting",
1372 "Message/CreateMeeting", GTK_UI_MANAGER_MENUITEM,
1374 MENUITEM_ADDUI_ID_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "CreateMeeting",
1375 "Message/CreateMeeting", GTK_UI_MANAGER_MENUITEM,
1380 void vcalendar_done(void)
1382 MainWindow *mainwin = mainwindow_get_mainwindow();
1383 FolderView *folderview = NULL;
1384 FolderItem *fitem = NULL;
1386 icalmemory_free_ring();
1388 vcal_folder_free_data();
1390 if (mainwin == NULL)
1393 folderview = mainwin->folderview;
1394 fitem = folderview->summaryview->folder_item;
1397 fitem->folder->klass == vcal_folder_get_class()) {
1398 folderview_unselect(folderview);
1399 summary_clear_all(folderview->summaryview);
1400 if (fitem->folder->klass->item_closed)
1401 fitem->folder->klass->item_closed(fitem);
1404 mimeview_unregister_viewer_factory(&vcal_viewer_factory);
1405 folder_unregister_class(vcal_folder_get_class());
1406 vcal_folder_gtk_done();
1408 g_source_remove(alert_timeout_tag);
1409 alert_timeout_tag = 0;
1410 g_source_remove(scan_timeout_tag);
1411 scan_timeout_tag = 0;
1413 MENUITEM_REMUI_MANAGER(mainwin->ui_manager,mainwin->action_group, "Message/CreateMeeting", main_menu_id);
1415 MENUITEM_REMUI_MANAGER(mainwin->ui_manager,mainwin->action_group, "Message/CreateMeeting", context_menu_id);
1416 context_menu_id = 0;