From aac2106c8a1eb8d10af2b5277e07af895a264320 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 10 Nov 2009 19:08:01 +0100 Subject: Bug #593751 - Show correct context menu in calendar views --- modules/calendar/e-cal-shell-view-actions.c | 8 +- modules/calendar/e-cal-shell-view-actions.h | 12 +++ modules/calendar/e-cal-shell-view-private.c | 20 +++- modules/calendar/e-cal-shell-view.c | 140 +++++++++++++++++++++++++--- 4 files changed, 164 insertions(+), 16 deletions(-) (limited to 'modules/calendar') diff --git a/modules/calendar/e-cal-shell-view-actions.c b/modules/calendar/e-cal-shell-view-actions.c index 4fa8b07eae..f3a0f209d5 100644 --- a/modules/calendar/e-cal-shell-view-actions.c +++ b/modules/calendar/e-cal-shell-view-actions.c @@ -1322,7 +1322,7 @@ static GtkActionEntry calendar_entries[] = { G_CALLBACK (action_event_delete_occurrence_all_cb) }, { "event-all-day-new", - NULL, + "stock_new-24h-appointment", N_("New All Day _Event..."), NULL, N_("Create a new all day event"), @@ -1336,7 +1336,7 @@ static GtkActionEntry calendar_entries[] = { G_CALLBACK (action_event_forward_cb) }, { "event-meeting-new", - NULL, + "stock_new-meeting", N_("New _Meeting..."), NULL, N_("Create a new meeting"), @@ -1350,7 +1350,7 @@ static GtkActionEntry calendar_entries[] = { G_CALLBACK (action_event_move_cb) }, { "event-new", - NULL, + "appointment-new", N_("New _Appointment..."), NULL, N_("Create a new appointment"), @@ -1364,7 +1364,7 @@ static GtkActionEntry calendar_entries[] = { G_CALLBACK (action_event_occurrence_movable_cb) }, { "event-open", - NULL, + GTK_STOCK_OPEN, N_("_Open Appointment"), "o", N_("View the current appointment"), diff --git a/modules/calendar/e-cal-shell-view-actions.h b/modules/calendar/e-cal-shell-view-actions.h index b02906f179..46d8992859 100644 --- a/modules/calendar/e-cal-shell-view-actions.h +++ b/modules/calendar/e-cal-shell-view-actions.h @@ -77,6 +77,18 @@ E_SHELL_WINDOW_ACTION ((window), "event-delete-occurrence-all") #define E_SHELL_WINDOW_ACTION_EVENT_OPEN(window) \ E_SHELL_WINDOW_ACTION ((window), "event-open") +#define E_SHELL_WINDOW_ACTION_OCCURRENCE_MOVABLE(window) \ + E_SHELL_WINDOW_ACTION ((window), "event-occurrence-movable") +#define E_SHELL_WINDOW_ACTION_EVENT_DELEGATE(window) \ + E_SHELL_WINDOW_ACTION ((window), "event-delegate") +#define E_SHELL_WINDOW_ACTION_EVENT_SCHEDULE(window) \ + E_SHELL_WINDOW_ACTION ((window), "event-schedule") +#define E_SHELL_WINDOW_ACTION_EVENT_FORWARD(window) \ + E_SHELL_WINDOW_ACTION ((window), "event-forward") +#define E_SHELL_WINDOW_ACTION_EVENT_REPLY(window) \ + E_SHELL_WINDOW_ACTION ((window), "event-reply") +#define E_SHELL_WINDOW_ACTION_EVENT_REPLY_ALL(window) \ + E_SHELL_WINDOW_ACTION ((window), "event-reply-all") /* Memo Pad Actions */ #define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_CLIPBOARD_COPY(window) \ diff --git a/modules/calendar/e-cal-shell-view-private.c b/modules/calendar/e-cal-shell-view-private.c index 8a7e3766e3..7c4cdbf9c0 100644 --- a/modules/calendar/e-cal-shell-view-private.c +++ b/modules/calendar/e-cal-shell-view-private.c @@ -226,8 +226,26 @@ cal_shell_view_popup_event_cb (EShellView *shell_view, GdkEventButton *event) { const gchar *widget_path; + GList *list; + gint n_selected; + GnomeCalendar *calendar; + ECalendarView *view; + ECalShellViewPrivate *priv; + + priv = E_CAL_SHELL_VIEW_GET_PRIVATE (shell_view); + + calendar = e_cal_shell_content_get_calendar (priv->cal_shell_content); + view = gnome_calendar_get_calendar_view (calendar, gnome_calendar_get_view (calendar)); + + list = e_calendar_view_get_selected_events (view); + n_selected = g_list_length (list); + g_list_free (list); + + if (n_selected <= 0) + widget_path = "/calendar-empty-popup"; + else + widget_path = "/calendar-event-popup"; - widget_path = "/calendar-event-popup"; e_shell_view_show_popup_menu (shell_view, widget_path, event); } diff --git a/modules/calendar/e-cal-shell-view.c b/modules/calendar/e-cal-shell-view.c index 392f1fb0bc..00a71f540d 100644 --- a/modules/calendar/e-cal-shell-view.c +++ b/modules/calendar/e-cal-shell-view.c @@ -204,10 +204,66 @@ cal_shell_view_execute_search (EShellView *shell_view) g_free (query); } +static icalproperty * +get_attendee_prop (icalcomponent *icalcomp, const gchar *address) +{ + + icalproperty *prop; + + if (!(address && *address)) + return NULL; + + for (prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY); + prop; + prop = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY)) { + const gchar *attendee = icalproperty_get_attendee (prop); + + if (g_str_equal (itip_strip_mailto (attendee), address)) { + return prop; + } + } + return NULL; +} + +static gboolean +is_delegated (icalcomponent *icalcomp, const gchar *user_email) +{ + icalproperty *prop; + icalparameter *param; + const gchar *delto = NULL; + + prop = get_attendee_prop (icalcomp, user_email); + + if (prop) { + param = icalproperty_get_first_parameter (prop, ICAL_DELEGATEDTO_PARAMETER); + if (param) + delto = icalparameter_get_delegatedto (param); + } else + return FALSE; + + prop = get_attendee_prop (icalcomp, itip_strip_mailto (delto)); + + if (prop) { + const gchar *delfrom = NULL; + icalparameter_partstat status = ICAL_PARTSTAT_NONE; + + param = icalproperty_get_first_parameter (prop, ICAL_DELEGATEDFROM_PARAMETER); + if (param) + delfrom = icalparameter_get_delegatedfrom (param); + param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER); + if (param) + status = icalparameter_get_partstat (param); + if ((delfrom && *delfrom) && g_str_equal (itip_strip_mailto (delfrom), user_email) + && status != ICAL_PARTSTAT_DECLINED) + return TRUE; + } + + return FALSE; +} + static void cal_shell_view_update_actions (EShellView *shell_view) { -#if 0 ECalShellViewPrivate *priv; ECalShellContent *cal_shell_content; ECalShellSidebar *cal_shell_sidebar; @@ -224,7 +280,10 @@ cal_shell_view_update_actions (EShellView *shell_view) gboolean user_created_source; gboolean editable = TRUE; gboolean recurring = FALSE; + gboolean is_instance = FALSE; gboolean sensitive; + gboolean is_meeting = FALSE; + gboolean is_delegatable = FALSE; gint n_selected; priv = E_CAL_SHELL_VIEW_GET_PRIVATE (shell_view); @@ -244,18 +303,54 @@ cal_shell_view_update_actions (EShellView *shell_view) n_selected = g_list_length (list); for (iter = list; iter != NULL; iter = iter->next) { - ECalModelComponent *comp_data = iter->data; - gboolean read_only; + ECalendarViewEvent *event = iter->data; + gboolean read_only = TRUE; + + if (!event || !event->comp_data) + continue; + + e_cal_is_read_only (event->comp_data->client, &read_only, NULL); + editable = editable && !read_only; + + if (e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) + recurring = TRUE; + + if (e_cal_util_component_is_instance (event->comp_data->icalcomp)) { + recurring = TRUE; + is_instance = TRUE; + } - e_cal_is_read_only (comp_data->client, &read_only, NULL); - editable &= !read_only; + if (iter == list && !iter->next) { + ECalComponent *comp; + gchar *user_email = NULL; + gboolean user_org = FALSE; - if (e_cal_util_component_has_recurrences (comp_data->icalcomp)) - recurring |= TRUE; - else if (e_cal_util_component_is_instance (comp_data->icalcomp)) - recurring |= TRUE; + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); + user_email = itip_get_comp_attendee (comp, event->comp_data->client); + + is_meeting = e_cal_util_component_has_attendee (event->comp_data->icalcomp); + + if (e_cal_util_component_has_organizer (event->comp_data->icalcomp)) { + if (itip_organizer_is_user (comp, event->comp_data->client)) { + user_org = TRUE; + } + } + + if (e_cal_get_static_capability (event->comp_data->client, CAL_STATIC_CAPABILITY_DELEGATE_SUPPORTED)) { + if (e_cal_get_static_capability (event->comp_data->client, CAL_STATIC_CAPABILITY_DELEGATE_TO_MANY)) + is_delegatable = TRUE; + else if (!user_org && !is_delegated (event->comp_data->icalcomp, user_email)) + is_delegatable = TRUE; + } + + g_free (user_email); + g_object_unref (comp); + } } + g_list_free (list); + source = e_source_selector_peek_primary_selection (selector); if (source != NULL) uri = e_source_peek_relative_uri (source); @@ -274,7 +369,7 @@ cal_shell_view_update_actions (EShellView *shell_view) gtk_action_set_sensitive (action, sensitive); action = ACTION (CALENDAR_RENAME); - sensitive = has_primary_source; + sensitive = (source != NULL); gtk_action_set_sensitive (action, sensitive); action = ACTION (EVENT_CLIPBOARD_COPY); @@ -304,7 +399,30 @@ cal_shell_view_update_actions (EShellView *shell_view) action = ACTION (EVENT_OPEN); sensitive = (n_selected == 1); gtk_action_set_sensitive (action, sensitive); -#endif + + action = ACTION (OCCURRENCE_MOVABLE); + sensitive = (n_selected == 1) && editable && recurring && is_instance; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (EVENT_DELEGATE); + sensitive = (n_selected == 1) && editable && is_delegatable && is_meeting; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (EVENT_SCHEDULE); + sensitive = (n_selected == 1) && editable && !is_meeting; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (EVENT_FORWARD); + sensitive = TRUE; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (EVENT_REPLY); + sensitive = (n_selected == 1) && is_meeting; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (EVENT_REPLY_ALL); + sensitive = (n_selected == 1) && is_meeting; + gtk_action_set_sensitive (action, sensitive); } static void -- cgit v1.2.3