views/week: Port week header to GListModel
Rework the add/remove functions to make them internal. The remove function can now operate on GcalEvent* instead of gchar* uuid, since it's not bound to GcalTimelineSubscriber anymore. Part-of: <https://gitlab.gnome.org/GNOME/gnome-calendar/-/merge_requests/742>
This commit is contained in:
committed by
Marge Bot
parent
c635db3495
commit
34e28e31fe
+196
-156
@@ -78,6 +78,9 @@ struct _GcalWeekHeader
|
||||
GtkBox *weekdays_box;
|
||||
GtkWidget *main_box;
|
||||
|
||||
GtkFilterListModel *events_model;
|
||||
GSequence *events_sequence;
|
||||
|
||||
/*
|
||||
* Stores the events as they come from the week-view
|
||||
* The list will later be iterated after the active date is changed
|
||||
@@ -369,26 +372,6 @@ on_weather_update (GcalWeatherService *weather_service,
|
||||
update_weather_infos (self);
|
||||
}
|
||||
|
||||
static GcalEvent*
|
||||
get_event_by_uuid (GcalWeekHeader *self,
|
||||
const gchar *uuid)
|
||||
{
|
||||
gint weekday;
|
||||
|
||||
for (weekday = 0; weekday < N_WEEKDAYS; weekday++)
|
||||
{
|
||||
for (gsize i = 0; i < self->events[weekday]->len; i++)
|
||||
{
|
||||
GcalEvent *event = g_ptr_array_index (self->events[weekday], i);
|
||||
|
||||
if (g_strcmp0 (gcal_event_get_uid (event), uuid) == 0)
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline gint
|
||||
get_today_column (GcalWeekHeader *self)
|
||||
{
|
||||
@@ -893,6 +876,135 @@ add_event_to_grid (GcalWeekHeader *self,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_event (GcalWeekHeader *self,
|
||||
GcalEvent *event)
|
||||
{
|
||||
g_autoptr (GDateTime) event_start = NULL;
|
||||
g_autoptr (GDateTime) event_end = NULL;
|
||||
g_autoptr (GDateTime) week_start = NULL;
|
||||
g_autoptr (GDateTime) week_end = NULL;
|
||||
gboolean all_day;
|
||||
gint start, end;
|
||||
|
||||
g_return_if_fail (GCAL_IS_WEEK_HEADER (self));
|
||||
|
||||
all_day = gcal_event_get_all_day (event);
|
||||
week_start = gcal_date_time_get_start_of_week (self->active_date);
|
||||
week_end = gcal_date_time_get_end_of_week (self->active_date);
|
||||
|
||||
/* Retrieve the real start and end dates */
|
||||
if (all_day)
|
||||
{
|
||||
GDateTime *utc_week_start, *utc_week_end, *aux;
|
||||
|
||||
utc_week_start = 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),
|
||||
0, 0, 0);
|
||||
utc_week_end = g_date_time_new_utc (g_date_time_get_year (week_end),
|
||||
g_date_time_get_month (week_end),
|
||||
g_date_time_get_day_of_month (week_end),
|
||||
0, 0, 0);
|
||||
|
||||
event_start = g_date_time_ref (gcal_event_get_date_start (event));
|
||||
event_end = g_date_time_ref (gcal_event_get_date_end (event));
|
||||
|
||||
/*
|
||||
* Switch the week start and end by the UTC variants, in
|
||||
* order to correctly compare all-day events.
|
||||
*/
|
||||
aux = week_start;
|
||||
week_start = utc_week_start;
|
||||
gcal_clear_date_time (&aux);
|
||||
|
||||
aux = week_end;
|
||||
week_end = utc_week_end;
|
||||
gcal_clear_date_time (&aux);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
event_start = g_date_time_to_local (gcal_event_get_date_start (event));
|
||||
event_end = g_date_time_to_local (gcal_event_get_date_end (event));
|
||||
}
|
||||
|
||||
/* Start position */
|
||||
if (g_date_time_compare (event_start, week_start) >= 0)
|
||||
start = floor (g_date_time_difference (event_start, week_start) / G_TIME_SPAN_DAY);
|
||||
else
|
||||
start = 0;
|
||||
|
||||
/* End position */
|
||||
if (g_date_time_compare (event_end, week_end) < 0)
|
||||
end = floor (g_date_time_difference (event_end, week_start) / G_TIME_SPAN_DAY) - all_day;
|
||||
else
|
||||
end = N_WEEKDAYS - 1;
|
||||
|
||||
/* Sanity checks */
|
||||
if (start > end || start > N_WEEKDAYS - 1 || end < 0)
|
||||
{
|
||||
g_warning ("Error adding event '%s' to the week header", gcal_event_get_summary (event));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add the event widget to the grid */
|
||||
add_event_to_grid (self, event, start, end);
|
||||
|
||||
/* Check if we eventually can merge events */
|
||||
check_mergeable_events (self);
|
||||
|
||||
/* And also update the overflow labels */
|
||||
update_overflow (self);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_event (GcalWeekHeader *self,
|
||||
GcalEvent *event)
|
||||
{
|
||||
GtkWidget *child;
|
||||
gint weekday;
|
||||
|
||||
g_return_if_fail (GCAL_IS_WEEK_HEADER (self));
|
||||
|
||||
child = gtk_widget_get_first_child (GTK_WIDGET (self->grid));
|
||||
while (child)
|
||||
{
|
||||
GtkWidget *next = gtk_widget_get_next_sibling (child);
|
||||
|
||||
if (GCAL_IS_EVENT_WIDGET (child))
|
||||
{
|
||||
GcalEventWidget *child_widget = GCAL_EVENT_WIDGET (child);
|
||||
|
||||
if (gcal_event_widget_get_event (child_widget) == event)
|
||||
destroy_event_widget (self, child);
|
||||
}
|
||||
|
||||
child = next;
|
||||
}
|
||||
|
||||
/* Remove from the weekday's GList */
|
||||
for (weekday = 0; weekday < N_WEEKDAYS; weekday++)
|
||||
{
|
||||
guint event_position;
|
||||
|
||||
if (!g_ptr_array_find (self->events[weekday], event, &event_position))
|
||||
continue;
|
||||
|
||||
/* Remove from the current weekday */
|
||||
g_ptr_array_remove_index (self->events[weekday], event_position);
|
||||
|
||||
/* Move remaining events up */
|
||||
move_events_at_column (self, UP, weekday, event_position);
|
||||
}
|
||||
|
||||
/* Check if we eventually can merge events */
|
||||
check_mergeable_events (self);
|
||||
|
||||
/* And also update the overflow labels */
|
||||
update_overflow (self);
|
||||
}
|
||||
|
||||
static void
|
||||
update_unchanged_events (GcalWeekHeader *self,
|
||||
GDateTime *new_date)
|
||||
@@ -967,8 +1079,8 @@ update_unchanged_events (GcalWeekHeader *self,
|
||||
GcalEvent *event;
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &event, NULL))
|
||||
{
|
||||
gcal_week_header_remove_event (self, gcal_event_get_uid (event));
|
||||
gcal_week_header_add_event (self, event);
|
||||
remove_event (self, event);
|
||||
add_event (self, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1297,6 +1409,53 @@ on_drop_target_motion_cb (GtkDropTarget *drop_target,
|
||||
GCAL_RETURN (self->dnd.cell != -1 ? GDK_ACTION_COPY : 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
event_is_all_day_or_multiday_func (gpointer item,
|
||||
gpointer user_data)
|
||||
{
|
||||
GcalEvent *event = (GcalEvent *) item;
|
||||
|
||||
g_assert (GCAL_IS_EVENT (event));
|
||||
|
||||
return gcal_event_get_all_day (event) || gcal_event_is_multiday (event);
|
||||
}
|
||||
|
||||
static void
|
||||
events_changed_cb (GListModel *model,
|
||||
guint position,
|
||||
guint removed,
|
||||
guint added,
|
||||
GcalWeekHeader *self)
|
||||
{
|
||||
while (removed != 0)
|
||||
{
|
||||
GSequenceIter *iter;
|
||||
GcalEvent *event;
|
||||
|
||||
iter = g_sequence_get_iter_at_pos (self->events_sequence, position);
|
||||
event = g_sequence_get (iter);
|
||||
|
||||
g_assert (GCAL_IS_EVENT (event));
|
||||
|
||||
remove_event (self, event);
|
||||
|
||||
g_sequence_remove (iter);
|
||||
|
||||
removed--;
|
||||
}
|
||||
|
||||
for (gsize i = 0; i < added; i++)
|
||||
{
|
||||
g_autoptr (GcalEvent) event = g_list_model_get_item (model, i);
|
||||
|
||||
g_assert (GCAL_IS_EVENT (event));
|
||||
|
||||
g_sequence_insert_before (g_sequence_get_iter_at_pos (self->events_sequence, position + i),
|
||||
g_object_ref (event));
|
||||
add_event (self, event);
|
||||
}
|
||||
}
|
||||
|
||||
/* Drawing area content and size */
|
||||
|
||||
static void
|
||||
@@ -1437,6 +1596,9 @@ gcal_week_header_finalize (GObject *object)
|
||||
GcalWeekHeader *self = GCAL_WEEK_HEADER (object);
|
||||
gint i;
|
||||
|
||||
g_clear_pointer (&self->events_sequence, g_sequence_free);
|
||||
g_clear_object (&self->events_model);
|
||||
|
||||
gcal_clear_date_time (&self->active_date);
|
||||
|
||||
for (i = 0; i < N_WEEKDAYS; i++)
|
||||
@@ -1544,9 +1706,17 @@ static void
|
||||
gcal_week_header_init (GcalWeekHeader *self)
|
||||
{
|
||||
GcalContext *context = gcal_application_get_context (GCAL_DEFAULT_APPLICATION);
|
||||
GtkCustomFilter *filter;
|
||||
GtkDropTarget *drop_target;
|
||||
gint i;
|
||||
|
||||
filter = gtk_custom_filter_new (event_is_all_day_or_multiday_func, NULL, NULL);
|
||||
|
||||
self->events_model = gtk_filter_list_model_new (NULL, GTK_FILTER (g_steal_pointer (&filter)));
|
||||
self->events_sequence = g_sequence_new (g_object_unref);
|
||||
|
||||
g_signal_connect (self->events_model, "items-changed", G_CALLBACK (events_changed_cb), self);
|
||||
|
||||
for (gsize i = 0; i < N_WEEKDAYS; i++)
|
||||
self->events[i] = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
@@ -1618,142 +1788,12 @@ gcal_week_header_init (GcalWeekHeader *self)
|
||||
}
|
||||
|
||||
void
|
||||
gcal_week_header_add_event (GcalWeekHeader *self,
|
||||
GcalEvent *event)
|
||||
gcal_week_header_set_model (GcalWeekHeader *self,
|
||||
GListModel *model)
|
||||
{
|
||||
g_autoptr (GDateTime) event_start = NULL;
|
||||
g_autoptr (GDateTime) event_end = NULL;
|
||||
g_autoptr (GDateTime) week_start = NULL;
|
||||
g_autoptr (GDateTime) week_end = NULL;
|
||||
gboolean all_day;
|
||||
gint start, end;
|
||||
g_assert (GCAL_IS_WEEK_HEADER (self));
|
||||
|
||||
g_return_if_fail (GCAL_IS_WEEK_HEADER (self));
|
||||
|
||||
all_day = gcal_event_get_all_day (event);
|
||||
week_start = gcal_date_time_get_start_of_week (self->active_date);
|
||||
week_end = gcal_date_time_get_end_of_week (self->active_date);
|
||||
|
||||
/* Retrieve the real start and end dates */
|
||||
if (all_day)
|
||||
{
|
||||
GDateTime *utc_week_start, *utc_week_end, *aux;
|
||||
|
||||
utc_week_start = 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),
|
||||
0, 0, 0);
|
||||
utc_week_end = g_date_time_new_utc (g_date_time_get_year (week_end),
|
||||
g_date_time_get_month (week_end),
|
||||
g_date_time_get_day_of_month (week_end),
|
||||
0, 0, 0);
|
||||
|
||||
event_start = g_date_time_ref (gcal_event_get_date_start (event));
|
||||
event_end = g_date_time_ref (gcal_event_get_date_end (event));
|
||||
|
||||
/*
|
||||
* Switch the week start and end by the UTC variants, in
|
||||
* order to correctly compare all-day events.
|
||||
*/
|
||||
aux = week_start;
|
||||
week_start = utc_week_start;
|
||||
gcal_clear_date_time (&aux);
|
||||
|
||||
aux = week_end;
|
||||
week_end = utc_week_end;
|
||||
gcal_clear_date_time (&aux);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
event_start = g_date_time_to_local (gcal_event_get_date_start (event));
|
||||
event_end = g_date_time_to_local (gcal_event_get_date_end (event));
|
||||
}
|
||||
|
||||
/* Start position */
|
||||
if (g_date_time_compare (event_start, week_start) >= 0)
|
||||
start = floor (g_date_time_difference (event_start, week_start) / G_TIME_SPAN_DAY);
|
||||
else
|
||||
start = 0;
|
||||
|
||||
/* End position */
|
||||
if (g_date_time_compare (event_end, week_end) < 0)
|
||||
end = floor (g_date_time_difference (event_end, week_start) / G_TIME_SPAN_DAY) - all_day;
|
||||
else
|
||||
end = N_WEEKDAYS - 1;
|
||||
|
||||
/* Sanity checks */
|
||||
if (start > end || start > N_WEEKDAYS - 1 || end < 0)
|
||||
{
|
||||
g_warning ("Error adding event '%s' to the week header", gcal_event_get_summary (event));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add the event widget to the grid */
|
||||
add_event_to_grid (self, event, start, end);
|
||||
|
||||
/* Check if we eventually can merge events */
|
||||
check_mergeable_events (self);
|
||||
|
||||
/* And also update the overflow labels */
|
||||
update_overflow (self);
|
||||
}
|
||||
|
||||
void
|
||||
gcal_week_header_remove_event (GcalWeekHeader *self,
|
||||
const gchar *uuid)
|
||||
{
|
||||
g_autoptr (GcalEvent) removed_event = NULL;
|
||||
GtkWidget *child;
|
||||
gint weekday;
|
||||
|
||||
g_return_if_fail (GCAL_IS_WEEK_HEADER (self));
|
||||
|
||||
removed_event = get_event_by_uuid (self, uuid);
|
||||
|
||||
if (!removed_event)
|
||||
return;
|
||||
|
||||
child = gtk_widget_get_first_child (GTK_WIDGET (self->grid));
|
||||
while (child)
|
||||
{
|
||||
GtkWidget *next = gtk_widget_get_next_sibling (child);
|
||||
|
||||
if (GCAL_IS_EVENT_WIDGET (child))
|
||||
{
|
||||
GcalEventWidget *child_widget;
|
||||
GcalEvent *event;
|
||||
|
||||
child_widget = GCAL_EVENT_WIDGET (child);
|
||||
event = gcal_event_widget_get_event (child_widget);
|
||||
|
||||
if (g_strcmp0 (uuid, gcal_event_get_uid (event)) == 0)
|
||||
destroy_event_widget (self, child);
|
||||
}
|
||||
|
||||
child = next;
|
||||
}
|
||||
|
||||
/* Remove from the weekday's GList */
|
||||
for (weekday = 0; weekday < N_WEEKDAYS; weekday++)
|
||||
{
|
||||
guint event_position;
|
||||
|
||||
if (!g_ptr_array_find (self->events[weekday], removed_event, &event_position))
|
||||
continue;
|
||||
|
||||
/* Remove from the current weekday */
|
||||
g_ptr_array_remove_index (self->events[weekday], event_position);
|
||||
|
||||
/* Move remaining events up */
|
||||
move_events_at_column (self, UP, weekday, event_position);
|
||||
}
|
||||
|
||||
/* Check if we eventually can merge events */
|
||||
check_mergeable_events (self);
|
||||
|
||||
/* And also update the overflow labels */
|
||||
update_overflow (self);
|
||||
gtk_filter_list_model_set_model (self->events_model, model);
|
||||
}
|
||||
|
||||
GList*
|
||||
|
||||
@@ -32,11 +32,8 @@ G_BEGIN_DECLS
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GcalWeekHeader, gcal_week_header, GCAL, WEEK_HEADER, GtkWidget)
|
||||
|
||||
void gcal_week_header_add_event (GcalWeekHeader *self,
|
||||
GcalEvent *event);
|
||||
|
||||
void gcal_week_header_remove_event (GcalWeekHeader *self,
|
||||
const gchar *uuid);
|
||||
void gcal_week_header_set_model (GcalWeekHeader *self,
|
||||
GListModel *model);
|
||||
|
||||
GList* gcal_week_header_get_children_by_uuid (GcalWeekHeader *self,
|
||||
GcalRecurrenceModType mod,
|
||||
|
||||
@@ -498,9 +498,7 @@ gcal_week_view_add_event (GcalTimelineSubscriber *subscriber,
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
if (gcal_event_is_multiday (event) || gcal_event_get_all_day (event))
|
||||
gcal_week_header_add_event (GCAL_WEEK_HEADER (self->header), event);
|
||||
else
|
||||
if (!gcal_event_is_multiday (event) && !gcal_event_get_all_day (event))
|
||||
gcal_week_grid_add_event (GCAL_WEEK_GRID (self->week_grid), event);
|
||||
|
||||
GCAL_EXIT;
|
||||
@@ -517,7 +515,6 @@ gcal_week_view_update_event (GcalTimelineSubscriber *subscriber,
|
||||
GCAL_ENTRY;
|
||||
|
||||
event_id = gcal_event_get_uid (old_event);
|
||||
gcal_week_header_remove_event (GCAL_WEEK_HEADER (self->header), event_id);
|
||||
gcal_week_grid_remove_event (GCAL_WEEK_GRID (self->week_grid), event_id);
|
||||
|
||||
gcal_week_view_add_event (subscriber, event);
|
||||
@@ -534,12 +531,26 @@ gcal_week_view_remove_event (GcalTimelineSubscriber *subscriber,
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
gcal_week_header_remove_event (GCAL_WEEK_HEADER (self->header), uuid);
|
||||
gcal_week_grid_remove_event (GCAL_WEEK_GRID (self->week_grid), uuid);
|
||||
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_week_view_set_model (GcalTimelineSubscriber *subscriber,
|
||||
GListModel *model)
|
||||
{
|
||||
GcalWeekView *self;
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
self = GCAL_WEEK_VIEW (subscriber);
|
||||
|
||||
gcal_week_header_set_model (GCAL_WEEK_HEADER (self->header), model);
|
||||
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_timeline_subscriber_interface_init (GcalTimelineSubscriberInterface *iface)
|
||||
{
|
||||
@@ -547,6 +558,7 @@ gcal_timeline_subscriber_interface_init (GcalTimelineSubscriberInterface *iface)
|
||||
iface->add_event = gcal_week_view_add_event;
|
||||
iface->update_event = gcal_week_view_update_event;
|
||||
iface->remove_event = gcal_week_view_remove_event;
|
||||
iface->set_model = gcal_week_view_set_model;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user