gui/edit-calendar-page: allow exporting calendars
Adds an export option to the edit page, allowing users to export an entire calendar at once. Closes: https://gitlab.gnome.org/GNOME/gnome-calendar/-/issues/31 Co-authored-by: Krifa75 <yahiaoui.fakhri@gmail.com> Part-of: <https://gitlab.gnome.org/GNOME/gnome-calendar/-/merge_requests/615>
This commit is contained in:
committed by
Marge Bot
co-authored by
Krifa75
parent
67ca9ed20c
commit
2d9afa938f
@@ -77,7 +77,14 @@ template $GcalEditCalendarPage: Adw.NavigationPage {
|
||||
}
|
||||
}
|
||||
|
||||
Adw.PreferencesGroup remove_group {
|
||||
Adw.PreferencesGroup {
|
||||
Adw.ButtonRow {
|
||||
title: _("_Export Calendar");
|
||||
end-icon-name: "go-next-symbolic";
|
||||
use-underline: true;
|
||||
activated => $on_export_button_row_activated_cb(template) not-swapped;
|
||||
}
|
||||
|
||||
Adw.ButtonRow remove_button_row {
|
||||
title: _("_Remove Calendar");
|
||||
use-underline: true;
|
||||
|
||||
@@ -37,7 +37,7 @@ struct _GcalEditCalendarPage
|
||||
AdwSwitchRow *calendar_visible_row;
|
||||
AdwActionRow *calendar_url_row;
|
||||
AdwEntryRow *name_entry;
|
||||
GtkWidget *remove_group;
|
||||
GtkWidget *remove_button_row;
|
||||
|
||||
GcalCalendar *calendar;
|
||||
|
||||
@@ -202,7 +202,7 @@ setup_calendar (GcalEditCalendarPage *self,
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->name_entry), gcal_calendar_get_name (calendar));
|
||||
adw_switch_row_set_active (self->calendar_visible_row, gcal_calendar_get_visible (calendar));
|
||||
|
||||
gtk_widget_set_visible (self->remove_group, e_source_get_removable (source));
|
||||
gtk_widget_set_visible (self->remove_button_row, e_source_get_removable (source));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -225,6 +225,136 @@ on_calendar_visibility_changed_cb (AdwSwitchRow *row,
|
||||
gcal_calendar_set_visible (self->calendar, adw_switch_row_get_active (row));
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GHashTable *zones;
|
||||
ECalClient *client;
|
||||
} TimeZoneData;
|
||||
|
||||
static void
|
||||
insert_tz_comps (ICalParameter *param,
|
||||
gpointer data)
|
||||
{
|
||||
g_autoptr (GError) error = NULL;
|
||||
TimeZoneData *tdata = data;
|
||||
ICalTimezone *zone = NULL;
|
||||
ICalComponent *tzcomp;
|
||||
const gchar *tzid;
|
||||
|
||||
tzid = i_cal_parameter_get_tzid (param);
|
||||
|
||||
if (g_hash_table_lookup (tdata->zones, tzid))
|
||||
return;
|
||||
|
||||
if (!e_cal_client_get_timezone_sync (tdata->client, tzid, &zone, NULL, &error))
|
||||
zone = NULL;
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
g_warning ("Could not get the timezone information for %s: %s", tzid, error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
tzcomp = i_cal_component_clone (i_cal_timezone_get_component (zone));
|
||||
g_hash_table_insert (tdata->zones, (gpointer) tzid, (gpointer) tzcomp);
|
||||
}
|
||||
|
||||
static void
|
||||
append_tz_to_comp (gpointer key,
|
||||
gpointer value,
|
||||
ICalComponent *toplevel)
|
||||
{
|
||||
i_cal_component_add_component (toplevel, (ICalComponent *) value);
|
||||
}
|
||||
|
||||
static void
|
||||
on_file_dialog_save_cb (GObject *object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GcalEditCalendarPage *self = user_data;
|
||||
g_autofree gchar *ics_str = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
g_autoptr (GSList) events = NULL;
|
||||
g_autoptr (GFile) file = NULL;
|
||||
ICalComponent *toplevel_component = NULL;
|
||||
ECalClient *client = NULL;
|
||||
TimeZoneData tz_data;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
client = gcal_calendar_get_client (self->calendar);
|
||||
e_cal_client_get_object_list_sync (client, "#t", &events, NULL, NULL);
|
||||
|
||||
/* Avoid exporting empty calendars */
|
||||
if (!events)
|
||||
return;
|
||||
|
||||
toplevel_component = e_cal_util_new_top_level ();
|
||||
tz_data.zones = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
tz_data.client = client;
|
||||
|
||||
for (GSList *l = events; l != NULL; l = l->next)
|
||||
{
|
||||
ICalComponent *component = i_cal_component_clone (l->data);
|
||||
|
||||
i_cal_component_foreach_tzid (component, insert_tz_comps, &tz_data);
|
||||
i_cal_component_take_component (toplevel_component, g_steal_pointer (&component));
|
||||
}
|
||||
|
||||
g_hash_table_foreach (tz_data.zones, (GHFunc) append_tz_to_comp, toplevel_component);
|
||||
g_clear_pointer (&tz_data.zones, g_hash_table_destroy);
|
||||
tz_data.zones = NULL;
|
||||
|
||||
i_cal_component_strip_errors (toplevel_component);
|
||||
ics_str = i_cal_component_as_ical_string (toplevel_component);
|
||||
|
||||
g_clear_pointer (&toplevel_component, i_cal_component_free);
|
||||
|
||||
g_file_replace_contents (file,
|
||||
ics_str,
|
||||
strlen (ics_str),
|
||||
NULL,
|
||||
FALSE,
|
||||
G_FILE_CREATE_REPLACE_DESTINATION,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_export_button_row_activated_cb (GtkButton *button,
|
||||
GcalEditCalendarPage *self)
|
||||
{
|
||||
g_autofree gchar *filename = NULL;
|
||||
GtkFileDialog *file_dialog = NULL;
|
||||
GtkWindow *window = NULL;
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
window = GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self)));
|
||||
file_dialog = gtk_file_dialog_new ();
|
||||
filename = g_strconcat (gcal_calendar_get_name (self->calendar), ".ics", NULL);
|
||||
|
||||
gtk_file_dialog_set_title (file_dialog, _("Export Calendar"));
|
||||
gtk_file_dialog_set_initial_name (file_dialog, filename);
|
||||
|
||||
gtk_file_dialog_save (file_dialog,
|
||||
window,
|
||||
NULL,
|
||||
on_file_dialog_save_cb,
|
||||
self);
|
||||
|
||||
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
on_remove_button_row_activated_cb (GtkButton *button,
|
||||
GcalEditCalendarPage *self)
|
||||
@@ -395,11 +525,12 @@ gcal_edit_calendar_page_class_init (GcalEditCalendarPageClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, GcalEditCalendarPage, calendar_url_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, GcalEditCalendarPage, calendar_visible_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, GcalEditCalendarPage, name_entry);
|
||||
gtk_widget_class_bind_template_child (widget_class, GcalEditCalendarPage, remove_group);
|
||||
gtk_widget_class_bind_template_child (widget_class, GcalEditCalendarPage, remove_button_row);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_calendar_color_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_calendar_visibility_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_remove_button_row_activated_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_export_button_row_activated_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_settings_button_clicked_cb);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user