From 9f5a04beb4ce18da2609e93adbb625a51c640e56 Mon Sep 17 00:00:00 2001 From: Chenthill Palanisamy Date: Mon, 6 Jun 2005 21:05:18 +0000 Subject: Added support for groupwise meeting delegation. svn path=/trunk/; revision=29463 --- calendar/ChangeLog | 42 ++++++++++++ calendar/gui/calendar-component.c | 4 +- calendar/gui/dialogs/comp-editor-page.h | 11 ++- calendar/gui/dialogs/comp-editor.c | 37 +++++++++- calendar/gui/dialogs/comp-editor.h | 9 +++ calendar/gui/dialogs/event-editor.c | 84 +++++++++++++---------- calendar/gui/dialogs/event-editor.h | 2 +- calendar/gui/dialogs/meeting-page.c | 73 ++++++++++++++++++-- calendar/gui/dialogs/meeting-page.glade | 33 ++++++++- calendar/gui/e-cal-popup.c | 8 +++ calendar/gui/e-cal-popup.h | 2 + calendar/gui/e-calendar-view.c | 116 +++++++++++++++++++++++++------- 12 files changed, 347 insertions(+), 74 deletions(-) diff --git a/calendar/ChangeLog b/calendar/ChangeLog index c4975be5e4..9c01e22cd9 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,45 @@ +2005-06-07 Chenthill Palanisamy + + * gui/calendar-component.c: (create_new_event): + call the event_editor_new with comp editor flags. + * gui/dialogs/comp-editor-page.h: + * gui/dialogs/comp-editor.c: (comp_editor_set_flags), + (comp_editor_get_flags), (comp_editor_append_page): + * gui/dialogs/comp-editor.h: Set the comp editor + flags, to indicate whether the item is a meeting, appointment, + a new event, or a delegated item etc. + * gui/dialogs/event-editor.c: (event_editor_construct), + (event_editor_edit_comp): Do not show the existing attendees + while delegating. + (event_editor_new): Replaced the meeting variable with + the comp editor flags + (show_meeting): Show the delegate page while delegating a + meeting. + * gui/dialogs/event-editor.h: Modified the event_editor_new + function. + * gui/dialogs/meeting-page.c: + (set_attendees): + (meeting_page_finalize),(clear_widgets), + (sensitize_widgets),(meeting_page_fill_widgets), + (meeting_page_fill_component), (get_widgets), + (add_clicked_cb), (meeting_page_construct): Set the label + for the meeting page to Delegatee. Changed the organizer label + to From since groupwise does have a concept of organizer. + Enabled Add, remove buttons for delegation. Added the delegte's + to the exiting attendee list while filling the component. Added + a boolean variable to the private structure to store the user's + address. Modified the label for meeting page as Attendees. If + the meeting is delegated, then to delegatees. + * gui/dialogs/meeting-page.glade: Added a reference to organizer + widget as org-label. + * gui/e-cal-popup.c: (e_cal_popup_target_new_select): + * gui/e-cal-popup.h: Added new masks for supporring delegation. + * gui/e-calendar-view.c: (set_attendee_status_for_delegate), + (on_delegate), (e_calendar_view_new_appointment_for), + (open_event_with_flags), (e_calendar_view_edit_appointment): + Call the event editor with comp editor flags. Set the users + partstat to delegated. + 2005-05-30 Thouis R. Jones Fixes #272301 diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c index c37e87e82a..03c0243581 100644 --- a/calendar/gui/calendar-component.c +++ b/calendar/gui/calendar-component.c @@ -1194,9 +1194,11 @@ create_new_event (CalendarComponent *calendar_component, CalendarComponentView * } else { ECalComponent *comp; EventEditor *editor; + CompEditorFlags flags; - editor = event_editor_new (ecal, is_meeting); + flags |= COMP_EDITOR_MEETING; comp = cal_comp_event_new_with_current_time (ecal, is_allday); + editor = event_editor_new (ecal, flags); e_cal_component_commit_sequence (comp); comp_editor_edit_comp (COMP_EDITOR (editor), comp); diff --git a/calendar/gui/dialogs/comp-editor-page.h b/calendar/gui/dialogs/comp-editor-page.h index 2b3c6c60ab..72a8f057a2 100644 --- a/calendar/gui/dialogs/comp-editor-page.h +++ b/calendar/gui/dialogs/comp-editor-page.h @@ -43,6 +43,13 @@ typedef struct { struct icaltimetype *complete; } CompEditorPageDates; +typedef enum { + COMP_EDITOR_PAGE_NEW_ITEM = 1<<0, + COMP_EDITOR_PAGE_MEETING = 1<<1, + COMP_EDITOR_PAGE_DELEGATE = 1<<2, + COMP_EDITOR_PAGE_USER_ORG = 1<<3, +} CompEditorPageFlags; + typedef struct { GtkObject object; @@ -55,6 +62,9 @@ typedef struct { normally, but we create our pages individually so have to do it ourselves. */ GtkAccelGroup *accel_group; + + CompEditorPageFlags flags; + } CompEditorPage; typedef struct { @@ -82,7 +92,6 @@ typedef struct { void (* set_dates) (CompEditorPage *page, CompEditorPageDates *dates); } CompEditorPageClass; - GtkType comp_editor_page_get_type (void); GtkWidget *comp_editor_page_get_widget (CompEditorPage *page); void comp_editor_page_focus_main_widget (CompEditorPage *page); diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c index cba7968268..495de600be 100644 --- a/calendar/gui/dialogs/comp-editor.c +++ b/calendar/gui/dialogs/comp-editor.c @@ -96,7 +96,10 @@ struct _CompEditorPrivate { GtkWidget *attachment_expander_num; guint32 attachment_bar_visible : 1; - + + /* TODO use this flags for setting all the boolean variables + below */ + CompEditorFlags flags; gboolean changed; gboolean needs_send; @@ -1281,6 +1284,35 @@ comp_editor_get_changed (CompEditor *editor) return priv->changed; } +void +comp_editor_set_flags (CompEditor *editor, CompEditorFlags flags) +{ + + CompEditorPrivate *priv; + + g_return_if_fail (editor != NULL); + g_return_if_fail (IS_COMP_EDITOR (editor)); + + priv = editor->priv; + + priv->flags = flags; +} + + +CompEditorFlags +comp_editor_get_flags (CompEditor *editor) +{ + + CompEditorPrivate *priv; + + g_return_val_if_fail (editor != NULL, FALSE); + g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE); + + priv = editor->priv; + + return priv->flags; +} + /** * comp_editor_set_needs_send: * @editor: A component editor @@ -1375,6 +1407,9 @@ comp_editor_append_page (CompEditor *editor, g_object_ref (page); + /* set the flags */ + page->flags = priv->flags; + /* If we are editing something, fill the widgets with current info */ if (priv->comp != NULL) { ECalComponent *comp; diff --git a/calendar/gui/dialogs/comp-editor.h b/calendar/gui/dialogs/comp-editor.h index 84381a476f..fe3a1e150b 100644 --- a/calendar/gui/dialogs/comp-editor.h +++ b/calendar/gui/dialogs/comp-editor.h @@ -56,6 +56,13 @@ typedef struct { gboolean (* send_comp) (CompEditor *page, ECalComponentItipMethod method); } CompEditorClass; +typedef enum { + COMP_EDITOR_NEW_ITEM = 1<<0, + COMP_EDITOR_MEETING = 1<<1, + COMP_EDITOR_DELEGATE = 1<<2, + COMP_EDITOR_USER_ORG = 1<<3, +} CompEditorFlags; + GtkType comp_editor_get_type (void); void comp_editor_set_changed (CompEditor *editor, gboolean changed); @@ -100,6 +107,8 @@ void comp_editor_focus (CompEditor *editor); void comp_editor_notify_client_changed (CompEditor *editor, ECal *client); void comp_editor_sensitize_attachment_bar (CompEditor *editor, gboolean set); +void comp_editor_set_flags (CompEditor *editor, CompEditorFlags flags); +CompEditorFlags comp_editor_get_flags (CompEditor *editor); G_END_DECLS diff --git a/calendar/gui/dialogs/event-editor.c b/calendar/gui/dialogs/event-editor.c index 20ded07a6c..223d4c4866 100644 --- a/calendar/gui/dialogs/event-editor.c +++ b/calendar/gui/dialogs/event-editor.c @@ -168,9 +168,16 @@ event_editor_construct (EventEditor *ee, ECal *client) priv->meet_page = meeting_page_new (priv->model, client); g_object_ref (priv->meet_page); gtk_object_sink (GTK_OBJECT (priv->meet_page)); - comp_editor_append_page (COMP_EDITOR (ee), + + if (comp_editor_get_flags (COMP_EDITOR (ee)) & COMP_EDITOR_DELEGATE) { + comp_editor_append_page (COMP_EDITOR (ee), COMP_EDITOR_PAGE (priv->meet_page), - _("Invitations")); + _("Delegatees")); + } else + comp_editor_append_page (COMP_EDITOR (ee), + COMP_EDITOR_PAGE (priv->meet_page), + _("Attendees")); + priv->meeting_shown=TRUE; } comp_editor_set_e_cal (COMP_EDITOR (ee), client); @@ -222,7 +229,7 @@ event_editor_edit_comp (CompEditor *editor, ECalComponent *comp) e_meeting_store_remove_all_attendees (priv->model); /* Set up the attendees */ - if (attendees == NULL) { + if (attendees == NULL && !(comp_editor_get_flags (COMP_EDITOR (editor)) & COMP_EDITOR_DELEGATE)) { if (priv->meet_page) comp_editor_remove_page (editor, COMP_EDITOR_PAGE (priv->meet_page)); if (priv->sched_page) @@ -231,6 +238,7 @@ event_editor_edit_comp (CompEditor *editor, ECalComponent *comp) } else { GSList *l; int row; + const char *user_email; if (!priv->meeting_shown) { comp_editor_append_page (COMP_EDITOR (ee), @@ -240,52 +248,53 @@ event_editor_edit_comp (CompEditor *editor, ECalComponent *comp) COMP_EDITOR_PAGE (priv->meet_page), _("Invitations")); } - - for (l = attendees; l != NULL; l = l->next) { - ECalComponentAttendee *ca = l->data; - EMeetingAttendee *ia; + + if (! (comp_editor_get_flags (COMP_EDITOR (editor)) & COMP_EDITOR_DELEGATE)) { + for (l = attendees; l != NULL; l = l->next) { + ECalComponentAttendee *ca = l->data; + EMeetingAttendee *ia; - ia = E_MEETING_ATTENDEE (e_meeting_attendee_new_from_e_cal_component_attendee (ca)); + ia = E_MEETING_ATTENDEE (e_meeting_attendee_new_from_e_cal_component_attendee (ca)); - /* If we aren't the organizer or the attendee is just delegating, don't allow editing */ - if (!comp_editor_get_user_org (editor) || e_meeting_attendee_is_set_delto (ia)) - e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_NONE); - e_meeting_store_add_attendee (priv->model, ia); + /* If we aren't the organizer or the attendee is just delegating, don't allow editing */ + if (!comp_editor_get_user_org (editor) || e_meeting_attendee_is_set_delto (ia)) + e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_NONE); + e_meeting_store_add_attendee (priv->model, ia); - g_object_unref(ia); - } + g_object_unref(ia); + } - /* If we aren't the organizer we can still change our own status */ - if (!comp_editor_get_user_org (editor)) { - EAccountList *accounts; - EAccount *account; - EIterator *it; + /* If we aren't the organizer we can still change our own status */ + if (!comp_editor_get_user_org (editor)) { + EAccountList *accounts; + EAccount *account; + EIterator *it; - accounts = itip_addresses_get (); - for (it = e_list_get_iterator((EList *)accounts);e_iterator_is_valid(it);e_iterator_next(it)) { - EMeetingAttendee *ia; + accounts = itip_addresses_get (); + for (it = e_list_get_iterator((EList *)accounts);e_iterator_is_valid(it);e_iterator_next(it)) { + EMeetingAttendee *ia; - account = (EAccount*)e_iterator_get(it); + account = (EAccount*)e_iterator_get(it); + + ia = e_meeting_store_find_attendee (priv->model, account->id->address, &row); + if (ia != NULL) + e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_STATUS); + } + g_object_unref(it); + } else if (e_cal_get_organizer_must_attend (client)) { + EMeetingAttendee *ia; - ia = e_meeting_store_find_attendee (priv->model, account->id->address, &row); + ia = e_meeting_store_find_attendee (priv->model, organizer.value, &row); if (ia != NULL) - e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_STATUS); + e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_NONE); } - g_object_unref(it); - } else if (e_cal_get_organizer_must_attend (client)) { - EMeetingAttendee *ia; - - ia = e_meeting_store_find_attendee (priv->model, organizer.value, &row); - if (ia != NULL) - e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_NONE); } - priv->meeting_shown = TRUE; } e_cal_component_free_attendee_list (attendees); comp_editor_set_needs_send (COMP_EDITOR (ee), priv->meeting_shown && itip_organizer_is_user (comp, client)); - + priv->updating = FALSE; } @@ -378,12 +387,13 @@ event_editor_finalize (GObject *object) * editor could not be created. **/ EventEditor * -event_editor_new (ECal *client, gboolean is_meeting) +event_editor_new (ECal *client, CompEditorFlags flags) { EventEditor *ee; ee = EVENT_EDITOR (g_object_new (TYPE_EVENT_EDITOR, NULL)); - ee->priv->is_meeting = is_meeting; + ee->priv->is_meeting = flags & COMP_EDITOR_MEETING; + comp_editor_set_flags (COMP_EDITOR (ee), flags); return event_editor_construct (ee, client); } @@ -408,6 +418,8 @@ show_meeting (EventEditor *ee) comp_editor_set_changed (COMP_EDITOR (ee), FALSE); comp_editor_set_needs_send (COMP_EDITOR (ee), priv->meeting_shown); } + if (comp_editor_get_flags (COMP_EDITOR (ee)) & COMP_EDITOR_DELEGATE) + comp_editor_show_page (COMP_EDITOR (ee), COMP_EDITOR_PAGE (priv->meet_page)); } diff --git a/calendar/gui/dialogs/event-editor.h b/calendar/gui/dialogs/event-editor.h index 0f934c28f2..311f17ce82 100644 --- a/calendar/gui/dialogs/event-editor.h +++ b/calendar/gui/dialogs/event-editor.h @@ -53,7 +53,7 @@ struct _EventEditorClass { GtkType event_editor_get_type (void); EventEditor *event_editor_construct (EventEditor *ee, ECal *client); -EventEditor *event_editor_new (ECal *client, gboolean is_meeting); +EventEditor *event_editor_new (ECal *client, CompEditorFlags flags); void event_editor_show_meeting (EventEditor *ee); diff --git a/calendar/gui/dialogs/meeting-page.c b/calendar/gui/dialogs/meeting-page.c index 5846e81652..ee51c4e4ad 100644 --- a/calendar/gui/dialogs/meeting-page.c +++ b/calendar/gui/dialogs/meeting-page.c @@ -62,6 +62,7 @@ struct _MeetingPagePrivate { EAccountList *accounts; EMeetingAttendee *ia; char *default_address; + char *user_add; /* Glade XML data */ GladeXML *xml; @@ -78,6 +79,7 @@ struct _MeetingPagePrivate { GtkWidget *remove; GtkWidget *invite; GtkWidget *att_label; + GtkWidget *org_label; /* ListView stuff */ EMeetingStore *model; @@ -196,6 +198,7 @@ set_attendees (ECalComponent *comp, const GPtrArray *attendees) } comp_attendees = g_slist_reverse (comp_attendees); + e_cal_component_set_attendee_list (comp, comp_attendees); for (l = comp_attendees; l != NULL; l = l->next) @@ -249,6 +252,10 @@ meeting_page_finalize (GObject *object) priv->default_address = NULL; } + if (priv->user_add) { + g_free (priv->user_add); + priv->user_add = NULL; + } g_free (priv); mpage->priv = NULL; @@ -292,7 +299,17 @@ clear_widgets (MeetingPage *mpage) priv = mpage->priv; + if (COMP_EDITOR_PAGE (mpage)->flags & COMP_EDITOR_PAGE_DELEGATE) { + gtk_label_set_markup_with_mnemonic (priv->att_label, _("Dele_gatees")); + } + + if (e_cal_get_static_capability (COMP_EDITOR_PAGE (mpage)->client, CAL_STATIC_CAPABILITY_NO_ORGANIZER)) { + gtk_label_set_label (GTK_LABEL (priv->org_label), _("From:")); + gtk_widget_hide (priv->existing_organizer_btn); + } + gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (priv->organizer)->entry), priv->default_address); + gtk_label_set_text (GTK_LABEL (priv->existing_organizer), _("None")); gtk_widget_show (priv->organizer_table); @@ -308,7 +325,12 @@ sensitize_widgets (MeetingPage *mpage) gboolean read_only = FALSE; MeetingPagePrivate *priv = mpage->priv; GError *error = NULL; + guint32 flags; + gboolean delegate; + flags = COMP_EDITOR_PAGE (mpage)->flags; + delegate = flags & COMP_EDITOR_PAGE_DELEGATE; + if (!e_cal_is_read_only (COMP_EDITOR_PAGE (mpage)->client, &read_only, &error)) { if (error->code != E_CALENDAR_STATUS_BUSY) read_only = TRUE; @@ -316,9 +338,9 @@ sensitize_widgets (MeetingPage *mpage) } gtk_widget_set_sensitive (priv->organizer, !read_only); gtk_widget_set_sensitive (priv->existing_organizer_btn, !read_only); - gtk_widget_set_sensitive (priv->add, !read_only && priv->user_org); - gtk_widget_set_sensitive (priv->remove, !read_only && priv->user_org); - gtk_widget_set_sensitive (priv->invite, !read_only && priv->user_org); + gtk_widget_set_sensitive (priv->add, !read_only && (priv->user_org || delegate)); + gtk_widget_set_sensitive (priv->remove, !read_only && (priv->user_org|| delegate)); + gtk_widget_set_sensitive (priv->invite, !read_only && (priv->user_org || delegate)); gtk_widget_set_sensitive (GTK_WIDGET (priv->list_view), !read_only); } @@ -335,6 +357,7 @@ meeting_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) priv->updating = TRUE; + /* Clean out old data */ if (priv->comp != NULL) g_object_unref (priv->comp); @@ -378,10 +401,13 @@ meeting_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) priv->user_org = FALSE; } - if (organizer.cn != NULL) + if (e_cal_get_static_capability (COMP_EDITOR_PAGE (mpage)->client, CAL_STATIC_CAPABILITY_NO_ORGANIZER)) + string = g_strdup (priv->user_add); + else if ( organizer.cn != NULL) string = g_strdup_printf ("%s <%s>", organizer.cn, strip); else string = g_strdup (strip); + gtk_label_set_text (GTK_LABEL (priv->existing_organizer), string); g_free (string); @@ -456,7 +482,28 @@ meeting_page_fill_component (CompEditorPage *page, ECalComponent *comp) _("At least one attendee is required.")); return FALSE; } - set_attendees (comp, e_meeting_store_get_attendees (priv->model)); + + + if (COMP_EDITOR_PAGE (mpage)->flags & COMP_EDITOR_PAGE_DELEGATE ) { + GSList *attendee_list, *l; + int i; + GPtrArray *attendees = e_meeting_store_get_attendees (priv->model); + + e_cal_component_get_attendee_list (priv->comp, &attendee_list); + + for (i = 0; i < attendees->len; i++) { + EMeetingAttendee *ia = g_ptr_array_index (attendees, i); + ECalComponentAttendee *ca; + + ca = e_meeting_attendee_as_e_cal_component_attendee (ia); + + attendee_list = g_slist_append (attendee_list, ca); + } + e_cal_component_set_attendee_list (comp, attendee_list); + e_cal_component_free_attendee_list (attendee_list); + } else + set_attendees (comp, e_meeting_store_get_attendees (priv->model)); + return TRUE; } @@ -512,6 +559,7 @@ get_widgets (MeetingPage *mpage) /* Attendees Label */ priv->att_label = GW ("attendees-label"); + priv->org_label = GW ("org-label"); #undef GW @@ -585,6 +633,11 @@ add_clicked_cb (GtkButton *btn, MeetingPage *mpage) EMeetingAttendee *attendee; attendee = e_meeting_store_add_attendee_with_defaults (mpage->priv->model); + + if (COMP_EDITOR_PAGE (mpage)->flags & COMP_EDITOR_PAGE_DELEGATE) { + e_meeting_attendee_set_delfrom (attendee, g_strdup (mpage->priv->user_add)); + } + e_meeting_list_view_edit (mpage->priv->list_view, attendee); } @@ -855,6 +908,7 @@ meeting_page_construct (MeetingPage *mpage, EMeetingStore *ems, EAccount *def_account; GList *address_strings = NULL, *l; GtkWidget *sw; + EAccount *a; priv = mpage->priv; @@ -879,7 +933,7 @@ meeting_page_construct (MeetingPage *mpage, EMeetingStore *ems, for (it = e_list_get_iterator((EList *)priv->accounts); e_iterator_is_valid(it); e_iterator_next(it)) { - EAccount *a = (EAccount *)e_iterator_get(it); + a = (EAccount *)e_iterator_get(it); char *full; full = g_strdup_printf("%s <%s>", a->id->name, a->id->address); @@ -898,8 +952,13 @@ meeting_page_construct (MeetingPage *mpage, EMeetingStore *ems, priv->default_address = g_strdup (full); } } + + if (backend_address) + priv->user_add = backend_address; + else + priv->user_add = g_strdup (a->id->address); + g_object_unref(it); - g_free (backend_address); if (address_strings) gtk_combo_set_popdown_strings (GTK_COMBO (priv->organizer), address_strings); diff --git a/calendar/gui/dialogs/meeting-page.glade b/calendar/gui/dialogs/meeting-page.glade index 51f7399b5f..254c0b0f1c 100644 --- a/calendar/gui/dialogs/meeting-page.glade +++ b/calendar/gui/dialogs/meeting-page.glade @@ -15,6 +15,7 @@ False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST + True @@ -49,6 +50,10 @@ 0 0 organizer-entry + PANGO_ELLIPSIZE_NONE + -1 + False + 0 0 @@ -78,7 +83,7 @@ 0 True - * + * False @@ -105,6 +110,10 @@ 0.5 0 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 @@ -133,7 +142,7 @@ 12 - + True Organizer: True @@ -146,6 +155,10 @@ 0 0 organizer-entry + PANGO_ELLIPSIZE_NONE + -1 + False + 0 0 @@ -167,6 +180,10 @@ 0.5 0 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 0 @@ -218,6 +235,10 @@ 0.5 0 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 0 @@ -318,6 +339,10 @@ 0.5 0 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 0 @@ -353,6 +378,10 @@ 0.5 0 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 0 diff --git a/calendar/gui/e-cal-popup.c b/calendar/gui/e-cal-popup.c index 00dd097b17..5dc4462833 100644 --- a/calendar/gui/e-cal-popup.c +++ b/calendar/gui/e-cal-popup.c @@ -159,6 +159,9 @@ e_cal_popup_target_new_select(ECalPopup *eabp, struct _ECalModel *model, GPtrArr if (e_cal_util_component_is_instance (comp_data->icalcomp)) mask &= ~E_CAL_POPUP_SELECT_INSTANCE; + if (e_cal_util_component_has_attendee (comp_data->icalcomp)) + mask &= ~E_CAL_POPUP_SELECT_MEETING; + if (e_cal_util_component_has_organizer (comp_data->icalcomp)) { ECalComponent *comp; @@ -180,6 +183,9 @@ e_cal_popup_target_new_select(ECalPopup *eabp, struct _ECalModel *model, GPtrArr if (!read_only) mask &= ~E_CAL_POPUP_SELECT_EDITABLE; + if (e_cal_get_static_capability (client, CAL_STATIC_CAPABILITY_DELEGATE_SUPPORTED)) + mask &= ~E_CAL_POPUP_SELECT_DELEGATABLE; + if (!e_cal_get_static_capability (client, CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT) && !e_cal_get_static_capability (client, CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK)) mask &= ~E_CAL_POPUP_SELECT_ASSIGNABLE; @@ -276,8 +282,10 @@ static const EPopupHookTargetMask ecalph_select_masks[] = { { "organizer", E_CAL_POPUP_SELECT_ORGANIZER }, { "not-editing", E_CAL_POPUP_SELECT_NOTEDITING }, { "not-meeting", E_CAL_POPUP_SELECT_NOTMEETING }, + { "meeting", E_CAL_POPUP_SELECT_MEETING }, { "assignable", E_CAL_POPUP_SELECT_ASSIGNABLE }, { "hasurl", E_CAL_POPUP_SELECT_HASURL }, + { "delegate", E_CAL_POPUP_SELECT_DELEGATABLE }, { 0 } }; diff --git a/calendar/gui/e-cal-popup.h b/calendar/gui/e-cal-popup.h index a5043b1726..0de18e70b4 100644 --- a/calendar/gui/e-cal-popup.h +++ b/calendar/gui/e-cal-popup.h @@ -80,6 +80,8 @@ enum _e_cal_popup_target_select_t { E_CAL_POPUP_SELECT_ASSIGNABLE = 1<<10, E_CAL_POPUP_SELECT_HASURL = 1<<11, + E_CAL_POPUP_SELECT_MEETING = 1 <<12, + E_CAL_POPUP_SELECT_DELEGATABLE = 1<<13, }; /** diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c index f879d3d63a..46acc4bf7d 100644 --- a/calendar/gui/e-calendar-view.c +++ b/calendar/gui/e-calendar-view.c @@ -82,6 +82,7 @@ struct _ECalendarViewPrivate { static void e_calendar_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void e_calendar_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void e_calendar_view_destroy (GtkObject *object); +static void open_event_with_flags (ECalendarView *cal_view, ECal *client, icalcomponent *icalcomp, guint32 flags); static GdkAtom clipboard_atom = GDK_NONE; extern ECompEditorRegistry *comp_editor_registry; @@ -1246,6 +1247,53 @@ on_meeting (EPopup *ep, EPopupItem *pitem, void *data) } } +static void +set_attendee_status_for_delegate (icalcomponent *icalcomp, const char *email_id, ECal *client) +{ + icalproperty *prop; + + if (!email_id) + return; + + for (prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY); + prop; + prop = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY)) { + const char *attendee = icalproperty_get_attendee (prop); + + if (g_str_equal (attendee + 7, email_id)) { + icalparameter *param; + + param = icalparameter_new_partstat (ICAL_PARTSTAT_DELEGATED); + icalproperty_set_parameter (prop, param); + break; + } + + } +} + +static void +on_delegate (EPopup *ep, EPopupItem *pitem, void *data) +{ + ECalendarView *cal_view = data; + GList *selected; + guint32 flags; + + selected = e_calendar_view_get_selected_events (cal_view); + if (selected) { + ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data; + char *address; + + e_cal_get_cal_address (event->comp_data->client, &address, NULL); + set_attendee_status_for_delegate (event->comp_data->icalcomp, address, event->comp_data->client); + + flags |= COMP_EDITOR_MEETING | COMP_EDITOR_DELEGATE; + + open_event_with_flags (cal_view, event->comp_data->client, event->comp_data->icalcomp, flags); + + g_list_free (selected); + } +} + static void on_forward (EPopup *ep, EPopupItem *pitem, void *data) { @@ -1430,8 +1478,9 @@ static EPopupItem ecv_child_items [] = { { E_POPUP_ITEM, "41.copyto", N_("Cop_y to Calendar..."), on_copy_to, NULL, NULL, 0, E_CAL_POPUP_SELECT_NOTEDITING }, { E_POPUP_ITEM, "42.moveto", N_("Mo_ve to Calendar..."), on_move_to, NULL, NULL, 0, E_CAL_POPUP_SELECT_NOTEDITING | E_CAL_POPUP_SELECT_EDITABLE }, - { E_POPUP_ITEM, "43.schedule", N_("_Schedule Meeting..."), on_meeting, NULL, NULL, 0, E_CAL_POPUP_SELECT_NOTEDITING | E_CAL_POPUP_SELECT_EDITABLE | E_CAL_POPUP_SELECT_NOTMEETING }, - { E_POPUP_ITEM, "44.forward", N_("_Forward as iCalendar..."), on_forward, NULL, "stock_mail-forward", 0, E_CAL_POPUP_SELECT_NOTEDITING }, + { E_POPUP_ITEM, "43.delegate", N_("_Delegate Meeting..."), on_delegate, NULL, NULL, 0, E_CAL_POPUP_SELECT_NOTEDITING | E_CAL_POPUP_SELECT_EDITABLE | E_CAL_POPUP_SELECT_DELEGATABLE }, + { E_POPUP_ITEM, "44.schedule", N_("_Schedule Meeting..."), on_meeting, NULL, NULL, 0, E_CAL_POPUP_SELECT_NOTEDITING | E_CAL_POPUP_SELECT_EDITABLE | E_CAL_POPUP_SELECT_NOTMEETING }, + { E_POPUP_ITEM, "45.forward", N_("_Forward as iCalendar..."), on_forward, NULL, "stock_mail-forward", 0, E_CAL_POPUP_SELECT_NOTEDITING }, { E_POPUP_BAR, "50." }, @@ -1543,6 +1592,7 @@ e_calendar_view_new_appointment_for (ECalendarView *cal_view, ECalComponent *comp; icalcomponent *icalcomp; ECalComponentTransparency transparency; + guint32 flags = 0; g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); @@ -1589,9 +1639,12 @@ e_calendar_view_new_appointment_for (ECalendarView *cal_view, /* edit the object */ e_cal_component_commit_sequence (comp); - e_calendar_view_edit_appointment (cal_view, - e_cal_model_get_default_client (priv->model), - icalcomp, meeting); + flags |= COMP_EDITOR_NEW_ITEM; + if (meeting) + flags |= COMP_EDITOR_MEETING; + + open_event_with_flags (cal_view, e_cal_model_get_default_client (priv->model), + icalcomp, flags); g_object_unref (comp); } @@ -1630,30 +1683,14 @@ e_calendar_view_new_appointment (ECalendarView *cal_view) e_calendar_view_new_appointment_full (cal_view, FALSE, FALSE); } -/** - * e_calendar_view_edit_appointment - * @cal_view: A calendar view. - * @client: Calendar client. - * @icalcomp: The object to be edited. - * @meeting: Whether the appointment is a meeting or not. - * - * Opens an editor window to allow the user to edit the selected - * object. - */ -void -e_calendar_view_edit_appointment (ECalendarView *cal_view, - ECal *client, - icalcomponent *icalcomp, - gboolean meeting) +static void +open_event_with_flags (ECalendarView *cal_view, ECal *client, icalcomponent *icalcomp, guint32 flags) { ECalendarViewPrivate *priv; CompEditor *ce; const char *uid; ECalComponent *comp; - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - g_return_if_fail (E_IS_CAL (client)); - g_return_if_fail (icalcomp != NULL); priv = cal_view->priv; @@ -1663,13 +1700,13 @@ e_calendar_view_edit_appointment (ECalendarView *cal_view, if (!ce) { EventEditor *ee; - ee = event_editor_new (client, meeting); + ee = event_editor_new (client, flags); ce = COMP_EDITOR (ee); comp = e_cal_component_new (); e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp)); comp_editor_edit_comp (ce, comp); - if (meeting) + if (flags & COMP_EDITOR_MEETING) event_editor_show_meeting (ee); e_comp_editor_registry_add (comp_editor_registry, ce, FALSE); @@ -1678,6 +1715,35 @@ e_calendar_view_edit_appointment (ECalendarView *cal_view, } comp_editor_focus (ce); + +} + +/** + * e_calendar_view_edit_appointment + * @cal_view: A calendar view. + * @client: Calendar client. + * @icalcomp: The object to be edited. + * @meeting: Whether the appointment is a meeting or not. + * + * Opens an editor window to allow the user to edit the selected + * object. + */ +void +e_calendar_view_edit_appointment (ECalendarView *cal_view, + ECal *client, + icalcomponent *icalcomp, + gboolean meeting) +{ + guint32 flags = 0; + + g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); + g_return_if_fail (E_IS_CAL (client)); + g_return_if_fail (icalcomp != NULL); + + if (meeting) + flags |= COMP_EDITOR_MEETING; + + open_event_with_flags (cal_view, client, icalcomp, flags); } void -- cgit v1.2.3