2 * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2018 Colin Leroy and the Claws Mail team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include "claws-features.h"
27 #include <glib/gi18n.h>
29 #include <libical/ical.h>
37 #include "folder_item_prefs.h"
40 #include "vcalendar.h"
41 #include "vcal_manager.h"
42 #include "vcal_folder.h"
43 #include "vcal_meeting_gtk.h"
44 #include "vcal_interface.h"
45 #include "prefs_account.h"
46 #include "prefs_common.h"
52 #include "alertpanel.h"
53 #include "vcal_prefs.h"
54 #include "statusbar.h"
58 MimeViewerFactory vcal_viewer_factory;
60 static void create_meeting_from_message_cb_ui(GtkAction *action, gpointer data);
62 static GdkColor uri_color = {
71 MimeViewer mimeviewer;
78 GtkWidget *scrolledwin;
86 GtkWidget *description;
94 GtkWidget *unavail_box;
97 static GtkActionEntry vcalendar_main_menu[] = {{
98 "Message/CreateMeeting",
99 NULL, N_("Create meeting from message..."), NULL, NULL, G_CALLBACK(create_meeting_from_message_cb_ui)
102 static void create_meeting_from_message_cb_ui(GtkAction *action, gpointer data)
104 MainWindow *mainwin = mainwindow_get_mainwindow();
105 SummaryView *summaryview = mainwin->summaryview;
106 GSList *msglist = summary_get_selected_msg_list(summaryview);
107 FolderItem *item = NULL;
112 if (summary_is_locked(summaryview) || !msglist) {
114 g_slist_free(msglist);
117 total = g_slist_length(msglist);
119 msg = g_strdup_printf(_("You are about to create %d "
120 "meetings, one by one. Do you "
121 "want to continue?"),
124 && 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_with_zone(t, FALSE, NULL)));
161 gchar *dtend = g_strdup(icaltime_as_ical_string(icaltime_from_timet_with_zone(t2, FALSE, NULL)));
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 uid = prefs_account_generate_msgid(account);
184 event = vcal_manager_new_event(uid,
185 org, NULL, NULL/*location*/, summary, description,
186 dtstart, dtend, recur, tzid, url, method, sequence,
187 ICAL_VTODO_COMPONENT);
190 /* hack to get default hours */
191 g_free(event->dtstart);
192 g_free(event->dtend);
193 event->dtstart = NULL;
196 vcal_meeting_create(event);
197 vcal_manager_free_event(event);
211 procmsg_msginfo_free(&msginfo);
214 statusbar_progress_all(0,0,0);
215 STATUSBAR_POP(mainwin);
217 folder_item_update_thaw();
218 gtk_cmclist_thaw(GTK_CMCLIST(summaryview->ctree));
219 main_window_cursor_normal(summaryview->mainwin);
220 g_slist_free(msglist);
223 static gchar *get_tmpfile(VCalViewer *vcalviewer)
225 gchar *tmpfile = NULL;
227 if (!vcalviewer->tmpfile) {
228 tmpfile = procmime_get_tmp_file_name(vcalviewer->mimeinfo);
229 debug_print("creating %s\n", tmpfile);
231 if (procmime_get_part(tmpfile, vcalviewer->mimeinfo) < 0) {
232 g_warning("Can't get mimepart file");
236 vcalviewer->tmpfile = tmpfile;
239 return vcalviewer->tmpfile;
242 static GtkWidget *vcal_viewer_get_widget(MimeViewer *_mimeviewer)
244 VCalViewer *vcalviewer = (VCalViewer *) _mimeviewer;
246 debug_print("vcal_viewer_get_widget\n");
247 gtk_widget_show_all(vcalviewer->scrolledwin);
248 return vcalviewer->scrolledwin;
251 static void vcal_viewer_clear_viewer(MimeViewer *_mimeviewer)
253 VCalViewer *vcalviewer = (VCalViewer *) _mimeviewer;
255 debug_print("vcal_viewer_clear_viewer\n");
257 g_free(vcalviewer->file);
258 vcalviewer->file = NULL;
259 if (vcalviewer->tmpfile) {
260 debug_print("unlinking %s\n", vcalviewer->tmpfile);
261 g_unlink(vcalviewer->tmpfile);
262 g_free(vcalviewer->tmpfile);
263 vcalviewer->tmpfile = NULL;
265 vcalviewer->mimeinfo = NULL;
268 static VCalEvent *vcalviewer_get_component(const gchar *file, const gchar *charset)
270 gchar *compstr = NULL;
271 VCalEvent *event = NULL;
277 g_return_val_if_fail(file != NULL, NULL);
279 if ((fp = g_fopen(file, "rb")) == NULL) {
280 FILE_OP_ERROR(file, "g_fopen");
284 array = g_byte_array_new();
286 while ((n_read = fread(buf, sizeof(gchar), sizeof(buf), fp)) > 0) {
287 if (n_read < sizeof(buf) && ferror(fp))
289 g_byte_array_append(array, (guchar *)buf, n_read);
293 FILE_OP_ERROR("file stream", "fread");
294 g_byte_array_free(array, TRUE);
300 g_byte_array_append(array, (guchar *)buf, 1);
301 compstr = (gchar *)array->data;
302 g_byte_array_free(array, FALSE);
307 event = vcal_get_event_from_ical(compstr, charset);
314 #define GTK_LABEL_SET_TEXT_TRIMMED(label, text) { \
315 gchar *tmplbl = strretchomp(g_strdup(text)); \
316 gtk_label_set_text(label, tmplbl); \
320 static void vcalviewer_answer_set_choices(VCalViewer *vcalviewer, VCalEvent *event, icalproperty_method method);
322 static void vcalviewer_reset(VCalViewer *vcalviewer)
324 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), "-");
325 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who), "-");
326 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->location), "-");
327 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->summary), "-");
328 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->description), "-");
329 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start), "-");
330 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->end), "-");
331 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->attendees), "-");
332 g_free(vcalviewer->url);
333 vcalviewer->url = NULL;
334 gtk_widget_hide(vcalviewer->uribtn);
335 vcalviewer_answer_set_choices(vcalviewer, NULL, ICAL_METHOD_CANCEL);
338 static void vcalviewer_show_error(VCalViewer *vcalviewer, const gchar *msg)
340 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), msg);
343 static void vcalviewer_hide_error(VCalViewer *vcalviewer)
345 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), "-");
348 static void vcalviewer_show_unavailable(VCalViewer *vcalviewer, gboolean visi)
351 gtk_widget_show_all(vcalviewer->unavail_box);
353 gtk_widget_hide(vcalviewer->unavail_box);
356 static void vcalviewer_answer_set_choices(VCalViewer *vcalviewer, VCalEvent *event, icalproperty_method method)
360 gtk_widget_hide(vcalviewer->reedit);
361 gtk_widget_hide(vcalviewer->cancel);
362 gtk_widget_hide(vcalviewer->answer);
363 gtk_widget_hide(vcalviewer->button);
365 for (i = 0; i < 3; i++)
366 gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(vcalviewer->answer), 0);
368 vcalviewer_show_unavailable(vcalviewer, FALSE);
370 if (method == ICAL_METHOD_REQUEST && event && !event->rec_occurrence) {
371 PrefsAccount *account = vcal_manager_get_account_from_event(event);
374 account = vcal_manager_get_account_from_event(vcalviewer->event);
376 if (!account && event) {
377 account = account_get_default();
378 vcal_manager_update_answer(event, account->address,
380 ICAL_PARTSTAT_NEEDSACTION,
381 ICAL_CUTYPE_INDIVIDUAL);
384 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(vcalviewer->answer), _("Accept"));
385 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(vcalviewer->answer), _("Tentatively accept"));
386 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(vcalviewer->answer), _("Decline"));
387 gtk_widget_set_sensitive(vcalviewer->answer, TRUE);
388 gtk_widget_set_sensitive(vcalviewer->button, TRUE);
389 gtk_widget_show(vcalviewer->answer);
390 gtk_widget_show(vcalviewer->button);
392 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(vcalviewer->answer), "-");
393 gtk_widget_set_sensitive(vcalviewer->answer, FALSE);
394 gtk_widget_set_sensitive(vcalviewer->button, FALSE);
397 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(vcalviewer->answer), "-");
398 gtk_widget_set_sensitive(vcalviewer->answer, FALSE);
399 gtk_widget_set_sensitive(vcalviewer->button, FALSE);
401 gtk_combo_box_set_active(GTK_COMBO_BOX(vcalviewer->answer), 0);
403 if (event && event->method == ICAL_METHOD_REQUEST) {
404 PrefsAccount *account = vcal_manager_get_account_from_event(event);
405 gchar *internal_ifb = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
406 "vcalendar", G_DIR_SEPARATOR_S,
407 "internal.ifb", NULL);
408 gchar *myfb = file_read_to_str(internal_ifb);
409 g_free(internal_ifb);
411 icalparameter_partstat answer =
412 vcal_manager_get_reply_for_attendee(event, account->address);
414 if (answer == ICAL_PARTSTAT_ACCEPTED)
415 gtk_combo_box_set_active(GTK_COMBO_BOX(vcalviewer->answer), 0);
416 if (answer == ICAL_PARTSTAT_TENTATIVE)
417 gtk_combo_box_set_active(GTK_COMBO_BOX(vcalviewer->answer), 1);
418 if (answer == ICAL_PARTSTAT_DECLINED)
419 gtk_combo_box_set_active(GTK_COMBO_BOX(vcalviewer->answer), 2);
420 if (event->dtstart && event->dtend && myfb && *myfb
421 && answer != ICAL_PARTSTAT_ACCEPTED
422 && answer != ICAL_PARTSTAT_TENTATIVE) {
423 if (!attendee_available(NULL, event->dtstart, event->dtend, myfb))
424 vcalviewer_show_unavailable(vcalviewer, TRUE);
430 g_free(vcalviewer->url);
431 if (event && event->url && *(event->url)) {
432 vcalviewer->url = g_strdup(event->url);
433 gtk_widget_show(vcalviewer->uribtn);
435 vcalviewer->url = NULL;
436 gtk_widget_hide(vcalviewer->uribtn);
440 static FolderItem *vcalendar_get_current_item(void)
442 MainWindow *mainwin = mainwindow_get_mainwindow();
443 FolderItem *item = NULL;
444 Folder *folder = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
447 item = mainwin->summaryview->folder_item;
448 if (item->folder == folder)
451 return folder->inbox;
457 void vcalviewer_display_event (VCalViewer *vcalviewer, VCalEvent *event)
460 gchar *attendees = NULL;
461 gboolean mine = FALSE;
463 gboolean save_evt = FALSE;
464 FolderItem *item = vcalendar_get_current_item();
471 if (event->type == ICAL_VTODO_COMPONENT) {
473 label = g_strjoin(" ", _("You have a Todo item."),
474 _("Details follow:"), NULL);
475 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
477 } else if (event->method == ICAL_METHOD_REQUEST) {
479 if (account_find_from_address(event->organizer, FALSE)) {
480 label = g_strjoin(" ", _("You have created a meeting."),
481 _("Details follow:"), NULL);
482 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
485 label = g_strjoin(" ", _("You have been invited to a meeting."),
486 _("Details follow:"), NULL);
487 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
490 } else if (event->method == ICAL_METHOD_CANCEL) {
492 label = g_strjoin(" ",
493 _("A meeting to which you had been invited has been cancelled."),
494 _("Details follow:"), NULL);
495 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
497 vcalendar_refresh_folder_contents(item);
498 } else if (event->method == ICAL_METHOD_REPLY) {
499 /* don't change label */
502 label = g_strjoin(" ", _("You have been forwarded an appointment."),
503 _("Details follow:"), NULL);
504 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
510 if (event->orgname && *(event->orgname)
511 && event->organizer && *(event->organizer)) {
512 gchar *addr = g_strconcat(event->orgname, " <", event->organizer, ">", NULL);
513 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who), addr);
515 } else if (event->organizer && *(event->organizer)) {
516 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who), event->organizer);
518 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who), "-");
522 if (event->location && *(event->location)) {
523 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->location), event->location);
525 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->location), "-");
529 if (event->summary && *(event->summary)) {
530 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->summary), event->summary);
532 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->summary), "-");
536 if (event->description && *(event->description)) {
537 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->description), event->description);
539 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->description), "-");
543 g_free(vcalviewer->url);
544 if (event->url && *(event->url)) {
545 vcalviewer->url = g_strdup(event->url);
546 gtk_widget_show(vcalviewer->uribtn);
548 vcalviewer->url = NULL;
549 gtk_widget_hide(vcalviewer->uribtn);
553 if (event->start && *(event->start)) {
554 if (event->recur && *(event->recur)) {
555 gchar *tmp = g_strdup_printf(g_strconcat("%s <span weight=\"bold\">",
556 _("(this event recurs)"),"</span>", NULL),
558 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start), tmp);
559 gtk_label_set_use_markup(GTK_LABEL(vcalviewer->start), TRUE);
561 } else if (event->rec_occurrence) {
562 gchar *tmp = g_strdup_printf(g_strconcat("%s <span weight=\"bold\">",
563 _("(this event is part of a recurring event)"),
566 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start), tmp);
567 gtk_label_set_use_markup(GTK_LABEL(vcalviewer->start), TRUE);
570 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start), event->start);
573 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start), "-");
577 if (event->end && *(event->end)) {
578 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->end), event->end);
580 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->end), "-");
584 attendees = g_strdup("");
585 for (list = vcal_manager_get_answers_emails(event);
586 list && list->data; list = list->next) {
587 gchar *attendee = (gchar *)list->data;
588 gchar *name = vcal_manager_get_attendee_name(event, attendee);
589 gchar *ename = g_markup_printf_escaped("%s", name?name:"");
590 gchar *eatt = g_markup_printf_escaped("%s", attendee);
591 icalparameter_partstat acode = vcal_manager_get_reply_for_attendee(event, attendee);
592 gchar *answer = vcal_manager_get_reply_text_for_attendee(event, attendee);
593 gchar *type = vcal_manager_get_cutype_text_for_attendee(event, attendee);
596 tmp = g_strdup_printf(
597 "%s%s<%s> (%s, <span%s>%s</span>)",
598 (ename && *(ename))?ename:"",
599 (ename && *(ename))?" ":"",
600 (eatt && *(eatt))?eatt:"",
601 (type && *(type))?type:"",
602 (acode != ICAL_PARTSTAT_ACCEPTED ? " foreground=\"red\"":""),
603 (answer && *(answer))?answer:"");
604 e_len = strlen(attendees);
607 attendees = g_realloc(attendees, e_len+n_len+2);
608 *(attendees+e_len) = '\n';
609 strcpy(attendees+e_len+1, tmp);
611 attendees = g_realloc(attendees, e_len+n_len+1);
612 strcpy(attendees, tmp);
622 if (attendees && *(attendees)) {
623 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->attendees), attendees);
625 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->attendees), "-");
628 gtk_label_set_use_markup(GTK_LABEL(vcalviewer->attendees), TRUE);
632 if (event->type != ICAL_VTODO_COMPONENT)
633 vcalviewer_answer_set_choices(vcalviewer, event, event->method);
635 vcalviewer_answer_set_choices(vcalviewer, event, ICAL_METHOD_PUBLISH);
637 vcalviewer_answer_set_choices(vcalviewer, event, ICAL_METHOD_REPLY);
638 gtk_widget_show(vcalviewer->reedit);
639 gtk_widget_show(vcalviewer->cancel);
642 /* save if cancelled */
644 vcal_manager_save_event(event, TRUE);
647 gchar *vcalviewer_get_uid_from_mimeinfo(MimeInfo *mimeinfo)
649 gchar *tmpfile = procmime_get_tmp_file_name(mimeinfo);
650 const gchar *charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
651 gchar *compstr = NULL;
653 VCalEvent *event = NULL;
656 charset = CS_WINDOWS_1252;
658 if (!strcasecmp(charset, CS_ISO_8859_1))
659 charset = CS_WINDOWS_1252;
661 if (procmime_get_part(tmpfile, mimeinfo) < 0) {
662 g_warning("Can't get mimepart file");
667 compstr = file_read_to_str(tmpfile);
669 event = vcal_get_event_from_ical(compstr, charset);
671 res = g_strdup(event->uid);
673 vcal_manager_free_event(event);
675 debug_print("got uid: %s\n", res);
680 static void vcalviewer_get_request_values(VCalViewer *vcalviewer, MimeInfo *mimeinfo, gboolean is_todo)
682 VCalEvent *saved_event = NULL;
683 const gchar *charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
684 const gchar *saveme = procmime_mimeinfo_get_parameter(mimeinfo, "vcalsave");
686 if (!vcalviewer->event)
690 charset = CS_WINDOWS_1252;
692 if (!strcasecmp(charset, CS_ISO_8859_1))
693 charset = CS_WINDOWS_1252;
695 /* see if we have it registered and more recent */
696 saved_event = vcal_manager_load_event(vcalviewer->event->uid);
697 if (saved_event && saved_event->sequence >= vcalviewer->event->sequence) {
698 charset = CS_INTERNAL;
699 saved_event->method = vcalviewer->event->method;
700 vcalviewer_display_event(vcalviewer, saved_event);
701 vcal_manager_free_event(saved_event);
703 } else if (saved_event) {
704 vcal_manager_free_event(saved_event);
707 /* load it and register it */
709 if (!saveme || strcmp(saveme,"no"))
710 vcal_manager_save_event(vcalviewer->event, FALSE);
712 vcalviewer_display_event(vcalviewer, vcalviewer->event);
715 static void vcalviewer_get_reply_values(VCalViewer *vcalviewer, MimeInfo *mimeinfo)
717 const gchar *charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
718 VCalEvent *saved_event = NULL;
719 gchar *attendee = NULL, *label = NULL;
720 Answer *answer = NULL;
722 if (!vcalviewer->event)
726 charset = CS_WINDOWS_1252;
728 if (!strcasecmp(charset, CS_ISO_8859_1))
729 charset = CS_WINDOWS_1252;
731 if (!vcalviewer->event->answers || g_slist_length(vcalviewer->event->answers) > 1) {
732 g_warning("strange, no answers or more than one");
735 if (vcalviewer->event->answers) {
736 answer = (Answer *)vcalviewer->event->answers->data;
737 attendee = g_strdup(answer->attendee);
742 label = g_strjoin(" ",
743 _("You have received an answer to an unknown meeting proposal."),
744 _("Details follow:"), NULL);
745 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
747 label = g_strdup_printf(_("You have received an answer to a meeting proposal.\n"
748 "%s has %s the invitation whose details follow:"),
749 attendee, vcal_manager_answer_get_text(answer->answer));
750 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->type), label);
755 saved_event = vcal_manager_load_event(vcalviewer->event->uid);
756 if (saved_event && answer) {
757 vcal_manager_update_answer(saved_event,
758 answer->attendee, answer->name, answer->answer, answer->cutype);
759 vcal_manager_save_event(saved_event, TRUE);
760 saved_event->method = vcalviewer->event->method;
761 vcalviewer_display_event(vcalviewer, saved_event);
762 vcal_manager_free_event(saved_event);
766 if (vcalviewer->event->organizer) {
767 if (vcalviewer->event->orgname) {
768 gchar *addr = g_strconcat(vcalviewer->event->orgname, " <",
769 vcalviewer->event->organizer, ">", NULL);
770 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who), addr);
773 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who),
774 vcalviewer->event->organizer);
777 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->who), "-");
780 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->location),
781 vcalviewer->event->location?vcalviewer->event->location:"-");
783 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->summary),
784 vcalviewer->event->summary?vcalviewer->event->summary:"-");
786 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->description),
787 vcalviewer->event->description?vcalviewer->event->description:"-");
789 g_free(vcalviewer->url);
790 if (vcalviewer->event->url) {
791 vcalviewer->url = g_strdup(vcalviewer->event->url);
792 gtk_widget_show(vcalviewer->uribtn);
794 vcalviewer->url = NULL;
795 gtk_widget_hide(vcalviewer->uribtn);
798 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->start),
799 vcalviewer->event->start?vcalviewer->event->start:"-");
800 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->end),
801 vcalviewer->event->end?vcalviewer->event->end:"-");
803 GTK_LABEL_SET_TEXT_TRIMMED(GTK_LABEL(vcalviewer->attendees), "-");
805 vcalviewer_answer_set_choices(vcalviewer, NULL, ICAL_METHOD_REPLY);
808 static void vcalviewer_get_event(VCalViewer *vcalviewer, MimeInfo *mimeinfo)
810 gchar *tmpfile = get_tmpfile(vcalviewer);
811 const gchar *charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
814 charset = CS_WINDOWS_1252;
816 if (!strcasecmp(charset, CS_ISO_8859_1))
817 charset = CS_WINDOWS_1252;
819 if (vcalviewer->event) {
820 vcal_manager_free_event(vcalviewer->event);
821 vcalviewer->event = NULL;
825 vcalviewer_reset(vcalviewer);
826 vcalviewer_show_error(vcalviewer, _("Error - could not get the calendar MIME part."));
830 vcalviewer->event = vcalviewer_get_component(tmpfile, charset);
831 if (!vcalviewer->event) {
832 vcalviewer_reset(vcalviewer);
833 vcalviewer_show_error(vcalviewer, _("Error - no calendar part found."));
837 if (vcalviewer->event->type == ICAL_VTODO_COMPONENT) {
838 vcalviewer_get_request_values(vcalviewer, mimeinfo, TRUE);
839 } else if (vcalviewer->event->method == ICAL_METHOD_REQUEST ||
840 vcalviewer->event->method == ICAL_METHOD_PUBLISH ||
841 vcalviewer->event->method == ICAL_METHOD_CANCEL) {
842 vcalviewer_get_request_values(vcalviewer, mimeinfo, FALSE);
843 } else if (vcalviewer->event->method == ICAL_METHOD_REPLY) {
844 vcalviewer_get_reply_values(vcalviewer, mimeinfo);
846 vcalviewer_reset(vcalviewer);
847 vcalviewer_show_error(vcalviewer, _("Error - Unknown calendar component type."));
851 static VCalViewer *s_vcalviewer = NULL;
853 static void vcal_viewer_show_mimepart(MimeViewer *_mimeviewer, const gchar *file, MimeInfo *mimeinfo)
855 VCalViewer *vcalviewer = (VCalViewer *) _mimeviewer;
856 GtkAllocation allocation;
860 s_vcalviewer = vcalviewer;
862 if (mimeinfo == NULL) {
863 vcal_viewer_clear_viewer(_mimeviewer);
867 debug_print("vcal_viewer_show_mimepart : %s\n", file);
869 vcal_viewer_clear_viewer(_mimeviewer);
870 gtk_widget_show_all(vcalviewer->scrolledwin);
871 g_free(vcalviewer->file);
872 vcalviewer->file = g_strdup(file);
873 vcalviewer->mimeinfo = mimeinfo;
874 vcalviewer_hide_error(vcalviewer);
875 vcalviewer_get_event(vcalviewer, mimeinfo);
877 gtk_widget_get_allocation(vcalviewer->scrolledwin, &allocation);
878 gtk_widget_set_size_request(vcalviewer->description,
879 allocation.width - 200, -1);
880 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->location), TRUE);
881 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->summary), TRUE);
882 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->description), TRUE);
883 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->attendees), FALSE);
885 if (prefs_common_get_prefs()->textfont) {
886 PangoFontDescription *font_desc;
888 font_desc = pango_font_description_from_string
889 (prefs_common_get_prefs()->textfont);
891 gtk_widget_modify_font(
892 vcalviewer->description, font_desc);
893 pango_font_description_free(font_desc);
899 void vcalviewer_reload(FolderItem *item)
902 MainWindow *mainwin = mainwindow_get_mainwindow();
903 Folder *folder = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
905 folder_item_scan(item);
906 if (mainwin && mainwin->summaryview->folder_item) {
907 FolderItem *cur = mainwin->summaryview->folder_item;
908 if (cur->folder == folder)
909 folder_item_scan(cur);
911 if (mainwin && mainwin->summaryview->folder_item == item) {
912 debug_print("reload: %p, %p\n", (MimeViewer *)s_vcalviewer, s_vcalviewer->mimeinfo);
913 summary_redisplay_msg(mainwin->summaryview);
918 static void vcal_viewer_destroy_viewer(MimeViewer *_mimeviewer)
920 VCalViewer *vcalviewer = (VCalViewer *) _mimeviewer;
922 debug_print("vcal_viewer_destroy_viewer\n");
924 if (s_vcalviewer == vcalviewer)
926 vcal_viewer_clear_viewer(_mimeviewer);
930 static gboolean vcalviewer_reedit_cb(GtkButton *widget, gpointer data)
932 VCalViewer *vcalviewer = (VCalViewer *)data;
933 gchar * uid = vcalviewer_get_uid_from_mimeinfo(vcalviewer->mimeinfo);
934 VCalEvent *event = NULL;
936 s_vcalviewer = vcalviewer;
937 /* see if we have it registered and more recent */
938 event = vcal_manager_load_event(uid);
939 vcal_meeting_create(event);
940 vcal_manager_free_event(event);
944 static gboolean vcalviewer_uribtn_cb(GtkButton *widget, gpointer data)
946 VCalViewer *vcalviewer = (VCalViewer *)data;
949 open_uri(vcalviewer->url, prefs_common_get_uri_cmd());
954 void vcalendar_refresh_folder_contents(FolderItem *item)
956 Folder *folder = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
957 if (folder && item->folder == folder) {
958 MainWindow *mainwin = mainwindow_get_mainwindow();
959 folder_item_scan(item);
960 if (mainwin->summaryview->folder_item == item) {
961 summary_show(mainwin->summaryview, item);
966 static void send_cancel_notify_toggled_cb(GtkToggleButton *button, gboolean *data)
968 *data = gtk_toggle_button_get_active(button);
971 void vcalendar_cancel_meeting(FolderItem *item, const gchar *uid)
973 VCalEvent *event = NULL;
974 VCalMeeting *meet = NULL;
977 Folder *folder = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
978 gboolean redisp = FALSE;
979 GtkWidget *send_notify_chkbtn = gtk_check_button_new_with_label(_("Send a notification to the attendees"));
980 gboolean send_notify = TRUE;
982 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(send_notify_chkbtn), TRUE);
983 gtk_widget_show(send_notify_chkbtn);
984 g_signal_connect(G_OBJECT(send_notify_chkbtn), "toggled",
985 G_CALLBACK(send_cancel_notify_toggled_cb),
988 val = alertpanel_full(_("Cancel meeting"),
989 _("Are you sure you want to cancel this meeting?"),
990 GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_FIRST, FALSE,
991 send_notify_chkbtn, ALERT_WARNING);
993 if (val != G_ALERTALTERNATE)
996 event = vcal_manager_load_event(uid);
999 event->method = ICAL_METHOD_CANCEL;
1002 MainWindow *mainwin = mainwindow_get_mainwindow();
1003 if (mainwin->summaryview->folder_item == item) {
1005 summary_show(mainwin->summaryview, NULL);
1010 meet = vcal_meeting_create_hidden(event);
1011 if (!vcal_meeting_send(meet)) {
1012 event->method = ICAL_METHOD_REQUEST;
1013 vcal_manager_save_event(event, TRUE);
1014 vcal_manager_free_event(event);
1016 folder_item_scan(item);
1018 if (folder && redisp) {
1019 MainWindow *mainwin = mainwindow_get_mainwindow();
1020 summary_show(mainwin->summaryview, item);
1026 vcal_manager_save_event(event, TRUE);
1028 file = vcal_manager_get_event_file(event->uid);
1030 vcal_manager_free_event(event);
1033 folder_item_scan(item);
1034 if (folder && redisp) {
1035 MainWindow *mainwin = mainwindow_get_mainwindow();
1036 summary_show(mainwin->summaryview, item);
1042 static gboolean vcalviewer_cancel_cb(GtkButton *widget, gpointer data)
1044 VCalViewer *vcalviewer = (VCalViewer *)data;
1045 FolderItem *item = vcalendar_get_current_item();
1046 gchar * uid = vcalviewer_get_uid_from_mimeinfo(vcalviewer->mimeinfo);
1047 vcalendar_cancel_meeting(item, uid);
1051 static gboolean vcalviewer_action_cb(GtkButton *widget, gpointer data)
1053 VCalViewer *vcalviewer = (VCalViewer *)data;
1054 gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(vcalviewer->answer));
1055 icalparameter_partstat reply[3] = {ICAL_PARTSTAT_ACCEPTED, ICAL_PARTSTAT_TENTATIVE, ICAL_PARTSTAT_DECLINED};
1056 PrefsAccount *account = NULL;
1057 VCalEvent *saved_event = NULL, *event = NULL;
1058 debug_print("index chosen %d\n", index);
1060 if (index < 0 || index > 2) {
1064 s_vcalviewer = vcalviewer;
1066 if (!vcalviewer->event) {
1067 g_warning("can't get event");
1071 /* see if we have it registered and more recent */
1072 event = vcalviewer->event;
1073 saved_event = vcal_manager_load_event(vcalviewer->event->uid);
1074 if (saved_event && saved_event->sequence >= vcalviewer->event->sequence) {
1075 saved_event->method = vcalviewer->event->method;
1076 event = saved_event;
1077 } else if (saved_event) {
1078 vcal_manager_free_event(saved_event);
1081 account = vcal_manager_get_account_from_event(event);
1084 AlertValue val = alertpanel_full(_("No account found"),
1085 _("You have no account matching any attendee.\n"
1086 "Do you want to reply anyway?"),
1087 GTK_STOCK_CANCEL, _("Reply anyway"), NULL,
1088 ALERTFOCUS_SECOND, FALSE, NULL, ALERT_QUESTION);
1089 if (val == G_ALERTALTERNATE) {
1090 account = account_get_default();
1091 vcal_manager_update_answer(event, account->address,
1093 ICAL_PARTSTAT_NEEDSACTION,
1094 ICAL_CUTYPE_INDIVIDUAL);
1097 vcal_manager_free_event(saved_event);
1102 vcal_manager_update_answer(event, account->address, account->name, reply[index], 0);
1104 if (event->organizer && *(event->organizer) &&
1105 !vcal_manager_reply(account, event)) {
1106 g_warning("couldn't send reply");
1108 debug_print("no organizer, not sending answer\n");
1111 vcal_manager_save_event(event, TRUE);
1113 vcalviewer_display_event(vcalviewer, event);
1115 vcal_manager_free_event(saved_event);
1119 #define TABLE_ADD_LINE(label_text, widget) { \
1120 gchar *tmpstr = g_strdup_printf("<span weight=\"bold\">%s</span>",\
1122 GtkWidget *label = gtk_label_new(tmpstr); \
1124 gtk_label_set_use_markup (GTK_LABEL (label), TRUE); \
1125 gtk_misc_set_alignment (GTK_MISC(label), 1, 0); \
1126 gtk_table_attach (GTK_TABLE (vcalviewer->table), \
1127 label, 0, 1, i, i+1, \
1128 GTK_FILL, GTK_FILL, 6, 6); \
1129 gtk_table_attach (GTK_TABLE (vcalviewer->table), \
1130 widget, 1, 2, i, i+1, \
1131 GTK_FILL, GTK_FILL, 6, 6); \
1132 if (GTK_IS_LABEL(widget)) { \
1133 gtk_label_set_use_markup(GTK_LABEL (widget), TRUE); \
1134 gtk_misc_set_alignment (GTK_MISC(widget),0, 0); \
1135 gtk_label_set_line_wrap(GTK_LABEL(widget), TRUE); \
1140 static gchar *vcal_viewer_get_selection(MimeViewer *_viewer)
1142 VCalViewer *viewer = (VCalViewer *)_viewer;
1143 if (viewer->summary == NULL)
1145 if (gtk_label_get_text(GTK_LABEL(viewer->description))
1146 && *(gtk_label_get_text(GTK_LABEL(viewer->description))) > 2) {
1148 if (gtk_label_get_selection_bounds(GTK_LABEL(viewer->description),
1150 gchar *tmp = g_strdup(gtk_label_get_text(
1151 GTK_LABEL(viewer->description))+start);
1152 tmp[end-start] = '\0';
1155 return g_strdup(gtk_label_get_text(GTK_LABEL(viewer->description)));
1158 else if (gtk_label_get_text(GTK_LABEL(viewer->summary))
1159 && *(gtk_label_get_text(GTK_LABEL(viewer->summary))) > 2)
1160 return g_strdup(gtk_label_get_text(GTK_LABEL(viewer->summary)));
1166 static gboolean vcal_viewer_scroll_page(MimeViewer *_viewer, gboolean up)
1168 VCalViewer *viewer = (VCalViewer *)_viewer;
1169 GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment(
1170 GTK_SCROLLED_WINDOW(viewer->scrolledwin));
1172 return gtkutils_scroll_page(viewer->table, vadj, up);
1175 static void vcal_viewer_scroll_one_line(MimeViewer *_viewer, gboolean up)
1177 VCalViewer *viewer = (VCalViewer *)_viewer;
1178 GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment(
1179 GTK_SCROLLED_WINDOW(viewer->scrolledwin));
1181 gtkutils_scroll_one_line(viewer->table, vadj, up);
1184 MimeViewer *vcal_viewer_create(void)
1186 VCalViewer *vcalviewer;
1188 GtkWidget *hbox = NULL, *vbox = NULL;
1189 GtkWidget *warning_img;
1190 GtkWidget *warning_label;
1192 debug_print("Creating vcal view...\n");
1193 vcalviewer = g_new0(VCalViewer, 1);
1194 vcalviewer->mimeviewer.factory = &vcal_viewer_factory;
1196 vcalviewer->mimeviewer.get_widget = vcal_viewer_get_widget;
1197 vcalviewer->mimeviewer.show_mimepart = vcal_viewer_show_mimepart;
1198 vcalviewer->mimeviewer.clear_viewer = vcal_viewer_clear_viewer;
1199 vcalviewer->mimeviewer.destroy_viewer = vcal_viewer_destroy_viewer;
1200 vcalviewer->mimeviewer.get_selection = vcal_viewer_get_selection;
1201 vcalviewer->mimeviewer.scroll_page = vcal_viewer_scroll_page;
1202 vcalviewer->mimeviewer.scroll_one_line = vcal_viewer_scroll_one_line;
1204 vcalviewer->table = gtk_table_new(8, 2, FALSE);
1205 vcalviewer->type = gtk_label_new("meeting");
1206 vcalviewer->who = gtk_label_new("who");
1207 vcalviewer->start = gtk_label_new("start");
1208 vcalviewer->end = gtk_label_new("end");
1209 vcalviewer->location = gtk_label_new("location");
1210 vcalviewer->summary = gtk_label_new("summary");
1211 vcalviewer->description = gtk_label_new("description");
1212 vcalviewer->attendees = gtk_label_new("attendees");
1214 vcalviewer->answer = gtk_combo_box_text_new();
1215 vcalviewer->url = NULL;
1216 vcalviewer->button = gtk_button_new_with_label(_("Answer"));
1217 vcalviewer->reedit = gtk_button_new_with_label(_("Edit meeting..."));
1218 vcalviewer->cancel = gtk_button_new_with_label(_("Cancel meeting..."));
1219 vcalviewer->uribtn = gtk_button_new_with_label(_("Launch website"));
1220 vcalviewer->unavail_box = gtk_hbox_new(FALSE, 6);
1221 warning_img = gtk_image_new_from_stock
1222 (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_SMALL_TOOLBAR);
1223 warning_label = gtk_label_new(_("You are already busy at this time."));
1225 gtk_box_pack_start(GTK_BOX(vcalviewer->unavail_box), warning_img, FALSE, FALSE, 0);
1226 gtk_box_pack_start(GTK_BOX(vcalviewer->unavail_box), warning_label, FALSE, FALSE, 0);
1228 hbox = gtk_hbox_new(FALSE, 6);
1229 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->answer, FALSE, FALSE, 0);
1230 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->button, FALSE, FALSE, 0);
1231 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->reedit, FALSE, FALSE, 0);
1232 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->cancel, FALSE, FALSE, 0);
1233 gtk_box_pack_start(GTK_BOX(hbox), vcalviewer->uribtn, FALSE, FALSE, 0);
1235 vbox = gtk_vbox_new(FALSE, 6);
1236 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1237 gtk_box_pack_start(GTK_BOX(vbox), vcalviewer->unavail_box, FALSE, FALSE, 0);
1239 vcalviewer_answer_set_choices(vcalviewer, NULL, ICAL_METHOD_REQUEST);
1241 gtk_label_set_selectable(GTK_LABEL(vcalviewer->type), TRUE);
1242 gtk_label_set_selectable(GTK_LABEL(vcalviewer->who), TRUE);
1243 gtk_label_set_selectable(GTK_LABEL(vcalviewer->start), TRUE);
1244 gtk_label_set_selectable(GTK_LABEL(vcalviewer->end), TRUE);
1245 gtk_label_set_selectable(GTK_LABEL(vcalviewer->location), TRUE);
1246 gtk_label_set_selectable(GTK_LABEL(vcalviewer->summary), TRUE);
1247 gtk_label_set_selectable(GTK_LABEL(vcalviewer->description), TRUE);
1248 gtk_label_set_selectable(GTK_LABEL(vcalviewer->attendees), TRUE);
1250 g_signal_connect(G_OBJECT(vcalviewer->button), "clicked",
1251 G_CALLBACK(vcalviewer_action_cb), vcalviewer);
1253 g_signal_connect(G_OBJECT(vcalviewer->reedit), "clicked",
1254 G_CALLBACK(vcalviewer_reedit_cb), vcalviewer);
1256 g_signal_connect(G_OBJECT(vcalviewer->cancel), "clicked",
1257 G_CALLBACK(vcalviewer_cancel_cb), vcalviewer);
1259 g_signal_connect(G_OBJECT(vcalviewer->uribtn), "clicked",
1260 G_CALLBACK(vcalviewer_uribtn_cb), vcalviewer);
1262 TABLE_ADD_LINE(_("Event:"), vcalviewer->type);
1263 TABLE_ADD_LINE(_("Organizer:"), vcalviewer->who);
1264 TABLE_ADD_LINE(_("Location:"), vcalviewer->location);
1265 TABLE_ADD_LINE(_("Summary:"), vcalviewer->summary);
1266 TABLE_ADD_LINE(_("Starting:"), vcalviewer->start);
1267 TABLE_ADD_LINE(_("Ending:"), vcalviewer->end);
1268 TABLE_ADD_LINE(_("Description:"), vcalviewer->description);
1269 TABLE_ADD_LINE(_("Attendees:"), vcalviewer->attendees);
1270 gtk_label_set_line_wrap(GTK_LABEL(vcalviewer->attendees), FALSE);
1271 TABLE_ADD_LINE(_("Action:"), vbox);
1273 vcalviewer->scrolledwin = gtk_scrolled_window_new(NULL, NULL);
1274 gtk_scrolled_window_add_with_viewport(
1275 GTK_SCROLLED_WINDOW(vcalviewer->scrolledwin),
1277 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(vcalviewer->scrolledwin),
1279 GTK_POLICY_AUTOMATIC);
1281 gtk_widget_show_all(vcalviewer->scrolledwin);
1282 return (MimeViewer *) vcalviewer;
1285 static gchar *content_types[] =
1286 {"text/calendar", NULL};
1288 MimeViewerFactory vcal_viewer_factory =
1295 static gint alert_timeout_tag = 0;
1296 static gint scan_timeout_tag = 0;
1298 static gboolean vcal_webcal_check(gpointer data)
1300 Folder *root = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
1302 if (prefs_common_get_prefs()->work_offline)
1305 manual_update = FALSE;
1306 folderview_check_new(root);
1307 manual_update = TRUE;
1311 static guint context_menu_id = 0;
1312 static guint main_menu_id = 0;
1314 void vcalendar_init(void)
1316 MainWindow *mainwin = mainwindow_get_mainwindow();
1317 Folder *folder = NULL;
1318 gchar *directory = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
1321 if (!is_dir_exist(directory) && make_dir (directory) != 0) {
1330 mimeview_register_viewer_factory(&vcal_viewer_factory);
1331 folder_register_class(vcal_folder_get_class());
1333 folder = folder_find_from_name (PLUGIN_NAME, vcal_folder_get_class());
1335 START_TIMING("creating folder");
1336 folder = folder_new(vcal_folder_get_class(), PLUGIN_NAME, NULL);
1337 folder->klass->create_tree(folder);
1339 folder_scan_tree(folder, TRUE);
1343 if (!folder->inbox) {
1344 folder->klass->create_tree(folder);
1345 folder_scan_tree(folder, TRUE);
1347 if (folder->klass->scan_required(folder, folder->inbox)) {
1348 START_TIMING("scanning folder");
1349 folder_item_scan(folder->inbox);
1353 vcal_folder_gtk_init();
1355 alert_timeout_tag = g_timeout_add(60*1000,
1356 (GSourceFunc)vcal_meeting_alert_check,
1358 scan_timeout_tag = g_timeout_add(3600*1000,
1359 (GSourceFunc)vcal_webcal_check,
1361 if (prefs_common_get_prefs()->enable_color) {
1362 gtkut_convert_int_to_gdk_color(prefs_common_get_prefs()->color[COL_URI],
1366 gtk_action_group_add_actions(mainwin->action_group, vcalendar_main_menu,
1367 1, (gpointer)mainwin);
1368 MENUITEM_ADDUI_ID_MANAGER(mainwin->ui_manager, "/Menu/Message", "CreateMeeting",
1369 "Message/CreateMeeting", GTK_UI_MANAGER_MENUITEM,
1371 MENUITEM_ADDUI_ID_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "CreateMeeting",
1372 "Message/CreateMeeting", GTK_UI_MANAGER_MENUITEM,
1377 void vcalendar_done(void)
1379 MainWindow *mainwin = mainwindow_get_mainwindow();
1380 FolderView *folderview = NULL;
1381 FolderItem *fitem = NULL;
1383 icalmemory_free_ring();
1385 vcal_folder_free_data();
1387 if (mainwin == NULL)
1390 folderview = mainwin->folderview;
1391 fitem = folderview->summaryview->folder_item;
1394 fitem->folder->klass == vcal_folder_get_class()) {
1395 folderview_unselect(folderview);
1396 summary_clear_all(folderview->summaryview);
1397 if (fitem->folder->klass->item_closed)
1398 fitem->folder->klass->item_closed(fitem);
1401 mimeview_unregister_viewer_factory(&vcal_viewer_factory);
1402 folder_unregister_class(vcal_folder_get_class());
1403 vcal_folder_gtk_done();
1405 g_source_remove(alert_timeout_tag);
1406 alert_timeout_tag = 0;
1407 g_source_remove(scan_timeout_tag);
1408 scan_timeout_tag = 0;
1410 MENUITEM_REMUI_MANAGER(mainwin->ui_manager,mainwin->action_group, "Message/CreateMeeting", main_menu_id);
1412 MENUITEM_REMUI_MANAGER(mainwin->ui_manager,mainwin->action_group, "Message/CreateMeeting", context_menu_id);
1413 context_menu_id = 0;