diff --git a/src/views/gcal-week-header.c b/src/views/gcal-week-header.c index bfa3ccf3..b6fc1dc3 100644 --- a/src/views/gcal-week-header.c +++ b/src/views/gcal-week-header.c @@ -1405,6 +1405,8 @@ gcal_week_header_drag_drop (GtkWidget *widget, GcalWeekHeader *self; g_autoptr (GDateTime) week_start; g_autoptr (GDateTime) dnd_date; + GDateTime *start_date; + GDateTime *end_date; GtkWidget *event_widget; GcalEvent *event; gboolean ltr; @@ -1422,30 +1424,56 @@ gcal_week_header_drag_drop (GtkWidget *widget, /* RTL languages swap the drop cell column */ if (!ltr) - { - drop_cell = 6 - drop_cell; - } + drop_cell = 6 - drop_cell; event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (event_widget)); + start_date = gcal_event_get_date_start (event); + end_date = gcal_event_get_date_end (event); week_start = get_start_of_week (self->active_date); - dnd_date = g_date_time_add_days (week_start, drop_cell); - /* - * Set the event's start and end dates. Since the event may have a - * NULL end date, so we have to check it here - */ - gcal_event_set_all_day (event, TRUE); - gcal_event_set_date_start (event, dnd_date); + if (gcal_event_is_multiday (event) && !gcal_event_get_all_day (event)) + { + /* + * The only case where we don't touch the timezone is for + * timed, multiday events. + */ + dnd_date = g_date_time_new (gcal_event_get_timezone (event), + g_date_time_get_year (week_start), + g_date_time_get_month (week_start), + g_date_time_get_day_of_month (week_start) + drop_cell, + g_date_time_get_hour (start_date), + g_date_time_get_minute (start_date), + 0); + } + else + { + dnd_date = g_date_time_new_utc (g_date_time_get_year (week_start), + g_date_time_get_month (week_start), + g_date_time_get_day_of_month (week_start) + drop_cell, + 0, 0, 0); - if (gcal_event_get_date_end (event)) + gcal_event_set_all_day (event, TRUE); + } + + /* Since the event may have a NULL end date, so we have to check it here */ + if (end_date) { g_autoptr (GDateTime) new_end; + GTimeSpan difference; - new_end = g_date_time_add_days (dnd_date, 1); + difference = g_date_time_difference (end_date, start_date); + difference /= G_TIME_SPAN_HOUR; + new_end = g_date_time_add_hours (dnd_date, difference); gcal_event_set_date_end (event, new_end); } + /* + * Set the start date ~after~ the end date, so we can compare + * the event's start and end dates above + */ + gcal_event_set_date_start (event, dnd_date); + /* Commit the changes */ gcal_manager_update_event (self->manager, event);