gui/event-popover: Add export button

Adds an export button to the event popover, allowing users to export
the selected event as an ICS file.

Closes: https://gitlab.gnome.org/GNOME/gnome-calendar/-/issues/1276
Part-of: <https://gitlab.gnome.org/GNOME/gnome-calendar/-/merge_requests/602>
This commit is contained in:
FineFindus
2025-07-11 16:25:30 +00:00
committed by Marge Bot
parent 1075857a34
commit a00a1f01bb
4 changed files with 87 additions and 0 deletions
+13
View File
@@ -64,6 +64,19 @@ template $GcalEventPopover: Popover {
]
}
Button ics_export_button {
valign: start;
halign: end;
icon-name: "share-symbolic";
tooltip-text: _("Export Event");
styles [
"circular",
]
clicked => $on_ics_export_button_clicked_cb(template) not-swapped;
}
Button action_button {
can-focus: true;
valign: start;
+71
View File
@@ -20,6 +20,7 @@
#define G_LOG_DOMAIN "GcalEventPopover"
#include "gcal-calendar.h"
#include "gcal-debug.h"
#include "gcal-event-popover.h"
#include "gcal-meeting-row.h"
@@ -537,6 +538,75 @@ on_action_button_clicked_cb (GtkButton *action_button,
gtk_popover_popdown (GTK_POPOVER (self));
}
static void
on_file_dialog_save_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
g_autoptr (GcalEventPopover) self = user_data;
g_autofree gchar* contents = NULL;
g_autoptr (GError) error = NULL;
g_autoptr (GFile) file = NULL;
ECalComponent *component = NULL;
ICalComponent *icalcomp = NULL;
GcalCalendar *calendar = NULL;
ECalClient *client = NULL;
file = gtk_file_dialog_save_finish (GTK_FILE_DIALOG (object), res, &error);
if (error)
{
if (!g_error_matches (error, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_DISMISSED))
g_warning ("Error saving file: %s", error->message);
return;
}
component = gcal_event_get_component (self->event);
icalcomp = e_cal_component_get_icalcomponent (component);
calendar = gcal_event_get_calendar (self->event);
client = gcal_calendar_get_client (calendar);
contents = e_cal_client_get_component_as_string (client, icalcomp);
g_file_replace_contents (file,
contents,
strlen (contents),
NULL,
FALSE,
G_FILE_CREATE_REPLACE_DESTINATION,
NULL,
NULL,
NULL);
}
static void
on_ics_export_button_clicked_cb (GtkButton *button,
GcalEventPopover *self)
{
g_autofree gchar *filename = NULL;
GtkFileDialog *file_dialog = NULL;
GtkWindow *window = NULL;
window = GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self)));
file_dialog = gtk_file_dialog_new ();
filename = g_strconcat (gcal_event_get_summary (self->event), ".ics", NULL);
gtk_file_dialog_set_title (file_dialog, _("Export Event"));
gtk_file_dialog_set_initial_name (file_dialog, filename);
/*
* We need to close the popover before showing the dialog, as otherwise the
* popover will continue to capture the first click (i.e. first click will
* appear unresponsive as it closes the popover)
*/
gtk_popover_popdown (GTK_POPOVER (self));
gtk_file_dialog_save (file_dialog,
window,
NULL,
on_file_dialog_save_cb,
g_object_ref (self));
}
static void
on_uri_launched_cb (GObject *source_object,
GAsyncResult *result,
@@ -732,6 +802,7 @@ gcal_event_popover_class_init (GcalEventPopoverClass *klass)
gtk_widget_class_bind_template_child (widget_class, GcalEventPopover, read_only_icon);
gtk_widget_class_bind_template_callback (widget_class, on_action_button_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, on_ics_export_button_clicked_cb);
}
static void
+1
View File
@@ -15,5 +15,6 @@
<file compressed="true">globe-symbolic.svg</file>
<file compressed="true">info-outline-symbolic.svg</file>
<file compressed="true">loupe-large-symbolic.svg</file>
<file compressed="true">share-symbolic.svg</file>
</gresource>
</gresources>
+2
View File
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><g fill="#222222"><path d="m 4 5.992188 h 1 c 0.257812 0 0.527344 -0.128907 0.71875 -0.3125 l 1.28125 -1.28125 v 6.59375 h 2 v -6.59375 l 1.28125 1.28125 c 0.191406 0.183593 0.410156 0.3125 0.71875 0.3125 h 1 v -1 c 0 -0.308594 -0.089844 -0.550782 -0.28125 -0.75 l -3.71875 -3.65625 l -3.71875 3.65625 c -0.191406 0.199218 -0.28125 0.441406 -0.28125 0.75 z m 0 0"/><path d="m 1.003906 11.964844 c 0 1.664062 1.371094 3.035156 3.035156 3.035156 h 7.917969 c 1.664063 0 3.03125 -1.371094 3.03125 -3.035156 v -1.972656 h -2 v 1.972656 c 0 0.589844 -0.441406 1.035156 -1.03125 1.035156 h -7.917969 c -0.589843 0 -1.035156 -0.445312 -1.035156 -1.035156 v -1.972656 h -2 z m 0 0"/><path d="m 4.039062 6.960938 c -1.664062 0 -3.035156 1.367187 -3.035156 3.03125 v 1.976562 h 2 v -1.976562 c 0 -0.589844 0.445313 -1.03125 1.035156 -1.03125 h 0.960938 v -2 z m 6.960938 0 v 2 h 0.957031 c 0.589844 0 1.03125 0.441406 1.03125 1.03125 v 1.976562 h 2 v -1.976562 c 0 -1.664063 -1.367187 -3.03125 -3.03125 -3.03125 z m 0 0"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB