From f4dffb28cf99aa0afbf583886d5b22f7ad87652d Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Wed, 29 Jan 2025 12:25:40 +0100 Subject: [PATCH] ews-I#295 - itip-formatter: Import of forwarded meeting as bare event This part adds an "Import as Event" button to the meeting request window when the selected calendar claims it can add only meetings organized by the calendar owner, which will remove the organizer and all the attendees before the import. Related to https://gitlab.gnome.org/GNOME/evolution-ews/-/issues/295 --- data/webkit/e-web-view.js | 7 +- data/webkit/webview.css | 4 +- src/mail/e-mail-display.c | 10 +- src/mail/e-mail-display.h | 2 + .../itip-view-elements-defines.h | 2 + src/modules/itip-formatter/itip-view.c | 116 +++++++++++++++--- src/modules/itip-formatter/itip-view.h | 3 +- 7 files changed, 115 insertions(+), 29 deletions(-) diff --git a/data/webkit/e-web-view.js b/data/webkit/e-web-view.js index a9aa57f14a..bdf15f30bc 100644 --- a/data/webkit/e-web-view.js +++ b/data/webkit/e-web-view.js @@ -1529,7 +1529,8 @@ var EvoItip = { CHECKBOX_INHERIT_ALARM : "checkbox_inherit_alarm", CHECKBOX_UPDATE : "checkbox_update", CHECKBOX_FREE_TIME : "checkbox_free_time", - TABLE_ROW_BUTTONS : "table_row_buttons" + TABLE_ROW_BUTTONS : "table_row_buttons", + BUTTON_IMPORT_BARE : "button_import_bare" }; EvoItip.alarmCheckClickedCb = function(check1) @@ -1842,6 +1843,10 @@ EvoItip.SetButtonsDisabled = function(iframe_id, disabled) if (elem) elem.disabled = disabled; + elem = doc.getElementById(EvoItip.BUTTON_IMPORT_BARE); + if (elem) + elem.disabled = disabled; + elem = doc.getElementById(EvoItip.TABLE_ROW_BUTTONS); if (!elem) return; diff --git a/data/webkit/webview.css b/data/webkit/webview.css index 3422cdf270..e070f3fbd0 100644 --- a/data/webkit/webview.css +++ b/data/webkit/webview.css @@ -221,13 +221,13 @@ th.rtl { font-weight: bold; } -#table_row_buttons button { +#table_row_buttons button, .table_row_buttons button { line-height: 28px; min-width: 150px; white-space: nowrap; } -#table_row_buttons img { +#table_row_buttons img, .table_row_buttons img { padding-right: 5px; vertical-align: middle; } diff --git a/src/mail/e-mail-display.c b/src/mail/e-mail-display.c index 1f0331412b..0b94b1ee12 100644 --- a/src/mail/e-mail-display.c +++ b/src/mail/e-mail-display.c @@ -548,8 +548,8 @@ mail_display_iframes_height_update_cb (gpointer user_data) return G_SOURCE_REMOVE; } -static void -mail_display_schedule_iframes_height_update (EMailDisplay *mail_display) +void +e_mail_display_schedule_iframes_height_update (EMailDisplay *mail_display) { if (mail_display_can_use_frame_flattening ()) return; @@ -1473,7 +1473,7 @@ mail_display_content_loaded_cb (EWebView *web_view, } } - mail_display_schedule_iframes_height_update (mail_display); + e_mail_display_schedule_iframes_height_update (mail_display); } static void @@ -1792,7 +1792,7 @@ mail_display_schedule_iframes_height_update_cb (WebKitUserContentManager *manage g_return_if_fail (mail_display != NULL); - mail_display_schedule_iframes_height_update (mail_display); + e_mail_display_schedule_iframes_height_update (mail_display); } static gboolean @@ -3068,7 +3068,7 @@ e_mail_display_init (EMailDisplay *display) g_signal_connect ( display, "resource-loaded", - G_CALLBACK (mail_display_schedule_iframes_height_update), NULL); + G_CALLBACK (e_mail_display_schedule_iframes_height_update), NULL); g_signal_connect_after ( display, "drag-data-get", diff --git a/src/mail/e-mail-display.h b/src/mail/e-mail-display.h index 3052bd6cf6..b16a380327 100644 --- a/src/mail/e-mail-display.h +++ b/src/mail/e-mail-display.h @@ -118,6 +118,8 @@ gboolean e_mail_display_process_magic_spacebar gboolean towards_bottom); gboolean e_mail_display_get_skip_insecure_parts (EMailDisplay *mail_display); +void e_mail_display_schedule_iframes_height_update + (EMailDisplay *mail_display); G_END_DECLS diff --git a/src/modules/itip-formatter/itip-view-elements-defines.h b/src/modules/itip-formatter/itip-view-elements-defines.h index 90b0719cfd..041b145e1f 100644 --- a/src/modules/itip-formatter/itip-view-elements-defines.h +++ b/src/modules/itip-formatter/itip-view-elements-defines.h @@ -63,6 +63,8 @@ #define BUTTON_UPDATE_ATTENDEE_STATUS "button_update_attendee_status" #define BUTTON_SAVE "button_save" #define BUTTON_IMPORT "button_import" +#define BUTTON_IMPORT_BARE "button_import_bare" +#define BUTTON_IMPORT_BARE_HINT "button_import_bare_hint" #define TABLE_UPPER_ITIP_INFO "table_upper_itip_info" #define TABLE_LOWER_ITIP_INFO "table_lower_itip_info" diff --git a/src/modules/itip-formatter/itip-view.c b/src/modules/itip-formatter/itip-view.c index 5f29e425a6..08ce979e0f 100644 --- a/src/modules/itip-formatter/itip-view.c +++ b/src/modules/itip-formatter/itip-view.c @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -1265,7 +1266,14 @@ buttons_table_write_button (GString *buffer, const gchar *icon, ItipViewResponse response) { - gchar *access_key, *html_label; + gchar *access_key, *html_label, *hint = NULL; + const gchar *colspan = ""; + + if (response == ITIP_VIEW_RESPONSE_IMPORT_BARE) { + hint = g_markup_printf_escaped (" ", + _("Imported event will have removed the organizer and all the attendees.")); + colspan = " colspan='11'"; + } html_label = e_mail_formatter_parse_html_mnemonics (label, &access_key); @@ -1279,23 +1287,23 @@ buttons_table_write_button (GString *buffer, g_string_append_printf ( buffer, - "\n", - name, itip_part_ptr, response, name, access_key ? access_key : "" , icon, - GTK_ICON_SIZE_BUTTON, icon_width, icon_height, html_label); + "%s\n", + colspan, name, itip_part_ptr, response, name, access_key ? access_key : "" , icon, + GTK_ICON_SIZE_BUTTON, icon_width, icon_height, html_label, hint ? hint : ""); } else { g_string_append_printf ( buffer, - "\n", - name, itip_part_ptr, response, name, access_key ? access_key : "" , html_label); + "%s\n", + colspan, name, itip_part_ptr, response, name, access_key ? access_key : "" , html_label, hint ? hint : ""); } g_free (html_label); - g_free (access_key); + g_free (hint); } static void @@ -1344,6 +1352,11 @@ append_buttons_table (GString *buffer, buffer, itip_part_ptr, BUTTON_IMPORT, _("Im_port"), NULL, ITIP_VIEW_RESPONSE_IMPORT); + g_string_append (buffer, ""); + buttons_table_write_button ( + buffer, itip_part_ptr, BUTTON_IMPORT_BARE, _("Im_port as Event"), + NULL, ITIP_VIEW_RESPONSE_IMPORT_BARE); + g_string_append (buffer, ""); } @@ -2392,6 +2405,57 @@ itip_view_new (const gchar *part_id, return view; } +static void +itip_view_update_import_bare_options (ItipView *self) +{ + ICalProperty *prop; + gchar *cal_email = NULL; + gboolean show = FALSE; + + if ((self->priv->method != I_CAL_METHOD_PUBLISH && self->priv->method != I_CAL_METHOD_REQUEST) || + !self->priv->current_client || + !self->priv->ical_comp || + !e_client_check_capability (E_CLIENT (self->priv->current_client), E_CAL_STATIC_CAPABILITY_USER_IS_ORGANIZER_ONLY) || + !e_cal_util_component_has_attendee (self->priv->ical_comp) || + !e_cal_util_component_has_organizer (self->priv->ical_comp) || + i_cal_component_isa (self->priv->ical_comp) != I_CAL_VEVENT_COMPONENT || + !e_client_get_backend_property_sync (E_CLIENT (self->priv->current_client), E_CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS, &cal_email, self->priv->cancellable, NULL)) { + hide_element (self, BUTTON_IMPORT_BARE, TRUE); + hide_element (self, BUTTON_IMPORT_BARE_HINT, TRUE); + enable_button (self, BUTTON_IMPORT_BARE, FALSE); + enable_button (self, BUTTON_IMPORT_BARE_HINT, FALSE); + return; + } + + prop = i_cal_component_get_first_property (self->priv->ical_comp, I_CAL_ORGANIZER_PROPERTY); + if (prop) { + const gchar *orgnzr_email; + + orgnzr_email = i_cal_property_get_organizer (prop); + show = orgnzr_email && cal_email && !e_cal_util_email_addresses_equal (orgnzr_email, cal_email); + + g_clear_object (&prop); + } + + hide_element (self, BUTTON_IMPORT_BARE, !show); + hide_element (self, BUTTON_IMPORT_BARE_HINT, !show); + enable_button (self, BUTTON_IMPORT_BARE, show); + enable_button (self, BUTTON_IMPORT_BARE_HINT, show); + + g_free (cal_email); + + if (show) { + EWebView *web_view; + + web_view = itip_view_ref_web_view (self); + + if (E_IS_MAIL_DISPLAY (web_view)) + e_mail_display_schedule_iframes_height_update (E_MAIL_DISPLAY (web_view)); + + g_clear_object (&web_view); + } +} + void itip_view_set_mode (ItipView *view, ItipViewMode mode) @@ -2424,6 +2488,8 @@ itip_view_set_mode (ItipView *view, if (view->priv->needs_decline) show_button (view, BUTTON_DECLINE); show_button (view, BUTTON_ACCEPT); + + itip_view_update_import_bare_options (view); } else { show_button (view, BUTTON_IMPORT); } @@ -4185,6 +4251,7 @@ itip_view_cal_opened_cb (GObject *source_object, view->priv->current_client = E_CAL_CLIENT (g_object_ref (client)); + itip_view_update_import_bare_options (view); set_buttons_sensitive (view); exit: @@ -4426,7 +4493,7 @@ find_cal_update_ui (FormatItipFindData *fd, itip_view_set_show_keep_alarm_check (view, fd->keep_alarm_check); - view->priv->current_client = cal_client; + itip_view_update_import_bare_options (view); /* Provide extra info, since its not in the component */ /* FIXME Check sequence number of meeting? */ @@ -5464,6 +5531,7 @@ receive_objects_ready_cb (GObject *ecalclient, } break; case ITIP_VIEW_RESPONSE_IMPORT: + case ITIP_VIEW_RESPONSE_IMPORT_BARE: switch (e_cal_client_get_source_type (client)) { case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: default: @@ -5704,7 +5772,8 @@ update_item (ItipView *view, } static void -import_item (ItipView *view) +import_item (ItipView *view, + gboolean bare_import) { ICalComponent *main_comp_clone; ICalComponent *subcomp; @@ -5723,14 +5792,20 @@ import_item (ItipView *view) if ((child_kind == I_CAL_VEVENT_COMPONENT || child_kind == I_CAL_VJOURNAL_COMPONENT || - child_kind == I_CAL_VTODO_COMPONENT) && - e_cal_util_component_has_property (subcomp, I_CAL_ATTACH_PROPERTY)) { - ECalComponent *comp; + child_kind == I_CAL_VTODO_COMPONENT)) { + if (bare_import) { + e_cal_util_component_remove_property_by_kind (subcomp, I_CAL_ORGANIZER_PROPERTY, TRUE); + e_cal_util_component_remove_property_by_kind (subcomp, I_CAL_ATTENDEE_PROPERTY, TRUE); + } - comp = e_cal_component_new_from_icalcomponent (g_object_ref (subcomp)); - if (comp) { - itip_view_add_attachments_from_message (view, comp); - g_clear_object (&comp); + if (e_cal_util_component_has_property (subcomp, I_CAL_ATTACH_PROPERTY)) { + ECalComponent *comp; + + comp = e_cal_component_new_from_icalcomponent (g_object_ref (subcomp)); + if (comp) { + itip_view_add_attachments_from_message (view, comp); + g_clear_object (&comp); + } } } @@ -5740,7 +5815,7 @@ import_item (ItipView *view) g_clear_object (&iter); - view->priv->update_item_response = ITIP_VIEW_RESPONSE_IMPORT; + view->priv->update_item_response = bare_import ? ITIP_VIEW_RESPONSE_IMPORT_BARE : ITIP_VIEW_RESPONSE_IMPORT; e_cal_client_receive_objects ( view->priv->current_client, @@ -6793,7 +6868,8 @@ view_response_cb (ItipView *view, idle_open_cb, g_object_ref (view), g_object_unref); return; case ITIP_VIEW_RESPONSE_IMPORT: - import_item (view); + case ITIP_VIEW_RESPONSE_IMPORT_BARE: + import_item (view, response == ITIP_VIEW_RESPONSE_IMPORT_BARE); break; default: break; diff --git a/src/modules/itip-formatter/itip-view.h b/src/modules/itip-formatter/itip-view.h index 3d7341726b..947c026f53 100644 --- a/src/modules/itip-formatter/itip-view.h +++ b/src/modules/itip-formatter/itip-view.h @@ -81,7 +81,8 @@ typedef enum { ITIP_VIEW_RESPONSE_REFRESH, ITIP_VIEW_RESPONSE_OPEN, ITIP_VIEW_RESPONSE_SAVE, - ITIP_VIEW_RESPONSE_IMPORT + ITIP_VIEW_RESPONSE_IMPORT, + ITIP_VIEW_RESPONSE_IMPORT_BARE } ItipViewResponse; typedef enum {