views/month: Port to GListModel
Neutralize the add/remove/update vfuncs (we can't remove them yet). Pass the event model to the individual week rows, and let them filter their events using a GtkFilterListModel. Part-of: <https://gitlab.gnome.org/GNOME/gnome-calendar/-/merge_requests/742>
This commit is contained in:
committed by
Marge Bot
parent
df8033b3ba
commit
039b75755e
@@ -51,15 +51,12 @@ struct _GcalMonthViewRow
|
|||||||
|
|
||||||
GcalRange *range;
|
GcalRange *range;
|
||||||
|
|
||||||
GListStore *events;
|
GListModel *events;
|
||||||
|
|
||||||
GHashTable *layout_blocks;
|
GHashTable *layout_blocks;
|
||||||
gboolean layout_blocks_valid;
|
gboolean layout_blocks_valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
static gint compare_events_cb (gconstpointer a,
|
|
||||||
gconstpointer b,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
static void on_event_widget_activated_cb (GcalEventWidget *widget,
|
static void on_event_widget_activated_cb (GcalEventWidget *widget,
|
||||||
GcalMonthViewRow *self);
|
GcalMonthViewRow *self);
|
||||||
|
|
||||||
@@ -547,7 +544,7 @@ prepare_layout_blocks (GcalMonthViewRow *self,
|
|||||||
|
|
||||||
g_assert (self->layout_blocks_valid);
|
g_assert (self->layout_blocks_valid);
|
||||||
|
|
||||||
n_events = g_list_model_get_n_items (G_LIST_MODEL (self->events));
|
n_events = g_list_model_get_n_items (self->events);
|
||||||
|
|
||||||
for (guint i = 0; i < N_WEEKDAYS; i++)
|
for (guint i = 0; i < N_WEEKDAYS; i++)
|
||||||
{
|
{
|
||||||
@@ -568,7 +565,7 @@ prepare_layout_blocks (GcalMonthViewRow *self,
|
|||||||
g_autoptr (GcalEvent) event = NULL;
|
g_autoptr (GcalEvent) event = NULL;
|
||||||
GPtrArray *blocks;
|
GPtrArray *blocks;
|
||||||
|
|
||||||
event = g_list_model_get_item (G_LIST_MODEL (self->events), i);
|
event = g_list_model_get_item (self->events, i);
|
||||||
|
|
||||||
blocks = g_hash_table_lookup (self->layout_blocks, event);
|
blocks = g_hash_table_lookup (self->layout_blocks, event);
|
||||||
g_assert (blocks != NULL);
|
g_assert (blocks != NULL);
|
||||||
@@ -653,7 +650,7 @@ recalculate_layout_blocks (GcalMonthViewRow *self)
|
|||||||
g_assert (!self->layout_blocks_valid);
|
g_assert (!self->layout_blocks_valid);
|
||||||
|
|
||||||
range_start = gcal_range_get_start (self->range);
|
range_start = gcal_range_get_start (self->range);
|
||||||
n_events = g_list_model_get_n_items (G_LIST_MODEL (self->events));
|
n_events = g_list_model_get_n_items (self->events);
|
||||||
|
|
||||||
g_hash_table_remove_all (self->layout_blocks);
|
g_hash_table_remove_all (self->layout_blocks);
|
||||||
|
|
||||||
@@ -665,7 +662,7 @@ recalculate_layout_blocks (GcalMonthViewRow *self)
|
|||||||
gint first_cell;
|
gint first_cell;
|
||||||
gint last_cell;
|
gint last_cell;
|
||||||
|
|
||||||
event = g_list_model_get_item (G_LIST_MODEL (self->events), i);
|
event = g_list_model_get_item (self->events, i);
|
||||||
|
|
||||||
calculate_event_cells (self, event, &first_cell, &last_cell);
|
calculate_event_cells (self, event, &first_cell, &last_cell);
|
||||||
g_assert (last_cell >= first_cell);
|
g_assert (last_cell >= first_cell);
|
||||||
@@ -770,18 +767,33 @@ invalidate_layout_blocks (GcalMonthViewRow *self)
|
|||||||
* Callbacks
|
* Callbacks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static gint
|
static gboolean
|
||||||
compare_events_cb (gconstpointer a,
|
filter_by_range_cb (GcalEvent *event,
|
||||||
gconstpointer b,
|
GcalRange *row_range,
|
||||||
gpointer user_data)
|
GcalMonthViewRow *self)
|
||||||
{
|
{
|
||||||
GcalEvent *event_a = (GcalEvent *)a;
|
g_assert (GCAL_IS_EVENT (event));
|
||||||
GcalEvent *event_b = (GcalEvent *)b;
|
g_assert (GCAL_IS_MONTH_VIEW_ROW (self));
|
||||||
|
g_assert (self->range == row_range);
|
||||||
|
|
||||||
if (gcal_event_is_multiday (event_a) != gcal_event_is_multiday (event_b))
|
if (!self->range)
|
||||||
return gcal_event_is_multiday (event_b) - gcal_event_is_multiday (event_a);
|
return FALSE;
|
||||||
|
|
||||||
return gcal_event_compare (event_a, event_b);
|
return gcal_event_overlaps (event, self->range);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
events_changed_cb (GListModel *model,
|
||||||
|
guint position,
|
||||||
|
guint removed,
|
||||||
|
guint added,
|
||||||
|
GcalMonthViewRow *self)
|
||||||
|
{
|
||||||
|
GCAL_ENTRY;
|
||||||
|
|
||||||
|
invalidate_layout_blocks (self);
|
||||||
|
|
||||||
|
GCAL_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1015,14 +1027,14 @@ gcal_month_view_row_size_allocate (GtkWidget *widget,
|
|||||||
for (guint i = 0; i < N_WEEKDAYS; i++)
|
for (guint i = 0; i < N_WEEKDAYS; i++)
|
||||||
cell_y[i] = gcal_month_cell_get_header_height (GCAL_MONTH_CELL (self->day_cells[i]));
|
cell_y[i] = gcal_month_cell_get_header_height (GCAL_MONTH_CELL (self->day_cells[i]));
|
||||||
|
|
||||||
n_events = g_list_model_get_n_items (G_LIST_MODEL (self->events));
|
n_events = g_list_model_get_n_items (self->events);
|
||||||
|
|
||||||
for (guint i = 0; i < n_events; i++)
|
for (guint i = 0; i < n_events; i++)
|
||||||
{
|
{
|
||||||
g_autoptr (GcalEvent) event = NULL;
|
g_autoptr (GcalEvent) event = NULL;
|
||||||
GPtrArray *blocks;
|
GPtrArray *blocks;
|
||||||
|
|
||||||
event = g_list_model_get_item (G_LIST_MODEL (self->events), i);
|
event = g_list_model_get_item (self->events, i);
|
||||||
|
|
||||||
blocks = g_hash_table_lookup (self->layout_blocks, event);
|
blocks = g_hash_table_lookup (self->layout_blocks, event);
|
||||||
g_assert (blocks != NULL);
|
g_assert (blocks != NULL);
|
||||||
@@ -1130,7 +1142,11 @@ gcal_month_view_row_class_init (GcalMonthViewRowClass *klass)
|
|||||||
static void
|
static void
|
||||||
gcal_month_view_row_init (GcalMonthViewRow *self)
|
gcal_month_view_row_init (GcalMonthViewRow *self)
|
||||||
{
|
{
|
||||||
self->events = g_list_store_new (GCAL_TYPE_EVENT);
|
self->events = G_LIST_MODEL (gtk_filter_list_model_new (NULL,
|
||||||
|
GTK_FILTER (gtk_custom_filter_new (event_in_range_func, self, NULL))));
|
||||||
|
gtk_filter_list_model_set_incremental (GTK_FILTER_LIST_MODEL (self->events), TRUE);
|
||||||
|
g_signal_connect (self->events, "items-changed", G_CALLBACK (events_changed_cb), self);
|
||||||
|
|
||||||
self->layout_blocks = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_ptr_array_unref);
|
self->layout_blocks = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_ptr_array_unref);
|
||||||
self->layout_blocks_valid = TRUE;
|
self->layout_blocks_valid = TRUE;
|
||||||
|
|
||||||
@@ -1166,6 +1182,7 @@ gcal_month_view_row_set_range (GcalMonthViewRow *self,
|
|||||||
GcalRange *range)
|
GcalRange *range)
|
||||||
{
|
{
|
||||||
g_autoptr (GDateTime) start = NULL;
|
g_autoptr (GDateTime) start = NULL;
|
||||||
|
GtkFilter *filter;
|
||||||
|
|
||||||
g_return_if_fail (GCAL_IS_MONTH_VIEW_ROW (self));
|
g_return_if_fail (GCAL_IS_MONTH_VIEW_ROW (self));
|
||||||
g_return_if_fail (range != NULL);
|
g_return_if_fail (range != NULL);
|
||||||
@@ -1178,10 +1195,10 @@ gcal_month_view_row_set_range (GcalMonthViewRow *self,
|
|||||||
g_clear_pointer (&self->range, gcal_range_unref);
|
g_clear_pointer (&self->range, gcal_range_unref);
|
||||||
self->range = gcal_range_ref (range);
|
self->range = gcal_range_ref (range);
|
||||||
|
|
||||||
/* Preemptively remove all event widgets */
|
/* Refilter */
|
||||||
g_list_store_remove_all (self->events);
|
filter = gtk_filter_list_model_get_filter (GTK_FILTER_LIST_MODEL (self->events));
|
||||||
g_hash_table_remove_all (self->layout_blocks);
|
g_assert (GTK_IS_CUSTOM_FILTER (filter));
|
||||||
invalidate_layout_blocks (self);
|
gtk_filter_changed (filter, GTK_FILTER_CHANGE_DIFFERENT);
|
||||||
|
|
||||||
start = gcal_range_get_start (range);
|
start = gcal_range_get_start (range);
|
||||||
for (guint i = 0; i < N_WEEKDAYS; i++)
|
for (guint i = 0; i < N_WEEKDAYS; i++)
|
||||||
@@ -1194,42 +1211,15 @@ gcal_month_view_row_set_range (GcalMonthViewRow *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gcal_month_view_row_add_event (GcalMonthViewRow *self,
|
gcal_month_view_row_set_model (GcalMonthViewRow *self,
|
||||||
GcalEvent *event)
|
GListModel *model)
|
||||||
{
|
{
|
||||||
g_assert (GCAL_IS_MONTH_VIEW_ROW (self));
|
g_return_if_fail (GCAL_IS_MONTH_VIEW_ROW (self));
|
||||||
g_assert (GCAL_IS_EVENT (event));
|
|
||||||
|
|
||||||
g_list_store_insert_sorted (self->events, event, compare_events_cb, self);
|
gtk_filter_list_model_set_model (GTK_FILTER_LIST_MODEL (self->events), model);
|
||||||
invalidate_layout_blocks (self);
|
invalidate_layout_blocks (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
gcal_month_view_row_remove_event (GcalMonthViewRow *self,
|
|
||||||
GcalEvent *event)
|
|
||||||
{
|
|
||||||
guint position;
|
|
||||||
|
|
||||||
g_assert (GCAL_IS_MONTH_VIEW_ROW (self));
|
|
||||||
g_assert (GCAL_IS_EVENT (event));
|
|
||||||
|
|
||||||
GCAL_ENTRY;
|
|
||||||
|
|
||||||
if (!g_list_store_find (self->events, event, &position))
|
|
||||||
{
|
|
||||||
g_warning ("%s: Widget with uuid: %s not found in view: %s",
|
|
||||||
G_STRFUNC,
|
|
||||||
gcal_event_get_uid (event),
|
|
||||||
G_OBJECT_TYPE_NAME (self));
|
|
||||||
GCAL_RETURN ();
|
|
||||||
}
|
|
||||||
|
|
||||||
g_list_store_remove (self->events, position);
|
|
||||||
invalidate_layout_blocks (self);
|
|
||||||
|
|
||||||
GCAL_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
GList*
|
GList*
|
||||||
gcal_month_view_row_get_children_by_uuid (GcalMonthViewRow *self,
|
gcal_month_view_row_get_children_by_uuid (GcalMonthViewRow *self,
|
||||||
GcalRecurrenceModType mod,
|
GcalRecurrenceModType mod,
|
||||||
|
|||||||
@@ -39,11 +39,8 @@ GcalRange * gcal_month_view_row_get_range (GcalMonthViewR
|
|||||||
void gcal_month_view_row_set_range (GcalMonthViewRow *self,
|
void gcal_month_view_row_set_range (GcalMonthViewRow *self,
|
||||||
GcalRange *range);
|
GcalRange *range);
|
||||||
|
|
||||||
void gcal_month_view_row_add_event (GcalMonthViewRow *self,
|
void gcal_month_view_row_set_model (GcalMonthViewRow *self,
|
||||||
GcalEvent *event);
|
GListModel *model);
|
||||||
|
|
||||||
void gcal_month_view_row_remove_event (GcalMonthViewRow *self,
|
|
||||||
GcalEvent *event);
|
|
||||||
|
|
||||||
GList* gcal_month_view_row_get_children_by_uuid (GcalMonthViewRow *self,
|
GList* gcal_month_view_row_get_children_by_uuid (GcalMonthViewRow *self,
|
||||||
GcalRecurrenceModType mod,
|
GcalRecurrenceModType mod,
|
||||||
|
|||||||
+16
-111
@@ -234,28 +234,6 @@ update_active_date (GcalMonthView *self)
|
|||||||
g_object_notify (G_OBJECT (self), "active-date");
|
g_object_notify (G_OBJECT (self), "active-date");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
add_cached_events_to_row (GcalMonthView *self,
|
|
||||||
GcalMonthViewRow *row)
|
|
||||||
{
|
|
||||||
g_autoptr (GcalRange) row_range = NULL;
|
|
||||||
GHashTableIter iter;
|
|
||||||
GcalEvent *event;
|
|
||||||
|
|
||||||
row_range = gcal_month_view_row_get_range (row);
|
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, self->events);
|
|
||||||
while (g_hash_table_iter_next (&iter, (gpointer *) &event, NULL))
|
|
||||||
{
|
|
||||||
GcalRangeOverlap overlap = gcal_range_calculate_overlap (row_range, gcal_event_get_range (event), NULL);
|
|
||||||
|
|
||||||
if (overlap == GCAL_RANGE_NO_OVERLAP)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
gcal_month_view_row_add_event (row, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
maybe_popdown_overflow_popover (GcalMonthView *self)
|
maybe_popdown_overflow_popover (GcalMonthView *self)
|
||||||
{
|
{
|
||||||
@@ -302,8 +280,6 @@ move_bottom_row_to_top (GcalMonthView *self)
|
|||||||
last_row = g_ptr_array_steal_index (self->week_rows, self->week_rows->len - 1);
|
last_row = g_ptr_array_steal_index (self->week_rows, self->week_rows->len - 1);
|
||||||
gcal_month_view_row_set_range (GCAL_MONTH_VIEW_ROW (last_row), new_range);
|
gcal_month_view_row_set_range (GCAL_MONTH_VIEW_ROW (last_row), new_range);
|
||||||
g_ptr_array_insert (self->week_rows, 0, last_row);
|
g_ptr_array_insert (self->week_rows, 0, last_row);
|
||||||
|
|
||||||
add_cached_events_to_row (self, GCAL_MONTH_VIEW_ROW (last_row));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -336,8 +312,6 @@ move_top_row_to_bottom (GcalMonthView *self)
|
|||||||
first_row = g_ptr_array_steal_index (self->week_rows, 0);
|
first_row = g_ptr_array_steal_index (self->week_rows, 0);
|
||||||
gcal_month_view_row_set_range (GCAL_MONTH_VIEW_ROW (first_row), new_range);
|
gcal_month_view_row_set_range (GCAL_MONTH_VIEW_ROW (first_row), new_range);
|
||||||
g_ptr_array_insert (self->week_rows, -1, first_row);
|
g_ptr_array_insert (self->week_rows, -1, first_row);
|
||||||
|
|
||||||
add_cached_events_to_row (self, GCAL_MONTH_VIEW_ROW (first_row));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@@ -1283,90 +1257,12 @@ static void
|
|||||||
gcal_month_view_add_event (GcalTimelineSubscriber *subscriber,
|
gcal_month_view_add_event (GcalTimelineSubscriber *subscriber,
|
||||||
GcalEvent *event)
|
GcalEvent *event)
|
||||||
{
|
{
|
||||||
GcalMonthView *self;
|
|
||||||
|
|
||||||
GCAL_ENTRY;
|
|
||||||
|
|
||||||
g_assert (event != NULL);
|
|
||||||
|
|
||||||
self = GCAL_MONTH_VIEW (subscriber);
|
|
||||||
|
|
||||||
if (!g_hash_table_add (self->events, g_object_ref (event)))
|
|
||||||
{
|
|
||||||
g_warning ("Event with uuid: %s already added", gcal_event_get_uid (event));
|
|
||||||
GCAL_RETURN ();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (guint i = 0; i < self->week_rows->len; i++)
|
|
||||||
{
|
|
||||||
g_autoptr (GcalRange) row_range = NULL;
|
|
||||||
GcalRangePosition position;
|
|
||||||
GcalRangeOverlap overlap;
|
|
||||||
GcalMonthViewRow *row;
|
|
||||||
|
|
||||||
row = g_ptr_array_index (self->week_rows, i);
|
|
||||||
row_range = gcal_month_view_row_get_range (row);
|
|
||||||
|
|
||||||
overlap = gcal_range_calculate_overlap (row_range, gcal_event_get_range (event), &position);
|
|
||||||
if (overlap != GCAL_RANGE_NO_OVERLAP)
|
|
||||||
{
|
|
||||||
gcal_month_view_row_add_event (row, event);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (position == GCAL_RANGE_AFTER)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GCAL_EXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gcal_month_view_remove_event (GcalTimelineSubscriber *subscriber,
|
gcal_month_view_remove_event (GcalTimelineSubscriber *subscriber,
|
||||||
GcalEvent *event)
|
GcalEvent *event)
|
||||||
{
|
{
|
||||||
g_autoptr (GcalEvent) G_GNUC_UNUSED owned_event = NULL;
|
|
||||||
GcalMonthView *self;
|
|
||||||
|
|
||||||
GCAL_ENTRY;
|
|
||||||
|
|
||||||
g_assert (event != NULL);
|
|
||||||
|
|
||||||
self = GCAL_MONTH_VIEW (subscriber);
|
|
||||||
|
|
||||||
/* Keep event alive while removing it */
|
|
||||||
owned_event = g_object_ref (event);
|
|
||||||
|
|
||||||
if (!g_hash_table_remove (self->events, event))
|
|
||||||
{
|
|
||||||
g_warning ("Event with uuid: %s not in %s", gcal_event_get_uid (event), G_OBJECT_TYPE_NAME (self));
|
|
||||||
GCAL_RETURN ();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (guint i = 0; i < self->week_rows->len; i++)
|
|
||||||
{
|
|
||||||
g_autoptr (GcalRange) row_range = NULL;
|
|
||||||
GcalRangePosition position;
|
|
||||||
GcalRangeOverlap overlap;
|
|
||||||
GcalMonthViewRow *row;
|
|
||||||
|
|
||||||
row = g_ptr_array_index (self->week_rows, i);
|
|
||||||
row_range = gcal_month_view_row_get_range (row);
|
|
||||||
|
|
||||||
overlap = gcal_range_calculate_overlap (row_range, gcal_event_get_range (event), &position);
|
|
||||||
if (overlap != GCAL_RANGE_NO_OVERLAP)
|
|
||||||
{
|
|
||||||
gcal_month_view_row_remove_event (row, event);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (position == GCAL_RANGE_AFTER)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GCAL_EXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1374,12 +1270,24 @@ gcal_month_view_update_event (GcalTimelineSubscriber *subscriber,
|
|||||||
GcalEvent *old_event,
|
GcalEvent *old_event,
|
||||||
GcalEvent *event)
|
GcalEvent *event)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcal_month_view_set_model (GcalTimelineSubscriber *subscriber,
|
||||||
|
GListModel *model)
|
||||||
|
{
|
||||||
|
GcalMonthView *self;
|
||||||
|
|
||||||
GCAL_ENTRY;
|
GCAL_ENTRY;
|
||||||
|
|
||||||
g_assert (event != NULL);
|
self = GCAL_MONTH_VIEW (subscriber);
|
||||||
|
|
||||||
gcal_month_view_remove_event (subscriber, old_event);
|
for (guint i = 0; i < self->week_rows->len; i++)
|
||||||
gcal_month_view_add_event (subscriber, event);
|
{
|
||||||
|
GcalMonthViewRow *row = g_ptr_array_index (self->week_rows, i);
|
||||||
|
|
||||||
|
gcal_month_view_row_set_model (row, model);
|
||||||
|
}
|
||||||
|
|
||||||
GCAL_EXIT;
|
GCAL_EXIT;
|
||||||
}
|
}
|
||||||
@@ -1391,6 +1299,7 @@ gcal_timeline_subscriber_interface_init (GcalTimelineSubscriberInterface *iface)
|
|||||||
iface->add_event = gcal_month_view_add_event;
|
iface->add_event = gcal_month_view_add_event;
|
||||||
iface->update_event = gcal_month_view_update_event;
|
iface->update_event = gcal_month_view_update_event;
|
||||||
iface->remove_event = gcal_month_view_remove_event;
|
iface->remove_event = gcal_month_view_remove_event;
|
||||||
|
iface->set_model = gcal_month_view_set_model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1807,8 +1716,6 @@ gcal_month_view_dispose (GObject *object)
|
|||||||
|
|
||||||
GCAL_ENTRY;
|
GCAL_ENTRY;
|
||||||
|
|
||||||
g_clear_pointer (&self->events, g_hash_table_destroy);
|
|
||||||
|
|
||||||
g_clear_object (&self->kinetic_scroll_animation);
|
g_clear_object (&self->kinetic_scroll_animation);
|
||||||
g_clear_object (&self->row_offset_animation);
|
g_clear_object (&self->row_offset_animation);
|
||||||
|
|
||||||
@@ -1927,8 +1834,6 @@ gcal_month_view_init (GcalMonthView *self)
|
|||||||
{
|
{
|
||||||
g_autoptr (GDateTime) now = NULL;
|
g_autoptr (GDateTime) now = NULL;
|
||||||
|
|
||||||
self->events = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
|
|
||||||
|
|
||||||
gtk_widget_init_template (GTK_WIDGET (self));
|
gtk_widget_init_template (GTK_WIDGET (self));
|
||||||
update_weekday_labels (self);
|
update_weekday_labels (self);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user